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 <common/rs_common_def.h>
25 #include <hisysevent.h>
26 #include <parameters.h>
27 #include <hitrace_meter.h>
28 #include "parameter.h"
29 #include "session/host/include/pc_fold_screen_manager.h"
30 #include "publish/scb_dump_subscriber.h"
31 #include <ui/rs_node.h>
32
33 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
34 #include <display_power_mgr_client.h>
35 #endif
36
37 #ifdef POWER_MANAGER_ENABLE
38 #include <power_mgr_client.h>
39 #endif
40
41 #ifdef RES_SCHED_ENABLE
42 #include "res_type.h"
43 #include "res_sched_client.h"
44 #endif
45 #include "scene_system_ability_listener.h"
46
47 #include "color_parser.h"
48 #include "common/include/session_permission.h"
49 #include "display_manager.h"
50 #include "scene_input_manager.h"
51 #include "session/host/include/main_session.h"
52 #include "session/host/include/scb_system_session.h"
53 #include "session/host/include/scene_persistent_storage.h"
54 #include "session/host/include/session_utils.h"
55 #include "session/host/include/sub_session.h"
56 #include "session_helper.h"
57 #include "window_helper.h"
58 #include "screen_session_manager_client/include/screen_session_manager_client.h"
59 #include "singleton_container.h"
60 #include "xcollie/watchdog.h"
61 #include "session_manager_agent_controller.h"
62 #include "distributed_client.h"
63 #include "softbus_bus_center.h"
64 #include "perform_reporter.h"
65 #include "dms_reporter.h"
66 #include "res_sched_client.h"
67 #include "anomaly_detection.h"
68 #include "session/host/include/ability_info_manager.h"
69 #include "session/host/include/multi_instance_manager.h"
70 #include "common/include/fold_screen_state_internel.h"
71
72 #include "hidump_controller.h"
73
74 #ifdef MEMMGR_WINDOW_ENABLE
75 #include "mem_mgr_client.h"
76 #include "mem_mgr_window_info.h"
77 #endif
78
79 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
80 #include "sec_comp_enhance_kit.h"
81 #endif
82
83 #ifdef IMF_ENABLE
84 #include <input_method_controller.h>
85 #endif // IMF_ENABLE
86
87 namespace OHOS::Rosen {
88 namespace {
89 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
90 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
91 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
92 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
93 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
94 constexpr const char* ATOMIC_SERVICE_SESSION_ID = "com.ohos.param.sessionId";
95 constexpr uint32_t MAX_BRIGHTNESS = 255;
96 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
97 constexpr int32_t SCALE_DIMENSION = 2;
98 constexpr int32_t TRANSLATE_DIMENSION = 2;
99 constexpr int32_t ROTAION_DIMENSION = 4;
100 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
101 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
102 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
103 const std::string EMPTY_DEVICE_ID = "";
104 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
105
106 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
107 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
108 constexpr int VALUE_MAX_WIDTH = 5;
109 constexpr int MAX_RESEND_TIMES = 6;
110 constexpr int ORIEN_MAX_WIDTH = 12;
111 constexpr int OFFSET_MAX_WIDTH = 8;
112 constexpr int SCALE_MAX_WIDTH = 8;
113 constexpr int PID_MAX_WIDTH = 8;
114 constexpr int PARENT_ID_MAX_WIDTH = 6;
115 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
116 constexpr int32_t CANCEL_POINTER_ID = 99999999;
117 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
118 const std::string ARG_DUMP_ALL = "-a";
119 const std::string ARG_DUMP_WINDOW = "-w";
120 const std::string ARG_DUMP_SCREEN = "-s";
121 const std::string ARG_DUMP_DISPLAY = "-d";
122 const std::string ARG_DUMP_PIPLINE = "-p";
123 const std::string ARG_DUMP_SCB = "-b";
124 const std::string ARG_DUMP_DETAIL = "-c";
125 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
126 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
127 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
128 constexpr char SMALL_FOLD_PRODUCT_TYPE = '2';
129 constexpr uint32_t MAX_SUB_WINDOW_LEVEL = 10;
130 constexpr uint64_t VIRTUAL_DISPLAY_ID = 999;
131 constexpr uint32_t DEFAULT_LOCK_SCREEN_ZORDER = 2000;
132 constexpr int32_t MAX_LOCK_STATUS_CACHE_SIZE = 1000;
133 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PC = 50;
134 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PAD = 8;
135 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PHONE = 3;
136 constexpr uint32_t LIFECYCLE_ISOLATE_VERSION = 18;
137 constexpr uint64_t NOTIFY_START_ABILITY_TIMEOUT = 4000;
138 constexpr uint64_t START_UI_ABILITY_TIMEOUT = 3000;
139
140 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
141 {"unspecified", OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
142 {"landscape", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
143 {"portrait", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
144 {"follow_recent", OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
145 {"landscape_inverted", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
146 {"portrait_inverted", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
147 {"auto_rotation", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
148 {"auto_rotation_landscape", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
149 {"auto_rotation_portrait", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
150 {"auto_rotation_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
151 {"auto_rotation_landscape_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
152 {"auto_rotation_portrait_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
153 {"locked", OHOS::AppExecFwk::DisplayOrientation::LOCKED},
154 {"auto_rotation_unspecified", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
155 {"follow_desktop", OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
156 };
157
158 const std::unordered_set<std::string> LAYOUT_INFO_WHITELIST = {
159 "SCBSmartDock",
160 "SCBExtScreenDock",
161 "status_bar_tray",
162 "status_bar_personal",
163 "status_bar_sound_panel",
164 "status_bar_notification_panel",
165 "status_bar_input_panel",
166 "status_bar_control_center",
167 "status_bar_wifi_panel",
168 "status_bar_input_method",
169 "status_bar_assistant_translate",
170 "status_bar_quick_note",
171 "status_bar_bluetooth_panel",
172 "status_bar_battery_panel",
173 "status_bar_focus_mode_paddle",
174 "SCBStatusBar"
175 };
176
177 const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
178
GetCurrentTime()179 std::string GetCurrentTime()
180 {
181 struct timespec tn;
182 clock_gettime(CLOCK_REALTIME, &tn);
183 uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
184 static_cast<uint64_t>(tn.tv_nsec);
185 return std::to_string(uTime);
186 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)187 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
188 {
189 return a.first < b.first;
190 }
191
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)192 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
193 {
194 if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
195 value = (*item.intsValue_)[0];
196 return true;
197 }
198 return false;
199 }
200
GetPid()201 int32_t GetPid()
202 {
203 static int32_t pid = static_cast<int32_t>(getpid());
204 return pid;
205 }
206
GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)207 bool GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
208 {
209 auto& metadata = abilityInfo->metadata;
210 for (const auto& item : metadata) {
211 if (item.name == "enable.remove.starting.window") {
212 TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "enable.remove.starting.window=%{public}s", item.value.c_str());
213 return item.value == "true";
214 }
215 }
216 TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "enable.remove.starting.window default false");
217 return false;
218 }
219
IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName & element,uint32_t callingTokenId,AppExecFwk::ExtensionAbilityType extensionAbilityType)220 bool IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName& element, uint32_t callingTokenId,
221 AppExecFwk::ExtensionAbilityType extensionAbilityType)
222 {
223 TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: bundleName: %{public}s, moduleName: %{public}s, ablilityName: %{public}s",
224 element.GetBundleName().c_str(), element.GetModuleName().c_str(), element.GetAbilityName().c_str());
225 static const std::unordered_set<AppExecFwk::ExtensionAbilityType> extensionAbilityTypeWhitelist = {
226 AppExecFwk::ExtensionAbilityType::LIVEVIEW_LOCKSCREEN
227 };
228 static const std::vector<std::tuple<std::string, std::string, std::string>> elementNameWhitelist = {
229 std::make_tuple("com.huawei.hmos.settings", "AccessibilityReConfirmDialog", "phone_settings"),
230 std::make_tuple("com.huawei.hmos.settings", "AccessibilityShortKeyDialog", "phone_settings"),
231 std::make_tuple("com.huawei.hmos.settings", "DefaultIntentUiExtensionAbility", "phone_settings"),
232 std::make_tuple("com.ohos.sceneboard", "ScbIntentUIExtensionAbility", "phone_sceneboard"),
233 std::make_tuple("com.ohos.sceneboard", "PoweroffAbility", "phone_sceneboard"),
234 std::make_tuple("com.ohos.sceneboard", "com.ohos.sceneboard.MetaBallsAbility", "metaBallsTurbo"),
235 std::make_tuple("com.huawei.hmos.motiongesture", "IntentUIExtensionAbility", "entry"),
236 std::make_tuple("com.ohos.useriam.authwidget", "userauthuiextensionability", "entry"),
237 std::make_tuple("com.ohos.sceneboard", "AodStyleAbility", "phone_sceneboard"),
238 std::make_tuple("com.ohos.sceneboard", "HomeThemeComponentExtAbility", "themecomponent"),
239 std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedResourceAbility", "engineservice"),
240 std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedEditingAbility", "engineservice"),
241 std::make_tuple("com.ohos.sceneboard", "CoverExtensionAbility", "coverthemecomponent"),
242 std::make_tuple("com.huawei.hmos.findservice", "SystemDialogAbility", "entry"),
243 std::make_tuple("com.huawei.hmos.mediacontroller", "UIExtAbility", "phone_deviceswitch"),
244 std::make_tuple("com.huawei.hmos.mediacontroller", "AnahsDialogAbility", "phone_deviceswitch"),
245 std::make_tuple("com.huawei.hmos.security.privacycenter", "SuperPrivacyProtectedAbility", "superprivacy"),
246 std::make_tuple("com.huawei.hmos.security.privacycenter", "PermDisabledReminderAbility", "superprivacy"),
247 std::make_tuple("com.huawei.hmos.audioaccessorymanager", "NearbyAbility", "phone"),
248 std::make_tuple("com.huawei.hmos.wallet", "WalletDialogUIExtensionAbility", "entry"),
249 std::make_tuple("com.huawei.hmos.settings", "WifiWindowSettingsAbility", "pc_settings"),
250 };
251
252 if (extensionAbilityTypeWhitelist.find(extensionAbilityType) != extensionAbilityTypeWhitelist.end()) {
253 TLOGI(WmsLogTag::WMS_UIEXT, "ability in white list");
254 return true;
255 }
256
257 auto it = std::find_if(elementNameWhitelist.begin(), elementNameWhitelist.end(), [&element](const auto& item) {
258 auto& [bundleName, abilityName, _] = item;
259 return (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName);
260 });
261 if (it != elementNameWhitelist.end()) {
262 return true;
263 }
264
265 TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in white list");
266 return SessionPermission::VerifyPermissionByCallerToken(callingTokenId,
267 PermissionConstants::PERMISSION_CALLED_EXTENSION_ON_LOCK_SCREEN);
268 }
269
270 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
271 public:
272 BundleStatusCallback() = default;
273 virtual ~BundleStatusCallback() = default;
274
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)275 void OnBundleStateChanged(const uint8_t installType,
276 const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
277
OnBundleAdded(const std::string & bundleName,const int userId)278 void OnBundleAdded(const std::string& bundleName, const int userId) override
279 {
280 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
281 }
282
OnBundleUpdated(const std::string & bundleName,const int userId)283 void OnBundleUpdated(const std::string& bundleName, const int userId) override
284 {
285 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
286 }
287
OnBundleRemoved(const std::string & bundleName,const int userId)288 void OnBundleRemoved(const std::string& bundleName, const int userId) override
289 {
290 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
291 }
292 };
293
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)294 bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
295 {
296 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
297 !avoidArea.rightRect_.IsUninitializedRect()) {
298 return false;
299 }
300 if (avoidArea.bottomRect_.IsUninitializedRect()) {
301 return true;
302 }
303 auto diff =
304 std::abs(avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) - sessionBottom);
305 return isVisible && diff <= 1;
306 }
307 } // namespace
308
CreateInstance()309 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
310 {
311 sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
312 sessionManager->Init();
313 return sessionManager;
314 }
315
GetInstance()316 SceneSessionManager& SceneSessionManager::GetInstance()
317 {
318 static sptr<SceneSessionManager> instance = CreateInstance();
319 return *instance;
320 }
321
SceneSessionManager()322 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
323 {
324 taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
325 if (!mainHandler_) {
326 auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
327 mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
328 }
329 currentUserId_ = DEFAULT_USERID;
330 launcherService_ = sptr<AppExecFwk::LauncherService>::MakeSptr();
331 if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
332 TLOGE(WmsLogTag::DEFAULT, "Failed to register bundle status callback.");
333 }
334
335 collaboratorDeathRecipient_ = sptr<AgentDeathRecipient>::MakeSptr(
336 [this](const sptr<IRemoteObject>& remoteObject) { this->ClearAllCollaboratorSessions(); });
337
338 scbDumpSubscriber_ = ScbDumpSubscriber::Subscribe();
339
340 listenerController_ = std::make_shared<SessionListenerController>(taskScheduler_);
341 windowFocusController_ = sptr<WindowFocusController>::MakeSptr();
342 ffrtQueueHelper_ = std::make_shared<FfrtQueueHelper>();
343 }
344
~SceneSessionManager()345 SceneSessionManager::~SceneSessionManager()
346 {
347 ScbDumpSubscriber::UnSubscribe(scbDumpSubscriber_);
348 }
349
Init()350 void SceneSessionManager::Init()
351 {
352 bool isScbCoreEnabled = system::GetParameter("persist.window.scbcore.enable", "1") == "1";
353 Session::SetScbCoreEnabled(isScbCoreEnabled);
354 bool isBackgroundWindowNotifyEnabled = system::GetParameter("persist.window.background.notify.enable", "0") == "1";
355 Session::SetBackgroundUpdateRectNotifyEnabled(isBackgroundWindowNotifyEnabled);
356
357 constexpr uint64_t interval = 5 * 1000; // 5 second
358 if (HiviewDFX::Watchdog::GetInstance().AddThread(
359 SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
360 TLOGW(WmsLogTag::DEFAULT, "Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
361 }
362
363 bundleMgr_ = GetBundleManager();
364
365 // Parse configuration.
366 LoadWindowSceneXml();
367 LoadWindowParameter();
368 InitPrepareTerminateConfig();
369
370 ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(sptr<DisplayChangeListener>::MakeSptr());
371 ScreenSessionManagerClient::GetInstance().RegisterScreenConnectionChangeListener(
372 sptr<ScreenConnectionChangeListener>::MakeSptr());
373
374 // create handler for inner command at server
375 eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
376 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
377 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
378 if (ret != 0) {
379 TLOGW(WmsLogTag::DEFAULT, "Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
380 }
381 taskScheduler_->SetExportHandler(eventHandler_);
382
383 scbSessionHandler_ = sptr<ScbSessionHandler>::MakeSptr();
384 AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
385 StartWindowInfoReportLoop();
386 TLOGI(WmsLogTag::DEFAULT, "SSM init success.");
387
388 RegisterAppListener();
389 openDebugTrace_ = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
390 isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1") == "1";
391
392 // Input init.
393 SceneInputManager::GetInstance().Init();
394 RegisterFlushWindowInfoCallback();
395
396 // MMI window state error check
397 int32_t retCode = MMI::InputManager::GetInstance()->
398 RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
399 this->NotifyWindowStateErrorFromMMI(pid, persistentId);
400 });
401 TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
402
403 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
404 MultiInstanceManager::GetInstance().Init(bundleMgr_, taskScheduler_);
405 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
406 }
407 AbilityInfoManager::GetInstance().Init(bundleMgr_);
408 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
409
410 InitVsyncStation();
411 UpdateDarkColorModeToRS();
412 CreateRootSceneSession();
413 std::shared_ptr<FoldScreenStatusChangeCallback> callback = std::make_shared<FoldScreenStatusChangeCallback>(
414 std::bind(&SceneSessionManager::UpdateSessionCrossAxisState, this, std::placeholders::_1,
415 std::placeholders::_2, std::placeholders::_3));
416 PcFoldScreenManager::GetInstance().RegisterFoldScreenStatusChangeCallback(0, callback);
417
418 InitSnapshotCache();
419 }
420
RegisterFlushWindowInfoCallback()421 void SceneSessionManager::RegisterFlushWindowInfoCallback()
422 {
423 SceneInputManager::GetInstance().
424 RegisterFlushWindowInfoCallback([this]() { FlushWindowInfoToMMI(); });
425 }
426
InitVsyncStation()427 void SceneSessionManager::InitVsyncStation()
428 {
429 NodeId nodeId = 0;
430 vsyncStation_ = std::make_shared<VsyncStation>(nodeId);
431 }
432
InitScheduleUtils()433 void SceneSessionManager::InitScheduleUtils()
434 {
435 #ifdef RES_SCHED_ENABLE
436 SCBThreadInfo threadInfo = {
437 .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
438 .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
439 };
440 std::unordered_map<std::string, std::string> payload {
441 { "pid", threadInfo.scbPid_ },
442 { "tid", threadInfo.scbTid_ },
443 { "uid", threadInfo.scbUid_ },
444 { "bundleName", threadInfo.scbBundleName_ },
445 };
446 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
447 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
448 auto task = [threadInfo = std::move(threadInfo)]() mutable {
449 threadInfo.ssmThreadName_ = "OS_SceneSession";
450 threadInfo.ssmTid_ = std::to_string(gettid());
451 const int32_t userInteraction = 2;
452 std::unordered_map<std::string, std::string> payload{
453 { "pid", threadInfo.scbPid_ },
454 { "tid", threadInfo.ssmTid_ },
455 { "uid", threadInfo.scbUid_ },
456 { "extType", "10002" },
457 { "cgroupPrio", "1" },
458 { "isSa", "0" },
459 { "threadName", threadInfo.ssmThreadName_ }
460 };
461 uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
462 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
463 TLOGNI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
464 sptr<ISystemAbilityManager> systemAbilityManager =
465 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
466 if (!systemAbilityManager) {
467 TLOGNE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
468 return;
469 }
470 auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
471 int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
472 if (ret != ERR_OK) {
473 TLOGNI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
474 }
475 };
476 taskScheduler_->PostAsyncTask(task, "changeQosTask");
477 #endif
478 }
479
UpdateSessionCrossAxisState(DisplayId displayId,SuperFoldStatus status,SuperFoldStatus prevStatus)480 void SceneSessionManager::UpdateSessionCrossAxisState(DisplayId displayId, SuperFoldStatus status,
481 SuperFoldStatus prevStatus)
482 {
483 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
484 for (const auto& [_, sceneSession] : sceneSessionMap_) {
485 if (sceneSession == nullptr) {
486 TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
487 continue;
488 }
489 sceneSession->UpdateCrossAxis();
490 }
491 }
492
RegisterAppListener()493 void SceneSessionManager::RegisterAppListener()
494 {
495 appAnrListener_ = sptr<AppAnrListener>::MakeSptr();
496 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
497 if (appMgrClient == nullptr) {
498 TLOGE(WmsLogTag::DEFAULT, "appMgrClient is nullptr.");
499 } else {
500 auto ret = static_cast<int32_t>(appMgrClient->RegisterAppDebugListener(appAnrListener_));
501 TLOGI(WmsLogTag::DEFAULT, "Register app debug listener, %{public}d.", ret);
502 }
503 }
504
LoadWindowParameter()505 void SceneSessionManager::LoadWindowParameter()
506 {
507 const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "HandsetSmartWindow");
508 if (multiWindowUIType == "HandsetSmartWindow") {
509 systemConfig_.windowUIType_ = WindowUIType::PHONE_WINDOW;
510 } else if (multiWindowUIType == "FreeFormMultiWindow") {
511 systemConfig_.windowUIType_ = WindowUIType::PC_WINDOW;
512 } else if (multiWindowUIType == "TabletSmartWindow") {
513 systemConfig_.windowUIType_ = WindowUIType::PAD_WINDOW;
514 } else {
515 TLOGE(WmsLogTag::DEFAULT, "unknown multiWindowUIType:%{public}s.", multiWindowUIType.c_str());
516 }
517 appWindowSceneConfig_.multiWindowUIType_ = multiWindowUIType;
518 }
519
LoadWindowSceneXml()520 void SceneSessionManager::LoadWindowSceneXml()
521 {
522 if (WindowSceneConfig::LoadConfigXml()) {
523 if (WindowSceneConfig::GetConfig().IsMap()) {
524 WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
525 }
526 ConfigWindowSceneXml();
527 } else {
528 TLOGE(WmsLogTag::DEFAULT, "Load window scene xml failed");
529 }
530 ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
531 appWindowSceneConfig_.keyboardAnimationOut_);
532 }
533
InitPrepareTerminateConfig()534 void SceneSessionManager::InitPrepareTerminateConfig()
535 {
536 char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
537 int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
538 PREPARE_TERMINATE_ENABLE_SIZE);
539 TLOGI(WmsLogTag::DEFAULT, "%{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
540 if (retSysParam > 0 && !std::strcmp(value, "true")) {
541 isPrepareTerminateEnable_ = true;
542 }
543 }
544
ConfigWindowSceneXml()545 void SceneSessionManager::ConfigWindowSceneXml()
546 {
547 const auto& config = WindowSceneConfig::GetConfig();
548 WindowSceneConfig::ConfigItem item = config["windowEffect"];
549 if (item.IsMap()) {
550 ConfigWindowEffect(item);
551 }
552
553 item = config["decor"];
554 if (item.IsMap()) {
555 ConfigDecor(item);
556 }
557
558 item = config["backgroundswitch"];
559 int32_t param = -1;
560 systemConfig_.backgroundswitch = GetSingleIntItem(item, param) && param == 1;
561 TLOGD(WmsLogTag::DEFAULT, "Load backgroundswitch %{public}d", systemConfig_.backgroundswitch);
562 item = config["defaultWindowMode"];
563 if (GetSingleIntItem(item, param) &&
564 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
565 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
566 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
567 }
568 item = config["defaultMaximizeMode"];
569 if (GetSingleIntItem(item, param) &&
570 (param == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
571 param == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
572 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(param);
573 }
574 item = config["keyboardAnimation"];
575 if (item.IsMap()) {
576 ConfigKeyboardAnimation(item);
577 }
578 item = config["maxFloatingWindowSize"];
579 if (GetSingleIntItem(item, param)) {
580 systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(param);
581 }
582 item = config["windowAnimation"];
583 if (item.IsMap()) {
584 ConfigWindowAnimation(item);
585 }
586 item = config["startWindowTransitionAnimation"];
587 if (item.IsMap()) {
588 ConfigStartingWindowAnimation(item);
589 }
590 ConfigFreeMultiWindow();
591 ConfigWindowSizeLimits();
592 ConfigSnapshotScale();
593 ConfigWindowSceneXml(config);
594 }
595
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)596 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
597 {
598 WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
599 if (item.IsMap()) {
600 ConfigSystemUIStatusBar(item);
601 }
602 item = config["backgroundScreenLock"].GetProp("enable");
603 if (item.IsBool()) {
604 appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
605 }
606 item = config["rotationMode"];
607 if (item.IsString()) {
608 appWindowSceneConfig_.rotationMode_ = item.stringValue_;
609 }
610 item = config["immersive"];
611 if (item.IsMap()) {
612 ConfigWindowImmersive(item);
613 }
614 item = config["supportTypeFloatWindow"].GetProp("enable");
615 if (item.IsBool()) {
616 systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
617 }
618 item = config["singleHandCompatibleMode"];
619 if (item.IsMap()) {
620 ConfigSingleHandCompatibleMode(item);
621 }
622 }
623
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)624 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
625 {
626 AppWindowSceneConfig config;
627 WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
628 if (item.IsMap()) {
629 if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
630 appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
631 config.windowImmersive_.desktopStatusBarConfig_;
632 }
633 }
634 item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
635 if (item.IsMap()) {
636 if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
637 appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
638 config.windowImmersive_.upDownStatusBarConfig_;
639 }
640 }
641 item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
642 if (item.IsMap()) {
643 if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
644 appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
645 config.windowImmersive_.leftRightStatusBarConfig_;
646 }
647 }
648 }
649
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)650 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
651 StatusBarConfig& statusBarConfig)
652 {
653 WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
654 if (item.IsBool()) {
655 statusBarConfig.showHide_ = item.boolValue_;
656 }
657 item = config["contentColor"];
658 if (item.IsString()) {
659 statusBarConfig.contentColor_ = item.stringValue_;
660 }
661 item = config["backgroundColor"];
662 if (item.IsString()) {
663 statusBarConfig.backgroundColor_ = item.stringValue_;
664 }
665 return true;
666 }
667
ConfigFreeMultiWindow()668 void SceneSessionManager::ConfigFreeMultiWindow()
669 {
670 const auto& config = WindowSceneConfig::GetConfig();
671 WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
672 if (freeMultiWindowConfig.IsMap()) {
673 auto supportItem = freeMultiWindowConfig.GetProp("enable");
674 if (supportItem.IsBool()) {
675 systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
676 }
677 auto item = freeMultiWindowConfig["decor"];
678 if (item.IsMap()) {
679 ConfigDecor(item, false);
680 }
681 int32_t param = -1;
682 item = freeMultiWindowConfig["defaultWindowMode"];
683 if (GetSingleIntItem(item, param) &&
684 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
685 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
686 systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
687 static_cast<WindowMode>(static_cast<uint32_t>(param));
688 }
689 item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
690 if (GetSingleIntItem(item, param) && (param > 0)) {
691 systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
692 }
693 }
694 }
695
LoadFreeMultiWindowConfig(bool enable)696 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
697 {
698 FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
699 if (enable) {
700 systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
701 systemConfig_.decorWindowModeSupportType_ = freeMultiWindowConfig.decorWindowModeSupportType_;
702 systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
703 } else {
704 const auto& config = WindowSceneConfig::GetConfig();
705 auto item = config["decor"];
706 if (item.IsMap()) {
707 ConfigDecor(item, true);
708 }
709 int32_t param = -1;
710 item = config["defaultWindowMode"];
711 if (GetSingleIntItem(item, param) &&
712 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
713 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
714 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
715 }
716 }
717 systemConfig_.freeMultiWindowEnable_ = enable;
718 rsInterface_.SetFreeMultiWindowStatus(enable);
719 }
720
GetSystemSessionConfig() const721 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
722 {
723 return systemConfig_;
724 }
725
SwitchFreeMultiWindow(bool enable)726 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
727 {
728 if (!systemConfig_.freeMultiWindowSupport_) {
729 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "device not support");
730 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
731 }
732 LoadFreeMultiWindowConfig(enable);
733 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
734 for (const auto& [_, sceneSession] : sceneSessionMap_) {
735 if (sceneSession == nullptr) {
736 continue;
737 }
738 sceneSession->SwitchFreeMultiWindow(enable);
739 }
740 WindowStyleType type = enable ?
741 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
742 SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
743 return WSError::WS_OK;
744 }
745
GetFreeMultiWindowEnableState(bool & enable)746 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
747 {
748 enable = systemConfig_.freeMultiWindowEnable_;
749 return WSError::WS_OK;
750 }
751
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)752 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject>& token,
753 const ContinueState& continueState)
754 {
755 TLOGI(WmsLogTag::WMS_LIFE, "in");
756 int32_t callingUid = IPCSkeleton::GetCallingUid();
757 return taskScheduler_->PostSyncTask([this, token, continueState, callingUid, where = __func__] {
758 sptr <SceneSession> sceneSession = FindSessionByToken(token);
759 if (sceneSession == nullptr) {
760 TLOGNE(WmsLogTag::DEFAULT, "fail to find session by token.");
761 return WSError::WS_ERROR_INVALID_PARAM;
762 }
763 sceneSession->SetSessionInfoContinueState(continueState);
764 DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
765 static_cast<AAFwk::ContinueState>(continueState), callingUid);
766 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: id:%{public}d, continueState:%{public}d",
767 where, sceneSession->GetPersistentId(), continueState);
768 return WSError::WS_OK;
769 }, __func__);
770 }
771
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)772 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
773 {
774 WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
775 if (item.IsBool()) {
776 if (mainConfig) {
777 systemConfig_.isSystemDecorEnable_ = item.boolValue_;
778 } else {
779 systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
780 }
781 bool decorEnable = item.boolValue_;
782 uint32_t support = 0;
783 std::vector<std::string> supportedModes;
784 item = decorConfig["supportedMode"];
785 if (item.IsStrings()) {
786 supportedModes = *item.stringsValue_;
787 }
788 for (auto mode : supportedModes) {
789 if (mode == "fullscreen") {
790 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
791 } else if (mode == "floating") {
792 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
793 } else if (mode == "pip") {
794 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
795 } else if (mode == "split") {
796 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
797 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
798 } else {
799 TLOGW(WmsLogTag::DEFAULT, "Invalid supporedMode");
800 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
801 break;
802 }
803 }
804 if (mainConfig && item.IsStrings()) {
805 systemConfig_.decorWindowModeSupportType_ = support;
806 }
807 if (!mainConfig && item.IsStrings()) {
808 systemConfig_.freeMultiWindowConfig_.decorWindowModeSupportType_ = support;
809 }
810 }
811 }
812
AddAlphaToColor(float alpha,std::string & color)813 static void AddAlphaToColor(float alpha, std::string& color)
814 {
815 if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
816 return;
817 }
818
819 uint32_t alphaValue = 0xFF * alpha;
820 std::ostringstream ss;
821 ss << std::hex << alphaValue;
822 std::string strAlpha = ss.str();
823 if (strAlpha.size() == 1) {
824 strAlpha.append(1, '0');
825 }
826
827 color.insert(1, strAlpha);
828 }
829
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)830 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
831 {
832 return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
833 (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) == AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
834 }
835
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)836 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
837 {
838 AppWindowSceneConfig config;
839 // config corner radius
840 WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
841 if (item.IsMap()) {
842 if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
843 appWindowSceneConfig_ = config;
844 }
845 }
846
847 // config shadow
848 item = effectConfig["appWindows"]["shadow"]["focused"];
849 if (item.IsMap()) {
850 if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
851 appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
852 }
853 }
854 item = effectConfig["appWindows"]["shadow"]["unfocused"];
855 if (item.IsMap()) {
856 if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
857 appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
858 }
859 }
860 AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
861 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
862
863 // config shadow in dark mode
864 item = effectConfig["appWindows"]["shadowDark"]["focused"];
865 if (item.IsMap()) {
866 if (ConfigAppWindowShadow(item, config.focusedShadowDark_)) {
867 appWindowSceneConfig_.focusedShadowDark_ = config.focusedShadowDark_;
868 }
869 }
870 item = effectConfig["appWindows"]["shadowDark"]["unfocused"];
871 if (item.IsMap()) {
872 if (ConfigAppWindowShadow(item, config.unfocusedShadowDark_)) {
873 appWindowSceneConfig_.unfocusedShadowDark_ = config.unfocusedShadowDark_;
874 }
875 }
876 AddAlphaToColor(appWindowSceneConfig_.focusedShadowDark_.alpha_, appWindowSceneConfig_.focusedShadowDark_.color_);
877 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadowDark_.alpha_,
878 appWindowSceneConfig_.unfocusedShadowDark_.color_);
879
880 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "successfully");
881 }
882
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)883 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
884 {
885 static const std::unordered_map<std::string, float> stringToCornerRadius = {
886 {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
887 {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
888 };
889
890 if (item.IsString()) {
891 auto value = item.stringValue_;
892 if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
893 out = stringToCornerRadius.at(value);
894 return true;
895 }
896 }
897 return false;
898 }
899
SetEnableInputEvent(bool enabled)900 void SceneSessionManager::SetEnableInputEvent(bool enabled)
901 {
902 TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
903 enableInputEvent_ = enabled;
904 }
905
IsInputEventEnabled() const906 bool SceneSessionManager::IsInputEventEnabled() const
907 {
908 return enableInputEvent_;
909 }
910
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)911 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
912 {
913 for (const auto persistentId : alivePersistentIds_) {
914 if (std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId) !=
915 recoveredPersistentIds.end()) {
916 continue;
917 }
918 auto sceneSession = GetSceneSession(persistentId);
919 if (sceneSession == nullptr) {
920 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
921 continue;
922 }
923 if (sceneSession->IsRecovered()) {
924 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
925 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
926 visibleWindowCountMap_.erase(sceneSession->GetCallingPid());
927 EraseSceneSessionAndMarkDirtyLocked(persistentId);
928 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
929 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
930 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
931 }
932 }
933 }
934 }
935
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)936 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
937 {
938 TLOGI(WmsLogTag::WMS_RECOVER, "persistentIds recovered=%{public}zu. CurrentUserId=%{public}d",
939 recoveredPersistentIds.size(), currentUserId_.load());
940
941 taskScheduler_->PostAsyncTask([this, recoveredPersistentIds]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
942 ClearUnrecoveredSessions(recoveredPersistentIds);
943 std::list<AAFwk::SessionInfo> abilitySessionInfos;
944 for (const auto persistentId : recoveredPersistentIds) {
945 if (failRecoveredPersistentIdSet_.count(persistentId)) {
946 TLOGNI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId=%{public}d, continue", persistentId);
947 continue;
948 }
949 auto sceneSession = GetSceneSession(persistentId);
950 if (sceneSession == nullptr) {
951 TLOGNE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
952 continue;
953 }
954 const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
955 TLOGND(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d", persistentId);
956 abilitySessionInfos.emplace_back(*abilitySessionInfo);
957 }
958 std::vector<int32_t> unrecoverableSessionIds;
959 AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
960 abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
961 TLOGNI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds=%{public}zu",
962 unrecoverableSessionIds.size());
963 for (const auto sessionId : unrecoverableSessionIds) {
964 auto sceneSession = GetSceneSession(sessionId);
965 if (sceneSession == nullptr) {
966 TLOGNW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId=%{public}d ",
967 sessionId);
968 continue;
969 }
970 const auto& sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
971 TLOGNI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId=%{public}d", sessionId);
972 ExceptionInfo exceptionInfo;
973 sceneSession->NotifySessionExceptionInner(sceneSessionInfo, exceptionInfo);
974 }
975 RemoveFailRecoveredSession();
976 }, __func__);
977 }
978
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)979 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
980 WindowShadowConfig& outShadow)
981 {
982 WindowSceneConfig::ConfigItem item = shadowConfig["color"];
983 if (item.IsString()) {
984 auto color = item.stringValue_;
985 uint32_t colorValue;
986 if (!ColorParser::Parse(color, colorValue)) {
987 return false;
988 }
989 outShadow.color_ = color;
990 }
991
992 item = shadowConfig["offsetX"];
993 if (item.IsFloats()) {
994 auto offsetX = *item.floatsValue_;
995 if (offsetX.size() != 1) {
996 return false;
997 }
998 outShadow.offsetX_ = offsetX[0];
999 }
1000
1001 item = shadowConfig["offsetY"];
1002 if (item.IsFloats()) {
1003 auto offsetY = *item.floatsValue_;
1004 if (offsetY.size() != 1) {
1005 return false;
1006 }
1007 outShadow.offsetY_ = offsetY[0];
1008 }
1009
1010 item = shadowConfig["alpha"];
1011 if (item.IsFloats()) {
1012 auto alpha = *item.floatsValue_;
1013 if (alpha.size() != 1 ||
1014 (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
1015 return false;
1016 }
1017 outShadow.alpha_ = alpha[0];
1018 }
1019
1020 item = shadowConfig["radius"];
1021 if (item.IsFloats()) {
1022 auto radius = *item.floatsValue_;
1023 if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
1024 return false;
1025 }
1026 outShadow.radius_ = radius[0];
1027 }
1028
1029 return true;
1030 }
1031
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)1032 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
1033 KeyboardSceneAnimationConfig& config)
1034 {
1035 if (item.IsMap() && item.mapValue_->count("curve")) {
1036 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1037 config.curveType_ = curveType;
1038 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1039 config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1040 config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1041 config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1042 config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1043 }
1044 }
1045
1046 const WindowSceneConfig::ConfigItem& duration = item["duration"];
1047 if (duration.IsInts()) {
1048 auto numbers = *duration.intsValue_;
1049 if (numbers.size() == 1) {
1050 config.duration_ = static_cast<uint32_t>(numbers[0]);
1051 }
1052 }
1053 }
1054
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)1055 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
1056 {
1057 LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
1058 LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
1059
1060 // config system animation
1061 const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
1062 systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
1063 {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
1064 appConfigIn.duration_);
1065 const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
1066 systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
1067 {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
1068 appConfigOut.duration_);
1069 }
1070
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)1071 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
1072 KeyboardSceneAnimationConfig& animationOut)
1073 {
1074 if (!systemConfig_.animationIn_.curveType_.empty() && !systemConfig_.animationOut_.curveType_.empty()) {
1075 TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
1076 "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
1077 systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
1078 systemConfig_.animationOut_.duration_);
1079 return;
1080 }
1081
1082 // default animation curve params
1083 constexpr char CURVETYPE[] = "interpolatingSpring";
1084 constexpr float IN_CTRLX1 = 0.0f;
1085 constexpr float OUT_CTRLX1 = 4.0f;
1086 constexpr float CTRLY1 = 1.0f;
1087 constexpr float CTRLX2 = 342.0f;
1088 constexpr float CTRLY2 = 37.0f;
1089 constexpr uint32_t DURATION = 150;
1090
1091 if (systemConfig_.animationIn_.curveType_.empty()) {
1092 std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1093 // update system config for client
1094 systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
1095 // update app config for server
1096 animationIn.curveType_ = CURVETYPE;
1097 animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
1098 animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
1099 animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
1100 animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
1101 animationIn.duration_ = DURATION;
1102 TLOGI(WmsLogTag::WMS_KEYBOARD, "config default animationIn");
1103 }
1104
1105 if (systemConfig_.animationOut_.curveType_.empty()) {
1106 std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1107 // update system config for client
1108 systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
1109 // update app config for server
1110 animationOut.curveType_ = CURVETYPE;
1111 animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
1112 animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
1113 animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
1114 animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
1115 animationOut.duration_ = DURATION;
1116 TLOGI(WmsLogTag::WMS_KEYBOARD, "config default animationOut");
1117 }
1118 }
1119
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)1120 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
1121 {
1122 WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
1123 if (item.IsMap() && item.mapValue_->count("curve")) {
1124 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1125 appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
1126 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1127 appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1128 appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1129 appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1130 appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1131 }
1132 }
1133 item = windowAnimationConfig["timing"]["duration"];
1134 if (item.IsInts() && item.intsValue_->size() == 1) {
1135 auto duration = *item.intsValue_;
1136 appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
1137 }
1138 item = windowAnimationConfig["scale"];
1139 if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
1140 auto scales = *item.floatsValue_;
1141 appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
1142 appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
1143 }
1144 item = windowAnimationConfig["rotation"];
1145 if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
1146 auto rotations = *item.floatsValue_;
1147 appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
1148 appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
1149 appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
1150 appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1151 }
1152 item = windowAnimationConfig["translate"];
1153 if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1154 auto translates = *item.floatsValue_;
1155 appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1156 appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1157 }
1158 item = windowAnimationConfig["opacity"];
1159 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1160 auto opacity = *item.floatsValue_;
1161 appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1162 }
1163 }
1164
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)1165 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1166 {
1167 auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1168 auto item = configItem.GetProp("enable");
1169 if (item.IsBool()) {
1170 config.enabled_ = item.boolValue_;
1171 }
1172 item = configItem["timing"];
1173 if (item.IsMap() && item.mapValue_->count("curve")) {
1174 config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1175 }
1176 item = configItem["timing"]["duration"];
1177 if (item.IsInts() && item.intsValue_->size() == 1) {
1178 config.duration_ = (*item.intsValue_)[0];
1179 }
1180 item = configItem["opacityStart"];
1181 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1182 config.opacityStart_ = (*item.floatsValue_)[0];
1183 }
1184 item = configItem["opacityEnd"];
1185 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1186 config.opacityEnd_ = (*item.floatsValue_)[0];
1187 }
1188 }
1189
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)1190 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1191 const WindowSceneConfig::ConfigItem& curveConfig)
1192 {
1193 static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1194 "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1195 static std::unordered_set<std::string> paramCurveSet = {
1196 "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1197
1198 std::string curveName = "easeOut";
1199 const auto& nameItem = curveConfig.GetProp("name");
1200 if (!nameItem.IsString()) {
1201 return {curveName, {}};
1202 }
1203
1204 std::string name = nameItem.stringValue_;
1205 std::vector<float> curveParams;
1206
1207 if (paramCurveSet.find(name) != paramCurveSet.end()) {
1208 curveName = name;
1209 curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1210 if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1211 std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1212 curveParams.begin());
1213 }
1214 } else {
1215 auto iter = curveSet.find(name);
1216 if (iter != curveSet.end()) {
1217 curveName = name;
1218 }
1219 }
1220
1221 return {curveName, curveParams};
1222 }
1223
1224
ConfigSingleHandCompatibleMode(const WindowSceneConfig::ConfigItem & configItem)1225 void SceneSessionManager::ConfigSingleHandCompatibleMode(const WindowSceneConfig::ConfigItem& configItem)
1226 {
1227 auto& config = singleHandCompatibleModeConfig_;
1228 auto item = configItem.GetProp("enable");
1229 if (item.IsBool()) {
1230 config.enabled = item.boolValue_;
1231 }
1232 item = configItem["singleHandScale"];
1233 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1234 config.singleHandScale = (*item.floatsValue_)[0];
1235 }
1236 item = configItem["heightChangeRatio"];
1237 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1238 config.heightChangeRatio = (*item.floatsValue_)[0];
1239 }
1240 item = configItem["widthChangeRatio"];
1241 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1242 config.widthChangeRatio = (*item.floatsValue_)[0];
1243 }
1244 }
1245
1246
ConfigWindowSizeLimits()1247 void SceneSessionManager::ConfigWindowSizeLimits()
1248 {
1249 const auto& config = WindowSceneConfig::GetConfig();
1250 WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1251 if (item.IsMap()) {
1252 ConfigMainWindowSizeLimits(item);
1253 }
1254
1255 item = config["subWindowSizeLimits"];
1256 if (item.IsMap()) {
1257 ConfigSubWindowSizeLimits(item);
1258 }
1259
1260 item = config["dialogWindowSizeLimits"];
1261 if (item.IsMap()) {
1262 ConfigDialogWindowSizeLimits(item);
1263 }
1264 }
1265
ConfigDialogWindowSizeLimits(const WindowSceneConfig::ConfigItem & dialogWindowSizeConifg)1266 void SceneSessionManager::ConfigDialogWindowSizeLimits(const WindowSceneConfig::ConfigItem& dialogWindowSizeConifg)
1267 {
1268 auto item = dialogWindowSizeConifg["miniWidth"];
1269 if (item.IsInts()) {
1270 auto numbers = *item.intsValue_;
1271 if (numbers.size() == 1) {
1272 systemConfig_.miniWidthOfDialogWindow_ = static_cast<uint32_t>(numbers[0]);
1273 }
1274 }
1275
1276 item = dialogWindowSizeConifg["miniHeight"];
1277 if (item.IsInts()) {
1278 auto numbers = *item.intsValue_;
1279 if (numbers.size() == 1) {
1280 systemConfig_.miniHeightOfDialogWindow_ = static_cast<uint32_t>(numbers[0]);
1281 }
1282 }
1283 }
1284
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1285 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1286 {
1287 auto item = mainWindowSizeConifg["miniWidth"];
1288 if (item.IsInts()) {
1289 auto numbers = *item.intsValue_;
1290 if (numbers.size() == 1) {
1291 systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1292 }
1293 }
1294
1295 item = mainWindowSizeConifg["miniHeight"];
1296 if (item.IsInts()) {
1297 auto numbers = *item.intsValue_;
1298 if (numbers.size() == 1) {
1299 systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1300 }
1301 }
1302 }
1303
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1304 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1305 {
1306 auto item = subWindowSizeConifg["miniWidth"];
1307 if (item.IsInts()) {
1308 auto numbers = *item.intsValue_;
1309 if (numbers.size() == 1) {
1310 systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1311 }
1312 }
1313
1314 item = subWindowSizeConifg["miniHeight"];
1315 if (item.IsInts()) {
1316 auto numbers = *item.intsValue_;
1317 if (numbers.size() == 1) {
1318 systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1319 }
1320 }
1321 }
1322
ConfigSnapshotScale()1323 void SceneSessionManager::ConfigSnapshotScale()
1324 {
1325 const auto& config = WindowSceneConfig::GetConfig();
1326 WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1327 if (item.IsFloats()) {
1328 auto snapshotScale = *item.floatsValue_;
1329 if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1330 return;
1331 }
1332 snapshotScale_ = snapshotScale[0];
1333 }
1334 }
1335
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1336 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1337 {
1338 TLOGI(WmsLogTag::WMS_IMMS, "load");
1339 WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1340 if (item.IsInts() && item.intsValue_->size() == 1) {
1341 bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1342 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1343 TLOGI(WmsLogTag::WMS_IMMS, "showInLandscapeMode %{public}d",
1344 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1345 }
1346
1347 item = statusBarConfig["immersiveStatusBarBgColor"];
1348 if (item.IsString()) {
1349 auto color = item.stringValue_;
1350 uint32_t colorValue;
1351 if (!ColorParser::Parse(color, colorValue)) {
1352 return;
1353 }
1354 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1355 TLOGI(WmsLogTag::WMS_IMMS, "immersiveStatusBarBgColor %{public}s",
1356 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1357 }
1358
1359 item = statusBarConfig["immersiveStatusBarContentColor"];
1360 if (item.IsString()) {
1361 auto color = item.stringValue_;
1362 uint32_t colorValue;
1363 if (!ColorParser::Parse(color, colorValue)) {
1364 return;
1365 }
1366 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1367 TLOGI(WmsLogTag::WMS_IMMS, "immersiveStatusBarContentColor %{public}s",
1368 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1369 }
1370 }
1371
ConfigSupportFollowParentWindowLayout()1372 void SceneSessionManager::ConfigSupportFollowParentWindowLayout()
1373 {
1374 TLOGI(WmsLogTag::WMS_SUB, "support");
1375 auto task = [this] {
1376 systemConfig_.supportFollowParentWindowLayout_ = true;
1377 };
1378 taskScheduler_->PostAsyncTask(task, "ConfigSupportFollowParentWindowLayout");
1379 }
1380
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1381 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1382 {
1383 rootSceneContextWeak_ = contextWeak;
1384 }
1385
CreateRootSceneSession()1386 void SceneSessionManager::CreateRootSceneSession()
1387 {
1388 system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1389 auto specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1390 specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1391 return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1392 };
1393 specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1394 return this->GetSceneSessionVectorByType(type);
1395 };
1396 specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1397 return this->GetAINavigationBarArea(displayId);
1398 };
1399 specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1400 this->UpdateAvoidArea(persistentId);
1401 };
1402 specificCb->onNotifyAvoidAreaChange_ = [this](const sptr<AvoidArea>& avoidArea, AvoidAreaType type) {
1403 onNotifyAvoidAreaChangeForRootFunc_(avoidArea, type);
1404 };
1405 rootSceneSession_ = sptr<RootSceneSession>::MakeSptr(specificCb);
1406 rootSceneSession_->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1407 rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1408 AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1409 rootSceneSession_->RegisterGetStatusBarAvoidHeightFunc([this](WSRect& barArea) {
1410 return this->GetStatusBarAvoidHeight(barArea);
1411 });
1412 rootSceneSession_->RegisterGetStatusBarConstantlyShowFunc([this](DisplayId displayId, bool& isVisible) {
1413 return this->GetStatusBarConstantlyShow(displayId, isVisible);
1414 });
1415 }
1416
GetRootSceneSession()1417 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1418 {
1419 return rootSceneSession_;
1420 }
1421
UpdateRootSceneAvoidArea()1422 void SceneSessionManager::UpdateRootSceneAvoidArea()
1423 {
1424 UpdateAvoidArea(rootSceneSession_->GetPersistentId());
1425 }
1426
RegisterNotifyRootSceneAvoidAreaChangeFunc(NotifyRootSceneAvoidAreaChangeFunc && func)1427 void SceneSessionManager::RegisterNotifyRootSceneAvoidAreaChangeFunc(NotifyRootSceneAvoidAreaChangeFunc&& func)
1428 {
1429 onNotifyAvoidAreaChangeForRootFunc_ = std::move(func);
1430 }
1431
RegisterNotifyRootSceneOccupiedAreaChangeFunc(NotifyRootSceneOccupiedAreaChangeFunc && func)1432 void SceneSessionManager::RegisterNotifyRootSceneOccupiedAreaChangeFunc(NotifyRootSceneOccupiedAreaChangeFunc&& func)
1433 {
1434 onNotifyOccupiedAreaChangeForRootFunc_ = std::move(func);
1435 }
1436
GetRootSessionAvoidAreaByType(AvoidAreaType type)1437 AvoidArea SceneSessionManager::GetRootSessionAvoidAreaByType(AvoidAreaType type)
1438 {
1439 if (auto rootSession = GetRootSceneSession()) {
1440 return rootSession->GetAvoidAreaByType(type);
1441 }
1442 return {};
1443 }
1444
GetSceneSession(int32_t persistentId)1445 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1446 {
1447 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1448 if (auto it = sceneSessionMap_.find(persistentId); it != sceneSessionMap_.end()) {
1449 return it->second;
1450 }
1451 TLOGD(WmsLogTag::DEFAULT, "Not found scene session with id: %{public}d", persistentId);
1452 return nullptr;
1453 }
1454
IsMainWindowByPersistentId(int32_t persistentId)1455 bool SceneSessionManager::IsMainWindowByPersistentId(int32_t persistentId)
1456 {
1457 if (persistentId <= INVALID_SESSION_ID) {
1458 return false;
1459 }
1460 if (auto sceneSession = GetSceneSession(persistentId)) {
1461 return SessionHelper::IsMainWindow(sceneSession->GetWindowType());
1462 }
1463 return false;
1464 }
1465
GetMainSessionByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::vector<sptr<SceneSession>> & mainSessions)1466 void SceneSessionManager::GetMainSessionByBundleNameAndAppIndex(
1467 const std::string& bundleName, int32_t appIndex, std::vector<sptr<SceneSession>>& mainSessions)
1468 {
1469 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1470 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1471 if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName &&
1472 sceneSession->GetSessionInfo().appIndex_ == appIndex &&
1473 SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1474 mainSessions.push_back(sceneSession);
1475 }
1476 }
1477 }
1478
GetMainSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,std::vector<sptr<SceneSession>> & mainSessions) const1479 void SceneSessionManager::GetMainSessionByAbilityInfo(const AbilityInfoBase& abilityInfo,
1480 std::vector<sptr<SceneSession>>& mainSessions) const
1481 {
1482 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1483 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1484 if (!sceneSession || !SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1485 continue;
1486 }
1487 if (sceneSession->GetSessionInfo().bundleName_ == abilityInfo.bundleName &&
1488 sceneSession->GetSessionInfo().moduleName_ == abilityInfo.moduleName &&
1489 sceneSession->GetSessionInfo().abilityName_ == abilityInfo.abilityName &&
1490 sceneSession->GetSessionInfo().appIndex_ == abilityInfo.appIndex) {
1491 mainSessions.push_back(sceneSession);
1492 }
1493 }
1494 }
1495
GetSceneSessionByIdentityInfo(const SessionIdentityInfo & info)1496 sptr<SceneSession> SceneSessionManager::GetSceneSessionByIdentityInfo(const SessionIdentityInfo& info)
1497 {
1498 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1499 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1500 if (!sceneSession) {
1501 return nullptr;
1502 }
1503 if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1504 sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1505 sceneSession->GetSessionInfo().appInstanceKey_ != info.instanceKey_ ||
1506 sceneSession->GetSessionInfo().specifiedFlag_ != info.specifiedFlag_ ||
1507 sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1508 continue;
1509 }
1510 const auto& sessionModuleName = sceneSession->GetSessionInfo().moduleName_;
1511 const auto& sessionAbilityName = sceneSession->GetSessionInfo().abilityName_;
1512 if (info.isAtomicService_) {
1513 if ((sessionModuleName.empty() || sessionModuleName == info.moduleName_) &&
1514 (sessionAbilityName.empty() || sessionAbilityName == info.abilityName_)) {
1515 return sceneSession;
1516 }
1517 } else if (sessionModuleName == info.moduleName_ && sessionAbilityName == info.abilityName_) {
1518 return sceneSession;
1519 }
1520 }
1521 return nullptr;
1522 }
1523
GetSceneSessionByType(WindowType type)1524 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1525 {
1526 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1527 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1528 if (sceneSession && sceneSession->GetWindowType() == type) {
1529 return sceneSession;
1530 }
1531 }
1532 return nullptr;
1533 }
1534
GetSceneSessionByBundleName(const std::string & bundleName)1535 sptr<SceneSession> SceneSessionManager::GetSceneSessionByBundleName(const std::string& bundleName)
1536 {
1537 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1538 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1539 if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName) {
1540 return sceneSession;
1541 }
1542 }
1543 return nullptr;
1544 }
1545
GetSceneSessionVectorByTypeAndDisplayId(WindowType type,uint64_t displayId)1546 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByTypeAndDisplayId(
1547 WindowType type, uint64_t displayId)
1548 {
1549 if (displayId == DISPLAY_ID_INVALID) {
1550 TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1551 return {};
1552 }
1553 std::vector<sptr<SceneSession>> sceneSessionVector;
1554 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1555 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1556 if (sceneSession->GetWindowType() == type &&
1557 sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1558 sceneSessionVector.emplace_back(sceneSession);
1559 }
1560 }
1561 return sceneSessionVector;
1562 }
1563
GetSceneSessionVectorByType(WindowType type)1564 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
1565 {
1566 std::vector<sptr<SceneSession>> sceneSessionVector;
1567 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1568 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1569 if (sceneSession->GetWindowType() == type) {
1570 sceneSessionVector.emplace_back(sceneSession);
1571 }
1572 }
1573 return sceneSessionVector;
1574 }
1575
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1576 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1577 sptr<WindowSessionProperty> property)
1578 {
1579 if (sceneSession == nullptr || property == nullptr) {
1580 TLOGD(WmsLogTag::WMS_DIALOG, "Session or property is null");
1581 return WSError::WS_ERROR_NULLPTR;
1582 }
1583 auto parentPersistentId = property->GetParentPersistentId();
1584 sceneSession->SetParentPersistentId(parentPersistentId);
1585 if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1586 auto parentSession = GetSceneSession(parentPersistentId);
1587 if (parentSession == nullptr) {
1588 TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1589 return WSError::WS_ERROR_NULLPTR;
1590 }
1591 parentSession->BindDialogSessionTarget(sceneSession);
1592 parentSession->BindDialogToParentSession(sceneSession);
1593 sceneSession->SetParentSession(parentSession);
1594 TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1595 sceneSession->GetPersistentId(), parentPersistentId);
1596 }
1597 return WSError::WS_OK;
1598 }
1599
CreateSpecificSessionCallback()1600 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1601 {
1602 sptr<SceneSession::SpecificSessionCallback> specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1603 specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1604 return this->RequestSceneSession(sessionInfo, property);
1605 };
1606 specificCb->onDestroy_ = [this](const int32_t persistentId) {
1607 return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1608 };
1609 specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1610 this->ClearDisplayStatusBarTemporarilyFlags();
1611 };
1612 specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1613 this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1614 };
1615 specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1616 return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1617 };
1618 specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1619 return this->GetSceneSessionVectorByType(type);
1620 };
1621 specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1622 this->UpdateAvoidArea(persistentId);
1623 };
1624 specificCb->onGetStatusBarDefaultVisibilityByDisplayId_ = [this](DisplayId displayId) {
1625 return this->GetStatusBarDefaultVisibilityByDisplayId(displayId);
1626 };
1627 specificCb->onUpdateOccupiedAreaIfNeed_ = [this](int32_t persistentId) {
1628 this->UpdateOccupiedAreaIfNeed(persistentId);
1629 };
1630 specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1631 this->NotifyWindowInfoChange(persistentId, type);
1632 };
1633 specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1634 this->NotifyMMIWindowPidChange(windowId, startMoving);
1635 };
1636 specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1637 this->NotifySessionTouchOutside(persistentId);
1638 };
1639 specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1640 return this->GetAINavigationBarArea(displayId);
1641 };
1642 specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1643 this->OnOutsideDownEvent(x, y);
1644 };
1645 specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1646 return this->HandleSecureSessionShouldHide(sceneSession);
1647 };
1648 specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1649 this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1650 };
1651 specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1652 this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1653 };
1654 specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1655 this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1656 };
1657 specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1658 this->UpdateGestureBackEnabled(persistentId);
1659 };
1660 specificCb->onGetSceneSessionByIdCallback_ = [this](int32_t persistentId) {
1661 return this->GetSceneSession(persistentId);
1662 };
1663 return specificCb;
1664 }
1665
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1666 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1667 {
1668 TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1669 auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1670 if (isSkip) {
1671 if (it == skipSurfaceNodeIds_.end()) {
1672 skipSurfaceNodeIds_.push_back(surfaceNodeId);
1673 } else {
1674 return;
1675 }
1676 } else {
1677 if (it != skipSurfaceNodeIds_.end()) {
1678 skipSurfaceNodeIds_.erase(it);
1679 } else {
1680 return;
1681 }
1682 }
1683 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1684 }
1685
AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)1686 WMError SceneSessionManager::AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
1687 {
1688 auto task = [this, &persistentIds] {
1689 for (const auto persistentId : persistentIds) {
1690 auto session = GetSceneSession(persistentId);
1691 if (!session || SessionHelper::IsSubWindow(session->GetWindowType())) {
1692 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] not found or is sub window", persistentId);
1693 continue;
1694 }
1695 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] add to virtual screen black list", persistentId);
1696 auto surfaceNode = session->GetSurfaceNode();
1697 if (surfaceNode) {
1698 auto surfaceNodeId = surfaceNode->GetId();
1699 if (std::count(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId) == 0) {
1700 skipSurfaceNodeIds_.push_back(surfaceNodeId);
1701 }
1702 }
1703 auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
1704 if (leashWinSurfaceNode) {
1705 auto leashWinSurfaceNodeId = leashWinSurfaceNode->GetId();
1706 if (std::count(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), leashWinSurfaceNodeId) == 0) {
1707 skipSurfaceNodeIds_.push_back(leashWinSurfaceNodeId);
1708 }
1709 }
1710 }
1711 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1712 return WMError::WM_OK;
1713 };
1714 return taskScheduler_->PostSyncTask(task, __func__);
1715 }
1716
RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)1717 WMError SceneSessionManager::RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
1718 {
1719 auto task = [this, &persistentIds] {
1720 for (const auto persistentId : persistentIds) {
1721 auto session = GetSceneSession(persistentId);
1722 if (!session || SessionHelper::IsSubWindow(session->GetWindowType())) {
1723 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] not found or is sub window", persistentId);
1724 continue;
1725 }
1726 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] remove from virtual screen black list", persistentId);
1727 auto surfaceNode = session->GetSurfaceNode();
1728 if (surfaceNode) {
1729 auto surfaceNodeId = surfaceNode->GetId();
1730 auto iter = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1731 if (iter != skipSurfaceNodeIds_.end()) {
1732 skipSurfaceNodeIds_.erase(iter);
1733 }
1734 }
1735 auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
1736 if (leashWinSurfaceNode) {
1737 auto leashWinSurfaceNodeId = leashWinSurfaceNode->GetId();
1738 auto iter = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), leashWinSurfaceNodeId);
1739 if (iter != skipSurfaceNodeIds_.end()) {
1740 skipSurfaceNodeIds_.erase(iter);
1741 }
1742 }
1743 }
1744 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1745 return WMError::WM_OK;
1746 };
1747 return taskScheduler_->PostSyncTask(task, __func__);
1748 }
1749
CreateKeyboardSessionCallback()1750 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1751 {
1752 auto keyboardCb = sptr<KeyboardSession::KeyboardSessionCallback>::MakeSptr();
1753 keyboardCb->onGetSceneSession = [this](int32_t persistentId) {
1754 return this->GetSceneSession(persistentId);
1755 };
1756 keyboardCb->onGetFocusedSessionId = [this] {
1757 return this->GetFocusedSessionId();
1758 };
1759 keyboardCb->onCallingSessionIdChange = callingSessionIdChangeFunc_;
1760 keyboardCb->onSystemKeyboardAvoidChange = [this](DisplayId displayId, SystemKeyboardAvoidChangeReason reason) {
1761 this->HandleKeyboardAvoidChange(nullptr, displayId, reason);
1762 };
1763 keyboardCb->onNotifyOccupiedAreaChange = [this](const sptr<OccupiedAreaChangeInfo>& info) {
1764 this->onNotifyOccupiedAreaChangeForRootFunc_(info);
1765 };
1766 return keyboardCb;
1767 }
1768
CheckWindowId(int32_t windowId,int32_t & pid)1769 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1770 {
1771 if (!SessionPermission::IsSystemCalling()) {
1772 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
1773 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1774 }
1775
1776 auto task = [this, windowId, &pid] {
1777 pid = INVALID_PID;
1778 auto sceneSession = GetSceneSession(windowId);
1779 if (sceneSession == nullptr) {
1780 TLOGNE(WmsLogTag::WMS_EVENT, "sceneSession(%{public}d) is nullptr", windowId);
1781 return WMError::WM_ERROR_INVALID_WINDOW;
1782 }
1783 pid = sceneSession->GetCallingPid();
1784 TLOGND(WmsLogTag::WMS_EVENT, "Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1785 return WMError::WM_OK;
1786 };
1787 return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1788 }
1789
GetLockScreenZOrder()1790 uint32_t SceneSessionManager::GetLockScreenZOrder()
1791 {
1792 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1793 for (const auto& [persistentId, session] : sceneSessionMap_) {
1794 if (session && session->IsScreenLockWindow()) {
1795 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: window %{public}d-%{public}d", persistentId,
1796 session->GetZOrder());
1797 return session->GetZOrder() < DEFAULT_LOCK_SCREEN_ZORDER ? DEFAULT_LOCK_SCREEN_ZORDER :
1798 session->GetZOrder();
1799 }
1800 }
1801 TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not found");
1802 return DEFAULT_LOCK_SCREEN_ZORDER;
1803 }
1804
CheckUIExtensionCreation(int32_t windowId,uint32_t callingTokenId,const AppExecFwk::ElementName & element,AppExecFwk::ExtensionAbilityType extensionAbilityType,int32_t & pid)1805 WMError SceneSessionManager::CheckUIExtensionCreation(int32_t windowId, uint32_t callingTokenId,
1806 const AppExecFwk::ElementName& element, AppExecFwk::ExtensionAbilityType extensionAbilityType, int32_t& pid)
1807 {
1808 if (!SessionPermission::IsSystemCalling()) {
1809 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
1810 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1811 }
1812 auto task = [this, windowId, callingTokenId, &element, extensionAbilityType, &pid] {
1813 pid = INVALID_PID;
1814 auto sceneSession = GetSceneSession(windowId);
1815 if (sceneSession == nullptr) {
1816 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sceneSession(%{public}d) is nullptr", windowId);
1817 return WMError::WM_ERROR_INVALID_WINDOW;
1818 }
1819 pid = sceneSession->GetCallingPid();
1820 if (!IsScreenLocked()) {
1821 TLOGND(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in lock screen");
1822 return WMError::WM_OK;
1823 }
1824 if (IsUserAuthPassed()) {
1825 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: auth passed");
1826 return WMError::WM_OK;
1827 }
1828 // 1. check window whether can show on main window
1829 if (!sceneSession->IsShowOnLockScreen(GetLockScreenZOrder())) {
1830 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not called on lock screen");
1831 return WMError::WM_OK;
1832 }
1833 // 2. check permission
1834 if (!IsUIExtCanShowOnLockScreen(element, callingTokenId, extensionAbilityType)) {
1835 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: no permisson, window id %{public}d, %{public}d", windowId,
1836 callingTokenId);
1837 return WMError::WM_ERROR_INVALID_PERMISSION;
1838 }
1839 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: pass");
1840 return WMError::WM_OK;
1841 };
1842
1843 std::ostringstream ss;
1844 ss << "UIExtOnLockCheck" << "_" << windowId << "_" << callingTokenId;
1845 return taskScheduler_->PostSyncTask(task, ss.str());
1846 }
1847
1848 // windowIds are all main window
OnNotifyAboveLockScreen(const std::vector<int32_t> & windowIds)1849 void SceneSessionManager::OnNotifyAboveLockScreen(const std::vector<int32_t>& windowIds)
1850 {
1851 taskScheduler_->PostSyncTask([this, &windowIds] {
1852 // check every window
1853 for (auto windowId : windowIds) {
1854 auto sceneSession = GetSceneSession(windowId);
1855 if (!sceneSession) {
1856 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sesssion is null for %{public}d", windowId);
1857 continue;
1858 }
1859 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: check for %{public}d", windowId);
1860 sceneSession->OnNotifyAboveLockScreen();
1861 }
1862 return WMError::WM_OK;
1863 }, __func__);
1864 }
1865
GetKeyboardSession(DisplayId displayId,bool isSystemKeyboard)1866 sptr<SceneSession> SceneSessionManager::GetKeyboardSession(DisplayId displayId, bool isSystemKeyboard)
1867 {
1868 if (displayId == DISPLAY_ID_INVALID) {
1869 TLOGE(WmsLogTag::WMS_KEYBOARD, "displayId is invalid.");
1870 return nullptr;
1871 }
1872 sptr<SceneSession> keyboardSession = nullptr;
1873 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1874 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1875 if (sceneSession && sceneSession->GetScreenId() == displayId &&
1876 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
1877 sceneSession->IsSystemKeyboard() == isSystemKeyboard) {
1878 keyboardSession = sceneSession;
1879 break;
1880 }
1881 }
1882 return keyboardSession;
1883 }
1884
HandleKeyboardAvoidChange(const sptr<SceneSession> & sceneSession,DisplayId displayId,SystemKeyboardAvoidChangeReason reason)1885 void SceneSessionManager::HandleKeyboardAvoidChange(const sptr<SceneSession>& sceneSession, DisplayId displayId,
1886 SystemKeyboardAvoidChangeReason reason)
1887 {
1888 if (!systemConfig_.IsPcWindow()) {
1889 TLOGI(WmsLogTag::WMS_KEYBOARD, "this device is not pc.");
1890 return;
1891 }
1892 switch (reason) {
1893 // if the system keyboard's avoid area is active first, deactivate the other keyboard's avoid area
1894 case SystemKeyboardAvoidChangeReason::KEYBOARD_CREATED: {
1895 if (!sceneSession || sceneSession->IsSystemKeyboard()) {
1896 return;
1897 }
1898 sptr<SceneSession> systemKeyboardSession = GetKeyboardSession(displayId, true);
1899 if (systemKeyboardSession && systemKeyboardSession->IsSessionForeground() &&
1900 systemKeyboardSession->GetKeyboardGravity() == SessionGravity::SESSION_GRAVITY_BOTTOM) {
1901 sceneSession->ActivateKeyboardAvoidArea(false, false);
1902 }
1903 break;
1904 }
1905 /*
1906 * activate the system keyboard's avoid area, while it is showing or it's gravity is bottom
1907 * and deactivate other keyboard's avoid area
1908 */
1909 case SystemKeyboardAvoidChangeReason::KEYBOARD_SHOW:
1910 case SystemKeyboardAvoidChangeReason::KEYBOARD_GRAVITY_BOTTOM: {
1911 UpdateKeyboardAvoidAreaActive(true);
1912 break;
1913 }
1914 /*
1915 * when the system keyboard is hiden, disconnect or it's gravity is float
1916 * check for whether other keyboard can be avoided: if yes, avoids the other keyboard
1917 * if no, restores the system keyboard
1918 */
1919 case SystemKeyboardAvoidChangeReason::KEYBOARD_HIDE:
1920 case SystemKeyboardAvoidChangeReason::KEYBOARD_DISCONNECT:
1921 case SystemKeyboardAvoidChangeReason::KEYBOARD_GRAVITY_FLOAT: {
1922 bool keyboardRecalculate = false;
1923 if (auto keyboardSession = GetKeyboardSession(displayId, false)) {
1924 if (keyboardSession->IsSessionForeground() &&
1925 keyboardSession->GetKeyboardGravity() == SessionGravity::SESSION_GRAVITY_BOTTOM) {
1926 keyboardRecalculate = true;
1927 }
1928 keyboardSession->ActivateKeyboardAvoidArea(true, keyboardRecalculate);
1929 }
1930 if (auto sysKeyboardSession = GetKeyboardSession(displayId, true)) {
1931 sysKeyboardSession->ActivateKeyboardAvoidArea(false, !keyboardRecalculate);
1932 }
1933 break;
1934 }
1935 default:
1936 break;
1937 }
1938 }
1939
UpdateKeyboardAvoidAreaActive(bool systemKeyboardAvoidAreaActive)1940 void SceneSessionManager::UpdateKeyboardAvoidAreaActive(bool systemKeyboardAvoidAreaActive)
1941 {
1942 const auto& keyboardSessionVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
1943 if (keyboardSessionVec.empty()) {
1944 TLOGI(WmsLogTag::WMS_KEYBOARD, "there is no keyboard window in the map");
1945 return;
1946 }
1947 for (const auto& keyboardSession : keyboardSessionVec) {
1948 if (!keyboardSession) {
1949 continue;
1950 }
1951 if (keyboardSession->IsSystemKeyboard()) {
1952 keyboardSession->ActivateKeyboardAvoidArea(systemKeyboardAvoidAreaActive, false);
1953 } else {
1954 keyboardSession->ActivateKeyboardAvoidArea(!systemKeyboardAvoidAreaActive, false);
1955 }
1956 }
1957 }
1958
RequestKeyboardPanelSession(const std::string & panelName,uint64_t displayId)1959 sptr<SceneSession> SceneSessionManager::RequestKeyboardPanelSession(const std::string& panelName, uint64_t displayId)
1960 {
1961 SessionInfo panelInfo = {
1962 .bundleName_ = panelName,
1963 .moduleName_ = panelName,
1964 .abilityName_ = panelName,
1965 .isSystem_ = true,
1966 .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1967 .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1968 .screenId_ = displayId,
1969 .isRotable_ = true,
1970 };
1971 if (systemConfig_.IsPcWindow()) {
1972 panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1973 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1974 } else {
1975 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1976 }
1977 return RequestSceneSession(panelInfo, nullptr);
1978 }
1979
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1980 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1981 {
1982 if (!isKeyboardPanelEnabled_) {
1983 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1984 return;
1985 }
1986 if (keyboardSession == nullptr) {
1987 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1988 return;
1989 }
1990 const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL);
1991 sptr<SceneSession> panelSession;
1992 for (const auto& session : panelVec) {
1993 if (session && session->IsSystemKeyboard() == keyboardSession->IsSystemKeyboard()) {
1994 panelSession = session;
1995 break;
1996 }
1997 }
1998 /*
1999 * Only 2 scenarios of panelSession is nullptr:
2000 * 1: neither keyboard panel session nor system keyboard panel session is created.
2001 * 2: a panel session has been created already, but it's isSystemKeyboard is not match with the keyboardSesion's
2002 */
2003 if (panelSession == nullptr) {
2004 if (panelVec.size() >= 2) { // 2 is max number of keyboard panel, one input method and one system keyboard
2005 TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
2006 return;
2007 }
2008 std::string panelName = keyboardSession->IsSystemKeyboard() ? "SCBSystemKeyboardPanel" : "SCBKeyboardPanel";
2009 panelSession = RequestKeyboardPanelSession(panelName,
2010 static_cast<uint64_t>(keyboardSession->GetSessionProperty()->GetDisplayId()));
2011 if (panelSession == nullptr) {
2012 TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
2013 return;
2014 }
2015 } else {
2016 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId: %{public}d",
2017 panelSession->GetPersistentId());
2018 }
2019 panelSession->SetIsSystemKeyboard(keyboardSession->IsSystemKeyboard());
2020 keyboardSession->BindKeyboardPanelSession(panelSession);
2021 panelSession->BindKeyboardSession(keyboardSession);
2022 TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
2023 panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
2024 }
2025
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)2026 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
2027 sptr<WindowSessionProperty> property)
2028 {
2029 sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
2030 sptr<SceneSession> sceneSession = nullptr;
2031 if (sessionInfo.isSystem_) {
2032 sceneSession = new SCBSystemSession(sessionInfo, specificCb);
2033 TLOGI(WmsLogTag::DEFAULT, "[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
2034 } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
2035 sceneSession = new MainSession(sessionInfo, specificCb);
2036 TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
2037 } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
2038 sceneSession = new SubSession(sessionInfo, specificCb);
2039 TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
2040 } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2041 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
2042 sceneSession = new KeyboardSession(sessionInfo, specificCb, keyboardCb);
2043 sceneSession->SetIsSystemKeyboard(property->IsSystemKeyboard());
2044 CreateKeyboardPanelSession(sceneSession);
2045 HandleKeyboardAvoidChange(sceneSession, sceneSession->GetScreenId(),
2046 SystemKeyboardAvoidChangeReason::KEYBOARD_CREATED);
2047 TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
2048 } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
2049 sceneSession = new SystemSession(sessionInfo, specificCb);
2050 TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
2051 } else {
2052 TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
2053 }
2054 if (sceneSession != nullptr) {
2055 sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
2056 sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
2057 sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
2058 return this->GetAppForceLandscapeConfig(bundleName);
2059 });
2060 sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
2061 this->UpdatePrivateStateAndNotify(persistentId);
2062 });
2063 sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
2064 this->NotifyVisibleChange(persistentId);
2065 });
2066 sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
2067 return this->IsLastFrameLayoutFinished(isLayoutFinished);
2068 });
2069 sceneSession->SetIsAINavigationBarAvoidAreaValidFunc([this](const AvoidArea& avoidArea, int32_t sessionBottom) {
2070 return CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea, sessionBottom);
2071 });
2072 sceneSession->RegisterGetStatusBarAvoidHeightFunc([this](WSRect& barArea) {
2073 return this->GetStatusBarAvoidHeight(barArea);
2074 });
2075 sceneSession->RegisterGetStatusBarConstantlyShowFunc([this](DisplayId displayId, bool& isVisible) {
2076 return this->GetStatusBarConstantlyShow(displayId, isVisible);
2077 });
2078 DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2079 GetAppDragResizeType(sessionInfo.bundleName_, dragResizeType);
2080 sceneSession->SetAppDragResizeType(dragResizeType);
2081 sceneSession->SetSingleHandTransform(singleHandTransform_);
2082 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, displayId: %{public}" PRIu64,
2083 sceneSession->GetPersistentId(), sceneSession->GetSessionProperty()->GetDisplayId());
2084 }
2085 return sceneSession;
2086 }
2087
GetEffectiveDragResizeType(DragResizeType & dragResizeType)2088 void SceneSessionManager::GetEffectiveDragResizeType(DragResizeType& dragResizeType)
2089 {
2090 if (dragResizeType != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2091 return;
2092 }
2093 if (systemConfig_.freeMultiWindowSupport_) {
2094 dragResizeType = DragResizeType::RESIZE_WHEN_DRAG_END;
2095 } else {
2096 dragResizeType = DragResizeType::RESIZE_EACH_FRAME;
2097 }
2098 }
2099
SetGlobalDragResizeType(DragResizeType dragResizeType)2100 WMError SceneSessionManager::SetGlobalDragResizeType(DragResizeType dragResizeType)
2101 {
2102 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
2103 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2104 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2105 return WMError::WM_ERROR_INVALID_PERMISSION;
2106 }
2107 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2108 globalDragResizeType_ = dragResizeType;
2109 taskScheduler_->PostAsyncTask([this] {
2110 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2111 for (const auto& [_, sceneSession] : sceneSessionMap_) {
2112 if (sceneSession != nullptr && WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2113 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
2114 DragResizeType appDragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2115 GetAppDragResizeType(bundleName, appDragResizeType);
2116 TLOGND(WmsLogTag::WMS_LAYOUT, "SetGlobalDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
2117 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), appDragResizeType);
2118 sceneSession->SetAppDragResizeType(appDragResizeType);
2119 }
2120 }
2121 }, __func__);
2122 return WMError::WM_OK;
2123 }
2124
GetGlobalDragResizeType(DragResizeType & dragResizeType)2125 WMError SceneSessionManager::GetGlobalDragResizeType(DragResizeType& dragResizeType)
2126 {
2127 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2128 dragResizeType = globalDragResizeType_;
2129 GetEffectiveDragResizeType(dragResizeType);
2130 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
2131 return WMError::WM_OK;
2132 }
2133
SetAppDragResizeType(const std::string & bundleName,DragResizeType dragResizeType)2134 WMError SceneSessionManager::SetAppDragResizeType(const std::string& bundleName, DragResizeType dragResizeType)
2135 {
2136 TLOGD(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2137 dragResizeType, bundleName.c_str());
2138 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2139 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2140 return WMError::WM_ERROR_INVALID_PERMISSION;
2141 }
2142 return SetAppDragResizeTypeInner(bundleName, dragResizeType);
2143 }
2144
SetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType dragResizeType)2145 WMError SceneSessionManager::SetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType dragResizeType)
2146 {
2147 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2148 dragResizeType, bundleName.c_str());
2149 if (bundleName.empty()) {
2150 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2151 return WMError::WM_ERROR_INVALID_PARAM;
2152 }
2153 std::lock_guard<std::mutex> dragResizeTypeLock(dragResizeTypeMutex_);
2154 appDragResizeTypeMap_[bundleName] = dragResizeType;
2155 GetAppDragResizeTypeInner(bundleName, dragResizeType);
2156 taskScheduler_->PostAsyncTask([this, bundleName, dragResizeType] {
2157 auto sceneSession = GetSceneSessionByBundleName(bundleName);
2158 if (sceneSession != nullptr) {
2159 TLOGNI(WmsLogTag::WMS_LAYOUT, "SetAppDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
2160 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), dragResizeType);
2161 sceneSession->SetAppDragResizeType(dragResizeType);
2162 }
2163 }, __func__);
2164 return WMError::WM_OK;
2165 }
2166
GetAppDragResizeType(const std::string & bundleName,DragResizeType & dragResizeType)2167 WMError SceneSessionManager::GetAppDragResizeType(const std::string& bundleName, DragResizeType& dragResizeType)
2168 {
2169 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2170 return GetAppDragResizeTypeInner(bundleName, dragResizeType);
2171 }
2172
GetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType & dragResizeType)2173 WMError SceneSessionManager::GetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType& dragResizeType)
2174 {
2175 if (bundleName.empty()) {
2176 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2177 return WMError::WM_ERROR_INVALID_PARAM;
2178 }
2179 if (globalDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2180 TLOGI(WmsLogTag::WMS_LAYOUT, "use global value");
2181 dragResizeType = globalDragResizeType_;
2182 return WMError::WM_OK;
2183 }
2184 dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2185 if (auto iter = appDragResizeTypeMap_.find(bundleName); iter != appDragResizeTypeMap_.end()) {
2186 dragResizeType = iter->second;
2187 }
2188 GetEffectiveDragResizeType(dragResizeType);
2189 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2190 dragResizeType, bundleName.c_str());
2191 return WMError::WM_OK;
2192 }
2193
GetSceneSessionBySessionInfo(const SessionInfo & sessionInfo)2194 sptr<SceneSession> SceneSessionManager::GetSceneSessionBySessionInfo(const SessionInfo& sessionInfo)
2195 {
2196 if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
2197 if (auto session = GetSceneSession(sessionInfo.persistentId_)) {
2198 TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
2199 return session;
2200 }
2201
2202 if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
2203 TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
2204 "abilityName: %{public}s, appIndex: %{public}d",
2205 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
2206 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
2207 SessionIdentityInfo identityInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_,
2208 sessionInfo.abilityName_, sessionInfo.appIndex_, sessionInfo.appInstanceKey_, sessionInfo.windowType_,
2209 sessionInfo.isAtomicService_ };
2210 auto sceneSession = GetSceneSessionByIdentityInfo(identityInfo);
2211 bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
2212 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
2213 if (isSingleStart) {
2214 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
2215 sessionInfo.persistentId_);
2216 return sceneSession;
2217 }
2218 }
2219 }
2220 return nullptr;
2221 }
2222
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)2223 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
2224 sptr<WindowSessionProperty> property)
2225 {
2226 auto task = [this, sessionInfo, property, where = __func__] {
2227 if (auto session = GetSceneSessionBySessionInfo(sessionInfo)) {
2228 UpdateSessionDisplayIdBySessionInfo(session, sessionInfo);
2229 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
2230 return session;
2231 }
2232 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: appName: [%{public}s %{public}s %{public}s] "
2233 "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
2234 where, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
2235 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
2236 static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
2237 sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
2238 if (sceneSession == nullptr) {
2239 TLOGNE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
2240 return sceneSession;
2241 }
2242 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2243 WindowHelper::IsMainWindow(sceneSession->GetWindowType()) &&
2244 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2245 MultiInstanceManager::GetInstance().FillInstanceKeyIfNeed(sceneSession);
2246 }
2247 LOCK_GUARD_EXPR(SCENE_GUARD, InitSceneSession(sceneSession, sessionInfo, property));
2248 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2249 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
2250 where, sceneSession->GetSessionInfo().ancoSceneState);
2251 bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
2252 const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
2253 if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
2254 TLOGNI(WmsLogTag::WMS_LIFE,
2255 "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
2256 where, reusedSceneSession->GetPersistentId(),
2257 reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
2258 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
2259 return reusedSceneSession;
2260 }
2261 if (isPreHandleSuccess) {
2262 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
2263 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
2264 }
2265 }
2266 {
2267 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2268 sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
2269 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2270 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2271 MultiInstanceManager::GetInstance().IncreaseInstanceKeyRefCount(sceneSession);
2272 }
2273 }
2274 PerformRegisterInRequestSceneSession(sceneSession);
2275 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
2276 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: id: %{public}d, type: %{public}d, instanceKey: %{public}s, "
2277 "displayId: %{public}" PRIu64, where, sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
2278 sceneSession->GetAppInstanceKey().c_str(), sceneSession->GetSessionProperty()->GetDisplayId());
2279 return sceneSession;
2280 };
2281 return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
2282 }
2283
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)2284 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
2285 const sptr<WindowSessionProperty>& property)
2286 {
2287 auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
2288 DisplayId currDisplayId = DISPLAY_ID_INVALID;
2289 if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
2290 currDisplayId = sessionInfo.screenId_;
2291 } else if (callerSession) {
2292 currDisplayId = callerSession->GetSessionProperty()->GetDisplayId();
2293 }
2294 sceneSession->GetSessionProperty()->SetDisplayId(currDisplayId);
2295 sceneSession->SetScreenId(currDisplayId);
2296 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "synchronous screenId with displayId %{public}" PRIu64, currDisplayId);
2297
2298 sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
2299 sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
2300 if (sessionInfo.isSystem_) {
2301 sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
2302 sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
2303 auto rootContext = rootSceneContextWeak_.lock();
2304 sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
2305 } else {
2306 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
2307 "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
2308 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2309 sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
2310 }
2311 RegisterSessionExceptionFunc(sceneSession);
2312 RegisterVisibilityChangedDetectFunc(sceneSession);
2313 // Skip FillSessionInfo when atomicService free-install start.
2314 if (!IsAtomicServiceFreeInstall(sessionInfo)) {
2315 FillSessionInfo(sceneSession);
2316 }
2317 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
2318 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2319 WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
2320 }
2321 if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
2322 sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
2323 }
2324 sceneSession->SetSystemConfig(systemConfig_);
2325 sceneSession->SetSnapshotScale(snapshotScale_);
2326 UpdateParentSessionForDialog(sceneSession, property);
2327 std::string key = sessionInfo.bundleName_ + "_" + sessionInfo.moduleName_ + "_" + sessionInfo.abilityName_ + "_" +
2328 std::to_string(sessionInfo.appIndex_);
2329 if (sessionLockedStateCacheSet_.find(key) != sessionLockedStateCacheSet_.end()) {
2330 sceneSession->NotifySessionLockStateChange(true);
2331 }
2332 }
2333
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)2334 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
2335 {
2336 taskScheduler_->PostAsyncTask([abilityName = sessionInfo.abilityName_,
2337 bundleName = sessionInfo.bundleName_, toScreenId = sessionInfo.screenId_, action, fromScreenId] {
2338 sptr<DisplayChangeInfo> info = sptr<DisplayChangeInfo>::MakeSptr();
2339 info->action_ = action;
2340 info->abilityName_ = std::move(abilityName);
2341 info->bundleName_ = std::move(bundleName);
2342 info->toScreenId_ = toScreenId;
2343 info->fromScreenId_ = fromScreenId;
2344 ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
2345 TLOGNI(WmsLogTag::DMS, "Notify ability %{public}s bundle %{public}s update toScreen id: %{public}" PRIu64,
2346 info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
2347 }, __func__);
2348 }
2349
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)2350 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
2351 {
2352 RegisterSessionSnapshotFunc(sceneSession);
2353 RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
2354 RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
2355 RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
2356 RegisterGetStateFromManagerFunc(sceneSession);
2357 RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
2358 RegisterAcquireRotateAnimationConfigFunc(sceneSession);
2359 RegisterRequestVsyncFunc(sceneSession);
2360 }
2361
UpdateSceneSessionWant(const SessionInfo & sessionInfo)2362 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
2363 {
2364 if (sessionInfo.persistentId_ != 0) {
2365 auto session = GetSceneSession(sessionInfo.persistentId_);
2366 if (session != nullptr && sessionInfo.want != nullptr) {
2367 TLOGI(WmsLogTag::WMS_MAIN, "Get session id:%{public}d", sessionInfo.persistentId_);
2368 if (!CheckCollaboratorType(session->GetCollaboratorType())) {
2369 session->SetSessionInfoWant(sessionInfo.want);
2370 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
2371 } else {
2372 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
2373 }
2374 } else {
2375 TLOGI(WmsLogTag::WMS_MAIN, "Get session fail(%{public}d), id:%{public}d",
2376 session == nullptr, sessionInfo.persistentId_);
2377 }
2378 } else {
2379 TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
2380 }
2381 }
2382
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)2383 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
2384 {
2385 if (session != nullptr && session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2386 FillSessionInfo(session);
2387 if (CheckCollaboratorType(session->GetCollaboratorType())) {
2388 PreHandleCollaborator(session, persistentId);
2389 }
2390 }
2391 }
2392
SetAbilitySessionInfo(const sptr<SceneSession> & sceneSession)2393 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& sceneSession)
2394 {
2395 const auto& sessionInfo = sceneSession->GetSessionInfo();
2396 auto abilitySessionInfo = sptr<AAFwk::SessionInfo>::MakeSptr();
2397 abilitySessionInfo->sessionToken = sptr<ISession>(sceneSession)->AsObject();
2398 abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
2399 std::chrono::system_clock::now()).time_since_epoch().count());
2400 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
2401 abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
2402 sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
2403 abilitySessionInfo->persistentId = sceneSession->GetPersistentId();
2404 abilitySessionInfo->requestCode = sessionInfo.requestCode;
2405 abilitySessionInfo->resultCode = sessionInfo.resultCode;
2406 abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
2407 abilitySessionInfo->startSetting = sessionInfo.startSetting;
2408 abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
2409 abilitySessionInfo->userId = currentUserId_;
2410 abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
2411 abilitySessionInfo->processOptions = sessionInfo.processOptions;
2412 abilitySessionInfo->requestId = sessionInfo.requestId;
2413 if (sessionInfo.want != nullptr) {
2414 abilitySessionInfo->want = *sessionInfo.want;
2415 } else {
2416 abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
2417 sessionInfo.moduleName_);
2418 }
2419 int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
2420 bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
2421 if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
2422 TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
2423 appIndex, sessionInfo.appIndex_);
2424 }
2425 if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
2426 TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
2427 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
2428 }
2429 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
2430 static_cast<int>(sceneSession->GetSessionProperty()->GetDisplayId()));
2431 abilitySessionInfo->instanceKey = sessionInfo.appInstanceKey_;
2432 if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
2433 sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2434 abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
2435 } else {
2436 TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
2437 }
2438 return abilitySessionInfo;
2439 }
2440
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)2441 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
2442 {
2443 if (!isPrepareTerminateEnable_) { // not support prepareTerminate
2444 isPrepareTerminate = false;
2445 TLOGE(WmsLogTag::WMS_MAIN, "not support prepareTerminate, Id:%{public}d", persistentId);
2446 return WSError::WS_OK;
2447 }
2448 auto sceneSession = GetSceneSession(persistentId);
2449 if (sceneSession == nullptr) {
2450 TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is null, Id:%{public}d", persistentId);
2451 isPrepareTerminate = false;
2452 return WSError::WS_ERROR_NULLPTR;
2453 }
2454 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2455 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
2456 PrepareTerminateAbilityBySCB(sceneSessionInfo, isPrepareTerminate);
2457 TLOGI(WmsLogTag::WMS_MAIN, "Id:%{public}d isPrepareTerminate:%{public}d "
2458 "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
2459 return WSError::WS_OK;
2460 }
2461
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)2462 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
2463 {
2464 auto task = [this, weakSceneSession = wptr(sceneSession), isNewActive]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
2465 sptr<SceneSession> sceneSession = weakSceneSession.promote();
2466 if (sceneSession == nullptr) {
2467 TLOGNE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
2468 return WSError::WS_ERROR_NULLPTR;
2469 }
2470 if (!Session::IsScbCoreEnabled()) {
2471 sceneSession->SetForegroundInteractiveStatus(true);
2472 }
2473 auto persistentId = sceneSession->GetPersistentId();
2474 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
2475 TLOGNI(WmsLogTag::WMS_MAIN,
2476 "Request active id:%{public}d, system:%{public}d, isNewActive:%{public}d, requestId:%{public}d",
2477 persistentId, sceneSession->GetSessionInfo().isSystem_,
2478 isNewActive, sceneSession->GetSessionInfo().requestId);
2479 if (!GetSceneSession(persistentId)) {
2480 TLOGNE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
2481 return WSError::WS_ERROR_INVALID_SESSION;
2482 }
2483 auto ret = RequestSceneSessionActivationInner(sceneSession, isNewActive);
2484 if (ret == WSError::WS_OK) {
2485 sceneSession->SetExitSplitOnBackground(false);
2486 }
2487 abilityInfoMap_.clear(); // clear cache after terminate
2488 return ret;
2489 };
2490 std::string taskName = "RequestSceneSessionActivation:PID:" +
2491 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2492 taskScheduler_->PostAsyncTask(task, taskName);
2493 return WSError::WS_OK;
2494 }
2495
IsKeyboardForeground()2496 bool SceneSessionManager::IsKeyboardForeground()
2497 {
2498 bool isKeyboardForeground = false;
2499 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2500 for (const auto& [_, sceneSession] : sceneSessionMap_) {
2501 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2502 isKeyboardForeground = sceneSession->IsSessionForeground();
2503 break;
2504 }
2505 }
2506 return isKeyboardForeground;
2507 }
2508
RequestInputMethodCloseKeyboard(const int32_t persistentId)2509 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
2510 {
2511 auto sceneSession = GetSceneSession(persistentId);
2512 if (sceneSession == nullptr) {
2513 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
2514 return;
2515 }
2516 // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
2517 if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
2518 !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
2519 TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
2520 persistentId, sceneSession->GetSessionState());
2521 sceneSession->RequestHideKeyboard(true);
2522 }
2523 }
2524
StartUIAbilityBySCBTimeoutCheck(const sptr<AAFwk::SessionInfo> & abilitySessionInfo,const uint32_t & windowStateChangeReason,bool & isColdStart)2525 int32_t SceneSessionManager::StartUIAbilityBySCBTimeoutCheck(const sptr<AAFwk::SessionInfo>& abilitySessionInfo,
2526 const uint32_t& windowStateChangeReason, bool& isColdStart)
2527 {
2528 std::shared_ptr<int32_t> retCode = std::make_shared<int32_t>(0);
2529 std::shared_ptr<bool> coldStartFlag = std::make_shared<bool>(false);
2530 bool isTimeout = ffrtQueueHelper_->SubmitTaskAndWait([abilitySessionInfo, coldStartFlag, retCode,
2531 windowStateChangeReason] {
2532 auto result = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo,
2533 *coldStartFlag, windowStateChangeReason);
2534 *retCode = static_cast<int32_t>(result);
2535 TLOGNI(WmsLogTag::WMS_LIFE, "start ui ability retCode: %{public}d", *retCode);
2536 }, START_UI_ABILITY_TIMEOUT);
2537
2538 if (isTimeout) {
2539 TLOGE(WmsLogTag::WMS_LIFE, "start ui ability timeout, currentUserId: %{public}d", currentUserId_.load());
2540 return static_cast<int32_t>(WSError::WS_ERROR_START_UI_ABILITY_TIMEOUT);
2541 }
2542 isColdStart = *coldStartFlag;
2543 return *retCode;
2544 }
2545
StartUIAbilityBySCB(sptr<SceneSession> & sceneSession)2546 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& sceneSession)
2547 {
2548 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
2549 return StartUIAbilityBySCB(abilitySessionInfo);
2550 }
2551
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo)2552 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
2553 {
2554 bool isColdStart = false;
2555 return StartUIAbilityBySCBTimeoutCheck(abilitySessionInfo,
2556 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
2557 }
2558
ChangeUIAbilityVisibilityBySCB(const sptr<SceneSession> & sceneSession,bool visibility,bool isFromClient)2559 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(const sptr<SceneSession>& sceneSession,
2560 bool visibility, bool isFromClient)
2561 {
2562 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
2563 if (!isFromClient) {
2564 sceneSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
2565 }
2566 return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
2567 }
2568
RequestSceneSessionActivationInner(sptr<SceneSession> & sceneSession,bool isNewActive)2569 WSError SceneSessionManager::RequestSceneSessionActivationInner(
2570 sptr<SceneSession>& sceneSession, bool isNewActive)
2571 {
2572 auto persistentId = sceneSession->GetPersistentId();
2573 RequestInputMethodCloseKeyboard(persistentId);
2574 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2575 sceneSession->SetIsStarting(true);
2576 sceneSession->SetStartingBeforeVisible(true);
2577 }
2578 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) && sceneSession->IsFocusedOnShow()) {
2579 if (Session::IsScbCoreEnabled()) {
2580 if (sceneSession->IsVisibleForeground()) {
2581 RequestSessionFocusImmediately(persistentId);
2582 } else {
2583 PostProcessFocusState state = { true, true, true, FocusChangeReason::SCB_START_APP };
2584 sceneSession->SetPostProcessFocusState(state);
2585 }
2586 } else {
2587 RequestSessionFocusImmediately(persistentId);
2588 }
2589 }
2590 if (sceneSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2591 FillSessionInfo(sceneSession);
2592 if (!PreHandleCollaborator(sceneSession, persistentId)) {
2593 TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
2594 persistentId, sceneSession->GetSessionInfo().ancoSceneState);
2595 ExceptionInfo exceptionInfo;
2596 exceptionInfo.needRemoveSession = true;
2597 sceneSession->NotifySessionExceptionInner(SetAbilitySessionInfo(sceneSession), exceptionInfo);
2598 return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
2599 }
2600 }
2601 sceneSession->NotifyActivation();
2602 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2603 sceneSessionInfo->isNewWant = isNewActive;
2604 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2605 sceneSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, sceneSessionInfo->persistentId);
2606 sceneSessionInfo->collaboratorType = sceneSession->GetCollaboratorType();
2607 }
2608 TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
2609 "module: %{public}s, uri: %{public}s, appIndex: %{public}d, requestId:%{public}d", persistentId,
2610 sceneSessionInfo->want.GetElement().GetAbilityName().c_str(),
2611 sceneSessionInfo->want.GetElement().GetBundleName().c_str(),
2612 sceneSessionInfo->want.GetElement().GetModuleName().c_str(),
2613 sceneSessionInfo->want.GetElement().GetURI().c_str(),
2614 sceneSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0),
2615 sceneSessionInfo->requestId);
2616 int32_t errCode = ERR_OK;
2617 bool isColdStart = false;
2618 if (!systemConfig_.backgroundswitch || sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc()) {
2619 TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
2620 static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
2621 errCode = StartUIAbilityBySCBTimeoutCheck(sceneSessionInfo,
2622 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
2623 } else {
2624 TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
2625 isNewActive, sceneSession->GetSessionState());
2626 if (isNewActive || sceneSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
2627 sceneSession->GetSessionState() == SessionState::STATE_END) {
2628 TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
2629 static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
2630 errCode = StartUIAbilityBySCBTimeoutCheck(sceneSessionInfo,
2631 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
2632 } else {
2633 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
2634 sceneSession->NotifySessionForeground(1, true);
2635 }
2636 }
2637 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2638 WindowInfoReporter::GetInstance().InsertShowReportInfo(sceneSession->GetSessionInfo().bundleName_);
2639 }
2640 NotifyCollaboratorAfterStart(sceneSession, sceneSessionInfo);
2641 if (errCode != ERR_OK) {
2642 TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
2643 ExceptionInfo exceptionInfo;
2644 exceptionInfo.needRemoveSession = true;
2645 sceneSession->NotifySessionExceptionInner(sceneSessionInfo, exceptionInfo, false, true);
2646 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
2647 startUIAbilityErrorFunc_(
2648 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
2649 }
2650 }
2651 if (isColdStart) {
2652 TLOGI(WmsLogTag::WMS_MAIN, "Cold start, identityToken:%{public}s, bundleName:%{public}s",
2653 sceneSessionInfo->identityToken.c_str(), sceneSession->GetSessionInfo().bundleName_.c_str());
2654 sceneSession->SetClientIdentityToken(sceneSessionInfo->identityToken);
2655 sceneSession->ResetSessionConnectState();
2656 sceneSession->ResetIsActive();
2657 }
2658 return WSError::WS_OK;
2659 }
2660
NotifyCollaboratorAfterStart(sptr<SceneSession> & sceneSession,sptr<AAFwk::SessionInfo> & sceneSessionInfo)2661 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& sceneSession,
2662 sptr<AAFwk::SessionInfo>& sceneSessionInfo)
2663 {
2664 if (sceneSession == nullptr || sceneSessionInfo == nullptr) {
2665 return;
2666 }
2667 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2668 NotifyLoadAbility(sceneSession->GetCollaboratorType(),
2669 sceneSessionInfo, sceneSession->GetSessionInfo().abilityInfo);
2670 NotifyUpdateSessionInfo(sceneSession);
2671 NotifyMoveSessionToForeground(sceneSession->GetCollaboratorType(), sceneSessionInfo->persistentId);
2672 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
2673 }
2674 }
2675
IsPcSceneSessionLifecycle(const sptr<SceneSession> & sceneSession)2676 bool SceneSessionManager::IsPcSceneSessionLifecycle(const sptr<SceneSession>& sceneSession)
2677 {
2678 bool isPcAppInPad = sceneSession->GetSessionProperty()->GetIsPcAppInPad();
2679 bool isAppSupportPhoneInPc = sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc();
2680 return (systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) || (isPcAppInPad && !IsScreenLocked());
2681 }
2682
InitSnapshotCache()2683 void SceneSessionManager::InitSnapshotCache()
2684 {
2685 const static std::unordered_map<WindowUIType, std::size_t> SNAPSHOT_CACHE_CAPACITY_MAP = {
2686 {WindowUIType::PC_WINDOW, MAX_SNAPSHOT_IN_RECENT_PC},
2687 {WindowUIType::PAD_WINDOW, MAX_SNAPSHOT_IN_RECENT_PAD},
2688 {WindowUIType::PHONE_WINDOW, MAX_SNAPSHOT_IN_RECENT_PHONE},
2689 {WindowUIType::INVALID_WINDOW, MAX_SNAPSHOT_IN_RECENT_PHONE},
2690 };
2691
2692 snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(WindowUIType::INVALID_WINDOW);
2693 auto uiType = systemConfig_.windowUIType_;
2694 if (SNAPSHOT_CACHE_CAPACITY_MAP.find(uiType) != SNAPSHOT_CACHE_CAPACITY_MAP.end()) {
2695 snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(uiType);
2696 }
2697 TLOGI(WmsLogTag::WMS_PATTERN, "type: %{public}hhu, capacity: %{public}zu", uiType, snapshotCapacity_);
2698 snapshotLruCache_ = std::make_unique<LruCache>(snapshotCapacity_);
2699 }
2700
PutSnapshotToCache(int32_t persistentId)2701 void SceneSessionManager::PutSnapshotToCache(int32_t persistentId)
2702 {
2703 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2704 if (int32_t removedCacheId = snapshotLruCache_->Put(persistentId);
2705 removedCacheId != UNDEFINED_REMOVED_KEY) {
2706 if (auto removedCacheSession = GetSceneSession(removedCacheId)) {
2707 removedCacheSession->ResetSnapshot();
2708 } else {
2709 TLOGW(WmsLogTag::WMS_PATTERN, "removedCacheSession:%{public}d nullptr", removedCacheId);
2710 }
2711 }
2712 }
2713
VisitSnapshotFromCache(int32_t persistentId)2714 void SceneSessionManager::VisitSnapshotFromCache(int32_t persistentId)
2715 {
2716 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2717 if (!snapshotLruCache_->Visit(persistentId)) {
2718 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d not in cache", persistentId);
2719 }
2720 }
2721
RemoveSnapshotFromCache(int32_t persistentId)2722 void SceneSessionManager::RemoveSnapshotFromCache(int32_t persistentId)
2723 {
2724 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2725 snapshotLruCache_->Remove(persistentId);
2726 if (auto sceneSession = GetSceneSession(persistentId)) {
2727 sceneSession->ResetSnapshot();
2728 }
2729 }
2730
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot)2731 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
2732 const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
2733 {
2734 auto task = [this, weakSceneSession = wptr(sceneSession), isDelegator, isToDesktop, isSaveSnapshot] {
2735 auto sceneSession = weakSceneSession.promote();
2736 if (sceneSession == nullptr) {
2737 TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr");
2738 return WSError::WS_ERROR_NULLPTR;
2739 }
2740 auto persistentId = sceneSession->GetPersistentId();
2741 TLOGNI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2742 "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2743 persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2744 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2745
2746 if (sceneSession->GetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) {
2747 TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId);
2748 if (!sceneSession->UpdateInteractiveInner(false)) {
2749 TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId);
2750 }
2751 }
2752 sceneSession->SetActive(false);
2753
2754 if (isToDesktop) {
2755 sceneSession->EditSessionInfo().callerToken_ = nullptr;
2756 sceneSession->EditSessionInfo().callingTokenId_ = 0;
2757 }
2758
2759 sceneSession->SetSaveSnapshotCallback([this, persistentId]() {
2760 this->PutSnapshotToCache(persistentId);
2761 });
2762 sceneSession->BackgroundTask(isSaveSnapshot);
2763 listenerController_->NotifySessionLifecycleEvent(
2764 ISessionLifecycleListener::SessionLifecycleEvent::BACKGROUND, sceneSession->GetSessionInfo());
2765 if (!GetSceneSession(persistentId)) {
2766 TLOGNE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2767 return WSError::WS_ERROR_INVALID_SESSION;
2768 }
2769 if (persistentId == brightnessSessionId_) {
2770 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
2771 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
2772 UpdateBrightness(focusedSessionId);
2773 }
2774 if (IsPcSceneSessionLifecycle(sceneSession)) {
2775 TLOGNI(WmsLogTag::WMS_MAIN, "Notify session background: %{public}d", persistentId);
2776 sceneSession->NotifySessionBackground(1, true, true);
2777 } else {
2778 TLOGNI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2779 persistentId, static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
2780 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2781 if (!isDelegator) {
2782 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, false,
2783 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
2784 } else {
2785 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, true,
2786 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
2787 }
2788 }
2789
2790 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2791 WindowInfoReporter::GetInstance().InsertHideReportInfo(sceneSession->GetSessionInfo().bundleName_);
2792 }
2793 return WSError::WS_OK;
2794 };
2795 std::string taskName = "RequestSceneSessionBackground:PID:" +
2796 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2797 taskScheduler_->PostAsyncTask(task, taskName);
2798 return WSError::WS_OK;
2799 }
2800
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)2801 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2802 {
2803 taskScheduler_->PostAsyncTask([this, weakSceneSession = wptr(sceneSession), interactive] {
2804 auto sceneSession = weakSceneSession.promote();
2805 if (sceneSession == nullptr) {
2806 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
2807 return;
2808 }
2809 auto persistentId = sceneSession->GetPersistentId();
2810 TLOGNI(WmsLogTag::WMS_LIFE, "NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2811 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2812 if (!GetSceneSession(persistentId)) {
2813 TLOGNE(WmsLogTag::WMS_LIFE, "session is invalid with %{public}d", persistentId);
2814 return;
2815 }
2816 sceneSession->NotifyForegroundInteractiveStatus(interactive);
2817 }, __func__);
2818 }
2819
DestroyDialogWithMainWindow(const sptr<SceneSession> & sceneSession)2820 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& sceneSession)
2821 {
2822 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2823 if (sceneSession == nullptr) {
2824 TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2825 return WSError::WS_ERROR_NULLPTR;
2826 }
2827 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2828 TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", sceneSession->GetPersistentId());
2829 const auto& dialogVec = sceneSession->GetDialogVector();
2830 for (const auto& dialog : dialogVec) {
2831 if (dialog == nullptr) {
2832 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2833 continue;
2834 }
2835 auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2836 if (sceneSession == nullptr) {
2837 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2838 return WSError::WS_ERROR_INVALID_SESSION;
2839 }
2840 WindowDestroyNotifyVisibility(sceneSession);
2841 dialog->NotifyDestroy();
2842 dialog->Disconnect();
2843
2844 auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2845 if (dialogSceneSession != nullptr) {
2846 dialogSceneSession->ClearSpecificSessionCbMap();
2847 }
2848 {
2849 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2850 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
2851 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2852 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2853 }
2854 }
2855 sceneSession->ClearDialogVector();
2856 return WSError::WS_OK;
2857 }
2858 return WSError::WS_ERROR_INVALID_SESSION;
2859 }
2860
DestroySubSession(const sptr<SceneSession> & sceneSession)2861 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2862 {
2863 if (sceneSession == nullptr) {
2864 TLOGW(WmsLogTag::WMS_SUB, "sceneSession is nullptr");
2865 return;
2866 }
2867 for (const auto& subSession : sceneSession->GetSubSession()) {
2868 if (subSession != nullptr) {
2869 const auto persistentId = subSession->GetPersistentId();
2870 TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
2871 DestroyAndDisconnectSpecificSessionInner(persistentId);
2872 }
2873 }
2874 }
2875
DestroyToastSession(const sptr<SceneSession> & sceneSession)2876 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2877 {
2878 if (sceneSession == nullptr) {
2879 TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2880 return;
2881 }
2882 for (const auto& toastSession : sceneSession->GetToastSession()) {
2883 if (toastSession != nullptr) {
2884 const auto persistentId = toastSession->GetPersistentId();
2885 TLOGI(WmsLogTag::WMS_TOAST, "id: %{public}d", persistentId);
2886 DestroyAndDisconnectSpecificSessionInner(persistentId);
2887 }
2888 }
2889 }
2890
BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,int32_t fingerId,int32_t action,int32_t wid)2891 void SceneSessionManager::BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2892 int32_t fingerId, int32_t action, int32_t wid)
2893 {
2894 if (pointerEvent == nullptr) {
2895 TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null, wid:%{public}d fingerId:%{public}d action:%{public}d",
2896 wid, fingerId, action);
2897 return;
2898 }
2899 pointerEvent->SetId(CANCEL_POINTER_ID);
2900 pointerEvent->SetTargetWindowId(wid);
2901 pointerEvent->SetPointerId(fingerId);
2902 pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
2903 MMI::PointerEvent::PointerItem item;
2904 item.SetPointerId(fingerId);
2905 pointerEvent->AddPointerItem(item);
2906 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN) {
2907 pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
2908 } else {
2909 pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_MOUSE);
2910 }
2911 }
2912
SendCancelEventBeforeEraseSession(const sptr<SceneSession> & sceneSession)2913 void SceneSessionManager::SendCancelEventBeforeEraseSession(const sptr<SceneSession>& sceneSession)
2914 {
2915 auto task = [this, needCancelEventSceneSession = sceneSession] {
2916 if (needCancelEventSceneSession == nullptr) {
2917 TLOGI(WmsLogTag::WMS_EVENT, "scenesession is nullptr, needn't send cancel event");
2918 return;
2919 }
2920 auto wid = needCancelEventSceneSession->GetPersistentId();
2921 if (needCancelEventSceneSession->GetMousePointerDownEventStatus()) {
2922 std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
2923 BuildCancelPointerEvent(pointerEvent, 1, MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN, wid);
2924 TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send mouse cancel. wid:%{public}d", wid);
2925 needCancelEventSceneSession->SetMousePointerDownEventStatus(false);
2926 needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
2927 }
2928 std::unordered_set<int32_t> fingerPointerDownStatusList = needCancelEventSceneSession->GetFingerPointerDownStatusList();
2929 if (fingerPointerDownStatusList.empty()) {
2930 return;
2931 }
2932 for (auto fingerId : fingerPointerDownStatusList) {
2933 std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
2934 BuildCancelPointerEvent(pointerEvent, fingerId, MMI::PointerEvent::POINTER_ACTION_DOWN, wid);
2935 TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send touch cancel. wid:%{public}d fingerId:%{public}d",
2936 wid, fingerId);
2937 needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
2938 needCancelEventSceneSession->RemoveFingerPointerDownStatus(fingerId);
2939 }
2940 };
2941 mainHandler_->PostTask(std::move(task), "wms:sendCancelBeforeEraseSession", 0, AppExecFwk::EventQueue::Priority::VIP);
2942 }
2943
EraseSceneSessionMapById(int32_t persistentId)2944 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2945 {
2946 auto sceneSession = GetSceneSession(persistentId);
2947 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2948 EraseSceneSessionAndMarkDirtyLocked(persistentId);
2949 systemTopSceneSessionMap_.erase(persistentId);
2950 nonSystemFloatSceneSessionMap_.erase(persistentId);
2951 SendCancelEventBeforeEraseSession(sceneSession);
2952 if (sceneSession && MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2953 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2954 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
2955 }
2956 }
2957
2958 /**
2959 * if visible session is erased, mark dirty
2960 * lock-free
2961 */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)2962 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
2963 {
2964 // get scene session lock-free
2965 auto iter = sceneSessionMap_.find(persistentId);
2966 if (iter == sceneSessionMap_.end()) {
2967 TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2968 return;
2969 }
2970 const auto& sceneSession = iter->second;
2971 if (sceneSession != nullptr && sceneSession->IsVisible()) {
2972 sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2973 }
2974 sceneSessionMap_.erase(persistentId);
2975 }
2976
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean,bool isUserRequestedExit)2977 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2978 bool needRemoveSession, bool isSaveSnapshot, bool isForceClean, bool isUserRequestedExit)
2979 {
2980 auto task = [this, weakSceneSession = wptr(sceneSession), needRemoveSession, isSaveSnapshot, isForceClean,
2981 isUserRequestedExit]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
2982 auto sceneSession = weakSceneSession.promote();
2983 if (sceneSession == nullptr) {
2984 TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2985 return WSError::WS_ERROR_NULLPTR;
2986 }
2987 auto persistentId = sceneSession->GetPersistentId();
2988 TLOGNI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d "
2989 "isForceClean:%{public}d isUserRequestedExit:%{public}d", persistentId, needRemoveSession, isSaveSnapshot,
2990 isForceClean, isUserRequestedExit);
2991 RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2992 avoidAreaListenerSessionSet_.erase(persistentId);
2993 DestroyDialogWithMainWindow(sceneSession);
2994 DestroyToastSession(sceneSession);
2995 DestroySubSession(sceneSession); // destroy sub session by destruction
2996 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2997 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2998 WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sceneSession->GetSessionInfo().bundleName_);
2999 }
3000 WindowDestroyNotifyVisibility(sceneSession);
3001 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
3002 sceneSession->SetRemoveSnapshotCallback([this, persistentId]() {
3003 this->RemoveSnapshotFromCache(persistentId);
3004 });
3005 if (sceneSession->GetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) {
3006 TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId);
3007 if (!sceneSession->UpdateInteractiveInner(false)) {
3008 TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId);
3009 }
3010 }
3011 sceneSession->DisconnectTask(false, isSaveSnapshot);
3012 if (!GetSceneSession(persistentId)) {
3013 TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
3014 return WSError::WS_ERROR_INVALID_SESSION;
3015 }
3016 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
3017 sceneSession->GetCloseAbilityWantAndClean(sceneSessionInfo->want);
3018 ResetSceneSessionInfoWant(sceneSessionInfo);
3019 return RequestSceneSessionDestructionInner(
3020 sceneSession, sceneSessionInfo, needRemoveSession, isForceClean, isUserRequestedExit);
3021 };
3022 std::string taskName = "RequestSceneSessionDestruction:PID:" +
3023 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
3024 taskScheduler_->PostAsyncTask(task, taskName);
3025 return WSError::WS_OK;
3026 }
3027
ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo> & sceneSessionInfo)3028 void SceneSessionManager::ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo>& sceneSessionInfo)
3029 {
3030 if (sceneSessionInfo->resultCode == -1) {
3031 AAFwk::Want want;
3032 std::string keySessionId = sceneSessionInfo->want.GetStringParam(ATOMIC_SERVICE_SESSION_ID);
3033 want.SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
3034 sceneSessionInfo->want = std::move(want);
3035 TLOGI(WmsLogTag::WMS_MAIN, "keySessionId: %{public}s", keySessionId.c_str());
3036 }
3037 }
3038
ResetWantInfo(const sptr<SceneSession> & sceneSession)3039 void SceneSessionManager::ResetWantInfo(const sptr<SceneSession>& sceneSession)
3040 {
3041 if (const auto sessionInfoWant = sceneSession->GetSessionInfo().want) {
3042 const auto& bundleName = sessionInfoWant->GetElement().GetBundleName();
3043 const auto& abilityName = sessionInfoWant->GetElement().GetAbilityName();
3044 const auto& keySessionId = sessionInfoWant->GetStringParam(ATOMIC_SERVICE_SESSION_ID);
3045 AppExecFwk::ElementName element;
3046 element.SetBundleName(bundleName);
3047 element.SetAbilityName(abilityName);
3048 auto want = std::make_shared<AAFwk::Want>();
3049 want->SetElement(element);
3050 want->SetBundle(bundleName);
3051 if (!keySessionId.empty()) {
3052 want->SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
3053 }
3054 sceneSession->SetSessionInfoWant(want);
3055 }
3056 }
3057
RequestSceneSessionDestructionInner(sptr<SceneSession> & sceneSession,sptr<AAFwk::SessionInfo> sceneSessionInfo,const bool needRemoveSession,const bool isForceClean,bool isUserRequestedExit)3058 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& sceneSession,
3059 sptr<AAFwk::SessionInfo> sceneSessionInfo, const bool needRemoveSession, const bool isForceClean,
3060 bool isUserRequestedExit)
3061 {
3062 auto persistentId = sceneSession->GetPersistentId();
3063 TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}d",
3064 persistentId, sceneSession->GetSessionInfo().isSystem_);
3065 if (isForceClean) {
3066 AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit,
3067 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3068 } else {
3069 AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit,
3070 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3071 }
3072 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
3073 if (needRemoveSession) {
3074 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3075 NotifyClearSession(sceneSession->GetCollaboratorType(), sceneSessionInfo->persistentId);
3076 }
3077 EraseSceneSessionMapById(persistentId);
3078 } else {
3079 // if terminate, reset want. so start from recent, start a new one.
3080 TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
3081 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3082 sceneSession->SetSessionInfoWant(nullptr);
3083 }
3084 ResetWantInfo(sceneSession);
3085 sceneSession->ResetSessionInfoResultCode();
3086 }
3087 NotifySessionForCallback(sceneSession, needRemoveSession);
3088 // Clear js cb map if needed.
3089 sceneSession->ClearJsSceneSessionCbMap(needRemoveSession);
3090 return WSError::WS_OK;
3091 }
3092
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)3093 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
3094 const sptr<SceneSession>& sceneSession)
3095 {
3096 if (sceneSession == nullptr || sessionStage == nullptr) {
3097 TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
3098 return;
3099 }
3100
3101 auto remoteObject = sessionStage->AsObject();
3102 remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
3103 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
3104 TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
3105 return;
3106 }
3107 TLOGD(WmsLogTag::WMS_LIFE, "Id: %{public}d", sceneSession->GetPersistentId());
3108 }
3109
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)3110 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
3111 {
3112 taskScheduler_->PostAsyncTask([this, remoteObject] {
3113 auto iter = remoteObjectMap_.find(remoteObject);
3114 if (iter == remoteObjectMap_.end()) {
3115 TLOGNE(WmsLogTag::WMS_DIALOG, "Invalid remoteObject");
3116 return;
3117 }
3118 TLOGND(WmsLogTag::WMS_DIALOG, "Remote died, id: %{public}d", iter->second);
3119 auto sceneSession = GetSceneSession(iter->second);
3120 if (sceneSession == nullptr) {
3121 TLOGNW(WmsLogTag::WMS_DIALOG, "Remote died, session is nullptr, id: %{public}d", iter->second);
3122 return;
3123 }
3124 DestroyAndDisconnectSpecificSessionInner(iter->second);
3125 }, __func__);
3126 }
3127
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)3128 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
3129 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3130 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
3131 SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
3132 {
3133 if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
3134 TLOGE(WmsLogTag::WMS_LIFE, "create system window or modal subwindow permission denied!");
3135 return WSError::WS_ERROR_NOT_SYSTEM_APP;
3136 }
3137 auto parentSession = GetSceneSession(property->GetParentPersistentId());
3138 if (parentSession) {
3139 auto parentProperty = parentSession->GetSessionProperty();
3140 if (parentProperty->GetSubWindowLevel() >= MAX_SUB_WINDOW_LEVEL) {
3141 TLOGE(WmsLogTag::WMS_SUB, "sub window level exceeds limit");
3142 return WSError::WS_ERROR_INVALID_WINDOW;
3143 }
3144 property->SetSubWindowLevel(parentProperty->GetSubWindowLevel() + 1);
3145 }
3146 auto initClientDisplayId = UpdateSpecificSessionClientDisplayId(property);
3147 TLOGI(WmsLogTag::WMS_LIFE, "The corner radius is %{public}f", appWindowSceneConfig_.floatCornerRadius_);
3148 property->SetWindowCornerRadius(appWindowSceneConfig_.floatCornerRadius_);
3149 bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
3150 property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
3151 bool isSystemCalling = SessionPermission::IsSystemCalling();
3152 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
3153 if (parentSession) {
3154 shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
3155 }
3156 }
3157 if (systemConfig_.IsPcWindow() && property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
3158 TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't block");
3159 shouldBlock = false;
3160 }
3161 if (shouldBlock) {
3162 TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
3163 return WSError::WS_ERROR_INVALID_OPERATION;
3164 }
3165
3166 if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
3167 WSError err = CheckSubSessionStartedByExtensionAndSetDisplayId(token, property, sessionStage);
3168 if (err != WSError::WS_OK) {
3169 return err;
3170 }
3171 }
3172 // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
3173 if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
3174 TLOGE(WmsLogTag::DEFAULT, "The alarm window has been deprecated!");
3175 return WSError::WS_ERROR_INVALID_WINDOW;
3176 }
3177
3178 TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
3179 property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
3180
3181 // Get pid and uid before posting task.
3182 auto pid = IPCSkeleton::GetCallingRealPid();
3183 auto uid = IPCSkeleton::GetCallingUid();
3184 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &persistentId, &session, &systemConfig, token,
3185 pid, uid, isSystemCalling, initClientDisplayId]() {
3186 if (property == nullptr) {
3187 TLOGNE(WmsLogTag::WMS_LIFE, "property is nullptr");
3188 return WSError::WS_ERROR_NULLPTR;
3189 }
3190 if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !IsEnablePiPCreate(property)) {
3191 TLOGNE(WmsLogTag::WMS_PIP, "pip window is not enable to create.");
3192 return WSError::WS_DO_NOTHING;
3193 }
3194 const auto type = property->GetWindowType();
3195 // create specific session
3196 SessionInfo info;
3197 info.windowType_ = static_cast<uint32_t>(type);
3198 info.bundleName_ = property->GetSessionInfo().bundleName_;
3199 info.abilityName_ = property->GetSessionInfo().abilityName_;
3200 info.moduleName_ = property->GetSessionInfo().moduleName_;
3201 info.screenId_ = property->GetDisplayId();
3202
3203 if (IsPiPForbidden(property, type)) {
3204 TLOGNE(WmsLogTag::WMS_PIP, "forbid pip");
3205 return WSError::WS_ERROR_INVALID_PERMISSION;
3206 }
3207 ClosePipWindowIfExist(type);
3208 sptr<SceneSession> newSession = RequestSceneSession(info, property);
3209 if (newSession == nullptr) {
3210 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
3211 return WSError::WS_ERROR_NULLPTR;
3212 }
3213 newSession->SetClientDisplayId(initClientDisplayId);
3214 newSession->GetSessionProperty()->SetWindowCornerRadius(property->GetWindowCornerRadius());
3215 property->SetSystemCalling(isSystemCalling);
3216 auto errCode = newSession->ConnectInner(
3217 sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
3218 newSession->SetIsSystemSpecificSession(isSystemCalling);
3219 systemConfig = systemConfig_;
3220 persistentId = property->GetPersistentId();
3221
3222 NotifyCreateSpecificSession(newSession, property, type);
3223 session = newSession;
3224 AddClientDeathRecipient(sessionStage, newSession);
3225
3226 if (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
3227 CheckFloatWindowIsAnco(pid, newSession);
3228 }
3229
3230 TLOGNI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
3231 "parentId: %{public}d, type: %{public}d",
3232 newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
3233 return errCode;
3234 };
3235
3236 return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
3237 }
3238
CheckSubSessionStartedByExtensionAndSetDisplayId(const sptr<IRemoteObject> & token,const sptr<WindowSessionProperty> & property,const sptr<ISessionStage> & sessionStage)3239 WSError SceneSessionManager::CheckSubSessionStartedByExtensionAndSetDisplayId(const sptr<IRemoteObject>& token,
3240 const sptr<WindowSessionProperty>& property, const sptr<ISessionStage>& sessionStage)
3241 {
3242 sptr<SceneSession> extensionParentSession = GetSceneSession(property->GetParentPersistentId());
3243 if (extensionParentSession == nullptr) {
3244 TLOGE(WmsLogTag::WMS_UIEXT, "extensionParentSession is invalid with %{public}d",
3245 property->GetParentPersistentId());
3246 return WSError::WS_ERROR_NULLPTR;
3247 }
3248 auto pid = IPCSkeleton::GetCallingRealPid();
3249 auto parentPid = extensionParentSession->GetCallingPid();
3250 WSError result = WSError::WS_ERROR_INVALID_WINDOW;
3251 if (pid == parentPid) { // Determine Whether to create a sub window in the same process.
3252 TLOGI(WmsLogTag::WMS_UIEXT, "pid == parentPid");
3253 result = WSError::WS_OK;
3254 }
3255 AAFwk::UIExtensionSessionInfo info;
3256 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
3257 if (info.persistentId != INVALID_SESSION_ID && info.hostWindowId != INVALID_SESSION_ID) {
3258 int32_t parentId = static_cast<int32_t>(info.hostWindowId);
3259 // Check the parent ids are the same in cross-process scenarios.
3260 if (parentId == property->GetParentPersistentId()) {
3261 TLOGI(WmsLogTag::WMS_UIEXT, "parentId == property->GetParentPersistentId(parentId:%{public}d)", parentId);
3262 result = WSError::WS_OK;
3263 }
3264 }
3265 if (SessionPermission::IsSystemCalling()) { // Fallback strategy.
3266 TLOGI(WmsLogTag::WMS_UIEXT, "is system app");
3267 result = WSError::WS_OK;
3268 }
3269 if (property->GetIsUIExtensionAbilityProcess() && SessionPermission::IsStartedByUIExtension()) {
3270 AAFwk::UIExtensionHostInfo hostInfo;
3271 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
3272 const auto& sessionInfo = extensionParentSession->GetSessionInfo();
3273 if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
3274 TLOGE(WmsLogTag::WMS_UIEXT, "The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s,"
3275 " hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
3276 hostInfo.elementName_.GetBundleName().c_str());
3277 ReportSubWindowCreationFailure(pid, info.elementName.GetAbilityName(), sessionInfo.bundleName_,
3278 hostInfo.elementName_.GetBundleName());
3279 return WSError::WS_ERROR_INVALID_WINDOW;
3280 }
3281 result = WSError::WS_OK;
3282 }
3283 if (result == WSError::WS_OK) {
3284 sptr<WindowSessionProperty> parentProperty = extensionParentSession->GetSessionProperty();
3285 if (sessionStage && property->GetIsUIExtFirstSubWindow()) {
3286 sessionStage->UpdateDisplayId(parentProperty->GetDisplayId());
3287 property->SetDisplayId(parentProperty->GetDisplayId());
3288 }
3289 } else {
3290 TLOGE(WmsLogTag::WMS_UIEXT, "can't create sub window: persistentId %{public}d", property->GetPersistentId());
3291 }
3292 return result;
3293 }
3294
ReportSubWindowCreationFailure(int32_t pid,const std::string & abilityName,const std::string & parentBundleName,const std::string & hostBundleName)3295 void SceneSessionManager::ReportSubWindowCreationFailure(int32_t pid, const std::string& abilityName,
3296 const std::string& parentBundleName, const std::string& hostBundleName)
3297 {
3298 taskScheduler_->PostAsyncTask([pid, abilityName, parentBundleName, hostBundleName]() {
3299 std::ostringstream oss;
3300 oss << "The hostWindow is not this parentwindow ! parentwindow bundleName: " << parentBundleName;
3301 oss << ", hostwindow bundleName: " << hostBundleName;
3302 oss << ", abilityName: " << abilityName;
3303 SingletonContainer::Get<WindowInfoReporter>().ReportWindowException(
3304 static_cast<int32_t>(WindowDFXHelperType::WINDOW_CREATE_SUB_WINDOW_FAILED), pid, oss.str());
3305 }, __func__);
3306 }
3307
CheckFloatWindowIsAnco(pid_t pid,const sptr<SceneSession> & newSession)3308 void SceneSessionManager::CheckFloatWindowIsAnco(pid_t pid, const sptr<SceneSession>& newSession)
3309 {
3310 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
3311 {
3312 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3313 sceneSessionMapCopy = sceneSessionMap_;
3314 }
3315 for (const auto& [_, session] : sceneSessionMapCopy) {
3316 if (session && session->GetCallingPid() == pid &&
3317 session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3318 auto sessionInfo = session->GetSessionInfo();
3319 if (AbilityInfoManager::GetInstance().IsAnco(sessionInfo.bundleName_,
3320 sessionInfo.abilityName_, sessionInfo.moduleName_)) {
3321 newSession->SetIsAncoForFloatingWindow(true);
3322 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Set float window is anco, wid: %{public}d", newSession->GetWindowId());
3323 break;
3324 }
3325 }
3326 }
3327 }
3328
ClosePipWindowIfExist(WindowType type)3329 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
3330 {
3331 if (type != WindowType::WINDOW_TYPE_PIP) {
3332 return;
3333 }
3334 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3335 for (const auto& [_, session] : sceneSessionMap_) {
3336 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
3337 session->NotifyCloseExistPipWindow();
3338 break;
3339 }
3340 }
3341 }
3342
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo)3343 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
3344 {
3345 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3346 for (const auto& [_, session] : sceneSessionMap_) {
3347 if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
3348 pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
3349 session->IsSessionForeground()) {
3350 if (startPiPFailedFunc_) {
3351 startPiPFailedFunc_();
3352 }
3353 TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
3354 return false;
3355 }
3356 }
3357 return true;
3358 }
3359
IsEnablePiPCreate(const sptr<WindowSessionProperty> & property)3360 bool SceneSessionManager::IsEnablePiPCreate(const sptr<WindowSessionProperty>& property)
3361 {
3362 if (isScreenLocked_) {
3363 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
3364 return false;
3365 }
3366 Rect pipRect = property->GetRequestRect();
3367 if (pipRect.width_ == 0 || pipRect.height_ == 0) {
3368 TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
3369 return false;
3370 }
3371 if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
3372 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
3373 return false;
3374 }
3375 auto parentSession = GetSceneSession(property->GetParentPersistentId());
3376 if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
3377 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
3378 return false;
3379 }
3380 return true;
3381 }
3382
IsPiPForbidden(const sptr<WindowSessionProperty> & property,const WindowType & type)3383 bool SceneSessionManager::IsPiPForbidden(const sptr<WindowSessionProperty>& property, const WindowType& type)
3384 {
3385 sptr<SceneSession> parentSession = GetSceneSession(property->GetParentPersistentId());
3386 if (parentSession == nullptr) {
3387 TLOGE(WmsLogTag::WMS_PIP, "invalid parentSession");
3388 return false;
3389 }
3390 sptr<WindowSessionProperty> parentProperty = parentSession->GetSessionProperty();
3391 if (parentProperty == nullptr) {
3392 TLOGE(WmsLogTag::WMS_PIP, "invalid parentProperty");
3393 return false;
3394 }
3395 DisplayId screenId = parentProperty->GetDisplayId();
3396 if (screenId == SCREEN_ID_INVALID) {
3397 TLOGE(WmsLogTag::WMS_PIP, "invalid screenId");
3398 return false;
3399 }
3400 sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(screenId);
3401 if (screenSession == nullptr) {
3402 TLOGE(WmsLogTag::WMS_PIP, "invalid screenSession");
3403 return false;
3404 }
3405 std::string screenName = screenSession->GetName();
3406 if (type == WindowType::WINDOW_TYPE_PIP &&
3407 (screenName == "HiCar" || screenName == "SuperLauncher")) {
3408 TLOGI(WmsLogTag::WMS_PIP, "screen name %{public}s", screenName.c_str());
3409 return true;
3410 }
3411 return false;
3412 }
3413
NotifyPiPWindowVisibleChange(bool screenLocked)3414 void SceneSessionManager::NotifyPiPWindowVisibleChange(bool screenLocked) {
3415 sptr<SceneSession> session = SelectSesssionFromMap(pipWindowSurfaceId_);
3416 if (session != nullptr) {
3417 std::vector<std::pair<uint64_t, WindowVisibilityState>> pipVisibilityChangeInfos;
3418 if (screenLocked) {
3419 pipVisibilityChangeInfos.emplace_back(pipWindowSurfaceId_, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
3420 } else {
3421 pipVisibilityChangeInfos.emplace_back(pipWindowSurfaceId_, WINDOW_VISIBILITY_STATE_NO_OCCLUSION);
3422 }
3423 DealwithVisibilityChange(pipVisibilityChangeInfos, lastVisibleData_);
3424 }
3425 }
3426
IsLastPiPWindowVisible(uint64_t surfaceId,WindowVisibilityState lastVisibilityState)3427 bool SceneSessionManager::IsLastPiPWindowVisible(uint64_t surfaceId, WindowVisibilityState lastVisibilityState) {
3428 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
3429 if (session == nullptr || session->GetWindowMode() != WindowMode::WINDOW_MODE_PIP) {
3430 TLOGD(WmsLogTag::WMS_PIP, "session is null or windowMode is not PIP");
3431 return false;
3432 }
3433 if (isScreenLocked_) {
3434 TLOGD(WmsLogTag::WMS_PIP, "pipWindow occlusion because of screen locked");
3435 return false;
3436 }
3437 if (lastVisibilityState != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
3438 // no visibility notification processing after pip is occlusion
3439 TLOGI(WmsLogTag::WMS_PIP, "pipWindow occlusion success. pipWindowSurfaceId: %{public}" PRIu64, surfaceId);
3440 pipWindowSurfaceId_ = surfaceId;
3441 return true;
3442 }
3443 return false;
3444 }
3445
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)3446 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
3447 {
3448 WindowType type = property->GetWindowType();
3449 if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
3450 return true;
3451 }
3452
3453 if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
3454 TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
3455 return false;
3456 }
3457
3458 if (!SessionPermission::IsSystemCalling()) {
3459 TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
3460 return false;
3461 }
3462
3463 return true;
3464 }
3465
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)3466 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
3467 {
3468 WindowType type = property->GetWindowType();
3469 if (WindowHelper::IsUIExtensionWindow(type)) {
3470 // UIExtension window disallowed.
3471 return false;
3472 }
3473 if (!WindowHelper::IsSystemWindow(type)) {
3474 // type is not system
3475 return true;
3476 }
3477 if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && property->IsSystemKeyboard()) {
3478 // system keyboard window can only be created by virtual keyboard service
3479 if (SessionPermission::VerifyCallingPermission("ohos.permission.VIRTUAL_KEYBOARD_WINDOW")) {
3480 TLOGD(WmsLogTag::WMS_KEYBOARD, "create system keyboard, permission check sucess.");
3481 return true;
3482 }
3483 TLOGE(WmsLogTag::WMS_KEYBOARD, "create system keyboard, permission check failed.");
3484 return false;
3485 }
3486 if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
3487 type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR) && SessionPermission::IsStartedByInputMethod()) {
3488 // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
3489 TLOGD(WmsLogTag::WMS_KEYBOARD, "check create permission success, input method app create input method window.");
3490 return true;
3491 }
3492 if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
3493 // some system types could be created by normal app
3494 return true;
3495 }
3496 if (type == WindowType::WINDOW_TYPE_FLOAT) {
3497 // WINDOW_TYPE_FLOAT could be created with the corresponding permission
3498 if (SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW") &&
3499 (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd() ||
3500 systemConfig_.supportTypeFloatWindow_)) {
3501 TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission success.");
3502 return true;
3503 } else {
3504 TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission failed.");
3505 return false;
3506 }
3507 }
3508 if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
3509 int32_t parentId = property->GetParentPersistentId();
3510 auto parentSession = GetSceneSession(parentId);
3511 if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
3512 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
3513 TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
3514 return true;
3515 } else {
3516 TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
3517 }
3518 }
3519 if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
3520 TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
3521 return true;
3522 }
3523 TLOGE(WmsLogTag::WMS_SYSTEM, "finally check permission failed.");
3524 return false;
3525 }
3526
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)3527 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
3528 {
3529 if (property == nullptr) {
3530 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
3531 return {};
3532 }
3533 SessionInfo sessionInfo = property->GetSessionInfo();
3534 sessionInfo.persistentId_ = property->GetPersistentId();
3535 sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
3536 sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
3537 sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
3538 sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
3539 ? SessionState::STATE_ACTIVE
3540 : SessionState::STATE_BACKGROUND;
3541 sessionInfo.isPersistentRecover_ = true;
3542 sessionInfo.appInstanceKey_ = property->GetAppInstanceKey();
3543 TLOGI(WmsLogTag::WMS_RECOVER,
3544 "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
3545 "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
3546 "windowState=%{public}u, appInstanceKey=%{public}s",
3547 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
3548 sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_,
3549 sessionInfo.appInstanceKey_.c_str());
3550 return sessionInfo;
3551 }
3552
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)3553 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
3554 {
3555 TLOGI(WmsLogTag::WMS_RECOVER, "Size of PersistentIds need to be recovered=%{public}zu, CurrentUserId=%{public}d",
3556 alivePersistentIds.size(), currentUserId_.load());
3557 alivePersistentIds_ = alivePersistentIds;
3558 }
3559
IsNeedRecover(const int32_t persistentId)3560 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
3561 {
3562 if (auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
3563 it == alivePersistentIds_.end()) {
3564 TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
3565 return false;
3566 }
3567 return true;
3568 }
3569
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)3570 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
3571 bool isSpecificSession)
3572 {
3573 if (property == nullptr) {
3574 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
3575 return WSError::WS_ERROR_NULLPTR;
3576 }
3577 if (!CheckSystemWindowPermission(property)) {
3578 TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
3579 return WSError::WS_ERROR_NOT_SYSTEM_APP;
3580 }
3581 if (isSpecificSession) {
3582 if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
3583 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
3584 return WSError::WS_ERROR_INVALID_PARAM;
3585 }
3586 } else {
3587 if (property->GetPersistentId() > 0 && !IsNeedRecover(property->GetPersistentId())) {
3588 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
3589 return WSError::WS_ERROR_INVALID_PARAM;
3590 }
3591 }
3592 return WSError::WS_OK;
3593 }
3594
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)3595 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
3596 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3597 sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
3598 {
3599 auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
3600 if (propCheckRet != WSError::WS_OK) {
3601 return propCheckRet;
3602 }
3603 auto pid = IPCSkeleton::GetCallingRealPid();
3604 auto uid = IPCSkeleton::GetCallingUid();
3605 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
3606 if (recoveringFinished_) {
3607 TLOGNW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3608 return WSError::WS_ERROR_INVALID_OPERATION;
3609 }
3610 UpdateRecoverPropertyForSuperFold(property);
3611 // recover specific session
3612 SessionInfo info = RecoverSessionInfo(property);
3613 TLOGNI(WmsLogTag::WMS_RECOVER, "callingWindowId=%{public}" PRIu32, property->GetCallingSessionId());
3614 ClosePipWindowIfExist(property->GetWindowType());
3615 sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
3616 if (sceneSession == nullptr) {
3617 TLOGNE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
3618 return WSError::WS_ERROR_NULLPTR;
3619 }
3620
3621 auto persistentId = sceneSession->GetPersistentId();
3622 if (persistentId != info.persistentId_) {
3623 TLOGNE(WmsLogTag::WMS_RECOVER,
3624 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
3625 info.persistentId_, persistentId, property->GetParentPersistentId());
3626 failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
3627 EraseSceneSessionMapById(persistentId);
3628 return WSError::WS_ERROR_INVALID_SESSION;
3629 }
3630
3631 auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3632 if (errCode != WSError::WS_OK) {
3633 TLOGNE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
3634 EraseSceneSessionMapById(persistentId);
3635 return errCode;
3636 }
3637 NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
3638 CacheSpecificSessionForRecovering(sceneSession, property);
3639 NotifySessionUnfocusedToClient(persistentId);
3640 AddClientDeathRecipient(sessionStage, sceneSession);
3641 session = sceneSession;
3642 return errCode;
3643 };
3644 return taskScheduler_->PostSyncTask(task, __func__);
3645 }
3646
NotifyRecoveringFinished()3647 void SceneSessionManager::NotifyRecoveringFinished()
3648 {
3649 taskScheduler_->PostAsyncTask([this]() {
3650 TLOGNI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
3651 recoveringFinished_ = true;
3652 recoverSubSessionCacheMap_.clear();
3653 recoverDialogSessionCacheMap_.clear();
3654 }, __func__);
3655 }
3656
CacheSpecificSessionForRecovering(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)3657 void SceneSessionManager::CacheSpecificSessionForRecovering(
3658 const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)
3659 {
3660 if (!IsWindowSupportCacheForRecovering(sceneSession, property)) {
3661 return;
3662 }
3663
3664 auto windowType = property->GetWindowType();
3665 auto parentId = property->GetParentPersistentId();
3666 TLOGI(WmsLogTag::WMS_RECOVER, "Cache specific session persistentId=%{public}d, parent persistentId="
3667 "%{public}d, window type=%{public}d", sceneSession->GetPersistentId(), parentId, windowType);
3668
3669 if (WindowHelper::IsSubWindow(windowType)) {
3670 recoverSubSessionCacheMap_[parentId].emplace_back(sceneSession);
3671 } else if (WindowHelper::IsDialogWindow(windowType)) {
3672 recoverDialogSessionCacheMap_[parentId].emplace_back(sceneSession);
3673 }
3674 }
3675
IsWindowSupportCacheForRecovering(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)3676 bool SceneSessionManager::IsWindowSupportCacheForRecovering(
3677 const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)
3678 {
3679 if (recoveringFinished_) {
3680 TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
3681 return false;
3682 }
3683
3684 if (sceneSession == nullptr || property == nullptr) {
3685 TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
3686 return false;
3687 }
3688
3689 auto windowType = property->GetWindowType();
3690 if (!WindowHelper::IsSubWindow(windowType) && !WindowHelper::IsDialogWindow(windowType)) {
3691 return false;
3692 }
3693
3694 auto parentId = property->GetParentPersistentId();
3695 if ((WindowHelper::IsSubWindow(windowType) &&
3696 createSubSessionFuncMap_.find(parentId) != createSubSessionFuncMap_.end()) ||
3697 (WindowHelper::IsDialogWindow(windowType) &&
3698 bindDialogTargetFuncMap_.find(parentId) != bindDialogTargetFuncMap_.end())) {
3699 return false;
3700 }
3701
3702 return true;
3703 }
3704
RecoverCachedSubSession(int32_t persistentId)3705 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
3706 {
3707 auto iter = recoverSubSessionCacheMap_.find(persistentId);
3708 if (iter == recoverSubSessionCacheMap_.end()) {
3709 return;
3710 }
3711 TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
3712 for (auto& sceneSession : iter->second) {
3713 NotifyCreateSubSession(persistentId, sceneSession);
3714 }
3715 recoverSubSessionCacheMap_.erase(iter);
3716 }
3717
RecoverCachedDialogSession(int32_t persistentId)3718 void SceneSessionManager::RecoverCachedDialogSession(int32_t persistentId)
3719 {
3720 auto iter = recoverDialogSessionCacheMap_.find(persistentId);
3721 if (iter == recoverDialogSessionCacheMap_.end()) {
3722 return;
3723 }
3724 TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
3725 for (auto& sceneSession : iter->second) {
3726 UpdateParentSessionForDialog(sceneSession, sceneSession->GetSessionProperty());
3727 }
3728 recoverDialogSessionCacheMap_.erase(iter);
3729 }
3730
NotifySessionUnfocusedToClient(int32_t persistentId)3731 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
3732 {
3733 TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
3734 listenerController_->NotifySessionUnfocused(persistentId);
3735 }
3736
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)3737 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
3738 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3739 sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
3740 {
3741 auto result = CheckSessionPropertyOnRecovery(property, false);
3742 if (result != WSError::WS_OK) {
3743 return result;
3744 }
3745 auto pid = IPCSkeleton::GetCallingRealPid();
3746 auto uid = IPCSkeleton::GetCallingUid();
3747 auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
3748 if (recoveringFinished_) {
3749 TLOGNW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3750 return WSError::WS_ERROR_INVALID_OPERATION;
3751 }
3752 if (recoverSceneSessionFunc_ == nullptr) {
3753 TLOGNE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
3754 return WSError::WS_ERROR_NULLPTR;
3755 }
3756 UpdateRecoverPropertyForSuperFold(property);
3757 SessionInfo sessionInfo = RecoverSessionInfo(property);
3758 sptr<SceneSession> sceneSession = RequestSceneSession(sessionInfo, nullptr);
3759 if (sceneSession == nullptr) {
3760 TLOGNE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
3761 return WSError::WS_ERROR_NULLPTR;
3762 }
3763 int32_t persistentId = sceneSession->GetPersistentId();
3764 if (persistentId != sessionInfo.persistentId_) {
3765 TLOGNE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
3766 sessionInfo.persistentId_, persistentId);
3767 EraseSceneSessionMapById(persistentId);
3768 return WSError::WS_ERROR_INVALID_SESSION;
3769 }
3770 auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3771 if (ret != WSError::WS_OK) {
3772 TLOGNE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
3773 EraseSceneSessionMapById(sessionInfo.persistentId_);
3774 return ret;
3775 }
3776 sceneSession->SetRecovered(true);
3777 recoverSceneSessionFunc_(sceneSession, sessionInfo);
3778 NotifySessionUnfocusedToClient(persistentId);
3779 session = sceneSession;
3780 return WSError::WS_OK;
3781 };
3782 return taskScheduler_->PostSyncTask(task, __func__);
3783 }
3784
UpdateRecoverPropertyForSuperFold(const sptr<WindowSessionProperty> & property)3785 void SceneSessionManager::UpdateRecoverPropertyForSuperFold(const sptr<WindowSessionProperty>& property)
3786 {
3787 if (property->GetDisplayId() != VIRTUAL_DISPLAY_ID) {
3788 return;
3789 }
3790 static auto foldCreaseRegion = SingletonContainer::Get<DisplayManager>().GetCurrentFoldCreaseRegion();
3791 if (foldCreaseRegion == nullptr) {
3792 return;
3793 }
3794 Rect recoverWindowRect = property->GetWindowRect();
3795 Rect recoverRequestRect = property->GetRequestRect();
3796 TLOGD(WmsLogTag::WMS_RECOVER,
3797 "WindowRect: %{public}s, RequestRect: %{public}s, DisplayId: %{public}d",
3798 recoverWindowRect.ToString().c_str(), recoverRequestRect.ToString().c_str(),
3799 static_cast<uint32_t>(property->GetDisplayId()));
3800
3801 auto foldCrease = foldCreaseRegion->GetCreaseRects().front();
3802 recoverWindowRect.posY_ += foldCrease.posY_ + foldCrease.height_;
3803 recoverRequestRect.posY_ += foldCrease.posY_ + foldCrease.height_;
3804 property->SetWindowRect(recoverWindowRect);
3805 property->SetRequestRect(recoverRequestRect);
3806 property->SetDisplayId(0);
3807 TLOGD(WmsLogTag::WMS_RECOVER,
3808 "WindowRect: %{public}s, RequestRect: %{public}s, DisplayId: %{public}d",
3809 recoverWindowRect.ToString().c_str(), recoverRequestRect.ToString().c_str(),
3810 static_cast<uint32_t>(property->GetDisplayId()));
3811 }
3812
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)3813 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
3814 {
3815 TLOGI(WmsLogTag::WMS_RECOVER, "in");
3816 recoverSceneSessionFunc_ = func;
3817 }
3818
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)3819 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
3820 {
3821 createSystemSessionFunc_ = func;
3822 }
3823
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)3824 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
3825 {
3826 createKeyboardSessionFunc_ = func;
3827 }
3828
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)3829 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
3830 {
3831 startPiPFailedFunc_ = std::move(func);
3832 }
3833
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)3834 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
3835 const NotifyCreateSubSessionFunc& func)
3836 {
3837 TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
3838 taskScheduler_->PostSyncTask([this, persistentId, func]() {
3839 createSubSessionFuncMap_[persistentId] = func;
3840 RecoverCachedSubSession(persistentId);
3841 return WMError::WM_OK;
3842 }, __func__);
3843 }
3844
RegisterBindDialogTargetListener(const sptr<SceneSession> & session,NotifyBindDialogSessionFunc && func)3845 void SceneSessionManager::RegisterBindDialogTargetListener(const sptr<SceneSession>& session,
3846 NotifyBindDialogSessionFunc&& func)
3847 {
3848 int32_t persistentId = session->GetPersistentId();
3849 TLOGI(WmsLogTag::WMS_DIALOG, "Id: %{public}d", persistentId);
3850 taskScheduler_->PostTask([this, session, persistentId, func = std::move(func)] {
3851 session->RegisterBindDialogSessionCallback(func);
3852 bindDialogTargetFuncMap_[persistentId] = std::move(func);
3853 RecoverCachedDialogSession(persistentId);
3854 }, __func__);
3855 }
3856
SetFocusedSessionDisplayIdIfNeeded(sptr<SceneSession> & newSession)3857 void SceneSessionManager::SetFocusedSessionDisplayIdIfNeeded(sptr<SceneSession>& newSession)
3858 {
3859 if (newSession->GetSessionProperty()->GetDisplayId() == DISPLAY_ID_INVALID) {
3860 uint64_t defaultDisplayId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
3861 int32_t focusSessionId = windowFocusController_->GetFocusedSessionId(defaultDisplayId);
3862 auto focusedSession = GetSceneSession(focusSessionId);
3863 DisplayId displayId = defaultDisplayId;
3864 if (focusedSession != nullptr && focusedSession->GetSessionProperty()->GetDisplayId() != DISPLAY_ID_INVALID) {
3865 displayId = focusedSession->GetSessionProperty()->GetDisplayId();
3866 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, focus id %{public}d, display id: %{public}" PRIu64,
3867 newSession->GetPersistentId(), focusedSession->GetPersistentId(), displayId);
3868 } else {
3869 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "get focus id failed, use default displayId %{public}" PRIu64, displayId);
3870 }
3871 newSession->SetScreenId(displayId);
3872 newSession->GetSessionProperty()->SetDisplayId(displayId);
3873 }
3874 }
3875
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)3876 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
3877 sptr<WindowSessionProperty> property, const WindowType& type)
3878 {
3879 if (newSession == nullptr || property == nullptr) {
3880 TLOGE(WmsLogTag::WMS_LIFE, "newSession or property is nullptr");
3881 return;
3882 }
3883 if (SessionHelper::IsSystemWindow(type)) {
3884 if (type == WindowType::WINDOW_TYPE_FLOAT) {
3885 auto parentSession = GetSceneSession(property->GetParentPersistentId());
3886 if (parentSession != nullptr) {
3887 newSession->SetParentSession(parentSession);
3888 }
3889 }
3890 if (type == WindowType::WINDOW_TYPE_TOAST) {
3891 NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
3892 }
3893 if (type != WindowType::WINDOW_TYPE_DIALOG) {
3894 if (WindowHelper::IsSystemSubWindow(type)) {
3895 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3896 } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
3897 && createKeyboardSessionFunc_) {
3898 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
3899 } else if (createSystemSessionFunc_) {
3900 SetFocusedSessionDisplayIdIfNeeded(newSession);
3901 property->SetDisplayId(newSession->GetSessionProperty()->GetDisplayId());
3902 createSystemSessionFunc_(newSession);
3903 }
3904 TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
3905 newSession->GetPersistentId(), type);
3906 } else {
3907 TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, "
3908 "type:%{public}d", newSession->GetPersistentId(), type);
3909 return;
3910 }
3911 } else if (SessionHelper::IsSubWindow(type)) {
3912 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3913 TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
3914 newSession->GetPersistentId(), property->GetParentPersistentId(), type);
3915 } else {
3916 TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
3917 newSession->GetPersistentId(), type);
3918 }
3919 }
3920
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)3921 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
3922 {
3923 if (session == nullptr) {
3924 TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
3925 return;
3926 }
3927 auto iter = createSubSessionFuncMap_.find(persistentId);
3928 if (iter == createSubSessionFuncMap_.end()) {
3929 recoverSubSessionCacheMap_[persistentId].push_back(session);
3930 TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
3931 return;
3932 }
3933 const auto& createSubSessionFunc = iter->second;
3934 sptr<SceneSession> parentSession = nullptr;
3935 if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
3936 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3937 parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
3938 } else {
3939 parentSession = GetSceneSession(persistentId);
3940 }
3941 if (parentSession == nullptr) {
3942 TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
3943 persistentId, session->GetPersistentId());
3944 return;
3945 }
3946 parentSession->AddSubSession(session);
3947 session->SetParentSession(parentSession);
3948 if (createSubSessionFunc) {
3949 createSubSessionFunc(session);
3950 }
3951 TLOGD(WmsLogTag::WMS_LIFE, "Notify success, parentId: %{public}d, subId: %{public}d",
3952 persistentId, session->GetPersistentId());
3953 }
3954
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)3955 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
3956 const std::map<int32_t, sptr<SceneSession>>& sessionMap)
3957 {
3958 if (persistentId == INVALID_SESSION_ID) {
3959 TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
3960 return nullptr;
3961 }
3962 auto iter = sessionMap.find(persistentId);
3963 if (iter == sessionMap.end()) {
3964 TLOGD(WmsLogTag::WMS_LIFE, "Error found scene session with id: %{public}d", persistentId);
3965 return nullptr;
3966 }
3967 sptr<SceneSession> parentSession = iter->second;
3968 if (parentSession == nullptr) {
3969 TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
3970 return nullptr;
3971 }
3972 bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
3973 parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
3974 if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
3975 TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
3976 return parentSession;
3977 }
3978 return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
3979 }
3980
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)3981 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
3982 {
3983 if (session == nullptr) {
3984 TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
3985 return;
3986 }
3987
3988 auto parentSession = GetSceneSession(persistentId);
3989 if (parentSession == nullptr) {
3990 TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
3991 persistentId, session->GetPersistentId());
3992 return;
3993 }
3994 parentSession->AddToastSession(session);
3995 session->SetParentSession(parentSession);
3996 TLOGD(WmsLogTag::WMS_LIFE, "Notify success, parentId: %{public}d, toastId: %{public}d",
3997 persistentId, session->GetPersistentId());
3998 }
3999
UnregisterSpecificSessionCreateListener(int32_t persistentId)4000 void SceneSessionManager::UnregisterSpecificSessionCreateListener(int32_t persistentId)
4001 {
4002 TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
4003 taskScheduler_->PostSyncTask([this, persistentId]() {
4004 if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
4005 createSubSessionFuncMap_.erase(persistentId);
4006 }
4007 if (bindDialogTargetFuncMap_.find(persistentId) != bindDialogTargetFuncMap_.end()) {
4008 bindDialogTargetFuncMap_.erase(persistentId);
4009 }
4010 return WMError::WM_OK;
4011 }, __func__);
4012 }
4013
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)4014 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
4015 {
4016 if (!func) {
4017 TLOGD(WmsLogTag::WMS_EVENT, "set func is null");
4018 }
4019 statusBarEnabledChangeFunc_ = func;
4020 }
4021
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)4022 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
4023 const ProcessGestureNavigationEnabledChangeFunc& func)
4024 {
4025 if (!func) {
4026 TLOGD(WmsLogTag::WMS_EVENT, "set func is null");
4027 }
4028 gestureNavigationEnabledChangeFunc_ = func;
4029 }
4030
OnOutsideDownEvent(int32_t x,int32_t y)4031 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
4032 {
4033 TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
4034 if (outsideDownEventFunc_) {
4035 outsideDownEventFunc_(x, y);
4036 }
4037 }
4038
NotifySessionTouchOutside(int32_t persistentId)4039 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
4040 {
4041 auto task = [this, persistentId]() {
4042 int32_t callingSessionId = INVALID_WINDOW_ID;
4043 auto sceneSession = GetSceneSession(persistentId);
4044 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
4045 callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
4046 TLOGND(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
4047 persistentId, callingSessionId);
4048 }
4049 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4050 for (const auto& [_, sceneSession] : sceneSessionMap_) {
4051 if (sceneSession == nullptr) {
4052 continue;
4053 }
4054 if (!(sceneSession->IsVisible() ||
4055 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4056 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
4057 continue;
4058 }
4059 auto sessionId = sceneSession->GetPersistentId();
4060 if (!sceneSession->CheckTouchOutsideCallbackRegistered() &&
4061 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
4062 TLOGND(WmsLogTag::WMS_KEYBOARD, "id: %{public}d is not in touchOutsideListenerNodes, don't notify.",
4063 sessionId);
4064 continue;
4065 }
4066 if (sessionId == callingSessionId || sessionId == persistentId) {
4067 TLOGND(WmsLogTag::WMS_KEYBOARD, "No need to notify touch window, id: %{public}d", sessionId);
4068 continue;
4069 }
4070 sceneSession->NotifyTouchOutside();
4071 }
4072 };
4073
4074 taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
4075 return;
4076 }
4077
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)4078 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
4079 {
4080 TLOGD(WmsLogTag::WMS_EVENT, "in");
4081 outsideDownEventFunc_ = func;
4082 }
4083
NotifyWatchGestureConsumeResult(int32_t keyCode,bool isConsumed)4084 WMError SceneSessionManager::NotifyWatchGestureConsumeResult(int32_t keyCode, bool isConsumed)
4085 {
4086 TLOGD(WmsLogTag::WMS_EVENT, "keyCode:%{public}d isConsumed:%{public}d", keyCode, isConsumed);
4087 if (onWatchGestureConsumeResultFunc_) {
4088 onWatchGestureConsumeResultFunc_(keyCode, isConsumed);
4089 } else {
4090 TLOGE(WmsLogTag::WMS_EVENT, "onWatchGestureConsumeResultFunc is null");
4091 return WMError::WM_ERROR_INVALID_PARAM;
4092 }
4093 return WMError::WM_OK;
4094 }
4095
RegisterWatchGestureConsumeResultCallback(NotifyWatchGestureConsumeResultFunc && func)4096 void SceneSessionManager::RegisterWatchGestureConsumeResultCallback(NotifyWatchGestureConsumeResultFunc&& func)
4097 {
4098 TLOGD(WmsLogTag::WMS_EVENT, "in");
4099 onWatchGestureConsumeResultFunc_ = std::move(func);
4100 }
4101
NotifyWatchFocusActiveChange(bool isActive)4102 WMError SceneSessionManager::NotifyWatchFocusActiveChange(bool isActive)
4103 {
4104 TLOGD(WmsLogTag::WMS_EVENT, "isActive:%{public}d", isActive);
4105 if (onWatchFocusActiveChangeFunc_) {
4106 onWatchFocusActiveChangeFunc_(isActive);
4107 } else {
4108 TLOGE(WmsLogTag::WMS_EVENT, "onWatchFocusActiveChangeFunc is null");
4109 return WMError::WM_ERROR_INVALID_PARAM;
4110 }
4111 return WMError::WM_OK;
4112 }
4113
RegisterWatchFocusActiveChangeCallback(NotifyWatchFocusActiveChangeFunc && func)4114 void SceneSessionManager::RegisterWatchFocusActiveChangeCallback(NotifyWatchFocusActiveChangeFunc&& func)
4115 {
4116 TLOGD(WmsLogTag::WMS_EVENT, "in");
4117 onWatchFocusActiveChangeFunc_ = std::move(func);
4118 }
4119
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)4120 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
4121 {
4122 for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
4123 if (iter->second != persistentId) {
4124 continue;
4125 }
4126 if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
4127 TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
4128 }
4129 remoteObjectMap_.erase(iter);
4130 break;
4131 }
4132 }
4133
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)4134 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
4135 {
4136 auto sceneSession = GetSceneSession(persistentId);
4137 if (sceneSession == nullptr) {
4138 return WSError::WS_ERROR_NULLPTR;
4139 }
4140 auto ret = sceneSession->UpdateActiveStatus(false);
4141 WindowDestroyNotifyVisibility(sceneSession);
4142 auto windowType = sceneSession->GetWindowType();
4143 if (windowType == WindowType::WINDOW_TYPE_DIALOG) {
4144 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4145 if (parentSession == nullptr) {
4146 TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
4147 } else {
4148 parentSession->RemoveDialogToParentSession(sceneSession);
4149 parentSession->UnregisterNotifySurfaceBoundsChangeFunc(persistentId);
4150 }
4151 } else if (windowType == WindowType::WINDOW_TYPE_TOAST) {
4152 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4153 if (parentSession != nullptr) {
4154 TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
4155 parentSession->RemoveToastSession(persistentId);
4156 } else {
4157 TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
4158 }
4159 } else if (windowType == WindowType::WINDOW_TYPE_FLOAT) {
4160 DestroySubSession(sceneSession);
4161 }
4162 ret = sceneSession->Disconnect();
4163 sceneSession->ClearSpecificSessionCbMap();
4164 if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
4165 DestroySubSession(sceneSession);
4166 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4167 if (parentSession != nullptr) {
4168 TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
4169 parentSession->RemoveSubSession(sceneSession->GetPersistentId());
4170 parentSession->UnregisterNotifySurfaceBoundsChangeFunc(persistentId);
4171 } else {
4172 TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
4173 }
4174 DestroyUIServiceExtensionSubWindow(sceneSession);
4175 }
4176 {
4177 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4178 EraseSceneSessionAndMarkDirtyLocked(persistentId);
4179 systemTopSceneSessionMap_.erase(persistentId);
4180 nonSystemFloatSceneSessionMap_.erase(persistentId);
4181 UnregisterSpecificSessionCreateListener(persistentId);
4182 }
4183 ClearSpecificSessionRemoteObjectMap(persistentId);
4184 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
4185 return ret;
4186 }
4187
DestroyAndDisconnectSpecificSession(const int32_t persistentId)4188 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
4189 {
4190 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
4191 auto task = [this, persistentId, callingPid]() {
4192 TLOGNI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
4193 auto sceneSession = GetSceneSession(persistentId);
4194 if (sceneSession == nullptr) {
4195 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
4196 return WSError::WS_ERROR_NULLPTR;
4197 }
4198
4199 if (callingPid != sceneSession->GetCallingPid()) {
4200 TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
4201 return WSError::WS_ERROR_INVALID_PERMISSION;
4202 }
4203 return DestroyAndDisconnectSpecificSessionInner(persistentId);
4204 };
4205
4206 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
4207 }
4208
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)4209 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
4210 const sptr<IRemoteObject>& callback)
4211 {
4212 if (callback == nullptr) {
4213 return WSError::WS_ERROR_NULLPTR;
4214 }
4215 const auto callingPid = IPCSkeleton::GetCallingRealPid();
4216 auto task = [this, persistentId, callingPid, callback]() {
4217 TLOGNI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
4218 auto sceneSession = GetSceneSession(persistentId);
4219 if (sceneSession == nullptr) {
4220 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
4221 return WSError::WS_ERROR_NULLPTR;
4222 }
4223
4224 if (callingPid != sceneSession->GetCallingPid()) {
4225 TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
4226 return WSError::WS_ERROR_INVALID_PERMISSION;
4227 }
4228 sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
4229 return DestroyAndDisconnectSpecificSessionInner(persistentId);
4230 };
4231
4232 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
4233 }
4234
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession> & sceneSession)4235 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
4236 {
4237 if (!sceneSession) {
4238 TLOGE(WmsLogTag::WMS_SUB, "sceneSession is null");
4239 return;
4240 }
4241 auto sessionProperty = sceneSession->GetSessionProperty();
4242 if (sessionProperty->GetIsUIExtFirstSubWindow() &&
4243 !sessionProperty->GetIsUIExtensionAbilityProcess()) {
4244 sceneSession->NotifyDestroy();
4245 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
4246 TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
4247 TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
4248 sceneSession->GetPersistentId(), errCode);
4249 }
4250 }
4251
GetWindowSceneConfig() const4252 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
4253 {
4254 return appWindowSceneConfig_;
4255 }
4256
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)4257 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
4258 {
4259 taskScheduler_->PostAsyncTask([this, config] {
4260 TLOGNI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
4261 rotateAnimationConfig_.duration_ = config.duration_;
4262 }, __func__);
4263 }
4264
ProcessBackEvent()4265 WSError SceneSessionManager::ProcessBackEvent()
4266 {
4267 taskScheduler_->PostAsyncTask([this]() {
4268 auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
4269 if (focusGroup == nullptr) {
4270 TLOGNE(WmsLogTag::WMS_MAIN, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
4271 return WSError::WS_ERROR_NULLPTR;
4272 }
4273 auto focusedSessionId = focusGroup->GetFocusedSessionId();
4274 auto needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
4275 auto session = GetSceneSession(focusedSessionId);
4276 if (!session) {
4277 TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId);
4278 return WSError::WS_ERROR_INVALID_SESSION;
4279 }
4280 TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
4281 focusedSessionId, needBlockNotifyFocusStatusUntilForeground);
4282 if (needBlockNotifyFocusStatusUntilForeground ||
4283 (!session->IsSessionValid() && !session->IsSystemSession())) {
4284 TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
4285 if (session->GetSessionInfo().abilityInfo != nullptr &&
4286 session->GetSessionInfo().abilityInfo->unclearableMission) {
4287 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
4288 return WSError::WS_OK;
4289 }
4290 session->RequestSessionBack(true);
4291 return WSError::WS_OK;
4292 }
4293 if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
4294 rootSceneProcessBackEventFunc_();
4295 } else {
4296 session->ProcessBackEvent();
4297 }
4298 return WSError::WS_OK;
4299 }, __func__);
4300 return WSError::WS_OK;
4301 }
4302
InitUserInfo(int32_t userId,std::string & fileDir)4303 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
4304 {
4305 if (userId == DEFAULT_USERID || fileDir.empty()) {
4306 TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
4307 return WSError::WS_DO_NOTHING;
4308 }
4309 TLOGI(WmsLogTag::WMS_MAIN, "userId: %{public}d, path: %{public}s", userId, fileDir.c_str());
4310 return taskScheduler_->PostSyncTask([this, userId, &fileDir]() {
4311 if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
4312 TLOGND(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
4313 }
4314 if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
4315 TLOGND(WmsLogTag::WMS_MAIN, "Create icon directory failed");
4316 }
4317 currentUserId_ = userId;
4318 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
4319 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
4320 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
4321 }
4322 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
4323 RegisterSecSurfaceInfoListener();
4324 RegisterConstrainedModalUIExtInfoListener();
4325 return WSError::WS_OK;
4326 }, __func__);
4327 }
4328
IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession> & sceneSession,int32_t pid)4329 bool SceneSessionManager::IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession>& sceneSession, int32_t pid)
4330 {
4331 auto sessionState = sceneSession->GetSessionState();
4332 auto isInvalidMainSession = !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
4333 sessionState == SessionState::STATE_DISCONNECT ||
4334 sessionState == SessionState::STATE_END;
4335 if (isInvalidMainSession) {
4336 TLOGD(WmsLogTag::WMS_MULTI_USER, "persistentId: %{public}d, type: %{public}d, state: %{public}d",
4337 sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState());
4338 }
4339 return sceneSession->GetCallingPid() != pid && IsPcSceneSessionLifecycle(sceneSession) && !isInvalidMainSession;
4340 }
4341
StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession> & sceneSession,bool isUserActive)4342 WSError SceneSessionManager::StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession>& sceneSession, bool isUserActive)
4343 {
4344 auto persistentId = sceneSession->GetPersistentId();
4345 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
4346 if (!isUserActive) {
4347 TLOGI(WmsLogTag::WMS_MULTI_USER,
4348 "MinimizeUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
4349 sceneSession->GetWindowType(), sceneSession->GetSessionState());
4350 bool isFromUser = false;
4351 if (sceneSession->GetSessionProperty()->GetApiVersion() >= LIFECYCLE_ISOLATE_VERSION) {
4352 TLOGI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause", persistentId);
4353 if (!sceneSession->UpdateInteractiveInner(false)) {
4354 TLOGI(WmsLogTag::WMS_LIFE, "Notify scene session id:%{public}d pause is duplicative", persistentId);
4355 }
4356 }
4357 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(
4358 abilitySessionInfo, isFromUser, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH));
4359 if (errCode == ERR_OK) {
4360 sceneSession->SetMinimizedFlagByUserSwitch(true);
4361 } else {
4362 TLOGE(WmsLogTag::WMS_MULTI_USER, "minimize failed! errCode: %{public}d", errCode);
4363 }
4364 } else if (sceneSession->IsMinimizedByUserSwitch()) {
4365 TLOGI(WmsLogTag::WMS_MULTI_USER,
4366 "StartUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
4367 sceneSession->GetWindowType(), sceneSession->GetSessionState());
4368 sceneSession->SetMinimizedFlagByUserSwitch(false);
4369 bool isColdStart = false;
4370 abilitySessionInfo->isNewWant = false;
4371 int32_t errCode = StartUIAbilityBySCBTimeoutCheck(
4372 abilitySessionInfo, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH), isColdStart);
4373 if (errCode != ERR_OK) {
4374 TLOGE(WmsLogTag::WMS_MULTI_USER, "start failed! errCode: %{public}d", errCode);
4375 ExceptionInfo exceptionInfo;
4376 exceptionInfo.needRemoveSession = true;
4377 sceneSession->NotifySessionExceptionInner(abilitySessionInfo, exceptionInfo, false, true);
4378 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
4379 startUIAbilityErrorFunc_(
4380 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
4381 }
4382 }
4383 }
4384 return WSError::WS_OK;
4385 }
4386
ProcessUIAbilityOnUserSwitch(bool isUserActive)4387 void SceneSessionManager::ProcessUIAbilityOnUserSwitch(bool isUserActive)
4388 {
4389 int32_t pid = GetPid();
4390 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4391 for (const auto& [_, sceneSession] : sceneSessionMap_) {
4392 if (sceneSession == nullptr) {
4393 TLOGE(WmsLogTag::WMS_MULTI_USER, "session is null");
4394 continue;
4395 }
4396 // Change app life cycle in pc when user switch, do app freeze or unfreeze
4397 if (IsNeedChangeLifeCycleOnUserSwitch(sceneSession, pid)) {
4398 StartOrMinimizeUIAbilityBySCB(sceneSession, isUserActive);
4399 }
4400 }
4401 }
4402
HandleUserSwitching(bool isUserActive)4403 void SceneSessionManager::HandleUserSwitching(bool isUserActive)
4404 {
4405 isUserBackground_ = !isUserActive;
4406 SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
4407 if (isUserActive) { // switch to current user
4408 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
4409 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
4410 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
4411 }
4412 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
4413 // notify screenSessionManager to recover current user
4414 ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
4415 FlushWindowInfoToMMI(true);
4416 NotifyAllAccessibilityInfo();
4417 rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
4418 UpdatePrivateStateAndNotifyForAllScreens();
4419 } else { // switch to another user
4420 SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
4421 rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
4422 // minimized UI abilities when the user is switching and inactive
4423 ProcessUIAbilityOnUserSwitch(isUserActive);
4424 }
4425 }
4426
HandleUserSwitched(bool isUserActive)4427 void SceneSessionManager::HandleUserSwitched(bool isUserActive)
4428 {
4429 if (isUserActive) {
4430 // start UI abilities only after the user has switched and become active
4431 ProcessUIAbilityOnUserSwitch(isUserActive);
4432 }
4433 }
4434
HandleUserSwitch(const UserSwitchEventType type,const bool isUserActive)4435 void SceneSessionManager::HandleUserSwitch(const UserSwitchEventType type, const bool isUserActive)
4436 {
4437 if (type == UserSwitchEventType::SWITCHING && !isUserActive) {
4438 ScreenSessionManagerClient::GetInstance().DisconnectAllExternalScreen();
4439 }
4440 taskScheduler_->PostSyncTask([this, type, isUserActive, where = __func__] {
4441 TLOGNI(WmsLogTag::WMS_MULTI_USER,
4442 "%{public}s: currentUserId: %{public}d, switchEventType: %{public}u, isUserActive: %{public}u",
4443 where, currentUserId_.load(), type, isUserActive);
4444 if (type == UserSwitchEventType::SWITCHING) {
4445 HandleUserSwitching(isUserActive);
4446 } else {
4447 HandleUserSwitched(isUserActive);
4448 }
4449 return WSError::WS_OK;
4450 }, __func__);
4451 }
4452
GetBundleManager()4453 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
4454 {
4455 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
4456 if (systemAbilityMgr == nullptr) {
4457 TLOGE(WmsLogTag::DEFAULT, "Failed to get SystemAbilityManager.");
4458 return nullptr;
4459 }
4460 auto bmsProxy = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
4461 if (bmsProxy == nullptr) {
4462 TLOGE(WmsLogTag::DEFAULT, "Failed to get BundleManagerService.");
4463 return nullptr;
4464 }
4465 return iface_cast<AppExecFwk::IBundleMgr>(bmsProxy);
4466 }
4467
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)4468 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
4469 const AppExecFwk::AbilityInfo& abilityInfo)
4470 {
4471 auto context = rootSceneContextWeak_.lock();
4472 if (!context) {
4473 TLOGE(WmsLogTag::DEFAULT, "context is nullptr.");
4474 return nullptr;
4475 }
4476 auto resourceMgr = context->GetResourceManager();
4477 if (!resourceMgr) {
4478 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
4479 return nullptr;
4480 }
4481 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
4482 if (!resConfig) {
4483 TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
4484 return nullptr;
4485 }
4486 resourceMgr->GetResConfig(*resConfig);
4487 resourceMgr = Global::Resource::CreateResourceManager(
4488 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
4489 if (!resourceMgr) {
4490 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
4491 return nullptr;
4492 }
4493 resourceMgr->UpdateResConfig(*resConfig);
4494
4495 std::string loadPath;
4496 if (!abilityInfo.hapPath.empty()) { // zipped hap
4497 loadPath = abilityInfo.hapPath;
4498 } else {
4499 loadPath = abilityInfo.resourcePath;
4500 }
4501
4502 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
4503 TLOGW(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
4504 }
4505 return resourceMgr;
4506 }
4507
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)4508 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
4509 std::string& path, uint32_t& bgColor)
4510 {
4511 auto resourceMgr = GetResourceManager(abilityInfo);
4512 if (!resourceMgr) {
4513 TLOGE(WmsLogTag::WMS_PATTERN, "resourceMgr is nullptr.");
4514 return false;
4515 }
4516
4517 if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
4518 TLOGE(WmsLogTag::WMS_PATTERN, "Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
4519 return false;
4520 }
4521
4522 if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
4523 TLOGE(WmsLogTag::WMS_PATTERN, "Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
4524 return false;
4525 }
4526
4527 if (!abilityInfo.hapPath.empty()) { // zipped hap
4528 auto pos = path.find_last_of('.');
4529 if (pos == std::string::npos) {
4530 TLOGE(WmsLogTag::WMS_PATTERN, "Format error, path %{private}s.", path.c_str());
4531 return false;
4532 }
4533 path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
4534 }
4535 return true;
4536 }
4537
GetIconFromDesk(const SessionInfo & sessionInfo,std::string & startupPagePath) const4538 bool SceneSessionManager::GetIconFromDesk(const SessionInfo& sessionInfo, std::string& startupPagePath) const
4539 {
4540 auto& want = sessionInfo.want;
4541 if (want == nullptr) {
4542 TLOGI(WmsLogTag::WMS_PATTERN, "want is nullPtr");
4543 return false;
4544 }
4545 startupPagePath = want->GetStringParam("realAppIcon");
4546 if (startupPagePath.empty()) {
4547 return false;
4548 }
4549 return true;
4550 }
4551
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)4552 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
4553 {
4554 if (GetIconFromDesk(sessionInfo, path)) {
4555 TLOGI(WmsLogTag::WMS_PATTERN, "get icon from desk success");
4556 return;
4557 }
4558
4559 if (!bundleMgr_) {
4560 TLOGE(WmsLogTag::WMS_PATTERN, "bundleMgr_ is nullptr.");
4561 return;
4562 }
4563 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
4564 if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
4565 TLOGW(WmsLogTag::WMS_PATTERN, "Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
4566 return;
4567 }
4568 AAFwk::Want want;
4569 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
4570 AppExecFwk::AbilityInfo abilityInfo;
4571 if (!bundleMgr_->QueryAbilityInfo(
4572 want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
4573 TLOGE(WmsLogTag::WMS_PATTERN, "Get ability info from BMS failed!");
4574 return;
4575 }
4576
4577 if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
4578 CacheStartingWindowInfo(abilityInfo, path, bgColor);
4579 }
4580 TLOGW(WmsLogTag::WMS_PATTERN, "%{public}d, %{public}d, %{public}s, %{public}x",
4581 abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
4582 }
4583
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)4584 bool SceneSessionManager::GetStartingWindowInfoFromCache(
4585 const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
4586 {
4587 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
4588 std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
4589 auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
4590 if (iter == startingWindowMap_.end()) {
4591 return false;
4592 }
4593 auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
4594 const auto& infoMap = iter->second;
4595 auto infoMapIter = infoMap.find(key);
4596 if (infoMapIter == infoMap.end()) {
4597 return false;
4598 }
4599 path = infoMapIter->second.startingWindowIconPath_;
4600 bgColor = infoMapIter->second.startingWindowBackgroundColor_;
4601 return true;
4602 }
4603
CacheStartingWindowInfo(const AppExecFwk::AbilityInfo & abilityInfo,const std::string & path,const uint32_t & bgColor)4604 void SceneSessionManager::CacheStartingWindowInfo(
4605 const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
4606 {
4607 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
4608 auto key = abilityInfo.moduleName + abilityInfo.name;
4609 StartingWindowInfo info = {
4610 .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
4611 .startingWindowIconId_ = abilityInfo.startWindowIconId,
4612 .startingWindowBackgroundColor_ = bgColor,
4613 .startingWindowIconPath_ = path,
4614 };
4615 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
4616 auto iter = startingWindowMap_.find(abilityInfo.bundleName);
4617 if (iter != startingWindowMap_.end()) {
4618 auto& infoMap = iter->second;
4619 infoMap.emplace(key, info);
4620 return;
4621 }
4622 if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
4623 startingWindowMap_.erase(startingWindowMap_.begin());
4624 }
4625 std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
4626 startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
4627 }
4628
OnBundleUpdated(const std::string & bundleName,int userId)4629 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
4630 {
4631 taskScheduler_->PostAsyncTask([this, bundleName]() {
4632 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
4633 if (auto iter = startingWindowMap_.find(bundleName); iter != startingWindowMap_.end()) {
4634 startingWindowMap_.erase(iter);
4635 }
4636 }, __func__);
4637 }
4638
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)4639 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
4640 {
4641 taskScheduler_->PostAsyncTask([this]() {
4642 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
4643 startingWindowMap_.clear();
4644 }, __func__);
4645 }
4646
FillSessionInfo(sptr<SceneSession> & sceneSession)4647 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
4648 {
4649 const auto& sessionInfo = sceneSession->GetSessionInfo();
4650 if (sessionInfo.bundleName_.empty()) {
4651 TLOGE(WmsLogTag::DEFAULT, "bundleName_ is empty");
4652 return;
4653 }
4654 if (sessionInfo.isSystem_) {
4655 TLOGD(WmsLogTag::DEFAULT, "is system scene!");
4656 return;
4657 }
4658 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
4659 sessionInfo.moduleName_);
4660 if (abilityInfo == nullptr) {
4661 TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
4662 return;
4663 }
4664 sceneSession->SetEnableRemoveStartingWindow(GetEnableRemoveStartingWindowFromBMS(abilityInfo));
4665 sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
4666 sceneSession->SetSessionInfoTime(GetCurrentTime());
4667 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
4668 sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
4669 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
4670 sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
4671 }
4672 TLOGI(WmsLogTag::WMS_MAIN, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
4673 "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
4674 abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
4675 abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
4676 }
4677
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)4678 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
4679 const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
4680 {
4681 if (!bundleMgr_) {
4682 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
4683 return nullptr;
4684 }
4685 SessionInfoList list = {
4686 .uid_ = uId, .bundleName_ = bundleName, .abilityName_ = abilityName, .moduleName_ = moduleName
4687 };
4688 if (abilityInfoMap_.count(list)) {
4689 return abilityInfoMap_[list];
4690 }
4691 AAFwk::Want want;
4692 want.SetElementName("", bundleName, abilityName, moduleName);
4693 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
4694 if (abilityInfo == nullptr) {
4695 TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
4696 return nullptr;
4697 }
4698 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
4699 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
4700 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
4701 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
4702 if (!ret) {
4703 TLOGE(WmsLogTag::DEFAULT, "Get ability info from BMS failed!");
4704 return nullptr;
4705 }
4706 abilityInfoMap_[list] = abilityInfo;
4707 return abilityInfo;
4708 }
4709
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)4710 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
4711 uint32_t& topWinId, uint32_t& zOrder)
4712 {
4713 const auto& subVec = session->GetSubSession();
4714 for (const auto& subSession : subVec) {
4715 if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
4716 TLOGW(WmsLogTag::WMS_SUB,
4717 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
4718 continue;
4719 }
4720 if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4721 subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
4722 subSession->GetZOrder() > zOrder) {
4723 topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
4724 zOrder = subSession->GetZOrder();
4725 TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
4726 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
4727 }
4728 if (subSession->GetSubSession().size() > 0) {
4729 GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
4730 }
4731 }
4732 }
4733
4734 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)4735 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
4736 {
4737 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
4738 auto task = [this, mainWinId, &topWinId, callingPid]() {
4739 const auto& mainSession = GetSceneSession(mainWinId);
4740 if (mainSession == nullptr) {
4741 return WMError::WM_ERROR_INVALID_WINDOW;
4742 }
4743
4744 if (callingPid != mainSession->GetCallingPid()) {
4745 TLOGNE(WmsLogTag::WMS_HIERARCHY, "Permission denied, not destroy by the same process");
4746 return WMError::WM_ERROR_INVALID_PERMISSION;
4747 }
4748 uint32_t zOrder = mainSession->GetZOrder();
4749 topWinId = mainWinId;
4750 GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
4751 TLOGNI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
4752 "zOrder: %{public}d", mainWinId, topWinId, zOrder);
4753 return WMError::WM_OK;
4754 };
4755
4756 if (!Session::IsScbCoreEnabled()) {
4757 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4758 }
4759 bool postNow = false;
4760 auto mainSession = GetSceneSession(mainWinId);
4761 if (mainSession != nullptr) {
4762 postNow = !(mainSession->GetUIStateDirty());
4763 }
4764 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
4765 if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
4766 taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
4767 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4768 }
4769 TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
4770 {
4771 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
4772 if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
4773 std::cv_status::timeout) {
4774 TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
4775 }
4776 }
4777 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4778 }
4779
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)4780 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
4781 int32_t windowId, int32_t& mainWindowId)
4782 {
4783 auto iter = sceneSessionMap.find(windowId);
4784 if (iter == sceneSessionMap.end()) {
4785 TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
4786 return WMError::WM_ERROR_NULLPTR;
4787 }
4788 sptr<SceneSession> sceneSession = iter->second;
4789 if (sceneSession == nullptr) {
4790 TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
4791 return WMError::WM_ERROR_NULLPTR;
4792 }
4793 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
4794 mainWindowId = sceneSession->GetPersistentId();
4795 return WMError::WM_OK;
4796 }
4797 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4798 WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
4799 return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
4800 }
4801 // not sub window, dialog, return invalid id
4802 mainWindowId = INVALID_SESSION_ID;
4803 return WMError::WM_OK;
4804 }
4805
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)4806 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
4807 {
4808 if (windowId == INVALID_SESSION_ID) {
4809 TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
4810 return WMError::WM_ERROR_INVALID_PARAM;
4811 }
4812 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4813 return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
4814 }
4815
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4816 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
4817 const sptr<SceneSession>& sceneSession)
4818 {
4819 auto systemBarProperties = property->GetSystemBarProperty();
4820 for (auto iter : systemBarProperties) {
4821 if (iter.first == type) {
4822 sceneSession->SetSystemBarProperty(iter.first, iter.second);
4823 TLOGD(WmsLogTag::WMS_IMMS, "type %{public}d enable %{public}d",
4824 static_cast<int32_t>(iter.first), iter.second.enable_);
4825 }
4826 }
4827 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
4828 }
4829
4830 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4831 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
4832 const sptr<SceneSession>& sceneSession)
4833 {
4834 if (!SessionPermission::IsSystemCalling()) {
4835 TLOGE(WmsLogTag::WMS_HIERARCHY, "UpdateTopmostProperty permission denied!");
4836 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4837 }
4838
4839 sceneSession->SetTopmost(property->IsTopmost());
4840 return WMError::WM_OK;
4841 }
4842
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4843 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
4844 const sptr<SceneSession>& sceneSession)
4845 {
4846 auto propertyOld = sceneSession->GetSessionProperty();
4847 bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
4848 bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
4849 if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
4850 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "property hideNonSystemFloatingWindows not change");
4851 return;
4852 }
4853
4854 if (IsSessionVisibleForeground(sceneSession)) {
4855 if (hideNonSystemFloatingWindowsOld) {
4856 UpdateForceHideState(sceneSession, propertyOld, false);
4857 } else {
4858 UpdateForceHideState(sceneSession, property, true);
4859 }
4860 }
4861 }
4862
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)4863 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
4864 const sptr<WindowSessionProperty>& property, bool add)
4865 {
4866 if (systemConfig_.IsPcWindow()) {
4867 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "IsPcWindow, ineffective");
4868 return;
4869 }
4870 if (property == nullptr) {
4871 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "property is null");
4872 return;
4873 }
4874 auto persistentId = sceneSession->GetPersistentId();
4875 bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
4876 bool notifyAll = false;
4877 if (add) {
4878 if (property->GetHideNonSystemFloatingWindows()) {
4879 systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
4880 notifyAll = !forceHideFloatOld;
4881 } else if ((property->IsFloatingWindowAppType() && !property->GetSystemCalling()) ||
4882 sceneSession->GetIsAncoForFloatingWindow()) {
4883 nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
4884 if (forceHideFloatOld) {
4885 sceneSession->NotifyForceHideChange(true);
4886 }
4887 }
4888 } else {
4889 if (property->GetHideNonSystemFloatingWindows()) {
4890 systemTopSceneSessionMap_.erase(persistentId);
4891 notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
4892 } else if ((property->IsFloatingWindowAppType() && !property->GetSystemCalling()) ||
4893 sceneSession->GetIsAncoForFloatingWindow()) {
4894 nonSystemFloatSceneSessionMap_.erase(persistentId);
4895 if (property->GetForceHide()) {
4896 sceneSession->NotifyForceHideChange(false);
4897 }
4898 }
4899 }
4900 if (notifyAll) {
4901 bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
4902 for (const auto& item : nonSystemFloatSceneSessionMap_) {
4903 auto forceHideSceneSession = item.second;
4904 if (forceHideFloatNew != forceHideSceneSession->GetSessionProperty()->GetForceHide()) {
4905 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
4906 }
4907 }
4908 }
4909 }
4910
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)4911 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
4912 {
4913 #ifdef POWER_MANAGER_ENABLE
4914 auto task = [this, sceneSession]() {
4915 if (sceneSession == nullptr) {
4916 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
4917 return;
4918 }
4919 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "Win: %{public}s, is turn on%{public}d",
4920 sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
4921 std::string identity = IPCSkeleton::ResetCallingIdentity();
4922 if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
4923 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "turn screen on");
4924 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
4925 }
4926 // set ipc identity to raw
4927 IPCSkeleton::SetCallingIdentity(identity);
4928 };
4929 taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
4930
4931 #else
4932 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
4933 #endif
4934 }
4935
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock,const std::string & screenLockPrefix,std::shared_ptr<PowerMgr::RunningLock> & screenLock)4936 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock,
4937 const std::string& screenLockPrefix, std::shared_ptr<PowerMgr::RunningLock>& screenLock)
4938 {
4939 #ifdef POWER_MANAGER_ENABLE
4940 wptr<SceneSession> weakSceneSession(sceneSession);
4941 auto task = [this, weakSceneSession, requireLock, &screenLockPrefix, &screenLock]() {
4942 auto sceneSession = weakSceneSession.promote();
4943 if (sceneSession == nullptr) {
4944 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
4945 return;
4946 }
4947 if (requireLock && screenLock == nullptr) {
4948 // reset ipc identity
4949 std::string identity = IPCSkeleton::ResetCallingIdentity();
4950 screenLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(
4951 screenLockPrefix + std::to_string(sceneSession->GetPersistentId()),
4952 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
4953 // set ipc identity to raw
4954 IPCSkeleton::SetCallingIdentity(identity);
4955 }
4956 if (screenLock == nullptr) {
4957 return;
4958 }
4959 auto currScreenId = sceneSession->GetSessionInfo().screenId_;
4960 auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
4961 if (auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(currScreenId)) {
4962 sourceMode = screenSession->GetSourceMode();
4963 }
4964 bool shouldLock = requireLock && IsSessionVisibleForeground(sceneSession) && sourceMode != ScreenSourceMode::SCREEN_UNIQUE;
4965 TLOGNI(WmsLogTag::WMS_ATTRIBUTE,
4966 "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d]",
4967 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionState(),
4968 sceneSession->IsVisible(), requireLock, shouldLock, currScreenId, sourceMode);
4969 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
4970 ErrCode res;
4971 std::string identity = IPCSkeleton::ResetCallingIdentity();
4972 if (shouldLock) {
4973 res = screenLock->Lock();
4974 } else {
4975 res = screenLock->UnLock();
4976 }
4977 // set ipc identity to raw
4978 IPCSkeleton::SetCallingIdentity(identity);
4979 if (res != ERR_OK) {
4980 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "handle keep screen running lock failed: [operation: %{public}d, "
4981 "err: %{public}d]", requireLock, res);
4982 }
4983 };
4984 taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
4985 #else
4986 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
4987 #endif
4988 }
4989
NotifyVisibleChange(int32_t persistentId)4990 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
4991 {
4992 auto sceneSession = GetSceneSession(persistentId);
4993 if (sceneSession == nullptr) {
4994 return false;
4995 }
4996 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
4997 sceneSession->keepScreenLock_);
4998 HandleKeepScreenOn(sceneSession, sceneSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
4999 sceneSession->viewKeepScreenLock_);
5000 return true;
5001 }
5002
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)5003 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
5004 {
5005 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
5006 if (GetDisplayBrightness() != brightness &&
5007 GetFocusedSessionId() == sceneSession->GetPersistentId()) {
5008 PostBrightnessTask(brightness);
5009 }
5010 #else
5011 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of DisplayPowerMgr");
5012 #endif
5013 brightnessSessionId_ = sceneSession->GetPersistentId();
5014 return WSError::WS_OK;
5015 }
5016
PostBrightnessTask(float brightness)5017 void SceneSessionManager::PostBrightnessTask(float brightness)
5018 {
5019 bool postTaskRet = true;
5020 bool isPC = systemConfig_.IsPcWindow();
5021 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
5022 if (!isPC) {
5023 auto task = [] {
5024 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
5025 };
5026 postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
5027 }
5028 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
5029 } else {
5030 auto task = [brightness, isPC] {
5031 if (isPC) {
5032 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
5033 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
5034 } else {
5035 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
5036 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
5037 }
5038 };
5039 postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
5040 SetDisplayBrightness(brightness);
5041 }
5042 if (!postTaskRet) {
5043 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "post task failed. task is SetBrightness");
5044 }
5045 }
5046
UpdateBrightness(int32_t persistentId)5047 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
5048 {
5049 if (systemConfig_.IsPcWindow()) {
5050 return WSError::WS_OK;
5051 }
5052 auto sceneSession = GetSceneSession(persistentId);
5053 if (sceneSession == nullptr) {
5054 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
5055 return WSError::WS_ERROR_NULLPTR;
5056 }
5057 if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
5058 sceneSession->GetSessionInfo().isSystem_)) {
5059 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window can set brightness");
5060 return WSError::WS_DO_NOTHING;
5061 }
5062 auto brightness = sceneSession->GetBrightness();
5063 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
5064 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
5065 if (IsNeedUpdateBrightness(brightness)) {
5066 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with default value");
5067 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
5068 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
5069 brightnessSessionId_ = INVALID_WINDOW_ID;
5070 }
5071 } else {
5072 if (std::fabs(brightness - GetDisplayBrightness()) > std::numeric_limits<float>::min()) {
5073 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with value");
5074 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
5075 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
5076 SetDisplayBrightness(brightness);
5077 }
5078 brightnessSessionId_ = sceneSession->GetPersistentId();
5079 }
5080 return WSError::WS_OK;
5081 }
5082
IsNeedUpdateBrightness(float brightness)5083 bool SceneSessionManager::IsNeedUpdateBrightness(float brightness)
5084 {
5085 if (std::fabs(brightness - GetDisplayBrightness()) < std::numeric_limits<float>::min()) {
5086 return false;
5087 }
5088 auto sceneSession = GetSceneSession(brightnessSessionId_);
5089 if (sceneSession != nullptr && sceneSession->IsSessionForeground()) {
5090 return false;
5091 }
5092 return true;
5093 }
5094
GetCurrentUserId() const5095 int32_t SceneSessionManager::GetCurrentUserId() const
5096 {
5097 return currentUserId_;
5098 }
5099
SetDisplayBrightness(float brightness)5100 void SceneSessionManager::SetDisplayBrightness(float brightness)
5101 {
5102 displayBrightness_ = brightness;
5103 }
5104
GetDisplayBrightness() const5105 float SceneSessionManager::GetDisplayBrightness() const
5106 {
5107 return displayBrightness_;
5108 }
5109
SetGestureNavigationEnabled(bool enable)5110 WMError SceneSessionManager::SetGestureNavigationEnabled(bool enable)
5111 {
5112 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5113 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
5114 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5115 }
5116 std::string callerBundleName = SessionPermission::GetCallingBundleName();
5117 TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
5118 auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
5119 SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
5120 if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
5121 TLOGNE(WmsLogTag::WMS_EVENT, "callback func is null");
5122 return WMError::WM_OK;
5123 }
5124 if (gestureNavigationEnabledChangeFunc_) {
5125 gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
5126 }
5127 if (statusBarEnabledChangeFunc_) {
5128 statusBarEnabledChangeFunc_(enable, bundleName);
5129 }
5130 return WMError::WM_OK;
5131 };
5132 return taskScheduler_->PostSyncTask(task, "SetGestureNavigationEnabled");
5133 }
5134
SetFocusedSessionId(const int32_t persistentId,const DisplayId displayId)5135 WSError SceneSessionManager::SetFocusedSessionId(const int32_t persistentId, const DisplayId displayId)
5136 {
5137 return windowFocusController_->UpdateFocusedSessionId(displayId, persistentId);
5138 }
5139
GetFocusedSessionId(DisplayId displayId) const5140 int32_t SceneSessionManager::GetFocusedSessionId(DisplayId displayId) const
5141 {
5142 return windowFocusController_->GetFocusedSessionId(displayId);
5143 }
5144
GetFocusWindowInfo(FocusChangeInfo & focusInfo,DisplayId displayId)5145 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo, DisplayId displayId)
5146 {
5147 if (!SessionPermission::IsSACalling()) {
5148 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
5149 return;
5150 }
5151 taskScheduler_->PostSyncTask([this, &focusInfo, displayId] {
5152 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
5153 if (focusGroup == nullptr) {
5154 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
5155 return WSError::WS_ERROR_DESTROYED_OBJECT;
5156 }
5157 if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
5158 focusInfo.windowId_ = sceneSession->GetWindowId();
5159 focusInfo.displayId_ = focusGroup->GetDisplayGroupId();
5160 focusInfo.pid_ = sceneSession->GetCallingPid();
5161 focusInfo.uid_ = sceneSession->GetCallingUid();
5162 focusInfo.windowType_ = sceneSession->GetWindowType();
5163 focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
5164 TLOGNI(WmsLogTag::WMS_FOCUS, "Get focus session info success");
5165 return WSError::WS_OK;
5166 }
5167 return WSError::WS_ERROR_DESTROYED_OBJECT;
5168 }, __func__);
5169 }
5170
AddFocusGroup(DisplayId displayId)5171 WSError SceneSessionManager::AddFocusGroup(DisplayId displayId)
5172 {
5173 return windowFocusController_->AddFocusGroup(displayId);
5174 }
5175
RemoveFocusGroup(DisplayId displayId)5176 WSError SceneSessionManager::RemoveFocusGroup(DisplayId displayId)
5177 {
5178 return windowFocusController_->RemoveFocusGroup(displayId);
5179 }
5180
IsValidDigitString(const std::string & windowIdStr)5181 static bool IsValidDigitString(const std::string& windowIdStr)
5182 {
5183 if (windowIdStr.empty()) {
5184 return false;
5185 }
5186 for (char ch : windowIdStr) {
5187 if (ch >= '0' && ch <= '9') {
5188 continue;
5189 }
5190 TLOGE(WmsLogTag::DEFAULT, "invalid window id");
5191 return false;
5192 }
5193 return true;
5194 }
5195
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)5196 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
5197 {
5198 if (sceneSession == nullptr) {
5199 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
5200 return;
5201 }
5202 sceneSession->SetSessionExceptionListener([this, where = __func__](
5203 const SessionInfo& info, const ExceptionInfo& exceptionInfo , bool startFail = false) {
5204 auto task = [this, info, where] {
5205 auto session = GetSceneSession(info.persistentId_);
5206 if (session == nullptr) {
5207 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Not found session, id:%{public}d", where, info.persistentId_);
5208 return;
5209 }
5210 if (session->GetSessionInfo().isSystem_) {
5211 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d is system", where, session->GetPersistentId());
5212 return;
5213 }
5214 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s errorCode: %{public}d, id: %{public}d",
5215 where, info.errorCode, info.persistentId_);
5216 if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
5217 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
5218 TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
5219 "or foreground timeout, id: %{public}d", info.persistentId_);
5220 listenerController_->NotifySessionClosed(session->GetSessionInfo());
5221 }
5222 };
5223 taskScheduler_->PostVoidSyncTask(task, "sessionException");
5224 }, false);
5225 TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
5226 }
5227
RegisterVisibilityChangedDetectFunc(const sptr<SceneSession> & sceneSession)5228 void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr<SceneSession>& sceneSession)
5229 {
5230 if (sceneSession == nullptr) {
5231 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
5232 return;
5233 }
5234 sceneSession->SetVisibilityChangedDetectFunc(
5235 [this](int32_t pid, bool isVisible, bool newIsVisible) THREAD_SAFETY_GUARD(SCENE_GUARD) {
5236 if (isVisible == newIsVisible || pid == -1) {
5237 return;
5238 }
5239 auto windowPidVisibilityInfo = sptr<WindowPidVisibilityInfo>::MakeSptr();
5240 windowPidVisibilityInfo->pid_ = pid;
5241 int32_t currentCount = 0;
5242 int32_t beforeCount = 0;
5243 if (visibleWindowCountMap_.find(pid) != visibleWindowCountMap_.end()) {
5244 beforeCount = visibleWindowCountMap_[pid];
5245 }
5246 currentCount = newIsVisible ? beforeCount + 1 : beforeCount - 1;
5247 visibleWindowCountMap_[pid] = currentCount;
5248 if (visibleWindowCountMap_[pid] == 0) {
5249 visibleWindowCountMap_.erase(pid);
5250 }
5251 if (beforeCount == 0 && currentCount == 1) {
5252 TLOGNI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid);
5253 windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE;
5254 SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
5255 } else if (beforeCount == 1 && currentCount == 0) {
5256 TLOGNI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid);
5257 windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE;
5258 SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
5259 } else if (beforeCount < 0 || currentCount < 0) {
5260 TLOGNE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid);
5261 RecoveryVisibilityPidCount(pid);
5262 }
5263 });
5264 }
5265
RecoveryVisibilityPidCount(int32_t pid)5266 void SceneSessionManager::RecoveryVisibilityPidCount(int32_t pid)
5267 {
5268 int32_t count = 0;
5269 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5270 for (const auto& [_, session] : sceneSessionMap_) {
5271 if (session && session->GetCallingPid() == pid && session->IsVisible()) {
5272 count++;
5273 }
5274 }
5275 if (count > 0) {
5276 visibleWindowCountMap_[pid] = count;
5277 }
5278 }
5279
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)5280 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
5281 {
5282 if (sceneSession == nullptr) {
5283 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5284 return;
5285 }
5286 NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
5287 auto sceneSession = GetSceneSession(persistentId);
5288 if (sceneSession == nullptr) {
5289 TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
5290 return;
5291 }
5292 if (sceneSession->GetSessionInfo().isSystem_) {
5293 TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, id: %{public}d is system",
5294 sceneSession->GetPersistentId());
5295 return;
5296 }
5297 auto abilityInfo = sceneSession->GetSessionInfo().abilityInfo;
5298 if (abilityInfo == nullptr) {
5299 TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, abilityInfo is nullptr");
5300 return;
5301 }
5302 if (!abilityInfo->excludeFromMissions) {
5303 listenerController_->NotifySessionSnapshotChanged(persistentId);
5304 }
5305 };
5306 sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
5307 TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d", sceneSession->GetPersistentId());
5308 }
5309
RegisterRequestVsyncFunc(const sptr<SceneSession> & sceneSession)5310 void SceneSessionManager::RegisterRequestVsyncFunc(const sptr<SceneSession>& sceneSession)
5311 {
5312 if (sceneSession == nullptr) {
5313 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5314 return;
5315 }
5316 sceneSession->SetRequestNextVsyncFunc([this](const std::shared_ptr<VsyncCallback>& callback) {
5317 vsyncStation_->RequestVsync(callback);
5318 });
5319 }
5320
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)5321 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
5322 {
5323 if (sceneSession == nullptr) {
5324 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5325 return;
5326 }
5327 AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
5328 config.duration_ = rotateAnimationConfig_.duration_;
5329 };
5330 sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
5331 TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d",
5332 sceneSession->GetPersistentId());
5333 }
5334
NotifySessionForCallback(const sptr<SceneSession> & sceneSession,const bool needRemoveSession)5335 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
5336 {
5337 if (sceneSession == nullptr) {
5338 TLOGW(WmsLogTag::DEFAULT, "session is null");
5339 return;
5340 }
5341 if (sceneSession->GetSessionInfo().isSystem_) {
5342 TLOGW(WmsLogTag::DEFAULT, "id: %{public}d is system", sceneSession->GetPersistentId());
5343 return;
5344 }
5345 if (sceneSession->GetSessionInfo().appIndex_ != 0) {
5346 TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, appIndex: %{public}d, id: %{public}d",
5347 sceneSession->GetSessionInfo().appIndex_, sceneSession->GetPersistentId());
5348 listenerController_->NotifySessionLifecycleEvent(
5349 ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
5350 return;
5351 }
5352 if (needRemoveSession) {
5353 TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, needRemoveSession, id: %{public}d", sceneSession->GetPersistentId());
5354 listenerController_->NotifySessionLifecycleEvent(
5355 ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
5356 return;
5357 }
5358 if (sceneSession->GetSessionInfo().abilityInfo == nullptr) {
5359 TLOGW(WmsLogTag::DEFAULT, "abilityInfo is null, id: %{public}d", sceneSession->GetPersistentId());
5360 } else if ((sceneSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
5361 (sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
5362 TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
5363 sceneSession->GetPersistentId());
5364 listenerController_->NotifySessionLifecycleEvent(
5365 ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
5366 return;
5367 }
5368 TLOGI(WmsLogTag::DEFAULT, "NotifyClosed, id: %{public}d", sceneSession->GetPersistentId());
5369 listenerController_->NotifySessionClosed(sceneSession->GetSessionInfo());
5370 }
5371
NotifyWindowInfoChangeFromSession(int32_t persistentId)5372 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
5373 {
5374 TLOGD(WmsLogTag::DEFAULT, "persistentId=%{public}d", persistentId);
5375 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
5376 if (sceneSession == nullptr) {
5377 TLOGE(WmsLogTag::DEFAULT, "sceneSession nullptr");
5378 return;
5379 }
5380
5381 SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
5382 }
5383
IsSessionVisible(const sptr<SceneSession> & session) const5384 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session) const
5385 {
5386 if (session == nullptr) {
5387 return false;
5388 }
5389 if (Session::IsScbCoreEnabled()) {
5390 return session->IsVisible();
5391 }
5392 const auto& state = session->GetSessionState();
5393 if (WindowHelper::IsSubWindow(session->GetWindowType())) {
5394 const auto& mainOrFloatSession = session->GetMainOrFloatSession();
5395 if (mainOrFloatSession == nullptr) {
5396 TLOGE(WmsLogTag::WMS_SUB, "Can not find parent for this sub window, id: %{public}d",
5397 session->GetPersistentId());
5398 return false;
5399 }
5400 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
5401 const auto mainOrFloatSessionState = mainOrFloatSession->GetSessionState();
5402 if (mainOrFloatSessionState == SessionState::STATE_INACTIVE ||
5403 mainOrFloatSessionState == SessionState::STATE_BACKGROUND) {
5404 TLOGD(WmsLogTag::WMS_SUB, "Parent of this sub window is at background, id: %{public}d",
5405 session->GetPersistentId());
5406 return false;
5407 }
5408 TLOGD(WmsLogTag::WMS_SUB, "Sub window is at foreground, id: %{public}d", session->GetPersistentId());
5409 return true;
5410 }
5411 TLOGD(WmsLogTag::WMS_SUB, "Sub window is at background, id: %{public}d", session->GetPersistentId());
5412 return false;
5413 }
5414
5415 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
5416 TLOGD(WmsLogTag::WMS_LIFE, "Window is at foreground, id: %{public}d", session->GetPersistentId());
5417 return true;
5418 }
5419 TLOGD(WmsLogTag::WMS_LIFE, "Window is at background, id: %{public}d", session->GetPersistentId());
5420 return false;
5421 }
5422
IsSessionVisibleForeground(const sptr<SceneSession> & session) const5423 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session) const
5424 {
5425 if (session == nullptr) {
5426 return false;
5427 }
5428 if (Session::IsScbCoreEnabled()) {
5429 return session->IsVisibleForeground();
5430 }
5431 return IsSessionVisible(session);
5432 }
5433
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)5434 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
5435 {
5436 if (session == nullptr) {
5437 return;
5438 }
5439 int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
5440 WSRect rect = session->GetSessionRect();
5441 std::string sName;
5442 if (session->GetSessionInfo().isSystem_) {
5443 sName = session->GetSessionInfo().abilityName_;
5444 } else {
5445 sName = session->GetWindowName();
5446 }
5447 uint32_t flag = session->GetSessionProperty()->GetWindowFlags();
5448 uint64_t displayId = session->GetSessionProperty()->GetDisplayId();
5449 uint32_t orientation = 0;
5450 const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
5451 sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
5452 // std::setw is used to set the output width and different width values are set to keep the format aligned.
5453 oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
5454 << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
5455 << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
5456 << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
5457 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
5458 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
5459 << std::left << std::setw(VALUE_MAX_WIDTH) << flag
5460 << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
5461 << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
5462 << "[ "
5463 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
5464 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
5465 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
5466 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
5467 << "]"
5468 << " [ "
5469 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
5470 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
5471 << "]"
5472 << " [ "
5473 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
5474 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
5475 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
5476 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
5477 << "]"
5478 << std::endl;
5479 }
5480
DumpFocusInfo(std::ostringstream & oss)5481 void SceneSessionManager::DumpFocusInfo(std::ostringstream& oss)
5482 {
5483 auto defaultFocusedSessionId = windowFocusController_->GetFocusedSessionId(DEFAULT_DISPLAY_ID);
5484 oss << "Focus window: " << defaultFocusedSessionId << std::endl;
5485 std::vector<std::pair<DisplayId, int32_t>> allFocusedSessionList =
5486 windowFocusController_->GetAllFocusedSessionList();
5487 oss << "All Focus window: " << std::endl;
5488 if (allFocusedSessionList.size() > 0) {
5489 for (const auto& focusState : allFocusedSessionList) {
5490 oss << "DisplayId: " << focusState.first << " WindowId: " << focusState.second << std::endl;
5491 }
5492 }
5493 }
5494
GetAllSessionDumpInfo(std::string & dumpInfo)5495 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
5496 {
5497 std::ostringstream oss;
5498 oss << "-------------------------------------ScreenGroup 0"
5499 << "-------------------------------------" << std::endl;
5500 oss << "WindowName DisplayId Pid WinId Type Mode Flag ZOrd Orientation [ x y w h ]"
5501 << " [ OffsetX OffsetY ] [ ScaleX ScaleY PivotX PivotY ]" << std::endl;
5502 std::vector<sptr<SceneSession>> allSession;
5503 std::vector<sptr<SceneSession>> backgroundSession;
5504 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
5505 {
5506 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5507 sceneSessionMapCopy = sceneSessionMap_;
5508 }
5509 for (const auto& elem : sceneSessionMapCopy) {
5510 auto curSession = elem.second;
5511 if (curSession == nullptr) {
5512 TLOGW(WmsLogTag::DEFAULT, "nullptr");
5513 continue;
5514 }
5515 if (!curSession->GetSessionInfo().isSystem_ &&
5516 (curSession->GetSessionState() < SessionState::STATE_FOREGROUND ||
5517 curSession->GetSessionState() > SessionState::STATE_BACKGROUND)) {
5518 TLOGW(WmsLogTag::DEFAULT, "id:%{public}d,invalid state:%{public}u",
5519 curSession->GetPersistentId(), curSession->GetSessionState());
5520 continue;
5521 }
5522 if (IsSessionVisibleForeground(curSession)) {
5523 allSession.push_back(curSession);
5524 } else {
5525 backgroundSession.push_back(curSession);
5526 }
5527 }
5528 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
5529 uint32_t count = 0;
5530 for (const auto& session : allSession) {
5531 if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
5532 oss << "---------------------------------------------------------------------------------------"
5533 << std::endl;
5534 }
5535 DumpSessionInfo(session, oss);
5536 count++;
5537 }
5538 DumpFocusInfo(oss);
5539 oss << "SingleHand: X[" << singleHandTransform_.posX << "] Y[" << singleHandTransform_.posY << "] scale["
5540 << singleHandTransform_.scaleX << "]" << std::endl;
5541 oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
5542 oss << "Highlighted windows: " << GetHighlightIdsStr() << std::endl;
5543 dumpInfo.append(oss.str());
5544 return WSError::WS_OK;
5545 }
5546
GetAllSessionDumpDetailInfo(std::string & dumpInfo)5547 WSError SceneSessionManager::GetAllSessionDumpDetailInfo(std::string& dumpInfo)
5548 {
5549 std::ostringstream oss;
5550 std::vector<sptr<SceneSession>> allSession;
5551 std::vector<sptr<SceneSession>> backgroundSession;
5552
5553 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
5554 {
5555 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5556 sceneSessionMapCopy = sceneSessionMap_;
5557 }
5558 for (const auto& elem : sceneSessionMapCopy) {
5559 auto curSession = elem.second;
5560 if (curSession == nullptr) {
5561 continue;
5562 }
5563 if (IsSessionVisibleForeground(curSession)) {
5564 allSession.push_back(curSession);
5565 } else {
5566 backgroundSession.push_back(curSession);
5567 }
5568 }
5569 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
5570 HidumpController::GetInstance().GetAllSessionDumpDetailedInfo(oss, allSession, backgroundSession);
5571 dumpInfo.append(oss.str());
5572 return WSError::WS_OK;
5573 }
5574
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)5575 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
5576 {
5577 dumpRootSceneFunc_ = func;
5578 }
5579
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)5580 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
5581 const std::vector<std::string>& params, std::string& dumpInfo)
5582 {
5583 std::vector<std::string> resetParams;
5584 resetParams.assign(params.begin() + 2, params.end()); // 2: params num
5585 if (resetParams.empty()) {
5586 TLOGND(WmsLogTag::DEFAULT, "do not dump ui info");
5587 return;
5588 }
5589
5590 if (!session->GetSessionInfo().isSystem_) {
5591 TLOGD(WmsLogTag::DEFAULT, "Dump normal session, not system");
5592 dumpInfoFuture_.ResetLock({});
5593 session->DumpSessionElementInfo(resetParams);
5594 std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
5595 for (auto& info: infos) {
5596 dumpInfo.append(info).append("\n");
5597 }
5598 } else {
5599 TLOGD(WmsLogTag::DEFAULT, "Dump system session");
5600 std::vector<std::string> infos;
5601 dumpRootSceneFunc_(resetParams, infos);
5602 for (auto& info: infos) {
5603 dumpInfo.append(info).append("\n");
5604 }
5605 }
5606 }
5607
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)5608 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
5609 const std::string& strId)
5610 {
5611 uint64_t persistentId = std::stoull(strId);
5612 auto session = GetSceneSession(persistentId);
5613 if (session == nullptr) {
5614 return WSError::WS_ERROR_INVALID_PARAM;
5615 }
5616 auto sessionProperty = session->GetSessionProperty();
5617 WSRect rect = session->GetSessionRect();
5618 std::string isVisible = session->IsVisible() ? "true" : "false";
5619 std::string focusable = session->GetFocusable() ? "true" : "false";
5620 std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
5621 bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
5622 std::string isPrivacyMode = privacyMode ? "true" : "false";
5623 bool isFirstFrameAvailable = true;
5624 std::ostringstream oss;
5625 oss << "WindowName: " << session->GetWindowName() << std::endl;
5626 oss << "DisplayId: " << 0 << std::endl;
5627 oss << "WinId: " << session->GetPersistentId() << std::endl;
5628 oss << "Pid: " << session->GetCallingPid() << std::endl;
5629 oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
5630 oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
5631 oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
5632 oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
5633 oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
5634 oss << "IsVisible: " << isVisible << std::endl;
5635 oss << "isRSVisible: " << (session->GetRSVisible() ? "true" : "false") << std::endl;
5636 oss << "Focusable: " << focusable << std::endl;
5637 oss << "DecoStatus: " << decoStatus << std::endl;
5638 oss << "isPrivacyMode: " << isPrivacyMode << std::endl;
5639 oss << "WindowRect: " << "[ "
5640 << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
5641 << " ]" << std::endl;
5642 oss << "scaleX: " << session->GetScaleX() << std::endl;
5643 oss << "scaleY: " << session->GetScaleY() << std::endl;
5644 oss << "Offset: " << "[ "
5645 << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
5646 oss << "Scale: " << "[ "
5647 << session->GetScaleX() << ", " << session->GetScaleY() << ", "
5648 << session->GetPivotX() << ", " << session->GetPivotY()
5649 << " ]" << std::endl;
5650 oss << "ParentWindowId: " << session->GetParentPersistentId() << std::endl;
5651 dumpInfo.append(oss.str());
5652
5653 DumpSessionElementInfo(session, params, dumpInfo);
5654 return WSError::WS_OK;
5655 }
5656
GetSCBDebugDumpInfo(std::string && cmd,std::string & dumpInfo)5657 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string&& cmd, std::string& dumpInfo)
5658 {
5659 // publish data
5660 bool ret = eventHandler_->PostSyncTask(
5661 [this, cmd = std::move(cmd)] { return scbDumpSubscriber_->Publish(cmd); }, "PublishSCBDumper");
5662 if (!ret) {
5663 return WSError::WS_ERROR_INVALID_OPERATION;
5664 }
5665 // get response event
5666 auto task = [this, &dumpInfo] {
5667 dumpInfo.append(scbDumpSubscriber_->GetDebugDumpInfo(WAIT_TIME));
5668 return WSError::WS_OK;
5669 };
5670 eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
5671 return WSError::WS_OK;
5672 }
5673
NotifyDumpInfoResult(const std::vector<std::string> & info)5674 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
5675 {
5676 dumpInfoFuture_.SetValue(info);
5677 TLOGD(WmsLogTag::DEFAULT, "NotifyDumpInfoResult");
5678 }
5679
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)5680 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
5681 {
5682 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
5683 TLOGE(WmsLogTag::DEFAULT, "GetSessionDumpInfo permission denied!");
5684 return WSError::WS_ERROR_INVALID_PERMISSION;
5685 }
5686
5687 if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
5688 return GetAllSessionDumpInfo(dumpInfo);
5689 }
5690 if (params.size() == 1 && params[0] == ARG_DUMP_DETAIL) { // 1: params num
5691 return GetAllSessionDumpDetailInfo(dumpInfo);
5692 }
5693 if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
5694 return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
5695 }
5696 if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2: params num
5697 std::string cmd;
5698 std::for_each(params.begin() + 1, params.end(),
5699 [&cmd](const std::string& value) {
5700 cmd += value;
5701 cmd += ' ';
5702 });
5703 return GetSCBDebugDumpInfo(std::move(cmd), dumpInfo);
5704 }
5705 if (params.size() >= 1 && params[0] == ARG_DUMP_PIPLINE) { // 1: params num
5706 return GetTotalUITreeInfo(dumpInfo);
5707 }
5708 return WSError::WS_ERROR_INVALID_OPERATION;
5709 }
5710
GetTotalUITreeInfo(std::string & dumpInfo)5711 WSError SceneSessionManager::GetTotalUITreeInfo(std::string& dumpInfo)
5712 {
5713 TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
5714 if (dumpUITreeFunc_) {
5715 dumpUITreeFunc_(dumpInfo);
5716 } else {
5717 TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
5718 }
5719 return WSError::WS_OK;
5720 }
5721
SetDumpUITreeFunc(const DumpUITreeFunc & func)5722 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
5723 {
5724 dumpUITreeFunc_ = func;
5725 }
5726
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)5727 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
5728 {
5729 onFlushUIParamsFunc_ = std::move(func);
5730 }
5731
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)5732 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
5733 {
5734 isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
5735 }
5736
SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId,bool visible)5737 void SceneSessionManager::SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId, bool visible)
5738 {
5739 taskScheduler_->PostAsyncTask([this, displayId, visible] {
5740 statusBarDefaultVisibilityPerDisplay_[displayId] = visible;
5741 TLOGNI(WmsLogTag::WMS_IMMS, "set default visibility, "
5742 "display id %{public}" PRIu64 " visible %{public}d", displayId, visible);
5743 }, __func__);
5744 }
5745
GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)5746 bool SceneSessionManager::GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)
5747 {
5748 return statusBarDefaultVisibilityPerDisplay_.count(displayId) != 0 ?
5749 statusBarDefaultVisibilityPerDisplay_[displayId] : true;
5750 }
5751
FocusIDChange(int32_t persistentId,const sptr<SceneSession> & sceneSession)5752 void FocusIDChange(int32_t persistentId, const sptr<SceneSession>& sceneSession)
5753 {
5754 // notify RS
5755 TLOGD(WmsLogTag::WMS_FOCUS, "current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s, "
5756 "abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
5757 sceneSession->GetSessionProperty()->GetWindowName().c_str(),
5758 sceneSession->GetSessionInfo().bundleName_.c_str(),
5759 sceneSession->GetSessionInfo().abilityName_.c_str(),
5760 sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
5761 uint64_t focusNodeId = 0; // 0 means invalid
5762 if (sceneSession->GetSurfaceNode() == nullptr) {
5763 TLOGW(WmsLogTag::WMS_FOCUS, "focused window surfaceNode is null");
5764 } else {
5765 focusNodeId = sceneSession->GetSurfaceNode()->GetId();
5766 }
5767 FocusAppInfo appInfo = {
5768 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
5769 sceneSession->GetSessionInfo().bundleName_,
5770 sceneSession->GetSessionInfo().abilityName_, focusNodeId};
5771 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
5772 }
5773
5774 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)5775 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
5776 {
5777 std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
5778 {
5779 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5780 for (auto& iter : sceneSessionMap_) {
5781 ret.push_back(iter);
5782 }
5783 }
5784 std::sort(ret.begin(), ret.end(), cmp);
5785 return ret;
5786 }
5787
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)5788 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
5789 {
5790 if (isFromTopToBottom) {
5791 TraverseSessionTreeFromTopToBottom(func);
5792 } else {
5793 TraverseSessionTreeFromBottomToTop(func);
5794 }
5795 return;
5796 }
5797
TraverseSessionTreeFromTopToBottom(TraverseFunc func)5798 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
5799 {
5800 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
5801 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
5802 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
5803 return lhsZOrder < rhsZOrder;
5804 };
5805 auto sceneSessionVector = GetSceneSessionVector(cmp);
5806
5807 for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
5808 auto session = iter->second;
5809 if (session == nullptr) {
5810 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5811 continue;
5812 }
5813 if (func(session)) {
5814 return;
5815 }
5816 }
5817 return;
5818 }
5819
TraverseSessionTreeFromBottomToTop(TraverseFunc func)5820 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
5821 {
5822 // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5823 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
5824 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
5825 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
5826 return lhsZOrder < rhsZOrder;
5827 };
5828 auto sceneSessionVector = GetSceneSessionVector(cmp);
5829 // std::map<int32_t, sptr<SceneSession>>::iterator iter;
5830 for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
5831 auto session = iter->second;
5832 if (session == nullptr) {
5833 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
5834 continue;
5835 }
5836 if (func(session)) {
5837 return;
5838 }
5839 }
5840 return;
5841 }
5842
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5843 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
5844 FocusChangeReason reason)
5845 {
5846 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5847 auto sceneSession = GetSceneSession(persistentId);
5848 if (sceneSession == nullptr) {
5849 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5850 return WMError::WM_ERROR_NULLPTR;
5851 }
5852 int32_t callingPid = IPCSkeleton::GetCallingPid();
5853 if (callingPid != sceneSession->GetCallingPid() &&
5854 !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
5855 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
5856 return WMError::WM_ERROR_INVALID_CALLING;
5857 }
5858 auto task = [this, persistentId, isFocused, byForeground, reason]() {
5859 if (isFocused) {
5860 RequestSessionFocus(persistentId, byForeground, reason);
5861 } else {
5862 RequestSessionUnfocus(persistentId, reason);
5863 }
5864 };
5865 taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
5866 focusChangeReason_ = reason;
5867 return WMError::WM_OK;
5868 }
5869
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5870 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
5871 FocusChangeReason reason)
5872 {
5873 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5874 auto task = [this, persistentId, isFocused, byForeground, reason]() {
5875 if (isFocused) {
5876 if (reason == FocusChangeReason::FOREGROUND) {
5877 RequestSessionFocusImmediately(persistentId);
5878 return;
5879 }
5880 if (reason == FocusChangeReason::MOVE_UP) {
5881 auto session = GetSceneSession(persistentId);
5882 if (session && !session->IsFocused()) {
5883 PostProcessFocusState state = { true, true, byForeground, reason };
5884 session->SetPostProcessFocusState(state);
5885 }
5886 return;
5887 }
5888 // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
5889 if (reason == FocusChangeReason::CLICK) {
5890 return;
5891 }
5892 if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
5893 auto session = GetSceneSession(persistentId);
5894 if (session && !session->IsFocused()) {
5895 PostProcessFocusState state = { true, true, byForeground, reason };
5896 session->SetPostProcessFocusState(state);
5897 }
5898 }
5899 } else {
5900 RequestSessionUnfocus(persistentId, reason);
5901 }
5902 };
5903 taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
5904 return WMError::WM_OK;
5905 }
5906
RequestFocusStatusBySA(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5907 WMError SceneSessionManager::RequestFocusStatusBySA(int32_t persistentId, bool isFocused,
5908 bool byForeground, FocusChangeReason reason)
5909 {
5910 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5911 if (!SessionPermission::IsSACalling()) {
5912 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, only support SA calling.");
5913 return WMError::WM_ERROR_INVALID_PERMISSION;
5914 }
5915 auto sceneSession = GetSceneSession(persistentId);
5916 if (sceneSession == nullptr) {
5917 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5918 return WMError::WM_ERROR_NULLPTR;
5919 }
5920 auto task = [this, persistentId, isFocused, byForeground, reason]() {
5921 if (isFocused) {
5922 RequestSessionFocus(persistentId, byForeground, reason);
5923 } else {
5924 RequestSessionUnfocus(persistentId, reason);
5925 }
5926 };
5927 taskScheduler_->PostAsyncTask(task, "RequestFocusOnPreviousWindow" + std::to_string(persistentId));
5928 return WMError::WM_OK;
5929 }
5930
RequestAllAppSessionUnfocus()5931 void SceneSessionManager::RequestAllAppSessionUnfocus()
5932 {
5933 auto task = [this]() {
5934 RequestAllAppSessionUnfocusInner();
5935 };
5936 taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
5937 return;
5938 }
5939
5940 /**
5941 * request focus and ignore its state
5942 * only used when app main window start before foreground
5943 */
RequestSessionFocusImmediately(int32_t persistentId,bool blockNotifyUntilVisible)5944 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId, bool blockNotifyUntilVisible)
5945 {
5946 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, blockNotify: %{public}d", persistentId, blockNotifyUntilVisible);
5947 auto sceneSession = GetSceneSession(persistentId);
5948 if (sceneSession == nullptr) {
5949 TLOGE(WmsLogTag::WMS_FOCUS, "[WMSComm]session is nullptr");
5950 return WSError::WS_ERROR_INVALID_SESSION;
5951 }
5952 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
5953 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
5954 if (focusGroup == nullptr) {
5955 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
5956 return WSError::WS_ERROR_NULLPTR;
5957 }
5958 // base block
5959 WSError basicCheckRet = RequestFocusBasicCheck(persistentId, focusGroup);
5960 if (basicCheckRet != WSError::WS_OK) {
5961 return basicCheckRet;
5962 }
5963 if (!sceneSession->CheckFocusable()) {
5964 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
5965 return WSError::WS_DO_NOTHING;
5966 }
5967 if (!sceneSession->IsFocusedOnShow()) {
5968 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
5969 return WSError::WS_DO_NOTHING;
5970 }
5971
5972 // specific block
5973 FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
5974 WSError specificCheckRet = RequestFocusSpecificCheck(displayId, sceneSession, true, reason);
5975 if (specificCheckRet != WSError::WS_OK) {
5976 return specificCheckRet;
5977 }
5978 auto needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
5979 focusGroup->SetNeedBlockNotifyUnfocusStatus(needBlockNotifyFocusStatusUntilForeground);
5980 if (!sceneSession->GetSessionInfo().isSystem_ && !blockNotifyUntilVisible && systemConfig_.IsPcWindow()) {
5981 if (!sceneSession->IsSessionForeground()) {
5982 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
5983 }
5984 } else if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
5985 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
5986 }
5987 ShiftFocus(displayId, sceneSession, false, reason);
5988 return WSError::WS_OK;
5989 }
5990
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)5991 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
5992 {
5993 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
5994 persistentId, byForeground, reason);
5995 auto sceneSession = GetSceneSession(persistentId);
5996 if (sceneSession == nullptr) {
5997 TLOGE(WmsLogTag::WMS_FOCUS, "[WMSComm]session is nullptr");
5998 return WSError::WS_ERROR_INVALID_SESSION;
5999 }
6000 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
6001 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6002 if (focusGroup == nullptr) {
6003 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6004 return WSError::WS_ERROR_NULLPTR;
6005 }
6006 WSError basicCheckRet = RequestFocusBasicCheck(persistentId, focusGroup);
6007 if (basicCheckRet != WSError::WS_OK) {
6008 return basicCheckRet;
6009 }
6010 if (!sceneSession->CheckFocusable() || !IsSessionVisibleForeground(sceneSession)) {
6011 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
6012 return WSError::WS_DO_NOTHING;
6013 }
6014 if (!sceneSession->IsFocusedOnShow()) {
6015 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
6016 return WSError::WS_DO_NOTHING;
6017 }
6018 if (!sceneSession->IsFocusableOnShow() &&
6019 (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
6020 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
6021 return WSError::WS_DO_NOTHING;
6022 }
6023
6024 // subwindow/dialog state block
6025 if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
6026 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
6027 GetSceneSession(sceneSession->GetParentPersistentId()) &&
6028 !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
6029 TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
6030 sceneSession->GetParentPersistentId());
6031 return WSError::WS_DO_NOTHING;
6032 }
6033 // specific block
6034 WSError specificCheckRet = RequestFocusSpecificCheck(displayId, sceneSession, byForeground, reason);
6035 if (specificCheckRet != WSError::WS_OK) {
6036 return specificCheckRet;
6037 }
6038 focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
6039 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
6040 ShiftFocus(displayId, sceneSession, false, reason);
6041 return WSError::WS_OK;
6042 }
6043
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)6044 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
6045 {
6046 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
6047 if (persistentId == INVALID_SESSION_ID) {
6048 TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid: %{public}d", persistentId);
6049 return WSError::WS_ERROR_INVALID_SESSION;
6050 }
6051 auto sceneSession = GetSceneSession(persistentId);
6052 if (sceneSession == nullptr) {
6053 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr: %{public}d", persistentId);
6054 return WSError::WS_ERROR_INVALID_SESSION;
6055 }
6056 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
6057 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6058 if (focusGroup == nullptr) {
6059 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6060 return WSError::WS_ERROR_NULLPTR;
6061 }
6062 auto focusedSession = GetSceneSession(focusGroup->GetFocusedSessionId());
6063 if (persistentId != focusGroup->GetFocusedSessionId() &&
6064 !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
6065 TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
6066 return WSError::WS_DO_NOTHING;
6067 }
6068 // if pop menu created by desktop request unfocus, back to desktop
6069 auto lastSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
6070 if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
6071 lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
6072 RequestSessionFocus(focusGroup->GetLastFocusedSessionId(), false) == WSError::WS_OK) {
6073 TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
6074 return WSError::WS_OK;
6075 }
6076 auto nextSession = GetNextFocusableSession(displayId, persistentId);
6077 if (nextSession == nullptr) {
6078 DumpAllSessionFocusableInfo(persistentId);
6079 }
6080 focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
6081 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
6082
6083 if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
6084 return WSError::WS_OK;
6085 }
6086 if (nextSession && !nextSession->IsSessionForeground() && !nextSession->GetSessionInfo().isSystem_) {
6087 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
6088 }
6089 return ShiftFocus(displayId, nextSession, true, reason);
6090 }
6091
RequestAllAppSessionUnfocusInner()6092 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
6093 {
6094 TLOGI(WmsLogTag::WMS_FOCUS, "in");
6095 auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
6096 if (focusGroup == nullptr) {
6097 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
6098 return WSError::WS_ERROR_NULLPTR;
6099 }
6100 auto focusedSession = GetSceneSession(focusGroup->GetFocusedSessionId());
6101 if (!focusedSession) {
6102 TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
6103 return WSError::WS_DO_NOTHING;
6104 }
6105 if (!focusedSession->IsAppSession()) {
6106 TLOGW(WmsLogTag::WMS_FOCUS, "Focused session is non app: %{public}d", focusGroup->GetFocusedSessionId());
6107 return WSError::WS_DO_NOTHING;
6108 }
6109 auto nextSession = GetTopFocusableNonAppSession();
6110
6111 focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
6112 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
6113 return ShiftFocus(DEFAULT_DISPLAY_ID, nextSession, true, FocusChangeReason::WIND);
6114 }
6115
RequestFocusBasicCheck(int32_t persistentId,const sptr<FocusGroup> & focusGroup)6116 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId, const sptr<FocusGroup>& focusGroup)
6117 {
6118 // basic focus rule
6119 if (persistentId == INVALID_SESSION_ID) {
6120 TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
6121 return WSError::WS_ERROR_INVALID_SESSION;
6122 }
6123 if (focusGroup == nullptr) {
6124 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr");
6125 return WSError::WS_ERROR_NULLPTR;
6126 }
6127 if (persistentId == focusGroup->GetFocusedSessionId()) {
6128 TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
6129 return WSError::WS_DO_NOTHING;
6130 }
6131 return WSError::WS_OK;
6132 }
6133
6134 /**
6135 * @note @window.focus
6136 * When high zOrder System Session unfocus, check if the last focused app window can focus.
6137 */
CheckLastFocusedAppSessionFocus(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & nextSession)6138 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(const sptr<SceneSession>& focusedSession,
6139 const sptr<SceneSession>& nextSession)
6140 {
6141 if (focusedSession == nullptr || nextSession == nullptr) {
6142 return false;
6143 }
6144 auto displayId = focusedSession->GetSessionProperty()->GetDisplayId();
6145 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6146 if (focusGroup == nullptr) {
6147 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6148 return false;
6149 }
6150 auto lastFocusedAppSessionId = focusGroup->GetLastFocusedAppSessionId();
6151 TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
6152 lastFocusedAppSessionId, nextSession->GetPersistentId());
6153
6154 if (lastFocusedAppSessionId == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId) {
6155 return false;
6156 }
6157
6158 if (!focusedSession->IsSystemSessionAboveApp()) {
6159 return false;
6160 }
6161
6162 auto mode = nextSession->GetWindowMode();
6163 // only when next session is app, and in split or floation
6164 if (nextSession->IsAppSession() &&
6165 (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
6166 mode == WindowMode::WINDOW_MODE_FLOATING)) {
6167 if (RequestSessionFocus(lastFocusedAppSessionId, false, FocusChangeReason::LAST_FOCUSED_APP) ==
6168 WSError::WS_OK) {
6169 return true;
6170 }
6171 focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
6172 }
6173 return false;
6174 }
6175
6176 /**
6177 * When switching focus, check if the blockingType window has been traversed downwards.
6178 *
6179 * @return true: traversed downwards, false: not.
6180 */
CheckFocusIsDownThroughBlockingType(const sptr<SceneSession> & requestSceneSession,const sptr<SceneSession> & focusedSession,bool includingAppSession)6181 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(const sptr<SceneSession>& requestSceneSession,
6182 const sptr<SceneSession>& focusedSession, bool includingAppSession)
6183 {
6184 uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
6185 uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
6186 auto displayId = requestSceneSession->GetSessionProperty()->GetDisplayId();
6187 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
6188 requestSessionZOrder, focusedSessionZOrder);
6189 if (requestSessionZOrder < focusedSessionZOrder) {
6190 auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(displayId, requestSessionZOrder,
6191 includingAppSession);
6192 uint32_t topNearestBlockingZOrder = 0;
6193 if (topNearestBlockingFocusSession) {
6194 topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
6195 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\
6196 topNearestBlockingZOrder: %{public}d", requestSessionZOrder, focusedSessionZOrder,
6197 topNearestBlockingZOrder);
6198 }
6199 if (focusedSessionZOrder >= topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder) {
6200 TLOGD(WmsLogTag::WMS_FOCUS, "focus pass through, needs to be intercepted");
6201 return true;
6202 }
6203 }
6204 TLOGD(WmsLogTag::WMS_FOCUS, "not through");
6205 return false;
6206 }
6207
CheckTopmostWindowFocus(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession)6208 bool SceneSessionManager::CheckTopmostWindowFocus(const sptr<SceneSession>& focusedSession,
6209 const sptr<SceneSession>& sceneSession)
6210 {
6211 bool isFocusedMainSessionTopmost =
6212 focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
6213 auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
6214 bool isFocusedSessionParentTopmost = parentSession &&
6215 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
6216 if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
6217 (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
6218 return true;
6219 }
6220 return false;
6221 }
6222
CheckRequestFocusImmdediately(const sptr<SceneSession> & sceneSession)6223 bool SceneSessionManager::CheckRequestFocusImmdediately(const sptr<SceneSession>& sceneSession)
6224 {
6225 if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
6226 (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
6227 (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
6228 ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
6229 TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
6230 return true;
6231 }
6232 return false;
6233 }
6234
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)6235 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
6236 const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
6237 {
6238 if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
6239 focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
6240 return false;
6241 }
6242 if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
6243 return false;
6244 }
6245 return sceneSession->GetZOrder() < focusedSession->GetZOrder();
6246 }
6247
RequestFocusSpecificCheck(DisplayId displayId,const sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)6248 WSError SceneSessionManager::RequestFocusSpecificCheck(DisplayId displayId, const sptr<SceneSession>& sceneSession,
6249 bool byForeground, FocusChangeReason reason)
6250 {
6251 TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
6252 int32_t persistentId = sceneSession->GetPersistentId();
6253 if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
6254 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
6255 return WSError::WS_ERROR_INVALID_OPERATION;
6256 }
6257 // dialog get focus
6258 if (CheckRequestFocusImmdediately(sceneSession)) {
6259 return WSError::WS_DO_NOTHING;
6260 }
6261 // blocking-type session will block lower zOrder request focus
6262 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
6263 auto focusedSession = GetSceneSession(focusedSessionId);
6264 if (focusedSession) {
6265 TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d", reason,
6266 byForeground);
6267 if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
6268 // return ok if focused session is topmost
6269 return WSError::WS_OK;
6270 }
6271 if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
6272 sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
6273 TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
6274 byForeground = false;
6275 }
6276 if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, true)) {
6277 TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
6278 return WSError::WS_DO_NOTHING;
6279 }
6280 if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
6281 !byForeground) {
6282 if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
6283 && focusedSession->IsAppSession()) {
6284 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
6285 return WSError::WS_OK;
6286 }
6287 }
6288 bool isBlockingType = focusedSession->IsAppSession() ||
6289 (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
6290 // temp check
6291 if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
6292 sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
6293 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
6294 persistentId);
6295 return WSError::WS_DO_NOTHING;
6296 }
6297 // desktop click temp check
6298 if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
6299 TLOGD(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
6300 return WSError::WS_DO_NOTHING;
6301 }
6302 }
6303 return WSError::WS_OK;
6304 }
6305
IsParentSessionVisible(const sptr<SceneSession> & session)6306 bool SceneSessionManager::IsParentSessionVisible(const sptr<SceneSession>& session)
6307 {
6308 if (WindowHelper::IsSubWindow(session->GetWindowType()) ||
6309 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
6310 auto parentSession = GetSceneSession(session->GetParentPersistentId());
6311 return parentSession == nullptr || IsSessionVisibleForeground(parentSession);
6312 }
6313 return true;
6314 }
6315
DumpAllSessionFocusableInfo(int32_t persistentId)6316 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
6317 {
6318 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
6319 auto func = [this](const sptr<SceneSession>& session) {
6320 if (session == nullptr) {
6321 return false;
6322 }
6323 bool parentVisible = IsParentSessionVisible(session);
6324 bool sessionVisible = IsSessionVisible(session);
6325 TLOGNI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
6326 "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
6327 session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
6328 session->GetFocusable(), sessionVisible, parentVisible);
6329 return false;
6330 };
6331 TraverseSessionTree(func, true);
6332 }
6333
GetNextFocusableSession(DisplayId displayId,int32_t persistentId)6334 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(DisplayId displayId, int32_t persistentId)
6335 {
6336 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
6337 bool previousFocusedSessionFound = false;
6338 sptr<SceneSession> ret = nullptr;
6339 DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
6340 auto func = [this, persistentId, &previousFocusedSessionFound, &ret, displayGroupId](sptr<SceneSession> session) {
6341 if (session == nullptr) {
6342 return false;
6343 }
6344 if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
6345 displayGroupId) {
6346 return false;
6347 }
6348 if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
6349 TLOGND(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
6350 return false;
6351 }
6352 if (previousFocusedSessionFound && session->CheckFocusable() &&
6353 session->IsVisible() && IsParentSessionVisible(session)) {
6354 ret = session;
6355 return true;
6356 }
6357 if (session->GetPersistentId() == persistentId) {
6358 previousFocusedSessionFound = true;
6359 }
6360 return false;
6361 };
6362 TraverseSessionTree(func, true);
6363 return ret;
6364 }
6365
6366 /**
6367 * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
6368 * and it is the closest;
6369 */
GetTopNearestBlockingFocusSession(DisplayId displayId,uint32_t zOrder,bool includingAppSession)6370 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(DisplayId displayId, uint32_t zOrder,
6371 bool includingAppSession)
6372 {
6373 sptr<SceneSession> ret = nullptr;
6374 DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
6375 auto func = [this, &ret, zOrder, includingAppSession, displayGroupId](sptr<SceneSession> session) {
6376 if (session == nullptr) {
6377 return false;
6378 }
6379 if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
6380 displayGroupId) {
6381 return false;
6382 }
6383 uint32_t sessionZOrder = session->GetZOrder();
6384 if (sessionZOrder <= zOrder) { // must be above the target session
6385 return false;
6386 }
6387 if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6388 TLOGND(WmsLogTag::WMS_FOCUS, "topmost window do not block");
6389 return false;
6390 }
6391 auto parentSession = GetSceneSession(session->GetParentPersistentId());
6392 if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
6393 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
6394 parentSession->IsTopmost()) {
6395 TLOGND(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
6396 return false;
6397 }
6398 bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
6399 bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
6400 (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
6401 (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
6402 if (IsSessionVisibleForeground(session) && isBlockingType) {
6403 ret = session;
6404 return true;
6405 }
6406 return false;
6407 };
6408 TraverseSessionTree(func, false);
6409 return ret;
6410 }
6411
GetTopFocusableNonAppSession()6412 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
6413 {
6414 TLOGD(WmsLogTag::WMS_FOCUS, "in.");
6415 sptr<SceneSession> ret = nullptr;
6416 auto func = [this, &ret](sptr<SceneSession> session) {
6417 if (session == nullptr) {
6418 return false;
6419 }
6420 if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
6421 DEFAULT_DISPLAY_ID) {
6422 return false;
6423 }
6424 if (session->IsAppSession()) {
6425 return true;
6426 }
6427 if (session->CheckFocusable() && IsSessionVisibleForeground(session)) {
6428 ret = session;
6429 }
6430 return false;
6431 };
6432 TraverseSessionTree(func, false);
6433 return ret;
6434 }
6435
SetShiftFocusListener(const ProcessShiftFocusFunc & func)6436 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
6437 {
6438 TLOGD(WmsLogTag::WMS_FOCUS, "in");
6439 shiftFocusFunc_ = func;
6440 }
6441
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)6442 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
6443 {
6444 TLOGD(WmsLogTag::WMS_FOCUS, "in");
6445 notifySCBAfterFocusedFunc_ = func;
6446 }
6447
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)6448 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
6449 {
6450 TLOGD(WmsLogTag::WMS_FOCUS, "in");
6451 notifySCBAfterUnfocusedFunc_ = func;
6452 }
6453
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)6454 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
6455 {
6456 TLOGD(WmsLogTag::DEFAULT, "in");
6457 callingSessionIdChangeFunc_ = func;
6458 }
6459
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)6460 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
6461 {
6462 TLOGD(WmsLogTag::DEFAULT, "in");
6463 startUIAbilityErrorFunc_ = func;
6464 }
6465
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)6466 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
6467 const AbilityManagerCollaboratorRegisteredFunc& func)
6468 {
6469 auto task = [this, func] {
6470 abilityManagerCollaboratorRegisteredFunc_ = func;
6471 };
6472 taskScheduler_->PostAsyncTask(task, __func__);
6473 }
6474
ShiftFocus(DisplayId displayId,const sptr<SceneSession> & nextSession,bool isProactiveUnfocus,FocusChangeReason reason)6475 WSError SceneSessionManager::ShiftFocus(DisplayId displayId, const sptr<SceneSession>& nextSession,
6476 bool isProactiveUnfocus, FocusChangeReason reason)
6477 {
6478 // unfocus
6479 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
6480 int32_t focusedId = focusedSessionId;
6481 auto focusedSession = GetSceneSession(focusedSessionId);
6482 UpdateFocusStatus(displayId, focusedSession, false);
6483 // focus
6484 int32_t nextId = INVALID_SESSION_ID;
6485 if (nextSession == nullptr) {
6486 std::string sessionLog(GetAllSessionFocusInfo());
6487 TLOGW(WmsLogTag::WMS_FOCUS, "next session nullptr! id: %{public}d, info: %{public}s",
6488 focusedSessionId, sessionLog.c_str());
6489 } else {
6490 nextId = nextSession->GetPersistentId();
6491 }
6492 UpdateFocusStatus(displayId, nextSession, true);
6493 UpdateHighlightStatus(displayId, focusedSession, nextSession, isProactiveUnfocus);
6494 if (shiftFocusFunc_ != nullptr) {
6495 shiftFocusFunc_(nextId, displayId);
6496 }
6497 bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
6498 bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
6499 if (!scbPrevFocus && scbCurrFocus) {
6500 if (notifySCBAfterFocusedFunc_ != nullptr) {
6501 notifySCBAfterFocusedFunc_();
6502 }
6503 } else if (scbPrevFocus && !scbCurrFocus) {
6504 if (notifySCBAfterUnfocusedFunc_ != nullptr) {
6505 notifySCBAfterUnfocusedFunc_();
6506 }
6507 }
6508 TLOGI(WmsLogTag::WMS_FOCUS, "displayId: %{public}" PRIu64
6509 ", focusedId: %{public}d, nextId: %{public}d, reason: %{public}d", displayId, focusedId, nextId, reason);
6510 return WSError::WS_OK;
6511 }
6512
UpdateFocusStatus(DisplayId displayId,const sptr<SceneSession> & sceneSession,bool isFocused)6513 void SceneSessionManager::UpdateFocusStatus(DisplayId displayId, const sptr<SceneSession>& sceneSession,
6514 bool isFocused)
6515 {
6516 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6517 if (focusGroup == nullptr) {
6518 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6519 return;
6520 }
6521 bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
6522 bool needBlockNotifyUnfocusStatus = focusGroup->GetNeedBlockNotifyUnfocusStatus();
6523 if (sceneSession == nullptr) {
6524 TLOGW(WmsLogTag::WMS_FOCUS, "session is nullptr");
6525 if (isFocused) {
6526 SetFocusedSessionId(INVALID_SESSION_ID, displayId);
6527 focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
6528 auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
6529 NotifyUnFocusedByMission(prevSession);
6530 }
6531 return;
6532 }
6533 TLOGD(WmsLogTag::WMS_FOCUS, "name: %{public}s, id: %{public}d, isFocused: %{public}d, displayId: %{public}" PRIu64,
6534 sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused, displayId);
6535 // set focused
6536 if (isFocused) {
6537 SetFocusedSessionId(sceneSession->GetPersistentId(), displayId);
6538 if (sceneSession->IsAppOrLowerSystemSession()) {
6539 focusGroup->SetLastFocusedAppSessionId(sceneSession->GetPersistentId());
6540 }
6541 }
6542 sceneSession->UpdateFocus(isFocused);
6543 // notify listenerController unfocused
6544 auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
6545 if (isFocused && MissionChanged(prevSession, sceneSession)) {
6546 NotifyUnFocusedByMission(prevSession);
6547 }
6548 if ((isFocused && !needBlockNotifyFocusStatusUntilForeground) || (!isFocused && !needBlockNotifyUnfocusStatus)) {
6549 NotifyFocusStatus(sceneSession, isFocused, focusGroup);
6550 }
6551 }
6552
6553 /** @note @window.focus */
UpdateHighlightStatus(DisplayId displayId,const sptr<SceneSession> & preSceneSession,const sptr<SceneSession> & currSceneSession,bool isProactiveUnfocus)6554 void SceneSessionManager::UpdateHighlightStatus(DisplayId displayId, const sptr<SceneSession>& preSceneSession,
6555 const sptr<SceneSession>& currSceneSession, bool isProactiveUnfocus)
6556 {
6557 if (preSceneSession == nullptr || currSceneSession == nullptr) {
6558 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6559 return;
6560 }
6561 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6562 if (focusGroup == nullptr) {
6563 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6564 return;
6565 }
6566 bool needBlockHighlightNotify = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
6567 if(isProactiveUnfocus){
6568 TLOGD(WmsLogTag::WMS_FOCUS, "proactiveUnfocus");
6569 RemoveHighlightSessionIds(preSceneSession);
6570 }
6571 if(currSceneSession->GetSessionProperty()->GetExclusivelyHighlighted()) {
6572 TLOGD(WmsLogTag::WMS_FOCUS, "exclusively highlighted");
6573 SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
6574 return;
6575 }
6576 if(currSceneSession->GetSessionInfo().isSystem_) {
6577 TLOGD(WmsLogTag::WMS_FOCUS, "system highlighted");
6578 AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
6579 return;
6580 }
6581 if(currSceneSession->IsSameMainSession(preSceneSession)) {
6582 TLOGD(WmsLogTag::WMS_FOCUS, "related highlighted");
6583 AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
6584 return;
6585 }
6586 TLOGD(WmsLogTag::WMS_FOCUS, "highlighted");
6587 SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
6588 }
6589
6590 /** @note @window.focus */
SetHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)6591 void SceneSessionManager::SetHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
6592 {
6593 if (sceneSession == nullptr) {
6594 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6595 return;
6596 }
6597 {
6598 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
6599 for (auto persistentId : highlightIds_) {
6600 auto session = GetSceneSession(persistentId);
6601 if (session == nullptr) {
6602 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr");
6603 continue;
6604 }
6605 if (sceneSession->GetPersistentId() != persistentId) {
6606 session->UpdateHighlightStatus(false, false);
6607 }
6608 }
6609 sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
6610 highlightIds_.clear();
6611 highlightIds_.insert(sceneSession->GetPersistentId());
6612 }
6613 TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
6614 }
6615
6616 /** @note @window.focus */
AddHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)6617 void SceneSessionManager::AddHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
6618 {
6619 if (sceneSession == nullptr) {
6620 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6621 return;
6622 }
6623 sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
6624 {
6625 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
6626 highlightIds_.insert(sceneSession->GetPersistentId());
6627 }
6628 TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
6629 }
6630
6631 /** @note @window.focus */
RemoveHighlightSessionIds(const sptr<SceneSession> & sceneSession)6632 void SceneSessionManager::RemoveHighlightSessionIds(const sptr<SceneSession>& sceneSession)
6633 {
6634 if (sceneSession == nullptr) {
6635 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6636 return;
6637 }
6638 {
6639 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
6640 if (highlightIds_.find(sceneSession->GetPersistentId()) != highlightIds_.end()) {
6641 sceneSession->UpdateHighlightStatus(false, false);
6642 highlightIds_.erase(sceneSession->GetPersistentId());
6643 } else {
6644 TLOGE(WmsLogTag::WMS_FOCUS, "not found scene session with id: %{public}d", sceneSession->GetPersistentId());
6645 }
6646
6647 }
6648 TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
6649 }
6650
6651 /** @note @window.focus */
GetHighlightIdsStr()6652 std::string SceneSessionManager::GetHighlightIdsStr()
6653 {
6654 std::ostringstream oss;
6655 {
6656 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
6657 for (auto it = highlightIds_.begin(); it != highlightIds_.end(); it++) {
6658 oss << *it;
6659 if(std::next(it) != highlightIds_.end()) {
6660 oss << ", ";
6661 }
6662 }
6663
6664 }
6665 return oss.str();
6666 }
6667
NotifyFocusStatus(const sptr<SceneSession> & sceneSession,bool isFocused,const sptr<FocusGroup> & focusGroup)6668 void SceneSessionManager::NotifyFocusStatus(const sptr<SceneSession>& sceneSession, bool isFocused,
6669 const sptr<FocusGroup>& focusGroup)
6670 {
6671 if (focusGroup == nullptr) {
6672 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr");
6673 return;
6674 }
6675 int32_t persistentId = sceneSession->GetPersistentId();
6676
6677 TLOGI(WmsLogTag::WMS_FOCUS,
6678 "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
6679 sceneSession->GetSessionInfo().bundleName_.c_str(),
6680 sceneSession->GetSessionInfo().abilityName_.c_str(),
6681 sceneSession->GetWindowNameAllType().c_str(),
6682 persistentId, isFocused);
6683 if (isFocused) {
6684 if (IsSessionVisibleForeground(sceneSession)) {
6685 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
6686 }
6687 UpdateBrightness(focusGroup->GetFocusedSessionId());
6688 FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
6689 }
6690 // notify window manager
6691 sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
6692 sceneSession->GetWindowId(),
6693 static_cast<DisplayId>(focusGroup->GetDisplayGroupId()),
6694 sceneSession->GetCallingPid(),
6695 sceneSession->GetCallingUid(),
6696 sceneSession->GetWindowType(),
6697 sceneSession->GetAbilityToken()
6698 );
6699 SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
6700 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
6701 sceneSession->NotifyFocusStatus(isFocused);
6702 // notify listenerController focused
6703 auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
6704 if (isFocused && MissionChanged(prevSession, sceneSession)) {
6705 NotifyFocusedByMission(sceneSession);
6706 }
6707 }
6708
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)6709 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
6710 const std::string& reason)
6711 {
6712 uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
6713 nlohmann::json payload;
6714 payload.emplace("uid", uid);
6715 payload.emplace("bundleName", bundleName);
6716 payload.emplace("reason", reason);
6717 nlohmann::json reply;
6718 return ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
6719 }
6720
NotifyFocusStatusByMission(const sptr<SceneSession> & prevSession,const sptr<SceneSession> & currSession)6721 void SceneSessionManager::NotifyFocusStatusByMission(const sptr<SceneSession>& prevSession,
6722 const sptr<SceneSession>& currSession)
6723 {
6724 if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
6725 TLOGD(WmsLogTag::WMS_FOCUS, "Unfocused, id: %{public}d", prevSession->GetMissionId());
6726 listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
6727 }
6728 if (currSession && !currSession->GetSessionInfo().isSystem_) {
6729 TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", currSession->GetMissionId());
6730 listenerController_->NotifySessionFocused(currSession->GetMissionId());
6731 }
6732 }
6733
NotifyUnFocusedByMission(const sptr<SceneSession> & sceneSession)6734 void SceneSessionManager::NotifyUnFocusedByMission(const sptr<SceneSession>& sceneSession)
6735 {
6736 if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
6737 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", sceneSession->GetMissionId());
6738 listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
6739 }
6740 }
6741
NotifyFocusedByMission(const sptr<SceneSession> & sceneSession)6742 void SceneSessionManager::NotifyFocusedByMission(const sptr<SceneSession>& sceneSession)
6743 {
6744 if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
6745 TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", sceneSession->GetMissionId());
6746 listenerController_->NotifySessionFocused(sceneSession->GetMissionId());
6747 }
6748 }
6749
MissionChanged(const sptr<SceneSession> & prevSession,const sptr<SceneSession> & currSession)6750 bool SceneSessionManager::MissionChanged(const sptr<SceneSession>& prevSession, const sptr<SceneSession>& currSession)
6751 {
6752 if (prevSession == nullptr && currSession == nullptr) {
6753 return false;
6754 }
6755 if (prevSession == nullptr || currSession == nullptr) {
6756 return true;
6757 }
6758 return prevSession->GetMissionId() != currSession->GetMissionId();
6759 }
6760
GetAllSessionFocusInfo()6761 std::string SceneSessionManager::GetAllSessionFocusInfo()
6762 {
6763 std::ostringstream os;
6764 auto func = [&os](sptr<SceneSession> session) {
6765 if (session == nullptr) {
6766 TLOGNE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
6767 return false;
6768 }
6769 os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
6770 ", focusable: " << session->GetFocusable() << ";";
6771 return false;
6772 };
6773 TraverseSessionTree(func, true);
6774 return os.str();
6775 }
6776
UpdateFocus(int32_t persistentId,bool isFocused)6777 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
6778 {
6779 auto task = [this, persistentId, isFocused]() {
6780 // notify session and client
6781 auto sceneSession = GetSceneSession(persistentId);
6782 if (sceneSession == nullptr) {
6783 TLOGNE(WmsLogTag::WMS_FOCUS, "UpdateFocus could not find window, persistentId:%{public}d", persistentId);
6784 return WSError::WS_ERROR_INVALID_WINDOW;
6785 }
6786 TLOGNI(WmsLogTag::WMS_FOCUS, "UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
6787 sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
6788 // focusId change
6789 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
6790 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
6791 if (isFocused) {
6792 SetFocusedSessionId(displayId, persistentId);
6793 UpdateBrightness(focusedSessionId);
6794 FocusIDChange(persistentId, sceneSession);
6795 } else if (persistentId == GetFocusedSessionId()) {
6796 SetFocusedSessionId(displayId, INVALID_SESSION_ID);
6797 }
6798 // notify window manager
6799 sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
6800 sceneSession->GetWindowId(),
6801 static_cast<DisplayId>(0),
6802 sceneSession->GetCallingPid(),
6803 sceneSession->GetCallingUid(),
6804 sceneSession->GetWindowType(),
6805 sceneSession->GetAbilityToken()
6806 );
6807 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
6808 WSError res = WSError::WS_OK;
6809 res = sceneSession->UpdateFocus(isFocused);
6810 if (res != WSError::WS_OK) {
6811 return res;
6812 }
6813 TLOGNI(WmsLogTag::WMS_FOCUS, "UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6814 sceneSession->GetSessionInfo().isSystem_);
6815 if (!sceneSession->GetSessionInfo().isSystem_) {
6816 if (isFocused) {
6817 TLOGND(WmsLogTag::WMS_FOCUS, "NotifyFocused, id: %{public}d", sceneSession->GetPersistentId());
6818 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
6819 } else {
6820 TLOGND(WmsLogTag::WMS_FOCUS, "NotifyUnFocused, id: %{public}d", sceneSession->GetPersistentId());
6821 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
6822 }
6823 }
6824 return WSError::WS_OK;
6825 };
6826
6827 taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
6828 return WSError::WS_OK;
6829 }
6830
UpdateWindowMode(int32_t persistentId,int32_t windowMode)6831 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
6832 {
6833 TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, mode: %{public}d", persistentId, windowMode);
6834 auto sceneSession = GetSceneSession(persistentId);
6835 if (sceneSession == nullptr) {
6836 TLOGE(WmsLogTag::DEFAULT, "could not find window, Id:%{public}d", persistentId);
6837 return WSError::WS_ERROR_INVALID_WINDOW;
6838 }
6839 WindowMode mode = static_cast<WindowMode>(windowMode);
6840 return sceneSession->UpdateWindowMode(mode);
6841 }
6842
GetNormalSingleHandTransform() const6843 SingleHandTransform SceneSessionManager::GetNormalSingleHandTransform() const
6844 {
6845 return singleHandTransform_;
6846 }
6847
GetSingleHandScreenInfo() const6848 SingleHandScreenInfo SceneSessionManager::GetSingleHandScreenInfo() const
6849 {
6850 return singleHandScreenInfo_;
6851 }
6852
GetOriginRect() const6853 WSRect SceneSessionManager::GetOriginRect() const
6854 {
6855 return originRect_;
6856 }
6857
GetSingleHandRect() const6858 WSRect SceneSessionManager::GetSingleHandRect() const
6859 {
6860 return singleHandRect_;
6861 }
6862
NotifySingleHandInfoChange(SingleHandScreenInfo singleHandScreenInfo,WSRect originRect,WSRect singleHandRect)6863 void SceneSessionManager::NotifySingleHandInfoChange(SingleHandScreenInfo singleHandScreenInfo, WSRect originRect, WSRect singleHandRect)
6864 {
6865 const char* const funcName = __func__;
6866 taskScheduler_->PostAsyncTask([this, singleHandScreenInfo, originRect, singleHandRect, funcName] {
6867 if (!systemConfig_.IsPhoneWindow()) {
6868 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: only support phone", funcName);
6869 return;
6870 }
6871 int32_t displayWidth = 0;
6872 int32_t displayHeight = 0;
6873 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
6874 if (!GetDisplaySizeById(defaultScreenId, displayWidth, displayHeight)) {
6875 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: get display size failed", funcName);
6876 return;
6877 }
6878 singleHandScreenInfo_ = singleHandScreenInfo;
6879 originRect_ = originRect;
6880 singleHandRect_ = singleHandRect;
6881 singleHandTransform_.posX = singleHandRect.posX_;
6882 singleHandTransform_.posY = singleHandRect.posY_;
6883 singleHandTransform_.scaleX = static_cast<float>(singleHandScreenInfo_.scaleRatio) / 100;
6884 singleHandTransform_.scaleY = singleHandTransform_.scaleX;
6885 {
6886 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6887 for (const auto& [_, sceneSession] : sceneSessionMap_) {
6888 if (sceneSession == nullptr || !IsInDefaultScreen(sceneSession) ||
6889 sceneSession->GetWindowName().find("OneHandModeBackground", 0) != std::string::npos) {
6890 continue;
6891 }
6892 sceneSession->SetSingleHandModeFlag(true);
6893 sceneSession->SetSingleHandTransform(singleHandTransform_);
6894 sceneSession->NotifySingleHandTransformChange(singleHandTransform_);
6895 }
6896 }
6897 FlushWindowInfoToMMI();
6898 }, funcName);
6899 }
6900
RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc && func)6901 void SceneSessionManager::RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc&& func)
6902 {
6903 getRSNodeByStringIDFunc_ = std::move(func);
6904 }
6905
RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc && func)6906 void SceneSessionManager::RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc&& func)
6907 {
6908 setTopWindowBoundaryByIDFunc_ = std::move(func);
6909 }
6910
RegisterSingleHandContainerNode(const std::string & stringId)6911 void SceneSessionManager::RegisterSingleHandContainerNode(const std::string& stringId)
6912 {
6913 if (getRSNodeByStringIDFunc_ == nullptr) {
6914 TLOGE(WmsLogTag::WMS_LAYOUT, "func is nullptr");
6915 return;
6916 }
6917 auto rsNode = getRSNodeByStringIDFunc_(stringId);
6918 if (rsNode == nullptr) {
6919 TLOGE(WmsLogTag::WMS_LAYOUT, "node is nullptr");
6920 return;
6921 }
6922 TLOGI(WmsLogTag::WMS_LAYOUT, "get OneHandModeBox node, id: %{public}" PRIu64, rsNode->GetId());
6923 setTopWindowBoundaryByIDFunc_(stringId);
6924 rsInterface_.SetWindowContainer(rsNode->GetId(), true);
6925 }
6926
GetSingleHandCompatibleModeConfig() const6927 const SingleHandCompatibleModeConfig& SceneSessionManager::GetSingleHandCompatibleModeConfig() const
6928 {
6929 return singleHandCompatibleModeConfig_;
6930 }
6931
6932 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6933 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6934 MMI::PointerEvent::PointerItem& pointerItem)
6935 {
6936 struct PointerEventData {
6937 double x;
6938 double y;
6939 uint64_t time;
6940 } pointerEventData = {
6941 .x = pointerItem.GetDisplayX(),
6942 .y = pointerItem.GetDisplayY(),
6943 .time = pointerEvent->GetActionTime()
6944 };
6945
6946 const uint32_t MAX_HMAC_SIZE = 64;
6947 uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
6948 uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
6949 uint32_t enhanceDataLen = MAX_HMAC_SIZE;
6950 if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
6951 sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
6952 pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
6953 }
6954 }
6955 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
6956
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)6957 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
6958 {
6959 if (!pointerEvent) {
6960 TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null");
6961 return WSError::WS_ERROR_NULLPTR;
6962 }
6963 MMI::PointerEvent::PointerItem pointerItem;
6964 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
6965 TLOGE(WmsLogTag::WMS_EVENT, "Failed to get pointerItem");
6966 return WSError::WS_ERROR_INVALID_PARAM;
6967 }
6968 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
6969 FillSecCompEnhanceData(pointerEvent, pointerItem);
6970 #endif
6971 TLOGI(WmsLogTag::WMS_EVENT, "eid=%{public}d,ac=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
6972 pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
6973 pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
6974 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
6975 return WSError::WS_OK;
6976 }
6977
SetScreenLocked(const bool isScreenLocked)6978 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
6979 {
6980 taskScheduler_->PostTask([this, isScreenLocked] {
6981 isScreenLocked_ = isScreenLocked;
6982 DeleteStateDetectTask();
6983 NotifyPiPWindowVisibleChange(isScreenLocked);
6984 }, __func__);
6985 }
6986
SetUserAuthPassed(bool isUserAuthPassed)6987 void SceneSessionManager::SetUserAuthPassed(bool isUserAuthPassed)
6988 {
6989 taskScheduler_->PostTask([this, isUserAuthPassed] {
6990 isUserAuthPassed_ = isUserAuthPassed;
6991 }, __func__);
6992 }
6993
DeleteStateDetectTask()6994 void SceneSessionManager::DeleteStateDetectTask()
6995 {
6996 if (!IsScreenLocked()) {
6997 return;
6998 }
6999 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7000 for (auto iter : sceneSessionMap_) {
7001 auto& session = iter.second;
7002 if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
7003 taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
7004 DetectTaskInfo detectTaskInfo;
7005 session->SetDetectTaskInfo(detectTaskInfo);
7006 }
7007 }
7008 }
7009
IsScreenLocked() const7010 bool SceneSessionManager::IsScreenLocked() const
7011 {
7012 return isScreenLocked_;
7013 }
7014
IsUserAuthPassed() const7015 bool SceneSessionManager::IsUserAuthPassed() const
7016 {
7017 return isUserAuthPassed_;
7018 }
7019
RegisterWindowChanged(const WindowChangedFunc & func)7020 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
7021 {
7022 WindowChangedFunc_ = func;
7023 }
7024
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)7025 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
7026 const std::unordered_set<std::string>& privacyBundles)
7027 {
7028 bool needNotify = false;
7029 static int reSendTimes = MAX_RESEND_TIMES;
7030 std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
7031 do {
7032 if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
7033 TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
7034 needNotify = !privacyBundles.empty();
7035 break;
7036 }
7037 const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
7038 if (lastPrivacyBundles.size() != privacyBundles.size()) {
7039 TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
7040 lastPrivacyBundles.size(), privacyBundles.size());
7041 needNotify = true;
7042 break;
7043 }
7044 for (const auto& bundle : lastPrivacyBundles) {
7045 if (privacyBundles.find(bundle) == privacyBundles.end()) {
7046 needNotify = true;
7047 break;
7048 }
7049 }
7050 } while (false);
7051
7052 TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
7053 displayId, needNotify);
7054 if (needNotify) {
7055 reSendTimes = MAX_RESEND_TIMES;
7056 privacyBundleMap_[displayId] = privacyBundles;
7057 } else if (reSendTimes > 0) {
7058 needNotify = true;
7059 reSendTimes--;
7060 privacyBundleMap_[displayId] = privacyBundles;
7061 }
7062 return needNotify;
7063 }
7064
UpdatePrivateStateAndNotify(uint32_t persistentId)7065 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
7066 {
7067 auto sceneSession = GetSceneSession(persistentId);
7068 if (sceneSession == nullptr) {
7069 TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid=%{public}u.", persistentId);
7070 return;
7071 }
7072
7073 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7074 std::unordered_set<std::string> privacyBundleList;
7075 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
7076 if (isUserBackground_ || !JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
7077 return;
7078 }
7079
7080 std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
7081 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
7082 !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
7083 ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
7084 if (!bundleListForNotify.empty()) {
7085 TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
7086 }
7087 for (const auto& bundle : bundleListForNotify) {
7088 TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display=%{public}" PRIu64 ", bundle=%{public}s.",
7089 displayId, bundle.c_str());
7090 }
7091 }
7092
UpdatePrivateStateAndNotifyForAllScreens()7093 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
7094 {
7095 auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
7096 for (auto& iter : screenProperties) {
7097 auto displayId = iter.first;
7098 std::unordered_set<std::string> privacyBundleList;
7099 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
7100
7101 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
7102 !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
7103 }
7104 }
7105
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)7106 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
7107 std::unordered_set<std::string>& privacyBundles)
7108 {
7109 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7110 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
7111 if (sceneSession == nullptr) {
7112 TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid=%{public}d.", persistentId);
7113 continue;
7114 }
7115 auto sessionProperty = sceneSession->GetSessionProperty();
7116 auto currentDisplayId = sessionProperty->GetDisplayId();
7117 if (displayId != currentDisplayId) {
7118 continue;
7119 }
7120 bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
7121 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
7122 if (isForeground && sceneSession->GetParentSession() != nullptr) {
7123 isForeground = isForeground &&
7124 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
7125 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
7126 }
7127 bool isPrivate = sessionProperty->GetPrivacyMode() ||
7128 sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
7129 bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
7130 if ((isForeground || IsSystemWindowVisible) && isPrivate) {
7131 if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
7132 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
7133 } else {
7134 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "bundle name is empty, wid=%{public}d.", persistentId);
7135 privacyBundles.insert(sceneSession->GetWindowName());
7136 }
7137 }
7138 }
7139 }
7140
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)7141 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
7142 {
7143 if (sceneSession == nullptr) {
7144 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7145 return;
7146 }
7147 sceneSession->SetSessionStateChangeNotifyManagerListener(
7148 [this](int32_t persistentId, const SessionState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
7149 OnSessionStateChange(persistentId, state);
7150 });
7151 TLOGD(WmsLogTag::DEFAULT, "success");
7152 }
7153
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)7154 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
7155 {
7156 if (sceneSession == nullptr) {
7157 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7158 return;
7159 }
7160 sceneSession->SetSessionInfoChangeNotifyManagerListener([this](int32_t persistentId) {
7161 NotifyWindowInfoChangeFromSession(persistentId);
7162 });
7163 }
7164
RegisterRequestFocusStatusNotifyManagerFunc(const sptr<SceneSession> & sceneSession)7165 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
7166 {
7167 if (sceneSession == nullptr) {
7168 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7169 return;
7170 }
7171 sceneSession->SetRequestFocusStatusNotifyManagerListener(
7172 [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
7173 RequestFocusStatus(persistentId, isFocused, byForeground, reason);
7174 });
7175 TLOGD(WmsLogTag::DEFAULT, "success");
7176 }
7177
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)7178 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
7179 {
7180 GetStateFromManagerFunc func = [this](const ManagerState key) {
7181 switch (key) {
7182 case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
7183 return this->IsScreenLocked();
7184 break;
7185 default:
7186 return false;
7187 break;
7188 }
7189 };
7190 if (sceneSession == nullptr) {
7191 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7192 return;
7193 }
7194 sceneSession->SetGetStateFromManagerListener(func);
7195 TLOGD(WmsLogTag::DEFAULT, "success");
7196 }
7197
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)7198 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
7199 {
7200 SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
7201 const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
7202 if (sceneSession == nullptr || property == nullptr) {
7203 TLOGNE(WmsLogTag::DEFAULT, "params is nullptr");
7204 return;
7205 }
7206 switch (action) {
7207 case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
7208 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
7209 sceneSession->keepScreenLock_);
7210 break;
7211 case WSPropertyChangeAction::ACTION_UPDATE_VIEW_KEEP_SCREEN_ON:
7212 HandleKeepScreenOn(sceneSession, property->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
7213 sceneSession->viewKeepScreenLock_);
7214 break;
7215 case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
7216 case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
7217 case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
7218 case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
7219 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
7220 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
7221 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
7222 break;
7223 case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
7224 SetBrightness(sceneSession, property->GetBrightness());
7225 break;
7226 case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
7227 case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
7228 UpdatePrivateStateAndNotify(property->GetPersistentId());
7229 break;
7230 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
7231 CheckAndNotifyWaterMarkChangedResult();
7232 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
7233 break;
7234 case WSPropertyChangeAction::ACTION_UPDATE_MODE:
7235 ProcessWindowModeType();
7236 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
7237 break;
7238 case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
7239 HandleHideNonSystemFloatingWindows(property, sceneSession);
7240 break;
7241 case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
7242 FlushWindowInfoToMMI();
7243 break;
7244 default:
7245 break;
7246 }
7247 };
7248 if (sceneSession != nullptr) {
7249 sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
7250 }
7251 }
7252
OnSessionStateChange(int32_t persistentId,const SessionState & state)7253 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
7254 int32_t persistentId, const SessionState& state)
7255 {
7256 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
7257 TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, state:%{public}u", persistentId, state);
7258 auto sceneSession = GetSceneSession(persistentId);
7259 if (sceneSession == nullptr) {
7260 TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
7261 return;
7262 }
7263 switch (state) {
7264 case SessionState::STATE_FOREGROUND:
7265 ProcessFocusWhenForeground(sceneSession);
7266 if (!IsSessionVisibleForeground(sceneSession)) {
7267 sceneSession->SetPostProcessProperty(true);
7268 break;
7269 }
7270 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
7271 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
7272 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
7273 sceneSession->keepScreenLock_);
7274 HandleKeepScreenOn(sceneSession, sceneSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
7275 sceneSession->viewKeepScreenLock_);
7276 UpdatePrivateStateAndNotify(persistentId);
7277 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7278 ProcessSubSessionForeground(sceneSession);
7279 }
7280 break;
7281 case SessionState::STATE_BACKGROUND:
7282 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
7283 RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
7284 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
7285 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
7286 HandleKeepScreenOn(sceneSession, false, WINDOW_SCREEN_LOCK_PREFIX, sceneSession->keepScreenLock_);
7287 HandleKeepScreenOn(sceneSession, false, VIEW_SCREEN_LOCK_PREFIX, sceneSession->viewKeepScreenLock_);
7288 UpdatePrivateStateAndNotify(persistentId);
7289 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7290 ProcessSubSessionBackground(sceneSession);
7291 }
7292 break;
7293 case SessionState::STATE_CONNECT:
7294 SetSessionSnapshotSkipForAppProcess(sceneSession);
7295 SetSessionSnapshotSkipForAppBundleName(sceneSession);
7296 SetSessionWatermarkForAppProcess(sceneSession);
7297 break;
7298 case SessionState::STATE_DISCONNECT:
7299 if (SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
7300 RemoveProcessSnapshotSkip(sceneSession->GetCallingPid());
7301 RemoveProcessWatermarkPid(sceneSession->GetCallingPid());
7302 }
7303 break;
7304 default:
7305 break;
7306 }
7307 }
7308
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)7309 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
7310 {
7311 auto persistentId = sceneSession->GetPersistentId();
7312 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7313 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7314 if (focusGroup == nullptr) {
7315 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7316 return;
7317 }
7318 bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7319 bool needBlockNotifyUnfocusStatus = focusGroup->GetNeedBlockNotifyUnfocusStatus();
7320 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
7321 persistentId == focusGroup->GetFocusedSessionId()) {
7322 if (focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground()) {
7323 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7324 focusGroup->SetNeedBlockNotifyUnfocusStatus(false);
7325 NotifyFocusStatus(sceneSession, true, focusGroup);
7326 sceneSession->NotifyHighlightChange(true);
7327 }
7328 } else if (!sceneSession->IsFocusedOnShow()) {
7329 if (IsSessionVisibleForeground(sceneSession)) {
7330 sceneSession->SetFocusedOnShow(true);
7331 }
7332 } else {
7333 if (Session::IsScbCoreEnabled()) {
7334 ProcessFocusWhenForegroundScbCore(sceneSession);
7335 } else {
7336 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
7337 }
7338 }
7339 }
7340
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)7341 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
7342 {
7343 if (sceneSession == nullptr) {
7344 TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
7345 return;
7346 }
7347 if (sceneSession->IsFocusableOnShow()) {
7348 if (IsSessionVisibleForeground(sceneSession)) {
7349 RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
7350 } else {
7351 PostProcessFocusState state = {true, true, true, FocusChangeReason::APP_FOREGROUND};
7352 sceneSession->SetPostProcessFocusState(state);
7353 }
7354 } else {
7355 TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
7356 sceneSession->GetPersistentId());
7357 }
7358 }
7359
ProcessWindowModeType()7360 void SceneSessionManager::ProcessWindowModeType()
7361 {
7362 if (isScreenLocked_) {
7363 return;
7364 }
7365 NotifyRSSWindowModeTypeUpdate();
7366 }
7367
IsSmallFoldProduct()7368 static bool IsSmallFoldProduct()
7369 {
7370 static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
7371 if (foldScreenType.empty()) {
7372 return false;
7373 }
7374 return foldScreenType[0] == SMALL_FOLD_PRODUCT_TYPE;
7375 }
7376
IsInDefaultScreen(const sptr<SceneSession> & sceneSession)7377 bool SceneSessionManager::IsInDefaultScreen(const sptr<SceneSession>& sceneSession)
7378 {
7379 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
7380 return sceneSession->GetSessionProperty()->GetDisplayId() == defaultScreenId;
7381 }
7382
IsNeedSkipWindowModeTypeCheck(const sptr<SceneSession> & sceneSession,bool isSmallFold)7383 bool SceneSessionManager::IsNeedSkipWindowModeTypeCheck(const sptr<SceneSession>& sceneSession, bool isSmallFold)
7384 {
7385 if (sceneSession == nullptr ||
7386 !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
7387 !sceneSession->GetRSVisible() ||
7388 !sceneSession->IsSessionForeground()) {
7389 return true;
7390 }
7391 if (isSmallFold && !IsInDefaultScreen(sceneSession)) {
7392 return true;
7393 }
7394 return false;
7395 }
7396
CheckWindowModeType()7397 WindowModeType SceneSessionManager::CheckWindowModeType()
7398 {
7399 bool inSplit = false;
7400 bool inFloating = false;
7401 bool fullScreen = false;
7402 bool isSmallFold = IsSmallFoldProduct();
7403 {
7404 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7405 for (const auto& session : sceneSessionMap_) {
7406 if (IsNeedSkipWindowModeTypeCheck(session.second, isSmallFold)) {
7407 continue;
7408 }
7409 auto mode = session.second->GetWindowMode();
7410 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
7411 inSplit = true;
7412 }
7413 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
7414 inFloating = true;
7415 }
7416 if (WindowHelper::IsFullScreenWindow(mode)) {
7417 fullScreen = true;
7418 }
7419 }
7420 }
7421
7422 WindowModeType type;
7423 if (inSplit) {
7424 if (inFloating) {
7425 type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
7426 } else {
7427 type = WindowModeType::WINDOW_MODE_SPLIT;
7428 }
7429 } else {
7430 if (inFloating) {
7431 if (fullScreen) {
7432 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
7433 } else {
7434 type = WindowModeType::WINDOW_MODE_FLOATING;
7435 }
7436 } else if (fullScreen) {
7437 type = WindowModeType::WINDOW_MODE_FULLSCREEN;
7438 } else {
7439 type = WindowModeType::WINDOW_MODE_OTHER;
7440 }
7441 }
7442 return type;
7443 }
7444
NotifyRSSWindowModeTypeUpdate()7445 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
7446 {
7447 WindowModeType type = CheckWindowModeType();
7448 if (lastWindowModeType_ == type) {
7449 return;
7450 }
7451 lastWindowModeType_ = type;
7452 TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
7453 static_cast<uint8_t>(type));
7454 SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
7455 }
7456
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)7457 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
7458 {
7459 if (sceneSession == nullptr) {
7460 TLOGD(WmsLogTag::WMS_SUB, "session is nullptr");
7461 return;
7462 }
7463 std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
7464 for (auto& subSession : sceneSession->GetSubSession()) {
7465 if (subSession == nullptr) {
7466 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
7467 continue;
7468 }
7469 if (!subSession->GetSubSession().empty()) {
7470 ProcessSubSessionForeground(subSession);
7471 }
7472 if (subSession->IsTopmost()) {
7473 modalVec.push_back(subSession);
7474 TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
7475 continue;
7476 }
7477 const auto& state = subSession->GetSessionState();
7478 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
7479 TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
7480 continue;
7481 }
7482 RequestSessionFocus(subSession->GetPersistentId(), true);
7483 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
7484 HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
7485 subSession->keepScreenLock_);
7486 HandleKeepScreenOn(subSession, subSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
7487 subSession->viewKeepScreenLock_);
7488 }
7489
7490 for (const auto& modal : modalVec) {
7491 if (modal == nullptr) {
7492 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
7493 continue;
7494 }
7495 const auto& state = modal->GetSessionState();
7496 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
7497 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
7498 continue;
7499 }
7500 auto modalSession = GetSceneSession(modal->GetPersistentId());
7501 if (modalSession == nullptr) {
7502 TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
7503 continue;
7504 }
7505 NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
7506 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7507 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7508 if (focusGroup == nullptr) {
7509 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7510 return;
7511 }
7512 auto focusedSessionId = focusGroup->GetFocusedSessionId();
7513 bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7514 if (modal->GetPersistentId() == focusedSessionId && needBlockNotifyFocusStatusUntilForeground) {
7515 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7516 focusGroup->SetNeedBlockNotifyUnfocusStatus(false);
7517 NotifyFocusStatus(modalSession, true, focusGroup);
7518 }
7519 HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
7520 modalSession->keepScreenLock_);
7521 HandleKeepScreenOn(modalSession, modalSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
7522 modalSession->viewKeepScreenLock_);
7523 }
7524 }
7525
ProcessModalTopmostRequestFocusImmdediately(const sptr<SceneSession> & sceneSession)7526 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(const sptr<SceneSession>& sceneSession)
7527 {
7528 // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
7529 sptr<SceneSession> mainSession = nullptr;
7530 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7531 mainSession = sceneSession;
7532 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
7533 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
7534 }
7535 if (mainSession == nullptr) {
7536 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
7537 return WSError::WS_DO_NOTHING;
7538 }
7539
7540 std::vector<sptr<SceneSession>> topmostVec;
7541 for (auto subSession : mainSession->GetSubSession()) {
7542 if (subSession && subSession->IsTopmost()) {
7543 topmostVec.push_back(subSession);
7544 }
7545 }
7546 auto displayId = mainSession->GetSessionProperty()->GetDisplayId();
7547 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
7548 auto conditionFunc = [this, focusedSessionId](const sptr<SceneSession>& iter) {
7549 return iter && iter->GetPersistentId() == focusedSessionId;
7550 };
7551 if (std::find_if(topmostVec.begin(), topmostVec.end(), std::move(conditionFunc)) != topmostVec.end()) {
7552 TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId);
7553 return WSError::WS_OK;
7554 }
7555 WSError ret = WSError::WS_DO_NOTHING;
7556 for (auto topmostSession : topmostVec) {
7557 if (topmostSession == nullptr) {
7558 continue;
7559 }
7560 // no need to consider order, since rule of zOrder
7561 if (RequestSessionFocusImmediately(topmostSession->GetPersistentId(), false) == WSError::WS_OK) {
7562 ret = WSError::WS_OK;
7563 }
7564 }
7565 return ret;
7566 }
7567
ProcessDialogRequestFocusImmdediately(const sptr<SceneSession> & sceneSession)7568 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(const sptr<SceneSession>& sceneSession)
7569 {
7570 // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
7571 sptr<SceneSession> mainSession = nullptr;
7572 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7573 mainSession = sceneSession;
7574 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
7575 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
7576 }
7577 if (mainSession == nullptr) {
7578 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
7579 return WSError::WS_DO_NOTHING;
7580 }
7581 std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
7582 auto displayId = mainSession->GetSessionProperty()->GetDisplayId();
7583 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
7584 auto conditionFunc = [this, focusedSessionId](const sptr<Session>& iter) {
7585 return iter && iter->GetPersistentId() == focusedSessionId;
7586 };
7587 if (std::find_if(dialogVec.begin(), dialogVec.end(), std::move(conditionFunc)) != dialogVec.end()) {
7588 TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId);
7589 return WSError::WS_OK;
7590 }
7591 WSError ret = WSError::WS_DO_NOTHING;
7592 for (auto dialog : dialogVec) {
7593 if (dialog == nullptr) {
7594 continue;
7595 }
7596 // no need to consider order, since rule of zOrder
7597 if (RequestSessionFocusImmediately(dialog->GetPersistentId(), false) == WSError::WS_OK) {
7598 ret = WSError::WS_OK;
7599 }
7600 }
7601 return ret;
7602 }
7603
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)7604 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
7605 {
7606 if (sceneSession == nullptr) {
7607 TLOGD(WmsLogTag::WMS_SUB, "session is nullptr");
7608 return;
7609 }
7610 for (auto& subSession : sceneSession->GetSubSession()) {
7611 if (subSession == nullptr) {
7612 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
7613 continue;
7614 }
7615 if (!subSession->GetSubSession().empty()) {
7616 ProcessSubSessionBackground(subSession);
7617 }
7618 const auto& state = subSession->GetSessionState();
7619 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
7620 TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
7621 continue;
7622 }
7623 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
7624 HandleKeepScreenOn(subSession, false, WINDOW_SCREEN_LOCK_PREFIX, subSession->keepScreenLock_);
7625 HandleKeepScreenOn(subSession, false, VIEW_SCREEN_LOCK_PREFIX, subSession->viewKeepScreenLock_);
7626 UpdatePrivateStateAndNotify(subSession->GetPersistentId());
7627 }
7628 std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
7629 for (const auto& dialog : dialogVec) {
7630 if (dialog == nullptr) {
7631 TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
7632 continue;
7633 }
7634 auto dialogSession = GetSceneSession(dialog->GetPersistentId());
7635 if (dialogSession == nullptr) {
7636 TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
7637 continue;
7638 }
7639 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
7640 HandleKeepScreenOn(dialogSession, false, WINDOW_SCREEN_LOCK_PREFIX, dialogSession->keepScreenLock_);
7641 HandleKeepScreenOn(dialogSession, false, VIEW_SCREEN_LOCK_PREFIX, dialogSession->viewKeepScreenLock_);
7642 UpdatePrivateStateAndNotify(dialog->GetPersistentId());
7643 }
7644 for (const auto& toastSession : sceneSession->GetToastSession()) {
7645 if (toastSession == nullptr) {
7646 TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
7647 continue;
7648 }
7649 const auto& state = toastSession->GetSessionState();
7650 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
7651 TLOGD(WmsLogTag::WMS_TOAST, "toast session is not active");
7652 continue;
7653 }
7654 NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
7655 HandleKeepScreenOn(toastSession, false, WINDOW_SCREEN_LOCK_PREFIX, toastSession->keepScreenLock_);
7656 HandleKeepScreenOn(toastSession, false, VIEW_SCREEN_LOCK_PREFIX, toastSession->viewKeepScreenLock_);
7657 UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
7658 toastSession->SetActive(false);
7659 toastSession->BackgroundTask();
7660 }
7661 }
7662
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)7663 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
7664 const sptr<WindowSessionProperty>& property)
7665 {
7666 if (sceneSession == nullptr) {
7667 TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
7668 return WSError::WS_ERROR_NULLPTR;
7669 }
7670 auto sessionProperty = sceneSession->GetSessionProperty();
7671 uint32_t flags = property->GetWindowFlags();
7672 uint32_t oldFlags = sessionProperty->GetWindowFlags();
7673 if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
7674 (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
7675 !property->GetSystemCalling()) {
7676 TLOGE(WmsLogTag::DEFAULT, "permission denied");
7677 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7678 }
7679 sessionProperty->SetWindowFlags(flags);
7680 CheckAndNotifyWaterMarkChangedResult();
7681 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
7682 sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
7683 }
7684 TLOGI(WmsLogTag::DEFAULT, "set flags: %{public}u", flags);
7685 return WSError::WS_OK;
7686 }
7687
CheckAndNotifyWaterMarkChangedResult()7688 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
7689 {
7690 bool currentWaterMarkShowState = false;
7691 {
7692 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7693 for (const auto& [_, session] : sceneSessionMap_) {
7694 if (!session) {
7695 continue;
7696 }
7697 bool hasWaterMark = session->GetSessionProperty()->GetWindowFlags() &
7698 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
7699 bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
7700 if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
7701 currentWaterMarkShowState = true;
7702 break;
7703 }
7704 }
7705 if (combinedExtWindowFlags_.waterMarkFlag) {
7706 TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
7707 currentWaterMarkShowState = true;
7708 }
7709 }
7710 if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
7711 lastWaterMarkShowState_ = currentWaterMarkShowState;
7712 NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
7713 }
7714 }
7715
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)7716 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
7717 {
7718 TLOGI(WmsLogTag::DEFAULT, "hasWaterMark: %{public}u", static_cast<uint32_t>(hasWaterMark));
7719 SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
7720 return WSError::WS_OK;
7721 }
7722
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const7723 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
7724 {
7725 if (!bundleMgr_) {
7726 TLOGE(WmsLogTag::DEFAULT, "bundle manager is nullptr.");
7727 return;
7728 }
7729
7730 AAFwk::Want want;
7731 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
7732 auto uid = abilityInfo.uid;
7733 want.SetParam("uid", uid);
7734 bundleMgr_->ProcessPreload(want);
7735 }
7736
NotifyCompleteFirstFrameDrawing(int32_t persistentId)7737 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
7738 {
7739 auto sceneSession = GetSceneSession(persistentId);
7740 if (sceneSession == nullptr) {
7741 TLOGE(WmsLogTag::WMS_MAIN, " sceneSession is nullptr.");
7742 return;
7743 }
7744
7745 const auto& sessionInfo = sceneSession->GetSessionInfo();
7746 if (IsAtomicServiceFreeInstall(sessionInfo)) {
7747 TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
7748 sceneSession->GetPersistentId(), sceneSession->GetWindowType());
7749 FillSessionInfo(sceneSession);
7750 }
7751 TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
7752 sceneSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
7753 sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
7754 auto abilityInfo = sessionInfo.abilityInfo;
7755 if (abilityInfo == nullptr) {
7756 TLOGE(WmsLogTag::WMS_MAIN, " abilityInfo is null, Id: %{public}d", persistentId);
7757 return;
7758 }
7759
7760 [this, persistentId] {
7761 auto task = [persistentId] {
7762 AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
7763 };
7764 TLOGNI(WmsLogTag::DEFAULT, "Post CompleteFirstFrameDrawing task. Id: %{public}d", persistentId);
7765 eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
7766 }();
7767
7768 auto task = [this, abilityInfo, sceneSession, persistentId] {
7769 if (!sceneSession->GetSessionInfo().isSystem_ && !(abilityInfo->excludeFromMissions)) {
7770 TLOGND(WmsLogTag::WMS_PATTERN, "NotifyCreated, id: %{public}d", persistentId);
7771 listenerController_->NotifySessionLifecycleEvent(
7772 ISessionLifecycleListener::SessionLifecycleEvent::CREATED, sceneSession->GetSessionInfo());
7773 }
7774 ProcessPreload(*abilityInfo);
7775 };
7776 return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
7777 }
7778
NotifySessionMovedToFront(int32_t persistentId)7779 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
7780 {
7781 auto sceneSession = GetSceneSession(persistentId);
7782 if (sceneSession == nullptr) {
7783 TLOGE(WmsLogTag::DEFAULT, "session is invalid with %{public}d", persistentId);
7784 return;
7785 }
7786 TLOGI(WmsLogTag::DEFAULT, "id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
7787 sceneSession->GetSessionInfo().isSystem_);
7788 if (!sceneSession->GetSessionInfo().isSystem_ &&
7789 sceneSession->GetSessionInfo().abilityInfo &&
7790 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
7791 listenerController_->NotifySessionMovedToFront(persistentId);
7792 listenerController_->NotifySessionLifecycleEvent(
7793 ISessionLifecycleListener::SessionLifecycleEvent::FOREGROUND, sceneSession->GetSessionInfo());
7794 }
7795 }
7796
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)7797 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
7798 {
7799 TLOGI(WmsLogTag::WMS_MAIN, "in");
7800 const char* const where = __func__;
7801 auto task = [this, &token, &label, where]() {
7802 auto sceneSession = FindSessionByToken(token);
7803 if (sceneSession == nullptr) {
7804 TLOGNE(WmsLogTag::WMS_MAIN, "fail to find session by token");
7805 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
7806 }
7807 sceneSession->SetSessionLabel(label);
7808 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d, system: %{public}d",
7809 where, sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().isSystem_);
7810 if (!sceneSession->GetSessionInfo().isSystem_) {
7811 TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, sceneSession->GetPersistentId());
7812 listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
7813 }
7814 return WSError::WS_OK;
7815 };
7816 return taskScheduler_->PostSyncTask(task, where);
7817 }
7818
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)7819 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
7820 const std::shared_ptr<Media::PixelMap>& icon)
7821 {
7822 TLOGI(WmsLogTag::WMS_MAIN, "in");
7823 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7824 TLOGE(WmsLogTag::WMS_MAIN, "The caller is not system-app, can not use system-api");
7825 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7826 }
7827 const char* const where = __func__;
7828 auto task = [this, &token, &icon, where]() {
7829 auto sceneSession = FindSessionByToken(token);
7830 if (sceneSession == nullptr) {
7831 TLOGNE(WmsLogTag::WMS_MAIN, "fail to find session by token");
7832 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
7833 }
7834 sceneSession->SetSessionIcon(icon);
7835 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d, system: %{public}d",
7836 where, sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().isSystem_);
7837 if (!sceneSession->GetSessionInfo().isSystem_ &&
7838 sceneSession->GetSessionInfo().abilityInfo &&
7839 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
7840 TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, sceneSession->GetPersistentId());
7841 listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
7842 }
7843 return WSError::WS_OK;
7844 };
7845 return taskScheduler_->PostSyncTask(task, where);
7846 }
7847
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)7848 WSError SceneSessionManager::IsValidSessionIds(
7849 const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
7850 {
7851 TLOGI(WmsLogTag::DEFAULT, "in");
7852 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7853 for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
7854 auto search = sceneSessionMap_.find(sessionIds.at(i));
7855 if (search == sceneSessionMap_.end() || search->second == nullptr) {
7856 results.push_back(false);
7857 continue;
7858 }
7859 results.push_back(true);
7860 }
7861 return WSError::WS_OK;
7862 }
7863
RegisterSessionListener(const sptr<ISessionListener> & listener)7864 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
7865 {
7866 TLOGI(WmsLogTag::DEFAULT, "in");
7867 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7868 TLOGE(WmsLogTag::DEFAULT, "not system-app, can not use system-api");
7869 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7870 }
7871 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
7872 TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
7873 return WSError::WS_ERROR_INVALID_PERMISSION;
7874 }
7875 auto task = [this, &listener] {
7876 WSError ret = listenerController_->AddSessionListener(listener);
7877 // app continue report for distributed scheduled service
7878 SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
7879 static_cast<int32_t>(ret));
7880 return ret;
7881 };
7882 return taskScheduler_->PostSyncTask(task, "AddSessionListener");
7883 }
7884
UnRegisterSessionListener(const sptr<ISessionListener> & listener)7885 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
7886 {
7887 TLOGI(WmsLogTag::DEFAULT, "in");
7888 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7889 TLOGE(WmsLogTag::DEFAULT, "not system-app, can not use system-api");
7890 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7891 }
7892 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
7893 TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
7894 return WSError::WS_ERROR_INVALID_PERMISSION;
7895 }
7896 auto task = [this, &listener] {
7897 listenerController_->DelSessionListener(listener);
7898 return WSError::WS_OK;
7899 };
7900 return taskScheduler_->PostSyncTask(task, "DelSessionListener");
7901 }
7902
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)7903 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
7904 std::vector<SessionInfoBean>& sessionInfos)
7905 {
7906 TLOGI(WmsLogTag::DEFAULT, "num max %{public}d", numMax);
7907 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7908 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
7909 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7910 }
7911 if (!SessionPermission::VerifySessionPermission()) {
7912 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
7913 return WSError::WS_ERROR_INVALID_PERMISSION;
7914 }
7915 auto task = [this, &deviceId, numMax, &sessionInfos]() {
7916 if (CheckIsRemote(deviceId)) {
7917 int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
7918 if (ret != ERR_OK) {
7919 return WSError::WS_ERROR_INVALID_PARAM;
7920 } else {
7921 return WSError::WS_OK;
7922 }
7923 }
7924 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7925 std::vector<sptr<SceneSession>> sceneSessionInfos;
7926 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7927 for (const auto& [_, sceneSession] : sceneSessionMap_) {
7928 if (sceneSession == nullptr) {
7929 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
7930 continue;
7931 }
7932 const auto& sessionInfo = sceneSession->GetSessionInfo();
7933 if (sessionInfo.isSystem_) {
7934 TLOGND(WmsLogTag::WMS_LIFE, "sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
7935 continue;
7936 }
7937 auto want = sessionInfo.want;
7938 if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
7939 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d, want is null or bundleName is empty "
7940 "or want bundleName is empty", sceneSession->GetPersistentId());
7941 continue;
7942 }
7943 if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
7944 break;
7945 }
7946 TLOGND(WmsLogTag::WMS_LIFE, "GetSessionInfos session: %{public}d, bundleName:%{public}s",
7947 sceneSession->GetPersistentId(), sessionInfo.bundleName_.c_str());
7948 sceneSessionInfos.emplace_back(sceneSession);
7949 }
7950 return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
7951 };
7952 return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
7953 }
7954
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)7955 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
7956 {
7957 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
7958 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
7959 TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
7960 return WSError::WS_ERROR_INVALID_PERMISSION;
7961 }
7962 if (pid < 0) {
7963 return WSError::WS_ERROR_INVALID_PARAM;
7964 }
7965 auto task = [this, pid, &windowStates] {
7966 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7967 for (const auto& [_, sceneSession] : sceneSessionMap_) {
7968 if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
7969 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
7970 MainWindowState windowState;
7971 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
7972 windowState.isVisible_ = sceneSession->GetRSVisible();
7973 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
7974 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
7975 windowStates.emplace_back(windowState);
7976 }
7977 }
7978 return WSError::WS_OK;
7979 };
7980 return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
7981 }
7982
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)7983 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
7984 std::vector<SessionInfoBean>& sessionInfos)
7985 {
7986 TLOGI(WmsLogTag::DEFAULT, "begin");
7987 int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
7988 if (result != ERR_OK) {
7989 TLOGE(WmsLogTag::DEFAULT, "failed, result=%{public}d", result);
7990 return result;
7991 }
7992 return ERR_OK;
7993 }
7994
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)7995 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
7996 int32_t persistentId, SessionInfoBean& sessionInfo)
7997 {
7998 TLOGI(WmsLogTag::DEFAULT, "id %{public}d", persistentId);
7999 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8000 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
8001 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8002 }
8003 if (!SessionPermission::VerifySessionPermission()) {
8004 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
8005 return WSError::WS_ERROR_INVALID_PERMISSION;
8006 }
8007 return taskScheduler_->PostSyncTask([this, &deviceId, persistentId, &sessionInfo]() {
8008 if (CheckIsRemote(deviceId)) {
8009 if (GetRemoteSessionInfo(deviceId, persistentId, sessionInfo) != ERR_OK) {
8010 return WSError::WS_ERROR_INVALID_PARAM;
8011 } else {
8012 return WSError::WS_OK;
8013 }
8014 }
8015
8016 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8017 if (auto iter = sceneSessionMap_.find(persistentId); iter != sceneSessionMap_.end()) {
8018 auto sceneSession = iter->second;
8019 if (sceneSession == nullptr) {
8020 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d is nullptr", persistentId);
8021 return WSError::WS_ERROR_INVALID_PARAM;
8022 }
8023 const auto& sceneSessionInfo = sceneSession->GetSessionInfo();
8024 if (sceneSessionInfo.isSystem_) {
8025 TLOGND(WmsLogTag::WMS_LIFE, "sessionId: %{public}d isSystemScene", persistentId);
8026 return WSError::WS_ERROR_INVALID_PARAM;
8027 }
8028 auto want = sceneSessionInfo.want;
8029 if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
8030 want->GetElement().GetBundleName().empty()) {
8031 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d, want is null or bundleName is empty "
8032 "or want bundleName is empty", persistentId);
8033 return WSError::WS_ERROR_INTERNAL_ERROR;
8034 }
8035 TLOGND(WmsLogTag::WMS_LIFE, "GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
8036 sceneSessionInfo.bundleName_.c_str());
8037 return SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
8038 } else {
8039 TLOGNW(WmsLogTag::WMS_LIFE, "sessionId: %{public}d not found", persistentId);
8040 return WSError::WS_ERROR_INVALID_PARAM;
8041 }
8042 }, __func__);
8043 }
8044
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)8045 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
8046 SessionInfoBean& sessionInfo)
8047 {
8048 TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
8049 continueSessionId.c_str());
8050 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8051 TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
8052 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8053 }
8054 if (!SessionPermission::VerifySessionPermission()) {
8055 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
8056 return WSError::WS_ERROR_INVALID_PERMISSION;
8057 }
8058 return taskScheduler_->PostSyncTask([this, continueSessionId, &sessionInfo]() {
8059 WSError ret = WSError::WS_ERROR_INVALID_SESSION;
8060 {
8061 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8062 for (const auto& [_, sceneSession] : sceneSessionMap_) {
8063 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
8064 ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
8065 break;
8066 }
8067 }
8068 }
8069
8070 TLOGNI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
8071 // app continue report for distributed scheduled service
8072 SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
8073 static_cast<int32_t>(ret));
8074 return ret;
8075 }, __func__);
8076 }
8077
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)8078 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
8079 int32_t persistentId, SessionInfoBean& sessionInfo)
8080 {
8081 TLOGI(WmsLogTag::DEFAULT, "in");
8082 std::vector<SessionInfoBean> sessionVector;
8083 int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
8084 if (result != ERR_OK) {
8085 return result;
8086 }
8087 for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
8088 if (iter->id == persistentId) {
8089 sessionInfo = *iter;
8090 return ERR_OK;
8091 }
8092 }
8093 TLOGW(WmsLogTag::DEFAULT, "missionId not found");
8094 return ERR_INVALID_VALUE;
8095 }
8096
CheckIsRemote(const std::string & deviceId)8097 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
8098 {
8099 if (deviceId.empty()) {
8100 TLOGI(WmsLogTag::DEFAULT, "empty");
8101 return false;
8102 }
8103 std::string localDeviceId;
8104 if (!GetLocalDeviceId(localDeviceId)) {
8105 TLOGE(WmsLogTag::DEFAULT, "GetLocalDeviceId failed");
8106 return false;
8107 }
8108 if (localDeviceId == deviceId) {
8109 TLOGI(WmsLogTag::DEFAULT, "deviceId is local.");
8110 return false;
8111 }
8112 TLOGD(WmsLogTag::DEFAULT, "Checked deviceId=%{public}s", AnonymizeDeviceId(deviceId).c_str());
8113 return true;
8114 }
8115
GetLocalDeviceId(std::string & localDeviceId)8116 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
8117 {
8118 auto localNode = std::make_unique<NodeBasicInfo>();
8119 int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
8120 if (errCode != ERR_OK) {
8121 TLOGE(WmsLogTag::DEFAULT, "GetLocalNodeDeviceInfo errCode=%{public}d", errCode);
8122 return false;
8123 }
8124 if (localNode != nullptr) {
8125 localDeviceId = localNode->networkId;
8126 TLOGD(WmsLogTag::DEFAULT, "get local deviceId, deviceId=%{public}s", AnonymizeDeviceId(localDeviceId).c_str());
8127 return true;
8128 }
8129 TLOGE(WmsLogTag::DEFAULT, "localDeviceId null");
8130 return false;
8131 }
8132
AnonymizeDeviceId(const std::string & deviceId)8133 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
8134 {
8135 if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
8136 return EMPTY_DEVICE_ID;
8137 }
8138 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
8139 anonDeviceId.append("******");
8140 return anonDeviceId;
8141 }
8142
DumpSessionAll(std::vector<std::string> & infos)8143 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
8144 {
8145 TLOGI(WmsLogTag::DEFAULT, "in.");
8146 if (!SessionPermission::IsSystemCalling()) {
8147 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
8148 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8149 }
8150
8151 return taskScheduler_->PostSyncTask([this, &infos]() {
8152 infos.push_back("User ID #" + std::to_string(currentUserId_));
8153 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8154 for (const auto& [_, session] : sceneSessionMap_) {
8155 if (session) {
8156 session->DumpSessionInfo(infos);
8157 }
8158 }
8159 return WSError::WS_OK;
8160 }, __func__);
8161 }
8162
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)8163 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
8164 {
8165 TLOGI(WmsLogTag::DEFAULT, "id %{public}d", persistentId);
8166 if (!SessionPermission::IsSystemCalling()) {
8167 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
8168 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8169 }
8170
8171 return taskScheduler_->PostSyncTask([this, persistentId, &infos]() {
8172 infos.push_back("User ID #" + std::to_string(currentUserId_));
8173 auto session = GetSceneSession(persistentId);
8174 if (session) {
8175 session->DumpSessionInfo(infos);
8176 } else {
8177 infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
8178 }
8179 return WSError::WS_OK;
8180 }, __func__);
8181 }
8182
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)8183 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
8184 const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
8185 {
8186 if (bundleMgr_ == nullptr) {
8187 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
8188 return WSError::WS_ERROR_NULLPTR;
8189 }
8190 const auto& elementName = want.GetElement();
8191 int32_t ret{0};
8192 auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
8193 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
8194 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
8195 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
8196 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
8197 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
8198 std::vector<AppExecFwk::BundleInfo> bundleInfos;
8199 if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
8200 TLOGD(WmsLogTag::DEFAULT, "want is empty queryAllAbilityInfos");
8201 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
8202 if (ret) {
8203 TLOGE(WmsLogTag::DEFAULT, "Query all ability infos from BMS failed!");
8204 return WSError::WS_ERROR_INVALID_PARAM;
8205 }
8206 } else if (!elementName.GetBundleName().empty()) {
8207 AppExecFwk::BundleInfo bundleInfo;
8208 TLOGD(WmsLogTag::DEFAULT, "bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
8209 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
8210 if (ret) {
8211 TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed!");
8212 return WSError::WS_ERROR_INVALID_PARAM;
8213 }
8214 bundleInfos.push_back(bundleInfo);
8215 } else {
8216 TLOGE(WmsLogTag::DEFAULT, "invalid want:%{public}s", want.ToString().c_str());
8217 return WSError::WS_ERROR_INVALID_PARAM;
8218 }
8219 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
8220 }
8221
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)8222 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
8223 const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
8224 {
8225 if (bundleMgr_ == nullptr) {
8226 TLOGE(WmsLogTag::WMS_RECOVER, "bundleMgr is nullptr");
8227 return WSError::WS_ERROR_NULLPTR;
8228 }
8229 if (bundleNames.empty()) {
8230 TLOGE(WmsLogTag::WMS_RECOVER, "bundleNames is empty");
8231 return WSError::WS_ERROR_INVALID_PARAM;
8232 }
8233 auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
8234 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
8235 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
8236 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
8237 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
8238 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
8239 std::vector<AppExecFwk::BundleInfo> bundleInfos;
8240 auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
8241 if (ret) {
8242 TLOGE(WmsLogTag::WMS_RECOVER, "Query batch ability infos from BMS failed!");
8243 return WSError::WS_ERROR_INVALID_PARAM;
8244 }
8245 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
8246 }
8247
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)8248 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
8249 const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
8250 {
8251 if (bundleMgr_ == nullptr) {
8252 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
8253 return WSError::WS_ERROR_NULLPTR;
8254 }
8255 auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
8256 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
8257 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
8258 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
8259 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
8260 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
8261 AppExecFwk::BundleInfo bundleInfo;
8262 if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
8263 TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
8264 return WSError::WS_ERROR_INVALID_PARAM;
8265 }
8266 auto& hapModulesList = bundleInfo.hapModuleInfos;
8267 if (hapModulesList.empty()) {
8268 TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
8269 return WSError::WS_ERROR_INVALID_PARAM;
8270 }
8271 auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
8272 for (auto& hapModule : hapModulesList) {
8273 auto& abilityInfoList = hapModule.abilityInfos;
8274 for (auto& abilityInfo : abilityInfoList) {
8275 if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
8276 scbAbilityInfo.abilityInfo_ = abilityInfo;
8277 scbAbilityInfo.sdkVersion_ = sdkVersion;
8278 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
8279 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
8280 return WSError::WS_OK;
8281 }
8282 }
8283 }
8284 TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
8285 return WSError::WS_ERROR_INVALID_PARAM;
8286 }
8287
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos)8288 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
8289 std::vector<SCBAbilityInfo>& scbAbilityInfos)
8290 {
8291 if (bundleInfos.empty()) {
8292 TLOGE(WmsLogTag::DEFAULT, "bundleInfos is empty");
8293 return WSError::WS_ERROR_INVALID_PARAM;
8294 }
8295 for (auto& bundleInfo : bundleInfos) {
8296 auto& hapModulesList = bundleInfo.hapModuleInfos;
8297 auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
8298 if (hapModulesList.empty()) {
8299 TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty");
8300 continue;
8301 }
8302 if (bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
8303 bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
8304 auto iter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
8305 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
8306 if (iter != hapModulesList.end()) {
8307 SCBAbilityInfo scbAbilityInfo;
8308 scbAbilityInfo.abilityInfo_ = iter->abilityInfos[0];
8309 scbAbilityInfo.sdkVersion_ = sdkVersion;
8310 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
8311 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
8312 scbAbilityInfos.push_back(scbAbilityInfo);
8313 continue;
8314 }
8315 }
8316 for (auto& hapModule : hapModulesList) {
8317 auto& abilityInfoList = hapModule.abilityInfos;
8318 for (auto& abilityInfo : abilityInfoList) {
8319 SCBAbilityInfo scbAbilityInfo;
8320 scbAbilityInfo.abilityInfo_ = abilityInfo;
8321 scbAbilityInfo.sdkVersion_ = sdkVersion;
8322 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
8323 scbAbilityInfos.push_back(scbAbilityInfo);
8324 }
8325 }
8326 }
8327 return WSError::WS_OK;
8328 }
8329
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo & abilityInfo)8330 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
8331 {
8332 if (abilityInfo.orientationId == 0) {
8333 return;
8334 }
8335 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
8336 if (resConfig == nullptr) {
8337 TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
8338 return;
8339 }
8340 std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
8341 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
8342 if (resourceMgr == nullptr) {
8343 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
8344 return;
8345 }
8346 std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
8347 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
8348 TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
8349 }
8350 std::string orientation;
8351 auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
8352 if (ret != Global::Resource::RState::SUCCESS) {
8353 TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
8354 static_cast<int32_t>(ret), abilityInfo.orientationId);
8355 return;
8356 }
8357 if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
8358 TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
8359 return;
8360 }
8361 abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
8362 }
8363
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)8364 WSError SceneSessionManager::TerminateSessionNew(
8365 const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
8366 {
8367 if (info == nullptr) {
8368 TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
8369 return WSError::WS_ERROR_INVALID_PARAM;
8370 }
8371 TLOGI(WmsLogTag::WMS_LIFE,
8372 "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
8373 info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
8374 int32_t callingPid = IPCSkeleton::GetCallingPid();
8375 uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
8376 auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
8377 sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
8378 if (sceneSession == nullptr) {
8379 TLOGNE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
8380 return WSError::WS_ERROR_INVALID_PARAM;
8381 }
8382 const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
8383 if (!pidCheck &&
8384 !SessionPermission::VerifyPermissionByCallerToken(callerToken,
8385 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8386 TLOGNE(WmsLogTag::WMS_LIFE,
8387 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
8388 sceneSession->GetCallingPid(), callingPid);
8389 return WSError::WS_ERROR_INVALID_PERMISSION;
8390 }
8391 WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
8392 return errCode;
8393 };
8394 return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
8395 }
8396
SetVmaCacheStatus(bool flag)8397 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
8398 {
8399 TLOGI(WmsLogTag::DEFAULT, "flag: %{public}d", flag);
8400 RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
8401 return WSError::WS_OK;
8402 }
8403
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)8404 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
8405 SessionSnapshot& snapshot, bool isLowResolution)
8406 {
8407 TLOGI(WmsLogTag::DEFAULT, "id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
8408 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8409 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
8410 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8411 }
8412 if (!SessionPermission::VerifySessionPermission()) {
8413 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
8414 return WSError::WS_ERROR_INVALID_PERMISSION;
8415 }
8416 return taskScheduler_->PostSyncTask([this, &deviceId, persistentId, &snapshot, isLowResolution]() {
8417 if (CheckIsRemote(deviceId)) {
8418 if (GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot) != ERR_OK) {
8419 return WSError::WS_ERROR_INVALID_PARAM;
8420 } else {
8421 return WSError::WS_OK;
8422 }
8423 }
8424 auto sceneSession = GetSceneSession(persistentId);
8425 if (!sceneSession) {
8426 TLOGNE(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
8427 return WSError::WS_ERROR_INVALID_PARAM;
8428 }
8429 const auto& sessionInfo = sceneSession->GetSessionInfo();
8430 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
8431 TLOGNW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
8432 sceneSession->GetPersistentId());
8433 }
8434 snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
8435 snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
8436 snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
8437 if (auto oriSnapshot = sceneSession->Snapshot()) {
8438 if (isLowResolution) {
8439 OHOS::Media::InitializationOptions options;
8440 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
8441 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
8442 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
8443 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
8444 } else {
8445 snapshot.snapshot = oriSnapshot;
8446 }
8447 }
8448 return WSError::WS_OK;
8449 }, __func__);
8450 }
8451
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)8452 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
8453 {
8454 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
8455 TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
8456 return WMError::WM_ERROR_NOT_SYSTEM_APP;
8457 }
8458 return taskScheduler_->PostSyncTask([this, persistentId, &snapshot]() {
8459 auto sceneSession = GetSceneSession(persistentId);
8460 if (!sceneSession) {
8461 TLOGNW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
8462 return WMError::WM_ERROR_INVALID_PARAM;
8463 }
8464 const auto& sessionInfo = sceneSession->GetSessionInfo();
8465 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
8466 TLOGNW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
8467 sceneSession->GetPersistentId());
8468 }
8469 snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
8470 snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
8471 snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
8472 float snapShotScale = sceneSession->GetFloatingScale() > 1.0f ? 1.0f : sceneSession->GetFloatingScale();
8473 if (auto oriSnapshot = sceneSession->Snapshot(false, snapShotScale, false)) {
8474 if (sceneSession->GetFloatingScale() > 1.0f) {
8475 oriSnapshot->scale(sceneSession->GetFloatingScale(), sceneSession->GetFloatingScale());
8476 }
8477 snapshot.snapshot = oriSnapshot;
8478 TLOGNI(WmsLogTag::WMS_SYSTEM, "snapshot WxH=%{public}dx%{public}d",
8479 oriSnapshot->GetWidth(), oriSnapshot->GetHeight());
8480 return WMError::WM_OK;
8481 }
8482 return WMError::WM_ERROR_NULLPTR;
8483 }, __func__);
8484 }
8485
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)8486 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
8487 {
8488 if (!SessionPermission::IsSACalling()) {
8489 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Permission denied!");
8490 return WSError::WS_ERROR_INVALID_PERMISSION;
8491 }
8492 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "PersistentId=%{public}d", persistentId);
8493 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8494 if (sceneSession == nullptr) {
8495 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sceneSession is nullptr");
8496 return WSError::WS_ERROR_NULLPTR;
8497 }
8498 return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
8499 }
8500
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)8501 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
8502 AAFwk::MissionSnapshot& sessionSnapshot)
8503 {
8504 TLOGI(WmsLogTag::DEFAULT, "begin");
8505 int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
8506 sessionId, sessionSnapshot);
8507 if (result != ERR_OK) {
8508 TLOGE(WmsLogTag::DEFAULT, "failed, result=%{public}d", result);
8509 return result;
8510 }
8511 return ERR_OK;
8512 }
8513
GetCollaboratorByType(int32_t collaboratorType)8514 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
8515 {
8516 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
8517 std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
8518 auto iter = collaboratorMap_.find(collaboratorType);
8519 if (iter == collaboratorMap_.end()) {
8520 TLOGE(WmsLogTag::WMS_MAIN, "Fail to found collaborator with type: %{public}d", collaboratorType);
8521 return collaborator;
8522 }
8523 collaborator = iter->second;
8524 if (collaborator == nullptr) {
8525 TLOGE(WmsLogTag::WMS_MAIN, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
8526 }
8527 return collaborator;
8528 }
8529
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)8530 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
8531 {
8532 const char* const where = __func__;
8533 auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession), where]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
8534 auto sceneSession = weakSceneSession.promote();
8535 if (sceneSession == nullptr) {
8536 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session is nullptr", where);
8537 return WSError::WS_ERROR_NULLPTR;
8538 }
8539 auto persistentId = sceneSession->GetPersistentId();
8540 if (!GetSceneSession(persistentId)) {
8541 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session is invalid, id:%{public}d", where, persistentId);
8542 return WSError::WS_ERROR_INVALID_SESSION;
8543 }
8544 const auto& sessionInfo = sceneSession->GetSessionInfo();
8545 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: state:%{public}d, id:%{public}d",
8546 where, sessionInfo.callState_, persistentId);
8547 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8548 bool isColdStart = false;
8549 AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
8550 if (isColdStart) {
8551 TLOGNI(WmsLogTag::WMS_MAIN, "Cold start, identityToken:%{public}s, bundleName:%{public}s",
8552 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
8553 sceneSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
8554 sceneSession->ResetSessionConnectState();
8555 }
8556 return WSError::WS_OK;
8557 };
8558 std::string taskName = "RequestSceneSessionByCall:PID:" +
8559 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
8560 taskScheduler_->PostAsyncTask(task, taskName);
8561 return WSError::WS_OK;
8562 }
8563
StartAbilityBySpecified(const SessionInfo & sessionInfo)8564 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
8565 {
8566 const char* const where = __func__;
8567 auto task = [this, sessionInfo, where]() {
8568 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: bundleName: %{public}s, "
8569 "moduleName: %{public}s, abilityName: %{public}s", where,
8570 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
8571 AAFwk::Want want;
8572 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
8573 if (sessionInfo.want != nullptr) {
8574 want.SetParams(sessionInfo.want->GetParams());
8575 want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast<int>(sessionInfo.screenId_));
8576 }
8577 AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
8578 };
8579
8580 taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
8581 }
8582
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)8583 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
8584 {
8585 TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
8586 if (pid == -1) {
8587 TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
8588 return;
8589 }
8590 int32_t ret = HiSysEventWrite(
8591 HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
8592 "WINDOW_STATE_ERROR",
8593 HiviewDFX::HiSysEvent::EventType::FAULT,
8594 "PID", pid,
8595 "PERSISTENT_ID", persistentId);
8596 if (ret != 0) {
8597 TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
8598 }
8599 auto task = [this, pid] {
8600 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8601 for (const auto& [_, sceneSession] : sceneSessionMap_) {
8602 if (!sceneSession || pid != sceneSession->GetCallingPid() ||
8603 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
8604 continue;
8605 }
8606 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8607 TLOGNI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
8608 abilitySessionInfo->persistentId);
8609 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
8610 }
8611 };
8612 // delay 2000ms, wait for hidumper
8613 taskScheduler_->PostAsyncTask(task, __func__, 2000);
8614 }
8615
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)8616 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
8617 {
8618 if (!targetToken) {
8619 TLOGE(WmsLogTag::DEFAULT, "Token is null, cannot find main window");
8620 return nullptr;
8621 }
8622
8623 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8624 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
8625 [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8626 if (pair.second->IsTerminated()) {
8627 return false;
8628 }
8629 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8630 return pair.second->GetAbilityToken() == targetToken;
8631 }
8632 return false;
8633 });
8634 if (iter == sceneSessionMap_.end()) {
8635 TLOGE(WmsLogTag::DEFAULT, "Cannot find session");
8636 return nullptr;
8637 }
8638 return iter->second;
8639 }
8640
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)8641 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
8642 {
8643 if (!SessionPermission::IsSystemCalling()) {
8644 TLOGE(WmsLogTag::WMS_DIALOG, "permission denied!");
8645 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8646 }
8647 if (targetToken == nullptr) {
8648 TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
8649 return WSError::WS_ERROR_NULLPTR;
8650 }
8651
8652 auto task = [this, persistentId, targetToken]() {
8653 auto sceneSession = GetSceneSession(static_cast<int32_t>(persistentId));
8654 if (sceneSession == nullptr) {
8655 TLOGNE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
8656 return WSError::WS_ERROR_NULLPTR;
8657 }
8658 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
8659 TLOGNE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", sceneSession->GetWindowType());
8660 return WSError::WS_OK;
8661 }
8662 sceneSession->dialogTargetToken_ = targetToken;
8663 sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
8664 if (parentSession == nullptr) {
8665 sceneSession->NotifyDestroy();
8666 return WSError::WS_ERROR_INVALID_PARAM;
8667 }
8668 sptr<WindowSessionProperty> parentProperty = parentSession->GetSessionProperty();
8669 sptr<WindowSessionProperty> property = sceneSession->GetSessionProperty();
8670 auto displayId = parentProperty->GetDisplayId();
8671 property->SetDisplayId(displayId);
8672 sceneSession->SetScreenId(displayId);
8673 sceneSession->SetParentSession(parentSession);
8674 sceneSession->SetParentPersistentId(parentSession->GetPersistentId());
8675 sceneSession->SetClientDisplayId(parentSession->GetClientDisplayId());
8676 UpdateParentSessionForDialog(sceneSession, sceneSession->GetSessionProperty());
8677 TLOGNI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
8678 persistentId, parentSession->GetPersistentId());
8679 return WSError::WS_OK;
8680 };
8681 return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
8682 }
8683
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)8684 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
8685 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
8686 {
8687 SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
8688 }
8689
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)8690 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
8691 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
8692 {
8693 auto isSaCall = SessionPermission::IsSACalling();
8694 if (!isSaCall) {
8695 TLOGE(WmsLogTag::DEFAULT, "The interface only support for sa call");
8696 return WMError::WM_ERROR_INVALID_PERMISSION;
8697 }
8698 auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
8699 std::map<int32_t, sptr<SceneSession>>::iterator iter;
8700 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8701 for (auto missionId : missionIds) {
8702 iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
8703 if (iter == sceneSessionMap_.end()) {
8704 continue;
8705 }
8706 auto sceneSession = iter->second;
8707 if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
8708 continue;
8709 }
8710 surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
8711 if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
8712 surfaceNodeIds.push_back(missionId);
8713 continue;
8714 }
8715 if (sceneSession->GetLeashWinSurfaceNode()) {
8716 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
8717 }
8718 }
8719 return WMError::WM_OK;
8720 };
8721 return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
8722 }
8723
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)8724 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
8725 const sptr<IWindowManagerAgent>& windowManagerAgent)
8726 {
8727 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
8728 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
8729 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
8730 if (!SessionPermission::IsSystemCalling()) {
8731 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
8732 return WMError::WM_ERROR_NOT_SYSTEM_APP;
8733 }
8734 } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
8735 if (!SessionPermission::IsSystemServiceCalling()) {
8736 return WMError::WM_ERROR_INVALID_PERMISSION;
8737 }
8738 }
8739 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
8740 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
8741 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
8742 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
8743 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE ||
8744 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY) {
8745 if (!SessionPermission::IsSACalling()) {
8746 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
8747 return WMError::WM_ERROR_INVALID_PERMISSION;
8748 }
8749 }
8750 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
8751 TLOGE(WmsLogTag::DEFAULT, "windowManagerAgent is null");
8752 return WMError::WM_ERROR_NULLPTR;
8753 }
8754 const auto callingPid = IPCSkeleton::GetCallingRealPid();
8755 auto task = [this, windowManagerAgent, type, callingPid]() {
8756 return SessionManagerAgentController::GetInstance()
8757 .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
8758 };
8759 return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
8760 }
8761
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)8762 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
8763 const sptr<IWindowManagerAgent>& windowManagerAgent)
8764 {
8765 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
8766 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
8767 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
8768 if (!SessionPermission::IsSystemCalling()) {
8769 TLOGE(WmsLogTag::DEFAULT, "IsSystemCalling permission denied!");
8770 return WMError::WM_ERROR_NOT_SYSTEM_APP;
8771 }
8772 }
8773 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
8774 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
8775 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
8776 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
8777 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
8778 if (!SessionPermission::IsSACalling()) {
8779 TLOGE(WmsLogTag::WMS_LIFE, "IsSACalling permission denied!");
8780 return WMError::WM_ERROR_INVALID_PERMISSION;
8781 }
8782 }
8783 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
8784 TLOGE(WmsLogTag::DEFAULT, "windowManagerAgent is null");
8785 return WMError::WM_ERROR_NULLPTR;
8786 }
8787 const auto callingPid = IPCSkeleton::GetCallingRealPid();
8788 auto task = [this, windowManagerAgent, type, callingPid]() {
8789 return SessionManagerAgentController::GetInstance()
8790 .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
8791 };
8792 return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
8793 }
8794
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)8795 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
8796 {
8797 SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
8798 }
8799
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)8800 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
8801 {
8802 SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
8803 }
8804
StartWindowInfoReportLoop()8805 void SceneSessionManager::StartWindowInfoReportLoop()
8806 {
8807 TLOGD(WmsLogTag::WMS_STARTUP_PAGE, "in");
8808 if (isReportTaskStart_) {
8809 TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "Report is ReportTask Start");
8810 return;
8811 }
8812 auto task = [this] {
8813 WindowInfoReporter::GetInstance().ReportRecordedInfos();
8814 ReportWindowProfileInfos();
8815 isReportTaskStart_ = false;
8816 StartWindowInfoReportLoop();
8817 };
8818 int64_t delayTime = 1000 * 60 * 60; // an hour.
8819 bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
8820 if (!ret) {
8821 TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "failed. task is WindowInfoReport");
8822 return;
8823 }
8824 isReportTaskStart_ = true;
8825 }
8826
InitPersistentStorage()8827 void SceneSessionManager::InitPersistentStorage()
8828 {
8829 if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
8830 int32_t storageMode = -1;
8831 ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
8832 if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
8833 storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
8834 TLOGI(WmsLogTag::DEFAULT, "init MaximizeMode as %{public}d from persistent storage", storageMode);
8835 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
8836 }
8837 }
8838 }
8839
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)8840 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
8841 {
8842 TLOGD(WmsLogTag::DEFAULT, "in.");
8843 if (!SessionPermission::IsSystemServiceCalling()) {
8844 TLOGE(WmsLogTag::DEFAULT, "Only support for system service.");
8845 return WMError::WM_ERROR_NOT_SYSTEM_APP;
8846 }
8847 auto task = [this, &infos]() {
8848 std::map<int32_t, sptr<SceneSession>>::iterator iter;
8849 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8850 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
8851 sptr<SceneSession> sceneSession = iter->second;
8852 if (sceneSession == nullptr) {
8853 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "null scene session");
8854 continue;
8855 }
8856 bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
8857 sceneSession->IsVisibleForAccessibility() :
8858 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
8859 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, "
8860 "winType=%{public}d, state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
8861 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
8862 sceneSession->GetSessionState(), isVisibleForAccessibility);
8863 if (isVisibleForAccessibility) {
8864 FillWindowInfo(infos, iter->second);
8865 }
8866 }
8867 return WMError::WM_OK;
8868 };
8869 return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
8870 }
8871
CheckUnreliableWindowType(WindowType windowType)8872 static bool CheckUnreliableWindowType(WindowType windowType)
8873 {
8874 if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
8875 windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
8876 windowType == WindowType::WINDOW_TYPE_TOAST) {
8877 return true;
8878 }
8879 TLOGD(WmsLogTag::DEFAULT, "false, WindowType=%{public}d", windowType);
8880 return false;
8881 }
8882
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)8883 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
8884 std::vector<sptr<UnreliableWindowInfo>>& infos)
8885 {
8886 if (sceneSession == nullptr) {
8887 TLOGW(WmsLogTag::DEFAULT, "null scene session.");
8888 return;
8889 }
8890 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
8891 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
8892 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
8893 TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
8894 return;
8895 }
8896 sptr<UnreliableWindowInfo> info = sptr<UnreliableWindowInfo>::MakeSptr();
8897 info->windowId_ = sceneSession->GetPersistentId();
8898 WSRect windowRect = sceneSession->GetSessionRect();
8899 info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
8900 info->zOrder_ = sceneSession->GetZOrder();
8901 info->floatingScale_ = sceneSession->GetFloatingScale();
8902 info->scaleX_ = sceneSession->GetScaleX();
8903 info->scaleY_ = sceneSession->GetScaleY();
8904 infos.emplace_back(info);
8905 TLOGD(WmsLogTag::WMS_MAIN, "wid=%{public}d", info->windowId_);
8906 }
8907
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)8908 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
8909 std::vector<sptr<UnreliableWindowInfo>>& infos)
8910 {
8911 TLOGD(WmsLogTag::DEFAULT, "in.");
8912 if (!SessionPermission::IsSystemServiceCalling()) {
8913 TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
8914 return WMError::WM_ERROR_NOT_SYSTEM_APP;
8915 }
8916 auto task = [this, windowId, &infos]() {
8917 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8918 for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
8919 if (sceneSession == nullptr) {
8920 TLOGNW(WmsLogTag::DEFAULT, "null scene session");
8921 continue;
8922 }
8923 if (sessionId == windowId) {
8924 TLOGNI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
8925 FillUnreliableWindowInfo(sceneSession, infos);
8926 continue;
8927 }
8928 if (!sceneSession->GetRSVisible()) {
8929 TLOGND(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
8930 continue;
8931 }
8932 TLOGND(WmsLogTag::DEFAULT, "name=%{public}s, isSystem=%{public}d, "
8933 "persistentId=%{public}d, winType=%{public}d, state=%{public}d, visible=%{public}d",
8934 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
8935 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
8936 if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
8937 TLOGI(WmsLogTag::DEFAULT, "persistentId=%{public}d, "
8938 "WindowType=%{public}d", sessionId, sceneSession->GetWindowType());
8939 FillUnreliableWindowInfo(sceneSession, infos);
8940 }
8941 }
8942 return WMError::WM_OK;
8943 };
8944 return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
8945 }
8946
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)8947 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
8948 {
8949 TLOGD(WmsLogTag::DEFAULT, "persistentId=%{public}d, updateType=%{public}d", persistentId, type);
8950 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8951 if (sceneSession == nullptr) {
8952 TLOGE(WmsLogTag::DEFAULT, "sceneSession nullptr!");
8953 return;
8954 }
8955 wptr<SceneSession> weakSceneSession(sceneSession);
8956 if (processingFlushUIParams_.load()) {
8957 TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
8958 auto task = [this, weakSceneSession, type]() {
8959 auto sceneSession = weakSceneSession.promote();
8960 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
8961 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8962 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
8963 }
8964 };
8965 taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
8966 return;
8967 }
8968 auto task = [this, weakSceneSession, type]() {
8969 auto sceneSession = weakSceneSession.promote();
8970 NotifyAllAccessibilityInfo();
8971 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
8972 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8973 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
8974 }
8975 };
8976 taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:PID:" + std::to_string(persistentId));
8977 auto notifySceneInputTask = [weakSceneSession, type]() {
8978 auto sceneSession = weakSceneSession.promote();
8979 if (sceneSession == nullptr) {
8980 return;
8981 }
8982 SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
8983 };
8984 taskScheduler_->PostAsyncTask(notifySceneInputTask, "notifySceneInputTask");
8985 }
8986
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)8987 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
8988 const sptr<SceneSession>& sceneSession)
8989 {
8990 if (sceneSession == nullptr) {
8991 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "null scene session.");
8992 return false;
8993 }
8994 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
8995 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
8996 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
8997 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "filter gesture window.");
8998 return false;
8999 }
9000 if (sceneSession->GetSessionInfo().bundleName_.find("SCBDragScale") != std::string::npos) {
9001 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "filter DragScale window.");
9002 return false;
9003 }
9004 sptr<AccessibilityWindowInfo> info = sptr<AccessibilityWindowInfo>::MakeSptr();
9005 if (sceneSession->GetSessionInfo().isSystem_) {
9006 info->wid_ = 1;
9007 info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
9008 } else {
9009 info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
9010 }
9011 info->uiNodeId_ = sceneSession->GetUINodeId();
9012 info->type_ = sceneSession->GetWindowType();
9013 info->mode_ = sceneSession->GetWindowMode();
9014 info->layer_ = sceneSession->GetZOrder();
9015 info->scaleVal_ = sceneSession->GetFloatingScale();
9016 info->scaleX_ = sceneSession->GetScaleX();
9017 info->scaleY_ = sceneSession->GetScaleY();
9018 info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
9019 info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
9020 info->isDecorEnable_ = sceneSession->GetSessionProperty()->IsDecorEnable();
9021 WSRect wsRect = sceneSession->GetSessionGlobalRectWithSingleHandScale(); // only accessability and mmi need global
9022 DisplayId displayId = sceneSession->GetSessionProperty()->GetDisplayId();
9023 if (!sceneSession->GetSessionInfo().isSystem_ &&
9024 PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(displayId)) {
9025 displayId = sceneSession->TransformGlobalRectToRelativeRect(wsRect);
9026 }
9027 info->displayId_ = displayId;
9028 info->focused_ = sceneSession->GetPersistentId() == GetFocusedSessionId(displayId);
9029 info->windowRect_ = { wsRect.posX_, wsRect.posY_, wsRect.width_, wsRect.height_ };
9030 infos.emplace_back(info);
9031 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, innerWid: %{public}d, nodeId: %{public}d"
9032 ", bundleName: %{public}s, displayId: %{public}" PRIu64 ", rect: %{public}s",
9033 info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str(),
9034 info->displayId_, info->windowRect_.ToString().c_str());
9035 return true;
9036 }
9037
SelectSesssionFromMap(const uint64_t & surfaceId)9038 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
9039 {
9040 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9041 for (const auto& [_, sceneSession] : sceneSessionMap_) {
9042 if (sceneSession == nullptr) {
9043 continue;
9044 }
9045 if (sceneSession->GetSurfaceNode() == nullptr) {
9046 continue;
9047 }
9048 if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
9049 return sceneSession;
9050 }
9051 }
9052 return nullptr;
9053 }
9054
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)9055 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
9056 {
9057 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "in");
9058 auto task = [this, weak = std::weak_ptr<RSOcclusionData>(occlusiontionData)]() {
9059 auto weakOcclusionData = weak.lock();
9060 if (weakOcclusionData == nullptr) {
9061 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "weak occlusionData is nullptr");
9062 return;
9063 }
9064 std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
9065 std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
9066 GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
9067 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
9068 if (currVisibleData.size() != 0) {
9069 visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
9070 }
9071 if (visibilityChangeInfos.size() != 0) {
9072 DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
9073 CacVisibleWindowNum();
9074 }
9075
9076 std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
9077 if (currDrawingContentData.size() != 0) {
9078 drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
9079 }
9080 if (drawingContentChangeInfos.size() != 0) {
9081 DealwithDrawingContentChange(drawingContentChangeInfos);
9082 }
9083 };
9084 taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
9085 }
9086
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)9087 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
9088 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
9089 std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
9090 {
9091 VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
9092 for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
9093 WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
9094 switch (windowLayerState) {
9095 case WINDOW_ALL_VISIBLE:
9096 case WINDOW_SEMI_VISIBLE:
9097 case WINDOW_IN_VISIBLE:
9098 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
9099 break;
9100 case WINDOW_LAYER_DRAWING:
9101 currDrawingContentData.emplace_back(iter->first, true);
9102 break;
9103 case WINDOW_LAYER_NO_DRAWING:
9104 currDrawingContentData.emplace_back(iter->first, false);
9105 break;
9106 default:
9107 break;
9108 }
9109 }
9110 }
9111
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)9112 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
9113 WindowVisibilityState visibleState,
9114 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
9115 std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
9116 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
9117 {
9118 if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
9119 visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9120 auto subSessions = GetSubSceneSession(session->GetWindowId());
9121 if (subSessions.empty()) {
9122 return;
9123 }
9124
9125 RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
9126
9127 for (const auto& subSession : subSessions) {
9128 if (subSession == nullptr) {
9129 continue;
9130 }
9131 if (GetSessionRSVisible(subSession, currVisibleData)) {
9132 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Update subwindow visibility for winId: %{public}d",
9133 subSession->GetWindowId());
9134 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
9135 }
9136 }
9137 }
9138 }
9139
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)9140 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
9141 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
9142 {
9143 bool sessionRSVisible = false;
9144 for (const auto& [surfaceId, visibleState] : currVisibleData) {
9145 sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
9146 if (visibilitySession == nullptr) {
9147 continue;
9148 }
9149 if (session->GetWindowId() == visibilitySession->GetWindowId()) {
9150 if (visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9151 sessionRSVisible = true;
9152 }
9153 break;
9154 }
9155 }
9156 return sessionRSVisible;
9157 }
9158
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)9159 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
9160 WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
9161 std::string& visibilityInfo)
9162 {
9163 if (session == nullptr) {
9164 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Session is invalid!");
9165 return;
9166 }
9167 session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
9168 session->SetVisibilityState(visibleState);
9169 int32_t windowId = session->GetWindowId();
9170 if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
9171 session->NotifyWindowVisibility();
9172 }
9173 auto windowVisibilityInfo = sptr<WindowVisibilityInfo>::MakeSptr(
9174 windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType());
9175 windowVisibilityInfo->SetAppIndex(session->GetSessionInfo().appIndex_);
9176 windowVisibilityInfo->SetBundleName(session->GetSessionInfo().bundleName_);
9177 windowVisibilityInfo->SetAbilityName(session->GetSessionInfo().abilityName_);
9178 windowVisibilityInfo->SetIsSystem(session->GetSessionInfo().isSystem_);
9179 windowVisibilityInfos.emplace_back(windowVisibilityInfo);
9180
9181 visibilityInfo +=
9182 "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
9183 }
9184
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)9185 void SceneSessionManager::RemoveDuplicateSubSession(
9186 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
9187 std::vector<sptr<SceneSession>>& subSessions)
9188 {
9189 for (const auto& elem : visibilityChangeInfo) {
9190 uint64_t surfaceId = elem.first;
9191 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9192 if (session == nullptr) {
9193 continue;
9194 }
9195 for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
9196 auto subSession = *iterator;
9197 if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
9198 iterator = subSessions.erase(iterator);
9199 } else {
9200 ++iterator;
9201 }
9202 }
9203 }
9204 }
9205
GetSubSceneSession(int32_t parentWindowId)9206 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
9207 {
9208 std::vector<sptr<SceneSession>> subSessions;
9209 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9210 for (const auto& iter : sceneSessionMap_) {
9211 auto sceneSession = iter.second;
9212 if (sceneSession == nullptr) {
9213 continue;
9214 }
9215 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9216 continue;
9217 }
9218 const auto& mainOrFloatSession = sceneSession->GetMainOrFloatSession();
9219 if (mainOrFloatSession != nullptr && mainOrFloatSession->GetWindowId() == parentWindowId) {
9220 subSessions.push_back(sceneSession);
9221 }
9222 }
9223 return subSessions;
9224 }
9225
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)9226 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
9227 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
9228 {
9229 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
9230 std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
9231 uint32_t i, j;
9232 i = j = 0;
9233 for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
9234 if (lastVisibleData_[i].first < currVisibleData[j].first) {
9235 if (IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
9236 i++;
9237 continue;
9238 }
9239 if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9240 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
9241 }
9242 i++;
9243 } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
9244 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9245 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
9246 }
9247 j++;
9248 } else {
9249 if (lastVisibleData_[i].second != currVisibleData[j].second &&
9250 !IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
9251 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
9252 }
9253 i++;
9254 j++;
9255 }
9256 }
9257 for (; i < lastVisibleData_.size(); ++i) {
9258 if (IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
9259 continue;
9260 }
9261 if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9262 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
9263 }
9264 }
9265 for (; j < currVisibleData.size(); ++j) {
9266 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
9267 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
9268 }
9269 }
9270 lastVisibleData_ = currVisibleData;
9271 return visibilityChangeInfo;
9272 }
9273
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)9274 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
9275 visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
9276 {
9277 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
9278 #ifdef MEMMGR_WINDOW_ENABLE
9279 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
9280 #endif
9281
9282 std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
9283 for (const auto& elem : visibilityChangeInfo) {
9284 uint64_t surfaceId = elem.first;
9285 WindowVisibilityState visibleState = elem.second;
9286 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
9287 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9288 if (session == nullptr) {
9289 continue;
9290 }
9291 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
9292 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
9293 if (session->GetParentSession() != nullptr &&
9294 !session->GetParentSession()->IsSessionForeground() &&
9295 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
9296 continue;
9297 }
9298 }
9299 SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
9300 UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
9301 #ifdef MEMMGR_WINDOW_ENABLE
9302 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
9303 session->GetCallingUid(), isVisible));
9304 #endif
9305 CheckAndNotifyWaterMarkChangedResult();
9306 }
9307 if (windowVisibilityInfos.size() != 0) {
9308 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
9309 visibilityInfo.c_str());
9310 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
9311 }
9312 ProcessWindowModeType();
9313 #ifdef MEMMGR_WINDOW_ENABLE
9314 if (memMgrWindowInfos.size() != 0) {
9315 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "Notify memMgrWindowInfos changed start");
9316 taskScheduler_ ->AddExportTask("notifyMemMgr", [memMgrWindowInfos = std::move(memMgrWindowInfos)]() {
9317 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
9318 });
9319 }
9320 #endif
9321 }
9322
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)9323 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
9324 drawingContentChangeInfo)
9325 {
9326 std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
9327 for (const auto& [surfaceId, drawingState] : drawingContentChangeInfo) {
9328 int32_t windowId = 0;
9329 int32_t pid = 0;
9330 int32_t uid = 0;
9331 WindowType type = WindowType::APP_WINDOW_BASE;
9332 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9333 if (session == nullptr) {
9334 if (!GetSpecifiedDrawingData(surfaceId, pid, uid)) {
9335 continue;
9336 }
9337 RemoveSpecifiedDrawingData(surfaceId);
9338 } else {
9339 windowId = session->GetWindowId();
9340 pid = session->GetCallingPid();
9341 uid = session->GetCallingUid();
9342 type = session->GetWindowType();
9343 }
9344 windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(windowId, pid, uid, drawingState, type));
9345 if (openDebugTrace_) {
9346 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
9347 "drawingState:(%d )", pid, surfaceId, drawingState);
9348 }
9349 TLOGD(WmsLogTag::DEFAULT, "drawing status changed pid:%{public}d, "
9350 "surfaceId:%{public}" PRIu64 ", drawingState:%{public}d", pid, surfaceId, drawingState);
9351 }
9352 if (windowDrawingContenInfos.size() != 0) {
9353 TLOGD(WmsLogTag::DEFAULT, "Notify WindowDrawingContenInfo changed start");
9354 SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
9355 }
9356 }
9357
NotifyAppUseControlList(ControlAppType type,int32_t userId,const std::vector<AppUseControlInfo> & controlList)9358 WSError SceneSessionManager::NotifyAppUseControlList(
9359 ControlAppType type, int32_t userId, const std::vector<AppUseControlInfo>& controlList)
9360 {
9361 TLOGI(WmsLogTag::WMS_LIFE,
9362 "controlApptype: %{public}d userId: %{public}d controlList size: %{public}zu",
9363 static_cast<int>(type), userId, controlList.size());
9364 if (!SessionPermission::IsSACalling()) {
9365 TLOGW(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9366 return WSError::WS_ERROR_INVALID_PERMISSION;
9367 }
9368 if (type == ControlAppType::APP_LOCK &&
9369 !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WRITE_APP_LOCK)) {
9370 TLOGW(WmsLogTag::WMS_LIFE, "write app lock permission denied");
9371 return WSError::WS_ERROR_INVALID_PERMISSION;
9372 }
9373 if (currentUserId_ != userId) {
9374 if (currentUserId_ != DEFAULT_USERID) {
9375 TLOGW(WmsLogTag::WMS_LIFE, "invalid userId, currentUserId_:%{public}d userId:%{public}d",
9376 currentUserId_.load(), userId);
9377 return WSError::WS_ERROR_INVALID_OPERATION;
9378 }
9379 int32_t userIdByUid = GetUserIdByUid(getuid());
9380 if (userId != userIdByUid) {
9381 TLOGW(WmsLogTag::WMS_LIFE,
9382 "invalid userId, currentUserId_:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
9383 currentUserId_.load(), userId, userIdByUid);
9384 return WSError::WS_ERROR_INVALID_OPERATION;
9385 }
9386 }
9387 taskScheduler_->PostAsyncTask([this, type, userId, controlList] {
9388 if (notifyAppUseControlListFunc_ != nullptr) {
9389 notifyAppUseControlListFunc_(type, userId, controlList);
9390 }
9391
9392 std::vector<sptr<SceneSession>> mainSessions;
9393 for (const auto& appUseControlInfo : controlList) {
9394 GetMainSessionByBundleNameAndAppIndex(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_, mainSessions);
9395 if (mainSessions.empty()) {
9396 continue;
9397 }
9398 SceneSession::ControlInfo controlInfo = {
9399 .isNeedControl = appUseControlInfo.isNeedControl_,
9400 .isControlRecentOnly = appUseControlInfo.isControlRecentOnly_
9401 };
9402 for (const auto& session : mainSessions) {
9403 session->NotifyUpdateAppUseControl(type, controlInfo);
9404 }
9405 mainSessions.clear();
9406 }
9407 }, __func__);
9408 return WSError::WS_OK;
9409 }
9410
RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc && func)9411 void SceneSessionManager::RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc&& func)
9412 {
9413 taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
9414 notifyAppUseControlListFunc_ = std::move(callback);
9415 }, __func__);
9416 }
9417
GetSpecifiedDrawingData(uint64_t surfaceId,int32_t & pid,int32_t & uid)9418 bool SceneSessionManager::GetSpecifiedDrawingData(uint64_t surfaceId, int32_t& pid, int32_t& uid)
9419 {
9420 auto it = lastDrawingSessionInfoMap_.find(surfaceId);
9421 if (it != lastDrawingSessionInfoMap_.end()) {
9422 pid = it->second.pid_;
9423 uid = it->second.uid_;
9424 return true;
9425 }
9426 return false;
9427 }
9428
RemoveSpecifiedDrawingData(uint64_t surfaceId)9429 void SceneSessionManager::RemoveSpecifiedDrawingData(uint64_t surfaceId)
9430 {
9431 auto it = lastDrawingSessionInfoMap_.find(surfaceId);
9432 if (it != lastDrawingSessionInfoMap_.end()) {
9433 lastDrawingSessionInfoMap_.erase(it);
9434 }
9435 }
9436
GetWindowDrawingContentChangeInfo(const std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)9437 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
9438 const std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
9439 {
9440 std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
9441 for (const auto& [surfaceId, isWindowDrawing] : currDrawingContentData) {
9442 int32_t pid = 0;
9443 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9444 bool isDrawingStateChanged =
9445 session == nullptr || (GetPreWindowDrawingState(surfaceId, isWindowDrawing, pid) != isWindowDrawing &&
9446 GetProcessDrawingState(surfaceId, pid));
9447 if (isDrawingStateChanged) {
9448 processDrawingContentChangeInfo.emplace_back(surfaceId, isWindowDrawing);
9449 }
9450 }
9451 return processDrawingContentChangeInfo;
9452 }
9453
GetPreWindowDrawingState(uint64_t surfaceId,bool currentWindowDrawing,int32_t & pid)9454 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t surfaceId, bool currentWindowDrawing, int32_t& pid)
9455 {
9456 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9457 if (session == nullptr) {
9458 return false;
9459 }
9460 pid = session->GetCallingPid();
9461 bool preWindowDrawing = session->GetDrawingContentState();
9462 session->SetDrawingContentState(currentWindowDrawing);
9463 UpdateWindowDrawingData(surfaceId, pid, session->GetCallingUid());
9464 return preWindowDrawing;
9465 }
9466
UpdateWindowDrawingData(uint64_t surfaceId,int32_t pid,int32_t uid)9467 void SceneSessionManager::UpdateWindowDrawingData(uint64_t surfaceId, int32_t pid, int32_t uid)
9468 {
9469 lastDrawingSessionInfoMap_[surfaceId] = { pid, uid };
9470 }
9471
GetProcessDrawingState(uint64_t surfaceId,int32_t pid)9472 bool SceneSessionManager::GetProcessDrawingState(uint64_t surfaceId, int32_t pid)
9473 {
9474 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9475 for (const auto& [_, sceneSession] : sceneSessionMap_) {
9476 if (sceneSession == nullptr) {
9477 continue;
9478 }
9479 if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
9480 surfaceId != sceneSession->GetSurfaceNode()->GetId()) {
9481 if (sceneSession->GetDrawingContentState()) {
9482 return false;
9483 }
9484 }
9485 }
9486 return true;
9487 }
9488
InitWithRenderServiceAdded()9489 void SceneSessionManager::InitWithRenderServiceAdded()
9490 {
9491 auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
9492 this->WindowLayerInfoChangeCallback(occlusiontionData);
9493 };
9494 TLOGI(WmsLogTag::DEFAULT, "RegisterWindowVisibilityChangeCallback");
9495 if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
9496 TLOGE(WmsLogTag::DEFAULT, "RegisterWindowVisibilityChangeCallback failed");
9497 }
9498 }
9499
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType,bool isRegularAnimation)9500 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType, bool isRegularAnimation)
9501 {
9502 if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
9503 TLOGE(WmsLogTag::DEFAULT, "The input scene type is valid, scene type is %{public}d", sceneType);
9504 return WMError::WM_ERROR_INVALID_PARAM;
9505 }
9506
9507 auto task = [this, sceneType, isRegularAnimation]() {
9508 TLOGND(WmsLogTag::WMS_PC, "Set system animated scene %{public}d.", sceneType);
9509 bool ret = rsInterface_.SetSystemAnimatedScenes(
9510 static_cast<SystemAnimatedScenes>(sceneType), isRegularAnimation);
9511 if (!ret) {
9512 TLOGNE(WmsLogTag::WMS_PC, "Set system animated scene failed.");
9513 }
9514 };
9515 taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
9516 return WMError::WM_OK;
9517 }
9518
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)9519 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
9520 {
9521 if (!SessionPermission::IsSystemCalling()) {
9522 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
9523 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9524 }
9525 if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
9526 TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
9527 return WSError::WS_ERROR_INVALID_PERMISSION;
9528 }
9529 TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
9530 visible ? "VISIBLE" : "INVISIBLE", pid, uid);
9531 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
9532 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
9533 visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
9534 WindowType::WINDOW_TYPE_APP_COMPONENT));
9535 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
9536 return WSError::WS_OK;
9537 }
9538
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)9539 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
9540 {
9541 if (sceneSession == nullptr) {
9542 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr!");
9543 return;
9544 }
9545 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "in, wid: %{public}d, RSVisible: %{public}d, WindowMode: %{public}u",
9546 sceneSession->GetWindowId(), sceneSession->GetRSVisible(), sceneSession->GetWindowMode());
9547 if (sceneSession->GetRSVisible() || sceneSession->GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
9548 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
9549 #ifdef MEMMGR_WINDOW_ENABLE
9550 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
9551 #endif
9552 sceneSession->SetRSVisible(false);
9553 sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
9554 sceneSession->ClearExtWindowFlags();
9555 auto windowVisibilityInfo = new WindowVisibilityInfo(sceneSession->GetWindowId(),
9556 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
9557 WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType());
9558 windowVisibilityInfo->SetAppIndex(sceneSession->GetSessionInfo().appIndex_);
9559 windowVisibilityInfo->SetBundleName(sceneSession->GetSessionInfo().bundleName_);
9560 windowVisibilityInfo->SetAbilityName(sceneSession->GetSessionInfo().abilityName_);
9561 windowVisibilityInfo->SetIsSystem(sceneSession->GetSessionInfo().isSystem_);
9562 windowVisibilityInfos.emplace_back(windowVisibilityInfo);
9563 #ifdef MEMMGR_WINDOW_ENABLE
9564 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
9565 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
9566 #endif
9567 TLOGD(WmsLogTag::DEFAULT, "covered status changed window:%{public}u, isVisible:%{public}d",
9568 sceneSession->GetWindowId(), sceneSession->GetRSVisible());
9569 CheckAndNotifyWaterMarkChangedResult();
9570 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
9571 #ifdef MEMMGR_WINDOW_ENABLE
9572 TLOGD(WmsLogTag::DEFAULT, "Notify memMgrWindowInfos changed start");
9573 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
9574 #endif
9575 }
9576 }
9577
FindSessionByToken(const sptr<IRemoteObject> & token,WindowType type)9578 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token, WindowType type)
9579 {
9580 if (token == nullptr) {
9581 TLOGW(WmsLogTag::WMS_MAIN, "token is nullptr");
9582 return nullptr;
9583 }
9584 sptr<SceneSession> session = nullptr;
9585 auto cmpFunc = [token, type](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
9586 if (pair.second == nullptr) {
9587 return false;
9588 }
9589 if (pair.second->GetWindowType() == type) {
9590 return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
9591 }
9592 return false;
9593 };
9594 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9595 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
9596 if (iter != sceneSessionMap_.end()) {
9597 session = iter->second;
9598 }
9599 return session;
9600 }
9601
FindSessionByAffinity(const std::string & affinity)9602 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(const std::string& affinity)
9603 {
9604 if (affinity.size() == 0) {
9605 TLOGI(WmsLogTag::DEFAULT, "AbilityInfo affinity is empty");
9606 return nullptr;
9607 }
9608 sptr<SceneSession> session = nullptr;
9609 auto cmpFunc = [this, &affinity](const auto& pair) {
9610 auto sceneSession = pair.second;
9611 if (sceneSession == nullptr || !CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
9612 return false;
9613 }
9614 return sceneSession->GetSessionInfo().sessionAffinity == affinity;
9615 };
9616 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9617 if (auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
9618 iter != sceneSessionMap_.end()) {
9619 session = iter->second;
9620 }
9621 return session;
9622 }
9623
PreloadInLakeApp(const std::string & bundleName)9624 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
9625 {
9626 TLOGD(WmsLogTag::DEFAULT, "name %{public}s", bundleName.c_str());
9627 if (auto collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE)) {
9628 TLOGI(WmsLogTag::DEFAULT, "NotifyPreloadAbility: %{public}s", bundleName.c_str());
9629 collaborator->NotifyPreloadAbility(bundleName);
9630 }
9631 }
9632
PendingSessionToForeground(const sptr<IRemoteObject> & token)9633 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
9634 {
9635 TLOGI(WmsLogTag::WMS_LIFE, "in");
9636 auto pid = IPCSkeleton::GetCallingRealPid();
9637 if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
9638 TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
9639 return WSError::WS_ERROR_INVALID_PERMISSION;
9640 }
9641
9642 return taskScheduler_->PostSyncTask([this, &token]() {
9643 if (auto session = FindSessionByToken(token)) {
9644 return session->PendingSessionToForeground();
9645 }
9646 TLOGNE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
9647 return WSError::WS_ERROR_INVALID_PARAM;
9648 }, __func__);
9649 }
9650
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)9651 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
9652 bool shouldBackToCaller)
9653 {
9654 return taskScheduler_->PostSyncTask([this, &token, shouldBackToCaller] {
9655 if (auto session = FindSessionByToken(token)) {
9656 return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
9657 }
9658 TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
9659 return WSError::WS_ERROR_INVALID_PARAM;
9660 }, __func__);
9661 }
9662
ClearDisplayStatusBarTemporarilyFlags()9663 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
9664 {
9665 for (auto persistentId : avoidAreaListenerSessionSet_) {
9666 auto sceneSession = GetSceneSession(persistentId);
9667 if (sceneSession == nullptr) {
9668 continue;
9669 }
9670 sceneSession->SetIsDisplayStatusBarTemporarily(false);
9671 }
9672 }
9673
GetFocusSessionToken(sptr<IRemoteObject> & token,DisplayId displayId)9674 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject>& token, DisplayId displayId)
9675 {
9676 if (!SessionPermission::IsSACalling()) {
9677 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
9678 return WSError::WS_ERROR_INVALID_PERMISSION;
9679 }
9680 return taskScheduler_->PostSyncTask([this, &token, where = __func__, displayId]() {
9681 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
9682 if (focusGroup == nullptr) {
9683 TLOGNE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
9684 return WSError::WS_ERROR_INVALID_SESSION;
9685 }
9686 TLOGND(WmsLogTag::WMS_FOCUS, "%{public}s with focusedSessionId: %{public}d",
9687 where, focusGroup->GetFocusedSessionId());
9688 if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
9689 token = sceneSession->GetAbilityToken();
9690 if (token == nullptr) {
9691 TLOGNE(WmsLogTag::WMS_FOCUS, "token is nullptr");
9692 return WSError::WS_ERROR_INVALID_PARAM;
9693 }
9694 return WSError::WS_OK;
9695 }
9696 return WSError::WS_ERROR_INVALID_SESSION;
9697 }, __func__);
9698 }
9699
GetFocusSessionElement(AppExecFwk::ElementName & element,DisplayId displayId)9700 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element, DisplayId displayId)
9701 {
9702 auto pid = IPCSkeleton::GetCallingRealPid();
9703 AppExecFwk::RunningProcessInfo info;
9704 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
9705 if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
9706 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
9707 return WSError::WS_ERROR_INVALID_PERMISSION;
9708 }
9709 return taskScheduler_->PostSyncTask([this, &element, where = __func__, displayId]() {
9710 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
9711 if (focusGroup == nullptr) {
9712 TLOGNE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
9713 return WSError::WS_ERROR_INVALID_SESSION;
9714 }
9715 TLOGND(WmsLogTag::WMS_FOCUS, "%{public}s with focusedSessionId: %{public}d",
9716 where, focusGroup->GetFocusedSessionId());
9717 if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
9718 const auto& sessionInfo = sceneSession->GetSessionInfo();
9719 element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
9720 sessionInfo.abilityName_, sessionInfo.moduleName_);
9721 return WSError::WS_OK;
9722 }
9723 return WSError::WS_ERROR_INVALID_SESSION;
9724 }, __func__);
9725 }
9726
UpdateSessionAvoidAreaListener(int32_t persistentId,bool haveListener)9727 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t persistentId, bool haveListener)
9728 {
9729 const auto callingPid = IPCSkeleton::GetCallingRealPid();
9730 auto task = [this, persistentId, haveListener, callingPid, where = __func__]() {
9731 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d haveListener %{public}d",
9732 where, persistentId, haveListener);
9733 auto sceneSession = GetSceneSession(persistentId);
9734 if (sceneSession == nullptr) {
9735 TLOGND(WmsLogTag::WMS_IMMS, "%{public}s sceneSession is nullptr", where);
9736 return WSError::WS_DO_NOTHING;
9737 }
9738 if (callingPid != sceneSession->GetCallingPid()) {
9739 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s Permission denied, not called by the same process", where);
9740 return WSError::WS_ERROR_INVALID_PERMISSION;
9741 }
9742 if (haveListener) {
9743 avoidAreaListenerSessionSet_.insert(persistentId);
9744 UpdateAvoidArea(persistentId);
9745 } else {
9746 avoidAreaListenerSessionSet_.erase(persistentId);
9747 }
9748 return WSError::WS_OK;
9749 };
9750 return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
9751 }
9752
UpdateAvoidSessionAvoidArea(WindowType type)9753 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type)
9754 {
9755 AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
9756 AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
9757 AvoidArea avoidArea = rootSceneSession_->GetAvoidAreaByType(avoidType);
9758 rootSceneSession_->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
9759
9760 for (auto persistentId : avoidAreaListenerSessionSet_) {
9761 auto sceneSession = GetSceneSession(persistentId);
9762 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
9763 continue;
9764 }
9765 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(avoidType);
9766 sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
9767 }
9768 }
9769
UpdateNormalSessionAvoidArea(int32_t persistentId,const sptr<SceneSession> & sceneSession,bool & needUpdate)9770 void SceneSessionManager::UpdateNormalSessionAvoidArea(
9771 int32_t persistentId, const sptr<SceneSession>& sceneSession, bool& needUpdate)
9772 {
9773 if (rootSceneSession_->GetPersistentId() == persistentId) {
9774 UpdateRootSceneSessionAvoidArea(persistentId, needUpdate);
9775 return;
9776 }
9777 if (sceneSession == nullptr) {
9778 TLOGE(WmsLogTag::WMS_IMMS, "session is nullptr, win %{public}d", persistentId);
9779 needUpdate = false;
9780 return;
9781 }
9782 if (!IsSessionVisibleForeground(sceneSession)) {
9783 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u isVisible %{public}u sessionState %{public}u",
9784 persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
9785 needUpdate = false;
9786 return;
9787 }
9788 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
9789 TLOGD(WmsLogTag::WMS_IMMS,
9790 "win %{public}d not in avoidAreaListenerNodes, cannot update avoid area", persistentId);
9791 needUpdate = false;
9792 return;
9793 }
9794 sceneSession->UpdateSizeChangeReason(SizeChangeReason::AVOID_AREA_CHANGE);
9795 sceneSession->NotifyClientToUpdateRect("AvoidAreaChange", nullptr);
9796 }
9797
UpdateRootSceneSessionAvoidArea(int32_t persistentId,bool & needUpdate)9798 void SceneSessionManager::UpdateRootSceneSessionAvoidArea(int32_t persistentId, bool& needUpdate)
9799 {
9800 using T = std::underlying_type_t<AvoidAreaType>;
9801 for (T avoidAreaType = static_cast<T>(AvoidAreaType::TYPE_START);
9802 avoidAreaType < static_cast<T>(AvoidAreaType::TYPE_END); avoidAreaType++) {
9803 AvoidArea avoidArea = rootSceneSession_->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidAreaType));
9804 if (avoidAreaType == static_cast<T>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
9805 !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
9806 rootSceneSession_->GetSessionRect().height_)) {
9807 continue;
9808 }
9809 rootSceneSession_->UpdateAvoidArea(new AvoidArea(avoidArea), static_cast<AvoidAreaType>(avoidAreaType));
9810 }
9811 needUpdate = true;
9812 }
9813
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)9814 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
9815 {
9816 int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
9817 auto sceneSession = GetSceneSession(windowId);
9818 if (sceneSession == nullptr) {
9819 TLOGW(WmsLogTag::WMS_EVENT, "window not exist: %{public}d", windowId);
9820 return;
9821 }
9822
9823 TLOGI(WmsLogTag::WMS_EVENT, "Notify window:%{public}d, pid:%{public}d", windowId, pid);
9824 taskScheduler_->PostAsyncTask([weakSceneSession = wptr<SceneSession>(sceneSession), startMoving] {
9825 auto sceneSession = weakSceneSession.promote();
9826 if (sceneSession == nullptr) {
9827 TLOGNW(WmsLogTag::WMS_EVENT, "session is null");
9828 return;
9829 }
9830 SceneInputManager::GetInstance().NotifyMMIWindowPidChange(sceneSession, startMoving);
9831 }, __func__);
9832 }
9833
UpdateAvoidArea(int32_t persistentId)9834 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
9835 {
9836 taskScheduler_->PostAsyncTask([this, persistentId] {
9837 bool needUpdate = false;
9838 auto sceneSession = GetSceneSession(persistentId);
9839 if (sceneSession != nullptr && sceneSession->IsImmersiveType()) {
9840 UpdateAvoidSessionAvoidArea(sceneSession->GetWindowType());
9841 } else {
9842 UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
9843 }
9844 if (needUpdate) {
9845 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
9846 }
9847 }, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
9848 }
9849
UpdateGestureBackEnabled(int32_t persistentId)9850 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
9851 {
9852 auto task = [this, persistentId, where = __func__] {
9853 auto sceneSession = GetSceneSession(persistentId);
9854 if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
9855 TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable");
9856 return;
9857 }
9858 auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
9859 if (needEnableGestureBack) {
9860 gestureBackEnableWindowIdSet_.erase(persistentId);
9861 } else {
9862 gestureBackEnableWindowIdSet_.insert(persistentId);
9863 }
9864 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
9865 sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
9866 (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
9867 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
9868 enterRecent_.load() || !sceneSession->IsFocused()) {
9869 needEnableGestureBack = true;
9870 }
9871 if (gestureNavigationEnabledChangeFunc_ != nullptr) {
9872 gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
9873 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
9874 } else {
9875 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s callback func is null", where);
9876 }
9877 };
9878 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
9879 }
9880
UpdateOccupiedAreaIfNeed(int32_t persistentId)9881 void SceneSessionManager::UpdateOccupiedAreaIfNeed(int32_t persistentId)
9882 {
9883 auto task = [this, persistentId]() {
9884 sptr<SceneSession> keyboardSession = nullptr;
9885 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9886 for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
9887 auto sceneSession = item->second;
9888 if (sceneSession != nullptr &&
9889 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
9890 keyboardSession = sceneSession;
9891 break;
9892 }
9893 }
9894 if (keyboardSession == nullptr) {
9895 TLOGNE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
9896 return;
9897 }
9898 if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
9899 return;
9900 }
9901
9902 keyboardSession->OnCallingSessionUpdated();
9903 return;
9904 };
9905 taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
9906 }
9907
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)9908 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
9909 {
9910 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u isVisible %{public}u",
9911 persistentId, isVisible);
9912 taskScheduler_->PostTask([this, persistentId, isVisible] {
9913 auto sceneSession = GetSceneSession(persistentId);
9914 if (sceneSession == nullptr) {
9915 TLOGNE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
9916 return;
9917 }
9918 sceneSession->SetIsStatusBarVisible(isVisible);
9919 }, __func__);
9920 return WSError::WS_OK;
9921 }
9922
NotifyStatusBarConstantlyShow(DisplayId displayId,bool isVisible)9923 void SceneSessionManager::NotifyStatusBarConstantlyShow(DisplayId displayId, bool isVisible)
9924 {
9925 TLOGD(WmsLogTag::WMS_IMMS, "displayId %{public}" PRIu64 " isVisible %{public}u", displayId, isVisible);
9926 const char* const where = __func__;
9927 auto task = [this, displayId, isVisible] {
9928 statusBarConstantlyShowMap_[displayId] = isVisible;
9929 return WMError::WM_OK;
9930 };
9931 taskScheduler_->PostAsyncTask(task, where);
9932 }
9933
GetStatusBarConstantlyShow(DisplayId displayId,bool & isVisible) const9934 void SceneSessionManager::GetStatusBarConstantlyShow(DisplayId displayId, bool& isVisible) const
9935 {
9936 auto it = statusBarConstantlyShowMap_.find(displayId);
9937 if (it != statusBarConstantlyShowMap_.end()) {
9938 isVisible = it->second;
9939 } else {
9940 isVisible = false;
9941 }
9942 }
9943
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)9944 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
9945 {
9946 TLOGI(WmsLogTag::WMS_IMMS, "isVisible %{public}u "
9947 "area %{public}s, displayId %{public}" PRIu64, isVisible, barArea.ToString().c_str(), displayId);
9948 taskScheduler_->PostAsyncTask([this, isVisible, barArea, displayId, where = __func__] {
9949 bool isNeedUpdate = true;
9950 {
9951 std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
9952 isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
9953 currAINavigationBarAreaMap_.count(displayId) == 0 ||
9954 currAINavigationBarAreaMap_[displayId] != barArea;
9955 if (isNeedUpdate) {
9956 isAINavigationBarVisible_ = isVisible;
9957 currAINavigationBarAreaMap_.clear();
9958 currAINavigationBarAreaMap_[displayId] = barArea;
9959 }
9960 if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
9961 TLOGND(WmsLogTag::WMS_IMMS, "%{public}s barArea should be empty if invisible", where);
9962 currAINavigationBarAreaMap_[displayId] = WSRect();
9963 }
9964 }
9965 if (isNeedUpdate) {
9966 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s isVisible %{public}u bar area %{public}s",
9967 where, isVisible, barArea.ToString().c_str());
9968 for (auto persistentId : avoidAreaListenerSessionSet_) {
9969 NotifySessionAINavigationBarChange(persistentId);
9970 }
9971 }
9972 }, __func__);
9973 return WSError::WS_OK;
9974 }
9975
NotifySessionAINavigationBarChange(int32_t persistentId)9976 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
9977 {
9978 auto sceneSession = GetSceneSession(persistentId);
9979 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
9980 TLOGD(WmsLogTag::WMS_IMMS, "scene session is nullptr or not visible");
9981 return;
9982 }
9983 bool isLastFrameLayoutFinished = true;
9984 IsLastFrameLayoutFinished(isLastFrameLayoutFinished);
9985 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d layout finished %{public}d",
9986 persistentId, isLastFrameLayoutFinished);
9987 if (isLastFrameLayoutFinished) {
9988 sceneSession->UpdateAvoidArea(
9989 new AvoidArea(sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR)),
9990 AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
9991 } else {
9992 sceneSession->MarkAvoidAreaAsDirty();
9993 }
9994 }
9995
GetAINavigationBarArea(uint64_t displayId)9996 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
9997 {
9998 std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
9999 if (currAINavigationBarAreaMap_.count(displayId) == 0) {
10000 return {};
10001 }
10002 return currAINavigationBarAreaMap_[displayId];
10003 }
10004
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)10005 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
10006 {
10007 const auto callingPid = IPCSkeleton::GetCallingRealPid();
10008 auto task = [this, persistentId, haveListener, callingPid]() {
10009 TLOGNI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
10010 persistentId, haveListener);
10011 auto sceneSession = GetSceneSession(persistentId);
10012 if (sceneSession == nullptr) {
10013 TLOGNE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
10014 return WSError::WS_DO_NOTHING;
10015 }
10016 if (callingPid != sceneSession->GetCallingPid()) {
10017 TLOGNE(WmsLogTag::WMS_EVENT, "Permission denied");
10018 return WSError::WS_ERROR_INVALID_PERMISSION;
10019 }
10020 if (haveListener) {
10021 touchOutsideListenerSessionSet_.insert(persistentId);
10022 } else {
10023 touchOutsideListenerSessionSet_.erase(persistentId);
10024 }
10025 return WSError::WS_OK;
10026 };
10027 return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
10028 }
10029
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)10030 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
10031 {
10032 const auto callingPid = IPCSkeleton::GetCallingRealPid();
10033 return taskScheduler_->PostSyncTask([this, persistentId, haveListener, callingPid]() -> WSError {
10034 TLOGNI(WmsLogTag::WMS_LIFE, "persistentId: %{public}d haveListener:%{public}d",
10035 persistentId, haveListener);
10036 auto sceneSession = GetSceneSession(persistentId);
10037 if (sceneSession == nullptr) {
10038 TLOGND(WmsLogTag::WMS_LIFE, "sceneSession is nullptr.");
10039 return WSError::WS_DO_NOTHING;
10040 }
10041 if (callingPid != sceneSession->GetCallingPid()) {
10042 TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
10043 return WSError::WS_ERROR_INVALID_PERMISSION;
10044 }
10045 if (haveListener) {
10046 windowVisibilityListenerSessionSet_.insert(persistentId);
10047 sceneSession->NotifyWindowVisibility();
10048 } else {
10049 windowVisibilityListenerSessionSet_.erase(persistentId);
10050 }
10051 return WSError::WS_OK;
10052 }, __func__);
10053 }
10054
UpdateDarkColorModeToRS()10055 void SceneSessionManager::UpdateDarkColorModeToRS()
10056 {
10057 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
10058 if (appContext == nullptr) {
10059 TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
10060 return;
10061 }
10062 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
10063 if (config == nullptr) {
10064 TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
10065 return;
10066 }
10067 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
10068 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
10069 bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
10070 TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d", colorMode.c_str(), ret);
10071 }
10072
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)10073 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
10074 {
10075 processVirtualPixelRatioChangeFunc_ = func;
10076 TLOGI(WmsLogTag::DEFAULT, "end");
10077 }
10078
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)10079 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
10080 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
10081 {
10082 if (displayInfo == nullptr) {
10083 TLOGE(WmsLogTag::DEFAULT, "displayInfo is nullptr.");
10084 return;
10085 }
10086 taskScheduler_->PostSyncTask([this, displayInfo, type, where = __func__]() {
10087 if (processVirtualPixelRatioChangeFunc_ != nullptr &&
10088 type == DisplayStateChangeType::RESOLUTION_CHANGE &&
10089 displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
10090 Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
10091 displayInfo->GetWidth(), displayInfo->GetHeight() };
10092 processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
10093 }
10094 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10095 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10096 if (sceneSession == nullptr) {
10097 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s null scene session", where);
10098 continue;
10099 }
10100 if (sceneSession->GetSessionProperty()->GetDisplayId() != displayInfo->GetDisplayId()) {
10101 continue;
10102 }
10103 if (sceneSession->GetSessionInfo().isSystem_) {
10104 continue;
10105 }
10106 if (sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
10107 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE) {
10108 sceneSession->UpdateDensity();
10109 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "UpdateDensity name=%{public}s, persistentId=%{public}d, "
10110 "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
10111 sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
10112 sceneSession->GetSessionState(), sceneSession->IsVisible());
10113 }
10114 }
10115 UpdateDisplayRegion(displayInfo);
10116 return WSError::WS_OK;
10117 }, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
10118 }
10119
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)10120 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
10121 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
10122 {
10123 if (displayInfo == nullptr) {
10124 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr.");
10125 return;
10126 }
10127 taskScheduler_->PostSyncTask([this, displayInfo, where = __func__]() {
10128 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10129 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10130 if (sceneSession == nullptr) {
10131 TLOGNE(WmsLogTag::DMS, "%{public}s null scene session", where);
10132 continue;
10133 }
10134 if (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
10135 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) {
10136 continue;
10137 }
10138 if (NearEqual(sceneSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
10139 NearEqual(sceneSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
10140 sceneSession->GetRotation() != displayInfo->GetRotation()) {
10141 sceneSession->UpdateRotationAvoidArea();
10142 TLOGND(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
10143 "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
10144 sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState(),
10145 sceneSession->IsVisible());
10146 }
10147 sceneSession->SetRotation(displayInfo->GetRotation());
10148 sceneSession->UpdateOrientation();
10149 }
10150 UpdateDisplayRegion(displayInfo);
10151 return WSError::WS_OK;
10152 }, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
10153 }
10154
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)10155 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
10156 {
10157 if (displayInfo == nullptr) {
10158 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
10159 return;
10160 }
10161
10162 taskScheduler_->PostAsyncTask([this, displayInfo] {
10163 ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
10164 displayInfo->GetScaleX(),
10165 displayInfo->GetScaleY(),
10166 displayInfo->GetPivotX(),
10167 displayInfo->GetPivotY(),
10168 displayInfo->GetTranslateX(),
10169 displayInfo->GetTranslateY());
10170 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
10171 FlushWindowInfoToMMI(true);
10172 }, __func__);
10173 }
10174
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)10175 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
10176 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
10177 {
10178 TLOGD(WmsLogTag::DEFAULT, "type: %{public}u", type);
10179 switch (type) {
10180 case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
10181 SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
10182 displayInfo, displayInfoMap, type);
10183 break;
10184 }
10185 case DisplayStateChangeType::UPDATE_ROTATION: {
10186 SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
10187 displayInfo, displayInfoMap, type);
10188 break;
10189 }
10190 case DisplayStateChangeType::UPDATE_SCALE: {
10191 SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
10192 break;
10193 }
10194 default:
10195 return;
10196 }
10197 }
10198
CheckIfNeedMultipleFocus(const std::string & name,const ScreenType & screenType)10199 bool CheckIfNeedMultipleFocus(const std::string& name, const ScreenType& screenType)
10200 {
10201 if (screenType == ScreenType::VIRTUAL && name == "CeliaView") {
10202 return true;
10203 }
10204 return false;
10205 }
10206
OnScreenConnected(const sptr<ScreenSession> & screenSession)10207 void ScreenConnectionChangeListener::OnScreenConnected(const sptr<ScreenSession>& screenSession)
10208 {
10209 if (screenSession == nullptr) {
10210 TLOGE(WmsLogTag::WMS_FOCUS, "screenSession is nullptr");
10211 return;
10212 }
10213 TLOGI(WmsLogTag::WMS_FOCUS, "name: %{public}s, screenId: %{public}" PRIu64 ", screenType: %{public}u",
10214 screenSession->GetName().c_str(), screenSession->GetScreenId(),
10215 screenSession->GetScreenProperty().GetScreenType());
10216 if (CheckIfNeedMultipleFocus(screenSession->GetName(), screenSession->GetScreenProperty().GetScreenType())) {
10217 SceneSessionManager::GetInstance().AddFocusGroup(screenSession->GetScreenId());
10218 }
10219 }
10220
OnScreenDisconnected(const sptr<ScreenSession> & screenSession)10221 void ScreenConnectionChangeListener::OnScreenDisconnected(const sptr<ScreenSession>& screenSession)
10222 {
10223 if (screenSession == nullptr) {
10224 TLOGE(WmsLogTag::WMS_FOCUS, "screenSession is nullptr");
10225 return;
10226 }
10227 TLOGI(WmsLogTag::WMS_FOCUS, "name: %{public}s, screenId: %{public}" PRIu64 ", screenType: %{public}u",
10228 screenSession->GetName().c_str(), screenSession->GetScreenId(),
10229 screenSession->GetScreenProperty().GetScreenType());
10230 if (CheckIfNeedMultipleFocus(screenSession->GetName(), screenSession->GetScreenProperty().GetScreenType())) {
10231 SceneSessionManager::GetInstance().RemoveFocusGroup(screenSession->GetScreenId());
10232 }
10233 }
10234
OnScreenshot(DisplayId displayId)10235 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
10236 {
10237 SceneSessionManager::GetInstance().OnScreenshot(displayId);
10238 }
10239
OnScreenshot(DisplayId displayId)10240 void SceneSessionManager::OnScreenshot(DisplayId displayId)
10241 {
10242 taskScheduler_->PostAsyncTask([this, displayId]() {
10243 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10244 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10245 if (sceneSession == nullptr) {
10246 continue;
10247 }
10248 auto state = sceneSession->GetSessionState();
10249 if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
10250 sceneSession->NotifyScreenshot();
10251 }
10252 }
10253 }, "OnScreenshot:PID:" + std::to_string(displayId));
10254 }
10255
ClearSession(int32_t persistentId)10256 WSError SceneSessionManager::ClearSession(int32_t persistentId)
10257 {
10258 TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", persistentId);
10259 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10260 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
10261 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10262 }
10263 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10264 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10265 return WSError::WS_ERROR_INVALID_PERMISSION;
10266 }
10267 taskScheduler_->PostAsyncTask([this, persistentId]() {
10268 auto sceneSession = GetSceneSession(persistentId);
10269 return ClearSession(sceneSession);
10270 }, "ClearSession:PID:" + std::to_string(persistentId));
10271 return WSError::WS_OK;
10272 }
10273
ClearSession(sptr<SceneSession> sceneSession)10274 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
10275 {
10276 TLOGD(WmsLogTag::WMS_LIFE, "in");
10277 if (sceneSession == nullptr) {
10278 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
10279 return WSError::WS_ERROR_INVALID_SESSION;
10280 }
10281 if (!IsSessionClearable(sceneSession)) {
10282 TLOGE(WmsLogTag::WMS_LIFE, "session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
10283 return WSError::WS_ERROR_INVALID_SESSION;
10284 }
10285 const WSError errCode = sceneSession->Clear();
10286 return errCode;
10287 }
10288
ClearAllSessions()10289 WSError SceneSessionManager::ClearAllSessions()
10290 {
10291 TLOGD(WmsLogTag::WMS_LIFE, "in");
10292 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10293 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
10294 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10295 }
10296 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10297 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10298 return WSError::WS_ERROR_INVALID_PERMISSION;
10299 }
10300 auto task = [this]() {
10301 std::vector<sptr<SceneSession>> sessionVector;
10302 GetAllClearableSessions(sessionVector);
10303 for (uint32_t i = 0; i < sessionVector.size(); i++) {
10304 ClearSession(sessionVector[i]);
10305 }
10306 return WSError::WS_OK;
10307 };
10308 taskScheduler_->PostAsyncTask(task, __func__);
10309 return WSError::WS_OK;
10310 }
10311
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)10312 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
10313 {
10314 TLOGD(WmsLogTag::WMS_LIFE, "in");
10315 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10316 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10317 if (IsSessionClearable(sceneSession)) {
10318 sessionVector.push_back(sceneSession);
10319 }
10320 }
10321 }
10322
LockSession(int32_t sessionId)10323 WSError SceneSessionManager::LockSession(int32_t sessionId)
10324 {
10325 TLOGI(WmsLogTag::DEFAULT, "id: %{public}d", sessionId);
10326 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10327 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
10328 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10329 }
10330 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10331 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10332 return WSError::WS_ERROR_INVALID_PERMISSION;
10333 }
10334 const char* const where = __func__;
10335 auto task = [this, sessionId, where]() {
10336 auto sceneSession = GetSceneSession(sessionId);
10337 if (sceneSession == nullptr) {
10338 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s cannot find session, id: %{public}d", where, sessionId);
10339 return WSError::WS_ERROR_INVALID_PARAM;
10340 }
10341 sceneSession->SetSessionInfoLockedState(true);
10342 return WSError::WS_OK;
10343 };
10344 return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
10345 }
10346
UnlockSession(int32_t sessionId)10347 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
10348 {
10349 TLOGI(WmsLogTag::DEFAULT, "id: %{public}d", sessionId);
10350 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10351 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
10352 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10353 }
10354 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10355 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10356 return WSError::WS_ERROR_INVALID_PERMISSION;
10357 }
10358 const char* const where = __func__;
10359 auto task = [this, sessionId, where]() {
10360 auto sceneSession = GetSceneSession(sessionId);
10361 if (sceneSession == nullptr) {
10362 TLOGNE(WmsLogTag::DEFAULT, "%{public}s cannot find session, id: %{public}d", where, sessionId);
10363 return WSError::WS_ERROR_INVALID_PARAM;
10364 }
10365 sceneSession->SetSessionInfoLockedState(false);
10366 return WSError::WS_OK;
10367 };
10368 return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
10369 }
10370
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)10371 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
10372 {
10373 TLOGI(WmsLogTag::WMS_LIFE, "in");
10374 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10375 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
10376 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10377 }
10378 if (!SessionPermission::VerifySessionPermission()) {
10379 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10380 return WSError::WS_ERROR_INVALID_PERMISSION;
10381 }
10382
10383 return WSError::WS_OK;
10384 }
10385
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)10386 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
10387 std::vector<int32_t>& result)
10388 {
10389 TLOGI(WmsLogTag::WMS_LIFE, "in");
10390 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
10391 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
10392 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10393 }
10394 if (!SessionPermission::VerifySessionPermission()) {
10395 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10396 return WSError::WS_ERROR_INVALID_PERMISSION;
10397 }
10398
10399 result.insert(result.end(), sessionIds.begin(), sessionIds.end());
10400 return WSError::WS_OK;
10401 }
10402
IsSessionClearable(sptr<SceneSession> sceneSession)10403 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> sceneSession)
10404 {
10405 if (sceneSession == nullptr) {
10406 TLOGI(WmsLogTag::WMS_MAIN, "sceneSession is nullptr");
10407 return false;
10408 }
10409 const auto& sessionInfo = sceneSession->GetSessionInfo();
10410 if (sessionInfo.abilityInfo == nullptr) {
10411 TLOGI(WmsLogTag::WMS_MAIN, "sceneSession abilityInfo is nullptr");
10412 return false;
10413 }
10414 if (sessionInfo.abilityInfo->excludeFromMissions && !sceneSession->IsAnco()) {
10415 TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is excludeFromMissions", sceneSession->GetPersistentId());
10416 return false;
10417 }
10418 if (sessionInfo.abilityInfo->unclearableMission) {
10419 TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is unclearable", sceneSession->GetPersistentId());
10420 return false;
10421 }
10422 if (sessionInfo.isSystem_) {
10423 TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is system app", sceneSession->GetPersistentId());
10424 return false;
10425 }
10426 if (sessionInfo.lockedState) {
10427 TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is in lockedState", sceneSession->GetPersistentId());
10428 return false;
10429 }
10430
10431 return true;
10432 }
10433
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)10434 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
10435 const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
10436 {
10437 TLOGI(WmsLogTag::DEFAULT, "type: %{public}d", type);
10438 auto isSaCall = SessionPermission::IsSACalling();
10439 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10440 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
10441 return WSError::WS_ERROR_INVALID_PERMISSION;
10442 }
10443 if (!CheckCollaboratorType(type)) {
10444 TLOGW(WmsLogTag::DEFAULT, "collaborator register failed, invalid type.");
10445 return WSError::WS_ERROR_INVALID_TYPE;
10446 }
10447 if (impl == nullptr) {
10448 TLOGE(WmsLogTag::DEFAULT, "Collaborator is nullptr");
10449 return WSError::WS_ERROR_NULLPTR;
10450 }
10451 if (impl->AsObject() == nullptr || !impl->AsObject()->AddDeathRecipient(collaboratorDeathRecipient_)) {
10452 TLOGE(WmsLogTag::DEFAULT, "Failed to add collaborator death recipient");
10453 return WSError::WS_ERROR_IPC_FAILED;
10454 }
10455 {
10456 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
10457 collaboratorMap_[type] = impl;
10458 }
10459 auto task = [this] {
10460 if (abilityManagerCollaboratorRegisteredFunc_) {
10461 abilityManagerCollaboratorRegisteredFunc_();
10462 }
10463 };
10464 taskScheduler_->PostTask(task, __func__);
10465 return WSError::WS_OK;
10466 }
10467
UnregisterIAbilityManagerCollaborator(int32_t type)10468 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
10469 {
10470 TLOGI(WmsLogTag::DEFAULT, "type: %{public}d", type);
10471 auto isSaCall = SessionPermission::IsSACalling();
10472 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10473 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
10474 return WSError::WS_ERROR_INVALID_PERMISSION;
10475 }
10476 if (!CheckCollaboratorType(type)) {
10477 TLOGE(WmsLogTag::DEFAULT, "collaborator unregister failed, invalid type.");
10478 return WSError::WS_ERROR_INVALID_TYPE;
10479 }
10480 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(type);
10481 if (collaborator != nullptr && collaborator->AsObject() != nullptr) {
10482 TLOGI(WmsLogTag::DEFAULT, "Remove collaborator death recipient");
10483 collaborator->AsObject()->RemoveDeathRecipient(collaboratorDeathRecipient_);
10484 }
10485 {
10486 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
10487 collaboratorMap_.erase(type);
10488 }
10489 return WSError::WS_OK;
10490 }
10491
ClearAllCollaboratorSessions()10492 void SceneSessionManager::ClearAllCollaboratorSessions()
10493 {
10494 TLOGI(WmsLogTag::WMS_MAIN, "in");
10495 std::vector<sptr<SceneSession>> collaboratorSessions;
10496 {
10497 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10498 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10499 if (sceneSession != nullptr && CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
10500 collaboratorSessions.push_back(sceneSession);
10501 }
10502 }
10503 }
10504 for (const auto& sceneSession : collaboratorSessions) {
10505 sceneSession->Clear();
10506 }
10507 }
10508
CheckCollaboratorType(int32_t type)10509 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
10510 {
10511 if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
10512 TLOGD(WmsLogTag::WMS_MAIN, "type is invalid");
10513 return false;
10514 }
10515 return true;
10516 }
10517
CheckIfReuseSession(SessionInfo & sessionInfo)10518 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
10519 {
10520 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
10521 sessionInfo.moduleName_);
10522 if (abilityInfo == nullptr) {
10523 TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
10524 return BrokerStates::BROKER_UNKOWN;
10525 }
10526 sessionInfo.abilityInfo = abilityInfo;
10527 int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
10528 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
10529 collaboratorType = CollaboratorType::RESERVE_TYPE;
10530 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
10531 collaboratorType = CollaboratorType::OTHERS_TYPE;
10532 }
10533 if (!CheckCollaboratorType(collaboratorType)) {
10534 TLOGW(WmsLogTag::DEFAULT, "checked not collaborator!");
10535 return BrokerStates::BROKER_UNKOWN;
10536 }
10537 BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
10538 sessionInfo.collaboratorType_ = collaboratorType;
10539 sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
10540 if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
10541 TLOGI(WmsLogTag::DEFAULT, "FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
10542 sessionInfo.reuse = true;
10543 } else {
10544 sessionInfo.reuse = false;
10545 }
10546 TLOGI(WmsLogTag::DEFAULT, "end: affinity %{public}s type %{public}d reuse %{public}d",
10547 sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
10548 return resultValue;
10549 }
10550
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)10551 BrokerStates SceneSessionManager::NotifyStartAbility(
10552 int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
10553 {
10554 TLOGI(WmsLogTag::WMS_LIFE, "type %{public}d id %{public}d", collaboratorType, persistentId);
10555 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
10556 if (collaborator == nullptr) {
10557 return BrokerStates::BROKER_UNKOWN;
10558 }
10559 if (sessionInfo.want == nullptr) {
10560 TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo.want is nullptr, init");
10561 sessionInfo.want = std::make_shared<AAFwk::Want>();
10562 sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
10563 sessionInfo.moduleName_);
10564 }
10565 auto accessTokenIDEx = sessionInfo.callingTokenId_;
10566 if (collaborator != nullptr) {
10567 containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
10568 std::chrono::system_clock::now().time_since_epoch()).count();
10569
10570 std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
10571 if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
10572 TLOGI(WmsLogTag::WMS_LIFE, "want affinity exit %{public}s.", affinity.c_str());
10573 return BrokerStates::BROKER_UNKOWN;
10574 }
10575 sessionInfo.want->SetParam("oh_persistentId", persistentId);
10576 std::shared_ptr<int32_t> ret = std::make_shared<int32_t>(0);
10577 std::shared_ptr<AAFwk::Want> notifyWant = std::make_shared<AAFwk::Want>(*(sessionInfo.want));
10578 bool isTimeout = ffrtQueueHelper_->SubmitTaskAndWait([this, collaborator, accessTokenIDEx,
10579 notifyWant, abilityInfo = sessionInfo.abilityInfo, ret] {
10580 auto result = collaborator->NotifyStartAbility(*abilityInfo, currentUserId_, *notifyWant,
10581 static_cast<uint64_t>(accessTokenIDEx));
10582 *ret = static_cast<int32_t>(result);
10583 }, NOTIFY_START_ABILITY_TIMEOUT);
10584
10585 if (isTimeout) {
10586 TLOGE(WmsLogTag::WMS_LIFE, "notify start ability timeout, id: %{public}d", persistentId);
10587 return BrokerStates::BROKER_NOT_START;
10588 }
10589 *(sessionInfo.want) = *notifyWant;
10590 TLOGI(WmsLogTag::WMS_LIFE, "collaborator ret: %{public}d", *ret);
10591 if (*ret == 0) {
10592 return BrokerStates::BROKER_STARTED;
10593 } else {
10594 return BrokerStates::BROKER_NOT_START;
10595 }
10596 }
10597 return BrokerStates::BROKER_UNKOWN;
10598 }
10599
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)10600 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
10601 {
10602 if (sceneSession == nullptr) {
10603 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
10604 return;
10605 }
10606 if (sessionInfo.want == nullptr) {
10607 TLOGI(WmsLogTag::DEFAULT, "sessionInfo.want is nullptr");
10608 return;
10609 }
10610 if (auto collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType())) {
10611 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
10612 abilitySessionInfo->want = *(sessionInfo.want);
10613 int32_t missionId = abilitySessionInfo->persistentId;
10614 std::string bundleName = sessionInfo.bundleName_;
10615 int64_t timestamp = containerStartAbilityTime_;
10616 WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
10617 TLOGI(WmsLogTag::DEFAULT, "call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
10618 missionId, bundleName.c_str());
10619 collaborator->NotifyMissionCreated(abilitySessionInfo);
10620 }
10621 }
10622
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)10623 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
10624 sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
10625 {
10626 TLOGD(WmsLogTag::DEFAULT, "type: %{public}d", collaboratorType);
10627 if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
10628 TLOGI(WmsLogTag::DEFAULT, "called");
10629 collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
10630 }
10631 }
10632
10633
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)10634 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
10635 {
10636 TLOGD(WmsLogTag::DEFAULT, "in");
10637 if (sceneSession == nullptr) {
10638 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
10639 return;
10640 }
10641 if (auto collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType())) {
10642 TLOGI(WmsLogTag::DEFAULT, "called UpdateMissionInfo");
10643 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
10644 collaborator->UpdateMissionInfo(abilitySessionInfo);
10645 }
10646 }
10647
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)10648 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
10649 {
10650 TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, type: %{public}d", persistentId, collaboratorType);
10651 if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
10652 TLOGI(WmsLogTag::DEFAULT, "called %{public}d", persistentId);
10653 collaborator->NotifyMoveMissionToForeground(persistentId);
10654 }
10655 }
10656
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)10657 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
10658 {
10659 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, type: %{public}d", persistentId, collaboratorType);
10660 if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
10661 const char* const where = __func__;
10662 ffrtQueueHelper_->SubmitTask([collaborator, persistentId, where] {
10663 int32_t ret = collaborator->NotifyClearMission(persistentId);
10664 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s called clear mission ret: %{public}d, persistent id: %{public}d",
10665 where, ret, persistentId);
10666 });
10667 }
10668 }
10669
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)10670 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
10671 {
10672 if (sceneSession == nullptr) {
10673 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
10674 return false;
10675 }
10676 std::string sessionAffinity;
10677 TLOGI(WmsLogTag::WMS_LIFE, "call");
10678 if (sceneSession->GetSessionInfo().want != nullptr) {
10679 sessionAffinity = sceneSession->GetSessionInfo().want
10680 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
10681 }
10682 if (sessionAffinity.empty()) {
10683 TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
10684 BrokerStates notifyReturn = NotifyStartAbility(
10685 sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
10686 if (notifyReturn == BrokerStates::BROKER_NOT_START) {
10687 TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
10688 return false;
10689 }
10690 }
10691 if (sceneSession->GetSessionInfo().want != nullptr) {
10692 sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
10693 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
10694 TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
10695 sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
10696 sceneSession->GetSessionInfo().sessionAffinity.c_str());
10697 } else {
10698 TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
10699 }
10700 return true;
10701 }
10702
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)10703 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
10704 {
10705 if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
10706 return false;
10707 }
10708 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
10709 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
10710 return true;
10711 }
10712
AddWindowDragHotArea(DisplayId displayId,uint32_t type,WSRect & area)10713 void SceneSessionManager::AddWindowDragHotArea(DisplayId displayId, uint32_t type, WSRect& area)
10714 {
10715 TLOGI(WmsLogTag::WMS_LAYOUT, "displayId: %{public}" PRIu64 ", "
10716 "type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
10717 "height: %{public}d", displayId, type, area.posX_, area.posY_, area.width_, area.height_);
10718 SceneSession::AddOrUpdateWindowDragHotArea(displayId, type, area);
10719 }
10720
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)10721 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
10722 {
10723 auto task = [this, persistentId, isMaximize]() {
10724 TLOGND(WmsLogTag::WMS_PC, "update maximize mode, id: %{public}d, isMaximize: %{public}d",
10725 persistentId, isMaximize);
10726 auto sceneSession = GetSceneSession(persistentId);
10727 if (sceneSession == nullptr) {
10728 TLOGNE(WmsLogTag::WMS_PC, "could not find window, persistentId:%{public}d", persistentId);
10729 return WSError::WS_ERROR_INVALID_WINDOW;
10730 }
10731 sceneSession->UpdateMaximizeMode(isMaximize);
10732 return WSError::WS_OK;
10733 };
10734 taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
10735 return WSError::WS_OK;
10736 }
10737
GetIsLayoutFullScreen(bool & isLayoutFullScreen)10738 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
10739 {
10740 auto task = [this, &isLayoutFullScreen]() {
10741 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10742 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10743 if (sceneSession == nullptr) {
10744 TLOGNE(WmsLogTag::WMS_IMMS, "Session is nullptr");
10745 continue;
10746 }
10747 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10748 continue;
10749 }
10750 auto state = sceneSession->GetSessionState();
10751 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
10752 continue;
10753 }
10754 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
10755 continue;
10756 }
10757 isLayoutFullScreen = sceneSession->GetSessionProperty()->IsLayoutFullScreen();
10758 if (isLayoutFullScreen) {
10759 TLOGND(WmsLogTag::WMS_IMMS, "Current window is immersive, persistentId:%{public}d",
10760 sceneSession->GetPersistentId());
10761 return WSError::WS_OK;
10762 } else {
10763 TLOGND(WmsLogTag::WMS_IMMS, "Current window is not immersive, persistentId:%{public}d",
10764 sceneSession->GetPersistentId());
10765 }
10766 }
10767 TLOGND(WmsLogTag::WMS_IMMS, "No immersive window");
10768 return WSError::WS_OK;
10769 };
10770
10771 taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
10772 return WSError::WS_OK;
10773 }
10774
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)10775 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
10776 {
10777 auto sceneSession = GetSceneSession(persistentId);
10778 if (!sceneSession) {
10779 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
10780 return WSError::WS_ERROR_INVALID_WINDOW;
10781 }
10782 auto fromScreenId = sceneSession->GetSessionInfo().screenId_;
10783 sceneSession->SetScreenId(screenId);
10784 sceneSession->GetSessionProperty()->SetDisplayId(screenId);
10785 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, move display %{public}" PRIu64 " from %{public}" PRIu64,
10786 sceneSession->GetPersistentId(), screenId, fromScreenId);
10787 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
10788 sceneSession->NotifyDisplayMove(fromScreenId, screenId);
10789 sceneSession->UpdateDensity();
10790
10791 // Find keyboard session.
10792 const auto& keyboardSessionVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
10793 for (const auto& keyboardSession : keyboardSessionVec) {
10794 if (!keyboardSession) {
10795 continue;
10796 }
10797 TLOGD(WmsLogTag::WMS_KEYBOARD, "isSystemKeyboard: %{public}d, callingSessionId: %{public}d",
10798 keyboardSession->IsSystemKeyboard(), keyboardSession->GetCallingSessionId());
10799 if (!keyboardSession->IsSystemKeyboard() &&
10800 static_cast<int32_t>(keyboardSession->GetCallingSessionId()) == persistentId) {
10801 CallingWindowInfo callingWindowInfo(persistentId, sceneSession->GetCallingPid(), screenId, GetUserIdByUid(getuid()));
10802 SessionManagerAgentController::GetInstance().NotifyCallingWindowDisplayChanged(callingWindowInfo);
10803 break;
10804 }
10805 }
10806 return WSError::WS_OK;
10807 }
10808
NotifyStackEmpty(int32_t persistentId)10809 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
10810 {
10811 TLOGI(WmsLogTag::WMS_LIFE, "persistentId %{public}d", persistentId);
10812 auto task = [this, persistentId]() {
10813 auto sceneSession = GetSceneSession(persistentId);
10814 if (!sceneSession) {
10815 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
10816 return WSError::WS_ERROR_INVALID_WINDOW;
10817 }
10818 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::STACK_EMPTY);
10819 return WSError::WS_OK;
10820 };
10821 taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
10822 return WSError::WS_OK;
10823 }
10824
OnImmersiveStateChange(ScreenId screenId,bool & immersive)10825 void DisplayChangeListener::OnImmersiveStateChange(ScreenId screenId, bool& immersive)
10826 {
10827 immersive = SceneSessionManager::GetInstance().GetImmersiveState(screenId);
10828 }
10829
GetImmersiveState(ScreenId screenId)10830 bool SceneSessionManager::GetImmersiveState(ScreenId screenId)
10831 {
10832 return taskScheduler_->PostSyncTask([this, screenId, where = __func__] {
10833 bool isPcOrPadFreeMultiWindowMode = false;
10834 IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
10835 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10836 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10837 if (sceneSession == nullptr) {
10838 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is nullptr", where);
10839 continue;
10840 }
10841 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10842 continue;
10843 }
10844 auto state = sceneSession->GetSessionState();
10845 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
10846 continue;
10847 }
10848 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
10849 continue;
10850 }
10851 if (sceneSession->GetSessionProperty()->GetDisplayId() != screenId) {
10852 continue;
10853 }
10854 if (isPcOrPadFreeMultiWindowMode) {
10855 if (sceneSession->IsLayoutFullScreen()) {
10856 return true;
10857 }
10858 continue;
10859 }
10860 auto sysBarProperty = sceneSession->GetSessionProperty()->GetSystemBarProperty();
10861 if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
10862 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s window is immersive. id: %{public}d", where,
10863 sceneSession->GetPersistentId());
10864 return true;
10865 } else {
10866 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s statusBar is enabled. id: %{public}d", where,
10867 sceneSession->GetPersistentId());
10868 break;
10869 }
10870 }
10871 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s not immersive", where);
10872 return false;
10873 }, __func__);
10874 }
10875
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)10876 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
10877 bool withAnimation)
10878 {
10879 session->NotifySessionForeground(reason, withAnimation);
10880 }
10881
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)10882 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
10883 bool withAnimation, bool isFromInnerkits)
10884 {
10885 session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
10886 }
10887
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)10888 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
10889 {
10890 auto sceneSession = GetSceneSession(persistentId);
10891 if (sceneSession == nullptr) {
10892 TLOGE(WmsLogTag::DEFAULT, "could not find window, persistentId:%{public}d", persistentId);
10893 return WSError::WS_ERROR_INVALID_WINDOW;
10894 }
10895 return sceneSession->UpdateTitleInTargetPos(isShow, height);
10896 }
10897
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)10898 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
10899 {
10900 TLOGI(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStarted");
10901 if (debugInfos.empty()) {
10902 TLOGE(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStarted debugInfos is empty");
10903 return;
10904 }
10905 }
10906
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)10907 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
10908 {
10909 TLOGI(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStoped");
10910 if (debugInfos.empty()) {
10911 TLOGE(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStoped debugInfos is empty");
10912 return;
10913 }
10914 }
10915
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)10916 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
10917 {
10918 if (!Session::IsScbCoreEnabled()) {
10919 return;
10920 }
10921 if (onFlushUIParamsFunc_ != nullptr) {
10922 onFlushUIParamsFunc_();
10923 }
10924 taskScheduler_->PostAsyncTask([this, screenId, uiParams = std::move(uiParams)]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
10925 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
10926 TLOGND(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
10927 {
10928 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
10929 nextFlushCompletedCV_.notify_all();
10930 }
10931 std::vector<uint32_t> startingAppZOrderList;
10932 processingFlushUIParams_.store(true);
10933 {
10934 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10935 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10936 if (sceneSession == nullptr) {
10937 continue;
10938 }
10939 if (sceneSession->GetSessionInfo().screenId_ != screenId) {
10940 continue;
10941 }
10942 if (auto iter = uiParams.find(sceneSession->GetPersistentId()); iter != uiParams.end()) {
10943 if ((systemConfig_.IsPhoneWindow() ||
10944 (systemConfig_.IsPadWindow() && !systemConfig_.IsFreeMultiWindowMode())) &&
10945 sceneSession->GetStartingBeforeVisible() && sceneSession->IsAppSession()) {
10946 startingAppZOrderList.push_back(iter->second.zOrder_);
10947 sceneSession->SetStartingBeforeVisible(false);
10948 }
10949 sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
10950 } else {
10951 sessionMapDirty_ |= sceneSession->UpdateUIParam();
10952 }
10953 }
10954 }
10955 processingFlushUIParams_.store(false);
10956
10957 // post process if dirty
10958 if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
10959 static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
10960 TLOGND(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
10961 for (const auto& item : uiParams) {
10962 TLOGND(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f,"
10963 " transY:%{public}f, needSync:%{public}d, interactive:%{public}d", item.first, item.second.zOrder_,
10964 item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
10965 item.second.needSync_, item.second.interactive_);
10966 }
10967 ProcessUpdateLastFocusedAppId(startingAppZOrderList);
10968 ProcessFocusZOrderChange(sessionMapDirty_);
10969 PostProcessFocus();
10970 PostProcessProperty(sessionMapDirty_);
10971 NotifyAllAccessibilityInfo();
10972 AnomalyDetection::SceneZOrderCheckProcess();
10973 } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
10974 PostProcessProperty(sessionMapDirty_);
10975 }
10976 FlushWindowInfoToMMI();
10977 sessionMapDirty_ = 0;
10978 {
10979 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10980 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10981 if (sceneSession == nullptr) {
10982 continue;
10983 }
10984 sceneSession->ResetSizeChangeReasonIfDirty();
10985 sceneSession->ResetDirtyFlags();
10986 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10987 sceneSession->SetUIStateDirty(false);
10988 }
10989 }
10990 }
10991 }, __func__);
10992 }
10993
ProcessUpdateLastFocusedAppId(const std::vector<uint32_t> & zOrderList)10994 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<uint32_t>& zOrderList)
10995 {
10996 auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
10997 if (focusGroup == nullptr) {
10998 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
10999 return;
11000 }
11001 auto lastFocusedAppSessionId = focusGroup->GetLastFocusedAppSessionId();
11002 TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu",
11003 lastFocusedAppSessionId, zOrderList.size());
11004 if (lastFocusedAppSessionId == INVALID_SESSION_ID || zOrderList.empty()) {
11005 return;
11006 }
11007 auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId);
11008 if (lastFocusedAppSession == nullptr) {
11009 return;
11010 }
11011 uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
11012 auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder](uint32_t zOrder) {
11013 return zOrder > lastFocusedAppZOrder;
11014 });
11015 if (it != zOrderList.end()) {
11016 TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
11017 focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
11018 }
11019 }
11020
ProcessFocusZOrderChange(uint32_t dirty)11021 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
11022 {
11023 if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
11024 return;
11025 }
11026 if (!systemConfig_.IsPhoneWindow() && !systemConfig_.IsPadWindow()) {
11027 return;
11028 }
11029 TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
11030 auto focusedSessionId = GetFocusedSessionId(DEFAULT_DISPLAY_ID);
11031 auto focusedSession = GetSceneSession(focusedSessionId);
11032 // only when it's from a high zOrder to a low zOrder
11033 if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
11034 focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
11035 return;
11036 }
11037 auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
11038 if (voiceInteractionSession == nullptr) {
11039 return;
11040 }
11041 TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
11042 "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
11043 voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
11044 if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
11045 focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
11046 return;
11047 }
11048 RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
11049 }
11050
PostProcessFocus()11051 void SceneSessionManager::PostProcessFocus()
11052 {
11053 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
11054 // priority process focus requests from top to bottom
11055 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
11056 {
11057 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11058 for (auto& iter : sceneSessionMap_) {
11059 auto session = iter.second;
11060 if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
11061 continue;
11062 }
11063 processingSessions.push_back(iter);
11064 }
11065 }
11066 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
11067 bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
11068 !rhs.second->GetPostProcessFocusState().isFocused_;
11069 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
11070 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
11071 return focusCmp || lhsZOrder > rhsZOrder;
11072 };
11073 std::sort(processingSessions.begin(), processingSessions.end(), cmp);
11074
11075 // only change focus one time
11076 std::unordered_set<DisplayId> focusChangedSet;
11077 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
11078 auto session = iter->second;
11079 if (session == nullptr) {
11080 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
11081 continue;
11082 }
11083 auto displayId = session->GetSessionProperty()->GetDisplayId();
11084 auto displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
11085 TLOGD(WmsLogTag::WMS_PIPELINE,
11086 "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
11087 session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
11088 session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
11089 if (focusChangedSet.find(displayGroupId) != focusChangedSet.end()) {
11090 session->ResetPostProcessFocusState();
11091 continue;
11092 }
11093 if (!session->IsFocusedOnShow() &&
11094 (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP ||
11095 session->GetPostProcessFocusState().reason_ == FocusChangeReason::FOREGROUND)) {
11096 if (IsSessionVisibleForeground(session)) {
11097 session->SetFocusedOnShow(true);
11098 }
11099 session->ResetPostProcessFocusState();
11100 continue;
11101 }
11102
11103 WSError ret = WSError::WS_DO_NOTHING;
11104 if (session->GetPostProcessFocusState().isFocused_) {
11105 if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
11106 ret = RequestSessionFocusImmediately(session->GetPersistentId());
11107 } else if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::RECENT) {
11108 ret = RequestSessionFocus(session->GetPersistentId(),
11109 session->GetPostProcessFocusState().byForeground_,
11110 session->GetPostProcessFocusState().reason_);
11111 } else {
11112 ret = RequestSessionFocus(session->GetPersistentId(), true,
11113 session->GetPostProcessFocusState().reason_);
11114 }
11115 } else {
11116 ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
11117 }
11118 session->ResetPostProcessFocusState();
11119 // if succeed then end process
11120 if (ret == WSError::WS_OK) {
11121 focusChangedSet.insert(displayGroupId);
11122 }
11123 }
11124 }
11125
PostProcessProperty(uint32_t dirty)11126 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
11127 {
11128 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
11129 if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
11130 // only trigger update avoid area
11131 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11132 for (auto& iter : sceneSessionMap_) {
11133 auto session = iter.second;
11134 if (session == nullptr) {
11135 continue;
11136 }
11137 session->PostProcessNotifyAvoidArea();
11138 }
11139 return;
11140 }
11141
11142 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
11143 {
11144 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11145 for (auto& iter : sceneSessionMap_) {
11146 auto session = iter.second;
11147 if (session == nullptr || !session->GetPostProcessProperty()) {
11148 continue;
11149 }
11150 processingSessions.push_back(iter);
11151 }
11152 }
11153
11154 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
11155 auto session = iter->second;
11156 if (session == nullptr) {
11157 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
11158 continue;
11159 }
11160 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
11161 UpdateForceHideState(session, session->GetSessionProperty(), true);
11162 HandleKeepScreenOn(session, session->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX, session->keepScreenLock_);
11163 HandleKeepScreenOn(session, session->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
11164 session->viewKeepScreenLock_);
11165 UpdatePrivateStateAndNotify(session->GetPersistentId());
11166 if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
11167 ProcessSubSessionForeground(session);
11168 }
11169 session->SetPostProcessProperty(false);
11170 }
11171
11172 // update avoid area
11173 {
11174 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11175 for (auto& iter : sceneSessionMap_) {
11176 auto session = iter.second;
11177 if (session == nullptr) {
11178 continue;
11179 }
11180 session->PostProcessNotifyAvoidArea();
11181 }
11182 }
11183 }
11184
11185 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)11186 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
11187 {
11188 TLOGI(WmsLogTag::WMS_HIERARCHY, "id %{public}d", persistentId);
11189 auto isSaCall = SessionPermission::IsSACalling();
11190 if (!isSaCall) {
11191 TLOGE(WmsLogTag::WMS_HIERARCHY, "The interface only support for sa call");
11192 return WSError::WS_ERROR_INVALID_PERMISSION;
11193 }
11194 auto task = [this, persistentId]() {
11195 auto sceneSession = GetSceneSession(persistentId);
11196 if (sceneSession == nullptr) {
11197 TLOGNE(WmsLogTag::WMS_HIERARCHY, "session is nullptr");
11198 return WSError::WS_ERROR_INVALID_SESSION;
11199 }
11200 if (!IsSessionVisibleForeground(sceneSession)) {
11201 TLOGND(WmsLogTag::WMS_HIERARCHY, "session is not visible!");
11202 return WSError::WS_DO_NOTHING;
11203 }
11204 FocusChangeReason reason = FocusChangeReason::MOVE_UP;
11205 RequestSessionFocus(persistentId, true, reason);
11206 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
11207 sceneSession->RaiseToAppTop();
11208 }
11209 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
11210 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
11211 TLOGND(WmsLogTag::WMS_HIERARCHY, "parent session id: %{public}d", sceneSession->GetParentPersistentId());
11212 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
11213 }
11214 if (sceneSession == nullptr) {
11215 TLOGNE(WmsLogTag::WMS_HIERARCHY, "parent session is nullptr");
11216 return WSError::WS_ERROR_INVALID_SESSION;
11217 }
11218 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
11219 sceneSession->NotifyClick(true, false);
11220 return WSError::WS_OK;
11221 } else {
11222 TLOGNE(WmsLogTag::WMS_HIERARCHY, "session is not app main window!");
11223 return WSError::WS_ERROR_INVALID_SESSION;
11224 }
11225 };
11226 taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
11227 return WSError::WS_OK;
11228 }
11229
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)11230 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
11231 {
11232 TLOGI(WmsLogTag::WMS_FOCUS, "from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
11233 sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
11234 if (sourceSession == nullptr) {
11235 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr, id: %{public}d", sourcePersistentId);
11236 return WSError::WS_ERROR_INVALID_SESSION;
11237 }
11238 auto displayId = sourceSession->GetSessionProperty()->GetDisplayId();
11239 auto focusedSessionId = GetFocusedSessionId(displayId);
11240 if (sourcePersistentId != focusedSessionId) {
11241 TLOGE(WmsLogTag::WMS_FOCUS, "source session need be focused, focusedSessionId: %{public}d", focusedSessionId);
11242 return WSError::WS_ERROR_INVALID_OPERATION;
11243 }
11244 if (targetPersistentId == focusedSessionId) {
11245 TLOGE(WmsLogTag::WMS_FOCUS, "target session has been focused, focusedSessionId: %{public}d", focusedSessionId);
11246 return WSError::WS_DO_NOTHING;
11247 }
11248 WSError ret = GetAppMainSceneSession(sourcePersistentId, sourceSession);
11249 if (ret != WSError::WS_OK) {
11250 return ret;
11251 }
11252 sptr<SceneSession> targetSession = nullptr;
11253 ret = GetAppMainSceneSession(targetPersistentId, targetSession);
11254 if (ret != WSError::WS_OK) {
11255 return ret;
11256 }
11257 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
11258 TLOGE(WmsLogTag::WMS_FOCUS, "verify bundle failed, source name is %{public}s but target name is %{public}s)",
11259 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
11260 return WSError::WS_ERROR_INVALID_CALLING;
11261 }
11262 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
11263 return WSError::WS_ERROR_INVALID_CALLING;
11264 }
11265 int32_t callingPid = IPCSkeleton::GetCallingPid();
11266 if (callingPid != targetSession->GetCallingPid()) {
11267 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
11268 return WSError::WS_ERROR_INVALID_CALLING;
11269 }
11270 targetSession->NotifyClick(true, false);
11271 FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
11272 return RequestSessionFocus(targetPersistentId, false, reason);
11273 }
11274
GetAppMainSceneSession(int32_t persistentId,sptr<SceneSession> & sceneSession)11275 WSError SceneSessionManager::GetAppMainSceneSession(int32_t persistentId, sptr<SceneSession>& sceneSession)
11276 {
11277 sceneSession = GetSceneSession(persistentId);
11278 if (sceneSession == nullptr) {
11279 TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) is nullptr", persistentId);
11280 return WSError::WS_ERROR_INVALID_SESSION;
11281 }
11282 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
11283 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
11284 TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) is not main window or sub window", persistentId);
11285 return WSError::WS_ERROR_INVALID_CALLING;
11286 }
11287 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
11288 if (sceneSession == nullptr) {
11289 TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) parent is nullptr", persistentId);
11290 return WSError::WS_ERROR_INVALID_SESSION;
11291 }
11292 }
11293 return WSError::WS_OK;
11294 }
11295
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)11296 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
11297 const float scaleParam)
11298 {
11299 auto sceneSession = GetSceneSession(persistentId);
11300 if (!sceneSession) {
11301 TLOGE(WmsLogTag::WMS_MAIN, "get scene session is nullptr");
11302 return nullptr;
11303 }
11304
11305 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
11306
11307 bool isPc = systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode();
11308 std::shared_ptr<Media::PixelMap> pixelMap = sceneSession->Snapshot(true, scaleParam, isPc);
11309 if (!pixelMap) {
11310 TLOGI(WmsLogTag::WMS_MAIN, "get local snapshot pixelmap start");
11311 pixelMap = sceneSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
11312 }
11313 return pixelMap;
11314 }
11315
GetSceneSessionMap()11316 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
11317 {
11318 std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
11319 {
11320 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11321 retSceneSessionMap = sceneSessionMap_;
11322 }
11323 EraseIf(retSceneSessionMap, [this](const auto& pair) {
11324 if (pair.second == nullptr) {
11325 return true;
11326 }
11327
11328 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
11329 if (pair.second->IsVisible()) {
11330 return false;
11331 }
11332 return true;
11333 }
11334
11335 if (pair.second->IsSystemInput()) {
11336 return false;
11337 } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
11338 return false;
11339 }
11340
11341 if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
11342 return true;
11343 }
11344 return false;
11345 });
11346 return retSceneSessionMap;
11347 }
11348
NotifyUpdateRectAfterLayout()11349 void SceneSessionManager::NotifyUpdateRectAfterLayout()
11350 {
11351 std::shared_ptr<RSTransaction> rsTransaction = nullptr;
11352 if (auto transactionController = RSSyncTransactionController::GetInstance()) {
11353 rsTransaction = transactionController->GetRSTransaction();
11354 }
11355 auto task = [this, rsTransaction] {
11356 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11357 for (const auto& [_, sceneSession] : sceneSessionMap_) {
11358 if (sceneSession && sceneSession->IsDirtyWindow()) {
11359 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
11360 }
11361 }
11362 };
11363 // need sync task since animation transcation need
11364 taskScheduler_->PostAsyncTask(task, __func__);
11365 }
11366
ListWindowInfo(const WindowInfoOption & windowInfoOption,std::vector<sptr<WindowInfo>> & infos)11367 WMError SceneSessionManager::ListWindowInfo(const WindowInfoOption& windowInfoOption,
11368 std::vector<sptr<WindowInfo>>& infos)
11369 {
11370 if (!(SessionPermission::IsSACalling())) {
11371 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied");
11372 return WMError::WM_ERROR_INVALID_PERMISSION;
11373 }
11374 return taskScheduler_->PostSyncTask([this, windowInfoOption, &infos] {
11375 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11376 for (const auto& [_, sceneSession] : sceneSessionMap_) {
11377 if (sceneSession == nullptr) {
11378 continue;
11379 }
11380 if (!FilterForListWindowInfo(windowInfoOption, sceneSession)) {
11381 continue;
11382 }
11383 auto windowInfo = sptr<WindowInfo>::MakeSptr();
11384 if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_UI_INFO)) {
11385 windowInfo->windowUIInfo = sceneSession->GetWindowUIInfoForWindowInfo();
11386 }
11387 if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_DISPLAY_INFO)) {
11388 windowInfo->windowDisplayInfo = sceneSession->GetWindowDisplayInfoForWindowInfo();
11389 }
11390 if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_LAYOUT_INFO)) {
11391 windowInfo->windowLayoutInfo = sceneSession->GetWindowLayoutInfoForWindowInfo();
11392 }
11393 if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_META_INFO)) {
11394 windowInfo->windowMetaInfo = sceneSession->GetWindowMetaInfoForWindowInfo();
11395 }
11396 infos.emplace_back(windowInfo);
11397 }
11398 return WMError::WM_OK;
11399 }, __func__);
11400 }
11401
FilterForListWindowInfo(const WindowInfoOption & windowInfoOption,const sptr<SceneSession> & sceneSession) const11402 bool SceneSessionManager::FilterForListWindowInfo(const WindowInfoOption& windowInfoOption,
11403 const sptr<SceneSession>& sceneSession) const
11404 {
11405 DisplayId displayId = windowInfoOption.displayId;
11406 if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(sceneSession->GetSessionProperty()->GetDisplayId())) {
11407 if (displayId == DEFAULT_DISPLAY_ID && sceneSession->GetSessionGlobalRect().posY_ >= GetFoldLowerScreenPosY()) {
11408 return false;
11409 }
11410 if (displayId == VIRTUAL_DISPLAY_ID) {
11411 if (sceneSession->GetSessionGlobalRect().posY_ +
11412 sceneSession->GetSessionGlobalRect().height_ < GetFoldLowerScreenPosY()) {
11413 return false;
11414 }
11415 displayId = DEFAULT_DISPLAY_ID;
11416 }
11417 }
11418 if (displayId != DISPLAY_ID_INVALID && sceneSession->GetSessionProperty()->GetDisplayId() != displayId) {
11419 return false;
11420 }
11421 if (windowInfoOption.windowId != 0 && sceneSession->GetWindowId() !=windowInfoOption.windowId) {
11422 return false;
11423 }
11424 if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::EXCLUDE_SYSTEM) &&
11425 sceneSession->GetSessionInfo().isSystem_) {
11426 return false;
11427 }
11428 if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::VISIBLE) &&
11429 (sceneSession->GetVisibilityState() == WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION ||
11430 sceneSession->GetVisibilityState() == WINDOW_LAYER_STATE_MAX)) {
11431 return false;
11432 }
11433 if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::FOREGROUND) &&
11434 !IsSessionVisibleForeground(sceneSession)) {
11435 return false;
11436 }
11437 return true;
11438 }
11439
GetAllWindowLayoutInfo(DisplayId displayId,std::vector<sptr<WindowLayoutInfo>> & infos)11440 WMError SceneSessionManager::GetAllWindowLayoutInfo(DisplayId displayId,
11441 std::vector<sptr<WindowLayoutInfo>>& infos)
11442 {
11443 auto task = [this, displayId, &infos]() mutable {
11444 bool isVirtualDisplay = false;
11445 if (displayId == VIRTUAL_DISPLAY_ID) {
11446 displayId = DEFAULT_DISPLAY_ID;
11447 isVirtualDisplay = true;
11448 }
11449 std::vector<sptr<SceneSession>> filteredSessions;
11450 FilterForGetAllWindowLayoutInfo(displayId, isVirtualDisplay, filteredSessions);
11451 for (const auto& session : filteredSessions) {
11452 Rect globalScaledRect;
11453 session->GetGlobalScaledRect(globalScaledRect);
11454 if (isVirtualDisplay) {
11455 globalScaledRect.posY_ -= GetFoldLowerScreenPosY();
11456 }
11457 auto windowLayoutInfo = sptr<WindowLayoutInfo>::MakeSptr();
11458 windowLayoutInfo->rect = globalScaledRect;
11459 infos.emplace_back(windowLayoutInfo);
11460 }
11461 return WMError::WM_OK;
11462 };
11463 return taskScheduler_->PostSyncTask(task, __func__);
11464 }
11465
FilterForGetAllWindowLayoutInfo(DisplayId displayId,bool isVirtualDisplay,std::vector<sptr<SceneSession>> & filteredSessions)11466 void SceneSessionManager::FilterForGetAllWindowLayoutInfo(DisplayId displayId, bool isVirtualDisplay,
11467 std::vector<sptr<SceneSession>>& filteredSessions)
11468 {
11469 {
11470 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11471 for (const auto& [_, session] : sceneSessionMap_) {
11472 if (session == nullptr) {
11473 continue;
11474 }
11475 if (session->GetSessionGlobalRect().IsInvalid()) {
11476 continue;
11477 }
11478 if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(session->GetSessionProperty()->GetDisplayId()) &&
11479 displayId == DEFAULT_DISPLAY_ID) {
11480 if (isVirtualDisplay &&
11481 session->GetSessionRect().posY_ + session->GetSessionRect().height_ < GetFoldLowerScreenPosY()) {
11482 continue;
11483 }
11484 if (!isVirtualDisplay && session->GetSessionRect().posY_ >= GetFoldLowerScreenPosY()) {
11485 continue;
11486 }
11487 }
11488 if (IsGetWindowLayoutInfoNeeded(session) && session->GetSessionProperty()->GetDisplayId() == displayId &&
11489 session->GetVisibilityState() != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11490 filteredSessions.emplace_back(session);
11491 }
11492 }
11493 }
11494 std::sort(filteredSessions.begin(), filteredSessions.end(),
11495 [](const sptr<SceneSession>& lhs, const sptr<SceneSession>& rhs) {
11496 return lhs->GetZOrder() > rhs->GetZOrder();
11497 });
11498 }
11499
GetFoldLowerScreenPosY() const11500 int32_t SceneSessionManager::GetFoldLowerScreenPosY() const
11501 {
11502 const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
11503 PcFoldScreenManager::GetInstance().GetDisplayRects();
11504 constexpr int32_t SUPER_FOLD_DIVIDE_FACTOR = 2;
11505 return foldCreaseRect.height_ != 0 ?
11506 defaultDisplayRect.height_ - foldCreaseRect.height_ / SUPER_FOLD_DIVIDE_FACTOR + foldCreaseRect.height_ :
11507 defaultDisplayRect.height_;
11508 }
11509
IsGetWindowLayoutInfoNeeded(const sptr<SceneSession> & session) const11510 bool SceneSessionManager::IsGetWindowLayoutInfoNeeded(const sptr<SceneSession>& session) const
11511 {
11512 constexpr int32_t GROUP_ONE = 1;
11513 std::string name = session->GetWindowName();
11514 std::regex pattern("^(.*?)(\\d*)$"); // Remove last digit
11515 std::smatch matches;
11516 name = std::regex_search(name, matches, pattern) ? matches[GROUP_ONE] : name;
11517 return !session->GetSessionInfo().isSystem_ || LAYOUT_INFO_WHITELIST.find(name) != LAYOUT_INFO_WHITELIST.end();
11518 }
11519
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)11520 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
11521 {
11522 if (!SessionPermission::IsSystemCalling() &&
11523 !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_VISIBLE_WINDOW_INFO)) {
11524 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
11525 return WMError::WM_ERROR_INVALID_PERMISSION;
11526 }
11527 auto task = [this, &infos]() {
11528 for (auto [surfaceId, _] : lastVisibleData_) {
11529 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11530 if (session == nullptr) {
11531 continue;
11532 }
11533 WSRect hostRect = session->GetSessionRect();
11534 Rect rect = {hostRect.posX_, hostRect.posY_,
11535 static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
11536 auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
11537 session->GetSessionProperty());
11538 auto windowVisibilityInfo = sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
11539 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
11540 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_,
11541 session->IsFocused());
11542 windowVisibilityInfo->SetAppIndex(session->GetSessionInfo().appIndex_);
11543 windowVisibilityInfo->SetIsSystem(session->GetSessionInfo().isSystem_);
11544 infos.emplace_back(windowVisibilityInfo);
11545 }
11546 return WMError::WM_OK;
11547 };
11548 return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
11549 }
11550
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)11551 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
11552 {
11553 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11554 for (const auto& [id, session] : sceneSessionMap_) {
11555 if (session == nullptr) {
11556 continue;
11557 }
11558 uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
11559 windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
11560 }
11561 }
11562
FlushWindowInfoToMMI(const bool forceFlush)11563 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
11564 {
11565 auto task = [this, forceFlush] {
11566 if (isUserBackground_) {
11567 TLOGND(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
11568 return;
11569 }
11570 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
11571 SceneInputManager::GetInstance().ResetSessionDirty();
11572 auto [windowInfoList, pixelMapList] = SceneInputManager::GetInstance().GetFullWindowInfoList();
11573 TLOGND(WmsLogTag::WMS_EVENT, "windowInfoList size: %{public}d", static_cast<int32_t>(windowInfoList.size()));
11574 if (windowInfoList.empty()) {
11575 std::ostringstream oss;
11576 oss << "windowInfoList flush to MMI is empty!";
11577 int32_t ret = WindowInfoReporter::GetInstance().ReportEventDispatchException(
11578 static_cast<int32_t>(WindowDFXHelperType::WINDOW_FLUSH_EMPTY_WINDOW_INFO_TO_MMI_EXCEPTION),
11579 getpid(), oss.str()
11580 );
11581 if (ret != 0) {
11582 TLOGNI(WmsLogTag::WMS_EVENT, "ReportEventDispatchException message failed, ret: %{public}d", ret);
11583 }
11584 }
11585 SceneInputManager::GetInstance().
11586 FlushDisplayInfoToMMI(std::move(windowInfoList), std::move(pixelMapList), forceFlush);
11587 };
11588 TLOGD(WmsLogTag::WMS_EVENT, "in");
11589 taskScheduler_->PostAsyncTask(task, __func__);
11590 }
11591
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string & taskName,const int delayTime)11592 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask&& task,
11593 const std::string& taskName, const int delayTime)
11594 {
11595 taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
11596 }
11597
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)11598 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
11599 int32_t& parentId)
11600 {
11601 // This function should be called in task
11602 auto iter = extSessionInfoMap_.find(token);
11603 if (iter == extSessionInfoMap_.end()) {
11604 return false;
11605 }
11606 persistentId = iter->second.persistentId;
11607 parentId = iter->second.parentId;
11608 return true;
11609 }
11610
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession,bool isConstrainedModal)11611 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession, bool isConstrainedModal)
11612 {
11613 const char* const where = __func__;
11614 auto task = [this, remoteExtSession, isConstrainedModal, where]() {
11615 auto iter = remoteExtSessionMap_.find(remoteExtSession);
11616 if (iter == remoteExtSessionMap_.end()) {
11617 TLOGNI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
11618 return;
11619 }
11620 int32_t persistentId = INVALID_SESSION_ID;
11621 int32_t parentId = INVALID_SESSION_ID;
11622 auto abilityToken = iter->second;
11623 if (!GetExtensionWindowIds(abilityToken, persistentId, parentId)) {
11624 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
11625 return;
11626 }
11627
11628 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: persistentId=%{public}d, parentId=%{public}d",
11629 where, persistentId, parentId);
11630 auto sceneSession = GetSceneSession(parentId);
11631 if (sceneSession != nullptr) {
11632 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
11633 sceneSession->RemoveExtWindowFlags(persistentId);
11634 if (oldFlags.hideNonSecureWindowsFlag) {
11635 HandleSecureSessionShouldHide(sceneSession);
11636 }
11637 if (oldFlags.waterMarkFlag) {
11638 CheckAndNotifyWaterMarkChangedResult();
11639 }
11640 if (oldFlags.privacyModeFlag) {
11641 UpdatePrivateStateAndNotify(parentId);
11642 }
11643 if (!isConstrainedModal) {
11644 sceneSession->RemoveNormalModalUIExtension(persistentId);
11645 }
11646 sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
11647 sceneSession->RemoveExtensionTokenInfo(abilityToken);
11648 } else {
11649 ExtensionWindowFlags actions;
11650 actions.SetAllActive();
11651 HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
11652 }
11653 extSessionInfoMap_.erase(iter->second);
11654 remoteExtSessionMap_.erase(iter);
11655 };
11656 taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
11657 }
11658
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)11659 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
11660 {
11661 auto pid = IPCSkeleton::GetCallingRealPid();
11662 const char* const where = __func__;
11663 auto task = [this, token, pid, rect, where]() {
11664 int32_t persistentId = INVALID_SESSION_ID;
11665 int32_t parentId = INVALID_SESSION_ID;
11666 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
11667 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
11668 return;
11669 }
11670 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid=%{public}d, persistentId=%{public}d, "
11671 "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
11672 where, pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
11673 auto parentSession = GetSceneSession(parentId);
11674 if (parentSession) {
11675 auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetClientRect().posX_;
11676 auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetClientRect().posY_;
11677 Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
11678 ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect, rect, true };
11679 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid: %{public}d, persistentId: %{public}d, "
11680 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
11681 where, pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
11682 parentSession->GetSessionGlobalRect().ToString().c_str());
11683 parentSession->UpdateNormalModalUIExtension(extensionInfo);
11684 }
11685 };
11686 taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
11687 }
11688
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)11689 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
11690 {
11691 auto pid = IPCSkeleton::GetCallingRealPid();
11692 const char* const where = __func__;
11693 auto task = [this, token, pid, posX, posY, where]() {
11694 int32_t persistentId = INVALID_SESSION_ID;
11695 int32_t parentId = INVALID_SESSION_ID;
11696 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
11697 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
11698 return;
11699 }
11700 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid=%{public}d, persistentId=%{public}d, "
11701 "parentId=%{public}d", where, pid, persistentId, parentId);
11702 auto parentSession = GetSceneSession(parentId);
11703 if (parentSession) {
11704 auto modalUIExtensionEventInfo = parentSession->GetLastModalUIExtensionEventInfo();
11705 if (modalUIExtensionEventInfo && modalUIExtensionEventInfo.value().pid == pid &&
11706 modalUIExtensionEventInfo.value().persistentId == persistentId) {
11707 parentSession->ProcessPointDownSession(posX, posY);
11708 }
11709 }
11710 };
11711 taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
11712 }
11713
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId,bool isConstrainedModal)11714 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
11715 const sptr<IRemoteObject>& token, uint64_t surfaceNodeId, bool isConstrainedModal)
11716 {
11717 auto pid = IPCSkeleton::GetCallingRealPid();
11718 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
11719 const char* const where = __func__;
11720 auto task = [this, sessionStage, token, surfaceNodeId, isConstrainedModal, pid, callingTokenId, where]() {
11721 if (sessionStage == nullptr || token == nullptr) {
11722 TLOGNE(WmsLogTag::WMS_UIEXT, "input is nullptr");
11723 return;
11724 }
11725 auto remoteExtSession = sessionStage->AsObject();
11726 if (remoteExtSession == nullptr) {
11727 TLOGNE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
11728 return;
11729 }
11730 if (extensionDeath_ == nullptr) {
11731 TLOGNE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
11732 return;
11733 }
11734 if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
11735 TLOGNE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
11736 return;
11737 }
11738
11739 AAFwk::UIExtensionSessionInfo info;
11740 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
11741 if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
11742 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
11743 return;
11744 }
11745
11746 int32_t persistentId = info.persistentId;
11747 int32_t parentId = static_cast<int32_t>(info.hostWindowId);
11748 UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
11749 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: persistentId=%{public}d, parentId=%{public}d, "
11750 "usage=%{public}u, surfaceNodeId=%{public}" PRIu64 ", pid=%{public}d",
11751 where, persistentId, parentId, usage, surfaceNodeId, pid);
11752
11753 remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
11754 extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
11755
11756 auto parentSession = GetSceneSession(parentId);
11757 if (!parentSession) {
11758 TLOGNI(WmsLogTag::WMS_UIEXT, "no parent session for %{public}d", persistentId);
11759 return;
11760 }
11761
11762 UIExtensionTokenInfo tokenInfo;
11763 tokenInfo.abilityToken = token;
11764 tokenInfo.callingTokenId = callingTokenId;
11765 tokenInfo.canShowOnLockScreen = IsUIExtCanShowOnLockScreen(info.elementName, callingTokenId,
11766 info.extensionAbilityType);
11767 parentSession->AddExtensionTokenInfo(tokenInfo);
11768 parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
11769 if (usage == UIExtensionUsage::MODAL && parentSession->GetCallingPid() != GetPid()) {
11770 ExtensionWindowEventInfo extensionInfo {
11771 .persistentId = persistentId,
11772 .pid = pid,
11773 };
11774 if (!isConstrainedModal) {
11775 parentSession->AddNormalModalUIExtension(extensionInfo);
11776 }
11777 }
11778 };
11779 taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
11780 }
11781
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,bool isConstrainedModal)11782 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
11783 const sptr<IRemoteObject>& token, bool isConstrainedModal)
11784 {
11785 TLOGI(WmsLogTag::WMS_UIEXT, "in");
11786 auto task = [this, sessionStage, token, isConstrainedModal]() {
11787 if (sessionStage == nullptr || token == nullptr) {
11788 TLOGNE(WmsLogTag::WMS_UIEXT, "input is nullptr");
11789 return;
11790 }
11791 auto remoteExtSession = sessionStage->AsObject();
11792 if (remoteExtSession == nullptr) {
11793 TLOGNE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
11794 return;
11795 }
11796 auto iter = remoteExtSessionMap_.find(remoteExtSession);
11797 if (iter == remoteExtSessionMap_.end() || iter->second != token) {
11798 TLOGNE(WmsLogTag::WMS_UIEXT, "token not match");
11799 return;
11800 }
11801
11802 DestroyExtensionSession(remoteExtSession, isConstrainedModal);
11803 };
11804 taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
11805 }
11806
CalculateCombinedExtWindowFlags()11807 void SceneSessionManager::CalculateCombinedExtWindowFlags()
11808 {
11809 // Only correct when each flag is true when active, and once a uiextension is active, the host is active
11810 combinedExtWindowFlags_.bitData = 0;
11811 for (const auto& iter: extWindowFlagsMap_) {
11812 combinedExtWindowFlags_.bitData |= iter.second.bitData;
11813 }
11814 specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
11815 }
11816
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)11817 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
11818 ExtensionWindowFlags actions)
11819 {
11820 auto iter = extWindowFlagsMap_.find(persistentId);
11821 // Each flag is false when inactive, 0 means all flags are inactive
11822 auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
11823 ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
11824 if (newFlags.bitData == 0) {
11825 extWindowFlagsMap_.erase(persistentId);
11826 } else {
11827 extWindowFlagsMap_[persistentId] = newFlags;
11828 }
11829 CalculateCombinedExtWindowFlags();
11830 }
11831
HideNonSecureFloatingWindows()11832 void SceneSessionManager::HideNonSecureFloatingWindows()
11833 {
11834 if (systemConfig_.IsPcWindow()) {
11835 TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't hide");
11836 return;
11837 }
11838 bool shouldHide = false;
11839 {
11840 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11841 for (const auto& iter: sceneSessionMap_) {
11842 auto& session = iter.second;
11843 if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
11844 shouldHide = true;
11845 break;
11846 }
11847 }
11848 }
11849 if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
11850 TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
11851 shouldHide = true;
11852 }
11853 if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
11854 return;
11855 }
11856
11857 shouldHideNonSecureFloatingWindows_.store(shouldHide);
11858 for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
11859 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
11860 session->NotifyForceHideChange(shouldHide);
11861 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
11862 session->GetWindowName().c_str(), persistentId, shouldHide);
11863 }
11864 }
11865 }
11866
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)11867 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
11868 {
11869 // don't let sub-window show when switching secure host window to background
11870 if (!sceneSession->IsSessionForeground()) {
11871 return;
11872 }
11873
11874 auto parentId = sceneSession->GetPersistentId();
11875 bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
11876 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11877 for (const auto& [_, session] : sceneSessionMap_) {
11878 if (!session) {
11879 continue;
11880 }
11881 auto sessionProperty = session->GetSessionProperty();
11882 if (sessionProperty->GetParentPersistentId() != parentId) {
11883 continue;
11884 }
11885 if (SessionHelper::IsNonSecureToUIExtension(sessionProperty->GetWindowType()) &&
11886 !session->IsSystemSpecificSession()) {
11887 session->NotifyForceHideChange(shouldHide);
11888 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
11889 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
11890 }
11891 }
11892 }
11893
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)11894 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
11895 {
11896 if (sceneSession == nullptr) {
11897 TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
11898 return WSError::WS_ERROR_INVALID_SESSION;
11899 }
11900
11901 HideNonSecureFloatingWindows();
11902 HideNonSecureSubWindows(sceneSession);
11903 return WSError::WS_OK;
11904 }
11905
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)11906 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
11907 ExtensionWindowFlags actions)
11908 {
11909 UpdateSpecialExtWindowFlags(persistentId, flags, actions);
11910 if (actions.waterMarkFlag) {
11911 CheckAndNotifyWaterMarkChangedResult();
11912 }
11913 if (actions.hideNonSecureWindowsFlag) {
11914 HideNonSecureFloatingWindows();
11915 }
11916 if (actions.privacyModeFlag) {
11917 UpdatePrivateStateAndNotifyForAllScreens();
11918 }
11919 }
11920
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)11921 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
11922 {
11923 TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
11924 if (!SessionPermission::IsSystemCalling()) {
11925 TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
11926 return WSError::WS_ERROR_NOT_SYSTEM_APP;
11927 }
11928 const auto callingPid = IPCSkeleton::GetCallingRealPid();
11929 const char* const where = __func__;
11930 auto task = [this, persistentId, shouldHide, callingPid, where]() {
11931 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11932 auto iter = sceneSessionMap_.find(persistentId);
11933 if (iter == sceneSessionMap_.end()) {
11934 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: Session with persistentId %{public}d not found",
11935 where, persistentId);
11936 return WSError::WS_ERROR_INVALID_SESSION;
11937 }
11938 auto sceneSession = iter->second;
11939 if (sceneSession == nullptr) {
11940 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: sceneSession is nullptr.", where);
11941 return WSError::WS_ERROR_NULLPTR;
11942 }
11943 if (callingPid != sceneSession->GetCallingPid()) {
11944 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: Permission denied", where);
11945 return WSError::WS_ERROR_INVALID_PERMISSION;
11946 }
11947 sceneSession->SetShouldHideNonSecureWindows(shouldHide);
11948 return HandleSecureSessionShouldHide(sceneSession);
11949 };
11950
11951 taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
11952 return WSError::WS_OK;
11953 }
11954
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const11955 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
11956 {
11957 auto ret = WSError::WS_OK;
11958 bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
11959 if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
11960 actions.hideNonSecureWindowsFlag = false;
11961 actions.waterMarkFlag = false;
11962 TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
11963 ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
11964 }
11965 auto needPrivacyWindow = actions.privacyModeFlag;
11966 if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
11967 actions.privacyModeFlag = false;
11968 TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
11969 ret = WSError::WS_ERROR_INVALID_PERMISSION;
11970 }
11971 return ret;
11972 }
11973
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)11974 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
11975 uint32_t extWindowActions)
11976 {
11977 ExtensionWindowFlags actions(extWindowActions);
11978 auto ret = CheckExtWindowFlagsPermission(actions);
11979 if (actions.bitData == 0) {
11980 return ret;
11981 }
11982
11983 ExtensionWindowFlags flags(extWindowFlags);
11984 const char* const where = __func__;
11985 auto task = [this, token, flags, actions, where]() {
11986 int32_t persistentId = INVALID_SESSION_ID;
11987 int32_t parentId = INVALID_SESSION_ID;
11988 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
11989 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
11990 return WSError::WS_ERROR_INVALID_OPERATION;
11991 }
11992
11993 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: parentId=%{public}d, persistentId=%{public}d, "
11994 "extWindowFlags=%{public}d, actions=%{public}d", where, parentId, persistentId,
11995 flags.bitData, actions.bitData);
11996 auto sceneSession = GetSceneSession(parentId);
11997 if (sceneSession == nullptr) {
11998 TLOGND(WmsLogTag::WMS_UIEXT, "%{public}s: Parent session with persistentId %{public}d not found",
11999 where, parentId);
12000 HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
12001 return WSError::WS_OK;
12002 }
12003
12004 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
12005 sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
12006 auto newFlags = sceneSession->GetCombinedExtWindowFlags();
12007 if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
12008 HandleSecureSessionShouldHide(sceneSession);
12009 }
12010 if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
12011 CheckAndNotifyWaterMarkChangedResult();
12012 }
12013 if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
12014 UpdatePrivateStateAndNotify(parentId);
12015 }
12016 return WSError::WS_OK;
12017 };
12018
12019 taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
12020 return ret;
12021 }
12022
GetHostWindowRect(int32_t hostWindowId,Rect & rect)12023 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
12024 {
12025 TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
12026 if (!SessionPermission::IsSystemCalling()) {
12027 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
12028 return WSError::WS_ERROR_NOT_SYSTEM_APP;
12029 }
12030 auto task = [this, hostWindowId, &rect]() {
12031 auto sceneSession = GetSceneSession(hostWindowId);
12032 if (sceneSession == nullptr) {
12033 TLOGNE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
12034 return WSError::WS_ERROR_INVALID_SESSION;
12035 }
12036 WSRect hostRect = sceneSession->GetSessionRect();
12037 auto currScreenFoldStatus = PcFoldScreenManager::GetInstance().GetScreenFoldStatus();
12038 auto needTransRect = currScreenFoldStatus != SuperFoldStatus::UNKNOWN &&
12039 currScreenFoldStatus != SuperFoldStatus::FOLDED && currScreenFoldStatus != SuperFoldStatus::EXPANDED;
12040 auto isSystemKeyboard = sceneSession->GetSessionProperty() != nullptr &&
12041 sceneSession->GetSessionProperty()->IsSystemKeyboard();
12042 if (!isSystemKeyboard && needTransRect) {
12043 WSRect globalRect = hostRect;
12044 sceneSession->TransformGlobalRectToRelativeRect(hostRect);
12045 TLOGI(WmsLogTag::WMS_UIEXT, "Transform globalRect: %{public}s to relativeRect: %{public}s",
12046 globalRect.ToString().c_str(), hostRect.ToString().c_str());
12047 }
12048 rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
12049 return WSError::WS_OK;
12050 };
12051 taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
12052 return WSError::WS_OK;
12053 }
12054
ReclaimPurgeableCleanMem()12055 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
12056 {
12057 #ifdef MEMMGR_WINDOW_ENABLE
12058 return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
12059 #else
12060 return -1;
12061 #endif
12062 }
12063
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)12064 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
12065 const std::vector<VisibleWindowNumInfo>& currentInfo)
12066 {
12067 if (lastInfo.size() != currentInfo.size()) {
12068 TLOGE(WmsLogTag::DEFAULT, "last and current info is not Same");
12069 return false;
12070 }
12071 int sizeOfLastInfo = static_cast<int>(lastInfo.size());
12072 for (int i = 0; i < sizeOfLastInfo; i++) {
12073 if (lastInfo[i].displayId != currentInfo[i].displayId ||
12074 lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
12075 TLOGE(WmsLogTag::DEFAULT, "last and current visible window num is not Same");
12076 return false;
12077 }
12078 }
12079 return true;
12080 }
12081
CacVisibleWindowNum()12082 void SceneSessionManager::CacVisibleWindowNum()
12083 {
12084 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
12085 {
12086 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12087 sceneSessionMapCopy = sceneSessionMap_;
12088 }
12089 std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
12090 bool isFullScreen = true;
12091 for (const auto& elem : sceneSessionMapCopy) {
12092 auto curSession = elem.second;
12093 if (curSession == nullptr) {
12094 continue;
12095 }
12096 bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
12097 curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
12098 if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
12099 continue;
12100 }
12101
12102 bool isWindowVisible = curSession->GetRSVisible();
12103 if (isWindowVisible) {
12104 auto windowMode = curSession->GetWindowMode();
12105 if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
12106 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
12107 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
12108 isFullScreen = false;
12109 }
12110 int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
12111 auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
12112 [displayId](const VisibleWindowNumInfo& info) {
12113 return (static_cast<int32_t>(info.displayId)) == displayId;
12114 });
12115 if (it == visibleWindowNumInfo.end()) {
12116 visibleWindowNumInfo.push_back({displayId, 1});
12117 } else {
12118 it->visibleWindowNum++;
12119 }
12120 }
12121 }
12122 if (isFullScreen) {
12123 std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
12124 [](auto& info) { info.visibleWindowNum = 1; });
12125 }
12126 std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
12127 if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
12128 SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
12129 lastInfo_ = visibleWindowNumInfo;
12130 }
12131 }
12132
ReportWindowProfileInfos()12133 void SceneSessionManager::ReportWindowProfileInfos()
12134 {
12135 enum class WindowVisibleState : int32_t {
12136 FOCUSBLE = 0,
12137 VISIBLE,
12138 MINIMIZED,
12139 OCCLUSION
12140 };
12141 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
12142 {
12143 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12144 sceneSessionMapCopy = sceneSessionMap_;
12145 }
12146 auto focusWindowId = GetFocusedSessionId();
12147 for (const auto& [_, currSession] : sceneSessionMapCopy) {
12148 if (currSession == nullptr || currSession->GetSessionInfo().isSystem_ ||
12149 currSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
12150 continue;
12151 }
12152 WindowProfileInfo windowProfileInfo;
12153 windowProfileInfo.bundleName = currSession->GetSessionInfo().bundleName_;
12154 windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
12155 currSession->GetSessionProperty()->GetDisplayId());
12156 windowProfileInfo.windowSceneMode = static_cast<int32_t>(currSession->GetWindowMode());
12157 if (focusWindowId == static_cast<int32_t>(currSession->GetWindowId())) {
12158 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
12159 } else if (currSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
12160 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
12161 } else if (!currSession->GetRSVisible()) {
12162 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
12163 } else {
12164 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
12165 }
12166 WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
12167 TLOGD(WmsLogTag::DEFAULT, "bundleName:%{public}s, windowVisibleState:%{public}d, "
12168 "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
12169 windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
12170 windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
12171 }
12172 }
12173
GetCustomDecorHeight(int32_t persistentId)12174 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
12175 {
12176 int32_t height = 0;
12177 auto sceneSession = GetSceneSession(persistentId);
12178 if (sceneSession == nullptr) {
12179 TLOGE(WmsLogTag::WMS_DECOR, "session is invalid, id: %{public}d", persistentId);
12180 return 0;
12181 }
12182 height = sceneSession->GetCustomDecorHeight();
12183 TLOGD(WmsLogTag::WMS_DECOR, "decor height: %{public}d", height);
12184 return height;
12185 }
12186
RemoveFailRecoveredSession()12187 void SceneSessionManager::RemoveFailRecoveredSession()
12188 {
12189 for (const auto persistentId : failRecoveredPersistentIdSet_) {
12190 auto sceneSession = GetSceneSession(persistentId);
12191 if (sceneSession == nullptr) {
12192 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
12193 continue;
12194 }
12195 if (!sceneSession->IsRecovered()) {
12196 TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId=%{public}d", persistentId);
12197 continue;
12198 }
12199 TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId=%{public}d", persistentId);
12200 ExceptionInfo exceptionInfo;
12201 exceptionInfo.needRemoveSession = true;
12202 sceneSession->NotifySessionExceptionInner(SetAbilitySessionInfo(sceneSession), exceptionInfo);
12203 }
12204 failRecoveredPersistentIdSet_.clear();
12205 }
12206
GetDisplayRegion(DisplayId displayId)12207 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
12208 {
12209 if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
12210 return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
12211 }
12212 TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
12213 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
12214 if (display == nullptr) {
12215 TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
12216 return nullptr;
12217 }
12218 auto displayInfo = display->GetDisplayInfo();
12219 if (displayInfo == nullptr) {
12220 TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
12221 return nullptr;
12222 }
12223 int32_t displayWidth = displayInfo->GetWidth();
12224 int32_t displayHeight = displayInfo->GetHeight();
12225 if (displayWidth == 0 || displayHeight == 0) {
12226 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
12227 return nullptr;
12228 }
12229 if (PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
12230 const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
12231 PcFoldScreenManager::GetInstance().GetDisplayRects();
12232 displayHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
12233 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "update display height in pc fold");
12234 }
12235 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
12236 auto region = std::make_shared<SkRegion>(rect);
12237 displayRegionMap_[displayId] = region;
12238 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w=%{public}d, h=%{public}d", displayWidth, displayHeight);
12239 return std::make_shared<SkRegion>(rect);
12240 }
12241
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)12242 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
12243 {
12244 if (displayInfo == nullptr) {
12245 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "update display region failed, displayInfo is nullptr.");
12246 return;
12247 }
12248 auto displayId = displayInfo->GetDisplayId();
12249 int32_t displayWidth = displayInfo->GetWidth();
12250 int32_t displayHeight = displayInfo->GetHeight();
12251 if (displayWidth == 0 || displayHeight == 0) {
12252 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid display size of display: %{public}" PRIu64, displayId);
12253 return;
12254 }
12255 if (PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
12256 const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
12257 PcFoldScreenManager::GetInstance().GetDisplayRects();
12258 displayHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
12259 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "update display height in pc fold");
12260 }
12261 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
12262 auto region = std::make_shared<SkRegion>(rect);
12263 displayRegionMap_[displayId] = region;
12264 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "update display region to w: %{public}d, h: %{public}d",
12265 displayWidth, displayHeight);
12266 }
12267
GetDisplaySizeById(DisplayId displayId,int32_t & displayWidth,int32_t & displayHeight)12268 bool SceneSessionManager::GetDisplaySizeById(DisplayId displayId, int32_t& displayWidth, int32_t& displayHeight)
12269 {
12270 auto region = GetDisplayRegion(displayId);
12271 if (region == nullptr) {
12272 TLOGW(WmsLogTag::WMS_LAYOUT, "failed, displayId:%{public}" PRIu64, displayId);
12273 return false;
12274 }
12275 const SkIRect& rect = region->getBounds();
12276 displayWidth = rect.fRight;
12277 displayHeight = rect.fBottom;
12278 return true;
12279 }
12280
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)12281 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
12282 {
12283 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12284 for (const auto& [_, sceneSession] : sceneSessionMap_) {
12285 if (sceneSession == nullptr) {
12286 continue;
12287 }
12288 if (Session::IsScbCoreEnabled()) {
12289 if (!sceneSession->IsVisibleForAccessibility()) {
12290 continue;
12291 }
12292 } else {
12293 if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
12294 continue;
12295 }
12296 }
12297 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
12298 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
12299 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
12300 continue;
12301 }
12302 if (sceneSession->GetSessionInfo().bundleName_.find("SCBDragScale") != std::string::npos) {
12303 continue;
12304 }
12305 sceneSessionList.push_back(sceneSession);
12306 }
12307 }
12308
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)12309 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
12310 std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
12311 {
12312 for (const auto& sceneSession : sceneSessionList) {
12313 if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
12314 TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
12315 }
12316 }
12317 }
12318
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)12319 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
12320 {
12321 std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
12322 return a->GetZOrder() > b->GetZOrder();
12323 });
12324 std::vector<sptr<SceneSession>> result;
12325 std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
12326 for (const auto& sceneSession : sceneSessionList) {
12327 if (sceneSession == nullptr) {
12328 TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
12329 continue;
12330 }
12331 std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
12332 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
12333 if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
12334 unaccountedSpace = unaccountedSpaceMap[displayId];
12335 } else {
12336 unaccountedSpace = GetDisplayRegion(displayId);
12337 if (unaccountedSpace == nullptr) {
12338 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
12339 continue;
12340 }
12341 unaccountedSpaceMap[displayId] = unaccountedSpace;
12342 }
12343 WSRect wsRect = sceneSession->GetSessionRect();
12344 SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
12345 .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
12346 SkRegion windowRegion(windowBounds);
12347 if (unaccountedSpace->quickReject(windowRegion)) {
12348 TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
12349 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
12350 continue;
12351 }
12352 if (!unaccountedSpace->intersects(windowRegion)) {
12353 TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
12354 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
12355 continue;
12356 }
12357 result.push_back(sceneSession);
12358 unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
12359 if (unaccountedSpace->isEmpty()) {
12360 break;
12361 }
12362 }
12363 sceneSessionList = result;
12364 }
12365
NotifyAllAccessibilityInfo()12366 void SceneSessionManager::NotifyAllAccessibilityInfo()
12367 {
12368 if (isUserBackground_) {
12369 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
12370 return;
12371 }
12372 std::vector<sptr<SceneSession>> sceneSessionList;
12373 GetAllSceneSessionForAccessibility(sceneSessionList);
12374 FilterSceneSessionCovered(sceneSessionList);
12375
12376 std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
12377 FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
12378
12379 for (const auto& item : accessibilityInfo) {
12380 TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid=%{public}d, inWid=%{public}d, "
12381 "bundle=%{public}s,bounds=(x=%{public}d, y=%{public}d, w=%{public}d, h=%{public}d)",
12382 item->wid_, item->innerWid_, item->bundleName_.c_str(),
12383 item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
12384 for (const auto& rect : item->touchHotAreas_) {
12385 TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d,"
12386 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
12387 }
12388 }
12389
12390 SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
12391 WindowUpdateType::WINDOW_UPDATE_ALL);
12392 }
12393
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)12394 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
12395 const sptr<WindowSessionProperty>& property)
12396 {
12397 auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
12398 if (property == nullptr) {
12399 return windowStatus;
12400 }
12401 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
12402 windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
12403 if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
12404 windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
12405 }
12406 } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
12407 windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
12408 } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
12409 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
12410 } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
12411 windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
12412 }
12413 return windowStatus;
12414 }
12415
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)12416 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
12417 {
12418 if (!SessionPermission::IsStartedByInputMethod()) {
12419 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
12420 return WMError::WM_ERROR_INVALID_PERMISSION;
12421 }
12422 auto sceneSession = GetSceneSession(persistentId);
12423 if (sceneSession == nullptr) {
12424 TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is null, persistentId: %{public}d", persistentId);
12425 return WMError::WM_ERROR_NULLPTR;
12426 }
12427 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
12428 auto focusedSessionId = GetFocusedSessionId(displayId);
12429 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
12430 persistentId, sceneSession->GetWindowType());
12431 uint32_t callingWindowId = sceneSession->GetSessionProperty()->GetCallingSessionId();
12432 auto callingSession = GetSceneSession(callingWindowId);
12433 if (callingSession == nullptr) {
12434 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
12435 callingSession = GetSceneSession(focusedSessionId);
12436 if (callingSession == nullptr) {
12437 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
12438 return WMError::WM_ERROR_INVALID_WINDOW;
12439 }
12440 }
12441 if (callingSession->IsSystemSession()) {
12442 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
12443 } else {
12444 windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
12445 callingSession->GetSessionProperty());
12446 }
12447 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
12448 persistentId, windowStatus);
12449 return WMError::WM_OK;
12450 }
12451
GetCallingWindowRect(int32_t persistentId,Rect & rect)12452 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
12453 {
12454 if (!SessionPermission::IsStartedByInputMethod()) {
12455 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
12456 return WMError::WM_ERROR_INVALID_PERMISSION;
12457 }
12458 auto sceneSession = GetSceneSession(persistentId);
12459 if (sceneSession == nullptr) {
12460 TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is null, persistentId: %{public}d", persistentId);
12461 return WMError::WM_ERROR_NULLPTR;
12462 }
12463 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
12464 auto focusedSessionId = GetFocusedSessionId(displayId);
12465 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
12466 persistentId, sceneSession->GetWindowType());
12467 uint32_t callingWindowId = sceneSession->GetSessionProperty()->GetCallingSessionId();
12468 auto callingSession = GetSceneSession(callingWindowId);
12469 if (callingSession == nullptr) {
12470 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
12471 callingSession = GetSceneSession(focusedSessionId);
12472 if (callingSession == nullptr) {
12473 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
12474 return WMError::WM_ERROR_INVALID_WINDOW;
12475 }
12476 }
12477 WSRect sessionRect = callingSession->GetSessionRect();
12478 rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
12479 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
12480 "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
12481 return WMError::WM_OK;
12482 }
12483
GetWindowModeType(WindowModeType & windowModeType)12484 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
12485 {
12486 if (!SessionPermission::IsSACalling()) {
12487 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
12488 return WMError::WM_ERROR_INVALID_PERMISSION;
12489 }
12490 windowModeType = CheckWindowModeType();
12491 return WMError::WM_OK;
12492 }
12493
GetWindowStyleType(WindowStyleType & windowStyleType)12494 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
12495 {
12496 if (!SessionPermission::IsSACalling()) {
12497 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
12498 return WMError::WM_ERROR_INVALID_PERMISSION;
12499 }
12500 if (systemConfig_.IsPcWindow()) {
12501 windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
12502 return WMError::WM_OK;
12503 }
12504 windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
12505 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
12506 return WMError::WM_OK;
12507 }
12508
CheckSceneZOrder()12509 void SceneSessionManager::CheckSceneZOrder()
12510 {
12511 auto task = [this]() {
12512 AnomalyDetection::SceneZOrderCheckProcess();
12513 };
12514 taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
12515 }
12516
NotifyEnterRecentTask(bool enterRecent)12517 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
12518 {
12519 TLOGI(WmsLogTag::WMS_IMMS, "enterRecent %{public}u", enterRecent);
12520 enterRecent_.store(enterRecent);
12521 SetSystemAnimatedScenes(enterRecent ?
12522 SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
12523 auto task = [this] {
12524 for (auto persistentId : gestureBackEnableWindowIdSet_) {
12525 auto sceneSession = GetSceneSession(persistentId);
12526 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
12527 continue;
12528 }
12529 UpdateGestureBackEnabled(persistentId);
12530 }
12531 };
12532 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
12533 return WSError::WS_OK;
12534 }
12535
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)12536 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
12537 {
12538 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
12539 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
12540 return WMError::WM_ERROR_INVALID_PERMISSION;
12541 }
12542
12543 if (!topNInfo.empty() || (topNum <= 0)) {
12544 return WMError::WM_ERROR_INVALID_PARAM;
12545 }
12546
12547 TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
12548 auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
12549 if (session == nullptr) {
12550 return false;
12551 }
12552
12553 if (topNum == 0) {
12554 return true;
12555 }
12556
12557 if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
12558 TLOGND(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
12559 return false;
12560 }
12561
12562 MainWindowInfo info;
12563 info.pid_ = session->GetCallingPid();
12564 info.bundleName_ = session->GetSessionInfo().bundleName_;
12565 topNInfo.push_back(info);
12566 topNum--;
12567 TLOGNE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
12568 topNum, info.pid_, info.bundleName_.c_str());
12569 return false;
12570 };
12571 TraverseSessionTree(func, true);
12572
12573 return WMError::WM_OK;
12574 }
12575
GetCallingWindowInfo(CallingWindowInfo & callingWindowInfo)12576 WMError SceneSessionManager::GetCallingWindowInfo(CallingWindowInfo& callingWindowInfo)
12577 {
12578 int32_t curUserId = GetUserIdByUid(getuid());
12579 if (curUserId != callingWindowInfo.userId_) {
12580 TLOGE(WmsLogTag::WMS_KEYBOARD, "Target user not exists, targetUserId: %{public}d, curUserId: %{public}d, id: %{public}d",
12581 callingWindowInfo.userId_, curUserId, callingWindowInfo.windowId_);
12582 return WMError::WM_ERROR_INVALID_PARAM;
12583 }
12584 auto sceneSession = GetSceneSession(callingWindowInfo.windowId_);
12585 if (sceneSession == nullptr) {
12586 TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is nullptr, id: %{public}d", callingWindowInfo.windowId_);
12587 return WMError::WM_ERROR_NULLPTR;
12588 }
12589 callingWindowInfo.callingPid_ = sceneSession->GetCallingPid();
12590 callingWindowInfo.displayId_ = sceneSession->GetSessionProperty()->GetDisplayId();
12591 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingWindowInfo: [id: %{public}d, pid: %{public}d, "
12592 "displayId: %{public}" PRIu64" , userId: %{public}d]", callingWindowInfo.windowId_,
12593 callingWindowInfo.callingPid_, callingWindowInfo.displayId_, callingWindowInfo.userId_);
12594 return WMError::WM_OK;
12595 }
12596
GetWindowIdsByCoordinate(DisplayId displayId,int32_t windowNumber,int32_t x,int32_t y,std::vector<int32_t> & windowIds)12597 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
12598 int32_t x, int32_t y, std::vector<int32_t>& windowIds)
12599 {
12600 TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
12601 displayId, windowNumber, x, y);
12602 if (displayId == DISPLAY_ID_INVALID) {
12603 TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
12604 return WMError::WM_ERROR_INVALID_PARAM;
12605 }
12606 bool findAllWindow = windowNumber <= 0;
12607 bool checkPoint = (x >= 0 && y >= 0);
12608 std::string callerBundleName = SessionPermission::GetCallingBundleName();
12609 auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
12610 findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
12611 if (session == nullptr) {
12612 return false;
12613 }
12614 if (!findAllWindow && windowNumber == 0) {
12615 return true;
12616 }
12617 bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
12618 bool isSameDisplayId = session->GetSessionProperty()->GetDisplayId() == displayId;
12619 bool isRsVisible = session->GetRSVisible();
12620 WSRect windowRect = session->GetSessionRect();
12621 bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
12622 TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
12623 " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
12624 session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
12625 session->GetSessionProperty()->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
12626 if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
12627 return false;
12628 }
12629 windowIds.emplace_back(session->GetPersistentId());
12630 windowNumber--;
12631 return false;
12632 };
12633 return taskScheduler_->PostSyncTask([this, func = std::move(func)] {
12634 TraverseSessionTree(func, true);
12635 return WMError::WM_OK;
12636 }, __func__);
12637 }
12638
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const12639 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
12640 {
12641 if (!infos.empty()) {
12642 TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
12643 return WMError::WM_ERROR_INVALID_PARAM;
12644 }
12645 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
12646 TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
12647 return WMError::WM_ERROR_INVALID_PERMISSION;
12648 }
12649 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12650 for (const auto& iter : sceneSessionMap_) {
12651 auto& session = iter.second;
12652 if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
12653 continue;
12654 }
12655 MainWindowInfo info;
12656 auto abilityInfo = session->GetSessionInfo().abilityInfo;
12657 info.pid_ = session->GetCallingPid();
12658 info.bundleName_ = session->GetSessionInfo().bundleName_;
12659 info.persistentId_ = session->GetPersistentId();
12660 if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
12661 TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
12662 info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
12663 infos.push_back(info);
12664 } else if (abilityInfo != nullptr) {
12665 info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
12666 infos.push_back(info);
12667 TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
12668 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
12669 info.bundleName_.c_str(), info.bundleType_);
12670 }
12671 }
12672 return WMError::WM_OK;
12673 }
12674
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)12675 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
12676 std::vector<int32_t>& clearFailedIds)
12677 {
12678 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
12679 TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
12680 return WMError::WM_ERROR_INVALID_PERMISSION;
12681 }
12682 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12683 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12684 return WMError::WM_ERROR_INVALID_PERMISSION;
12685 }
12686 clearFailedIds.clear();
12687 for (const auto persistentId : persistentIds) {
12688 auto sceneSession = GetSceneSession(persistentId);
12689 if (sceneSession == nullptr) {
12690 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
12691 clearFailedIds.push_back(persistentId);
12692 continue;
12693 }
12694 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
12695 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
12696 clearFailedIds.push_back(persistentId);
12697 continue;
12698 }
12699 sceneSession->Clear();
12700 TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
12701 }
12702 return WMError::WM_OK;
12703 }
12704
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)12705 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
12706 bool enable)
12707 {
12708 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
12709 width, height, density, enable);
12710
12711 DMHookInfo dmHookInfo;
12712 dmHookInfo.width_ = width;
12713 dmHookInfo.height_ = height;
12714 dmHookInfo.density_ = density;
12715 dmHookInfo.rotation_ = 0;
12716 dmHookInfo.enableHookRotation_ = false;
12717 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
12718 return WMError::WM_OK;
12719 }
12720
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)12721 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
12722 {
12723 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
12724 "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
12725 hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
12726 if (enable && (uid <= 0 || hookInfo.width_ <= 0 || hookInfo.height_ <= 0 || hookInfo.density_ <= 0)) {
12727 TLOGE(WmsLogTag::WMS_LAYOUT, "App hookInfo param error.");
12728 return WMError::WM_ERROR_INVALID_PARAM;
12729 }
12730 DMHookInfo dmHookInfo;
12731 dmHookInfo.width_ = hookInfo.width_;
12732 dmHookInfo.height_ = hookInfo.height_;
12733 dmHookInfo.density_ = hookInfo.density_;
12734 dmHookInfo.rotation_ = hookInfo.rotation_;
12735 dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
12736 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
12737 return WMError::WM_OK;
12738 }
12739
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)12740 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
12741 {
12742 SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
12743 }
12744
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)12745 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
12746 {
12747 ScreenFoldData screenFoldData;
12748 WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
12749 if (ret != WMError::WM_OK) {
12750 return ret;
12751 }
12752 return CheckAndReportScreenFoldStatus(screenFoldData);
12753 }
12754
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)12755 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
12756 ScreenFoldData& screenFoldData)
12757 {
12758 if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
12759 TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
12760 return WMError::WM_DO_NOTHING;
12761 }
12762
12763 screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
12764 screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
12765 screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
12766 screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
12767 screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
12768 if (!screenFoldData.GetTypeCThermalWithUtil()) {
12769 TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
12770 return WMError::WM_DO_NOTHING;
12771 }
12772 AppExecFwk::ElementName element = {};
12773 WSError ret = GetFocusSessionElement(element);
12774 auto sceneSession = GetSceneSession(windowFocusController_->GetFocusedSessionId(DEFAULT_DISPLAY_ID));
12775 if (sceneSession == nullptr || ret != WSError::WS_OK) {
12776 TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
12777 return WMError::WM_DO_NOTHING;
12778 }
12779 screenFoldData.SetFocusedPkgName(element.GetURI());
12780 int32_t ret_z = HiSysEventWrite(
12781 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
12782 "FOCUS_WINDOW",
12783 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
12784 "PID", getpid(),
12785 "UID", getuid(),
12786 "BUNDLE_NAME", sceneSession->GetSessionInfo().bundleName_,
12787 "WINDOW_TYPE", static_cast<uint32_t>(sceneSession->GetWindowType()));
12788 if (ret_z != 0) {
12789 TLOGE(WmsLogTag::DMS, "Write FOCUS_WINDOW HiSysEvent error, ret_z: %{public}d.", ret_z);
12790 }
12791 return WMError::WM_OK;
12792 }
12793
CheckAndReportScreenFoldStatus(ScreenFoldData & data)12794 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
12795 {
12796 static ScreenFoldData lastScreenHalfFoldData;
12797 if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
12798 lastScreenHalfFoldData = data;
12799 return WMError::WM_DO_NOTHING;
12800 }
12801 WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
12802 if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
12803 if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
12804 lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
12805 } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
12806 // if stay at half-fold less than 15s, combine this change with last
12807 data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
12808 data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
12809 data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
12810 }
12811 lastScreenHalfFoldData.SetInvalid();
12812 }
12813 WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
12814 return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
12815 currentScreenFoldStatusReportRet;
12816 }
12817
12818 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)12819 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
12820 {
12821 if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
12822 return WMError::WM_DO_NOTHING;
12823 }
12824
12825 int32_t ret = HiSysEventWrite(
12826 OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
12827 "FOLDSCREEN_STATE_CHANGE",
12828 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
12829 "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
12830 "LASTFOLDSTATE", data.currentScreenFoldStatus_,
12831 "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
12832 "STATE", -1,
12833 "TIME", data.currentScreenFoldStatusDuration_,
12834 "ROTATION", data.screenRotation_,
12835 "PACKAGE", data.focusedPackageName_,
12836 "ANGLE", data.postureAngle_,
12837 "TYPECTHERMAL", data.typeCThermal_,
12838 "SCREENTHERMAL", -1,
12839 "SCANGLE", -1,
12840 "ISTENT", -1);
12841 if (ret != 0) {
12842 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
12843 return WMError::WM_DO_NOTHING;
12844 }
12845 return WMError::WM_OK;
12846 }
12847
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userId)12848 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userId)
12849 {
12850 if (currentUserId_ != static_cast<int32_t>(userId)) {
12851 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
12852 currentUserId_.load(), userId);
12853 return;
12854 }
12855 if (secExtensionData == nullptr) {
12856 TLOGE(WmsLogTag::WMS_EVENT, "invalid secExtensionData");
12857 return;
12858 }
12859 auto secSurfaceInfoMap = secExtensionData->GetSecData();
12860 auto task = [secSurfaceInfoMap]()-> WSError {
12861 SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
12862 return WSError::WS_OK;
12863 };
12864 taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
12865 }
12866
RegisterSecSurfaceInfoListener()12867 void SceneSessionManager::RegisterSecSurfaceInfoListener()
12868 {
12869 auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
12870 this->UpdateSecSurfaceInfo(secExtensionData, userid);
12871 };
12872 TLOGI(WmsLogTag::WMS_EVENT, "in");
12873 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
12874 TLOGE(WmsLogTag::WMS_EVENT, "failed");
12875 }
12876 }
12877
UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,uint64_t userId)12878 void SceneSessionManager::UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,
12879 uint64_t userId)
12880 {
12881 if (currentUserId_ != static_cast<int32_t>(userId)) {
12882 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
12883 currentUserId_.load(), userId);
12884 return;
12885 }
12886 if (constrainedModalUIExtData == nullptr) {
12887 TLOGE(WmsLogTag::WMS_EVENT, "invalid constrainedModalUIExtData");
12888 return;
12889 }
12890 auto constrainedModalUIExtInfoMap = constrainedModalUIExtData->GetSecData();
12891 auto task = [constrainedModalUIExtInfoMap]()-> WSError {
12892 SceneInputManager::GetInstance().UpdateConstrainedModalUIExtInfo(constrainedModalUIExtInfoMap);
12893 return WSError::WS_OK;
12894 };
12895 taskScheduler_->PostAsyncTask(task, "UpdateConstrainedModalUIExtInfo");
12896 }
12897
RegisterConstrainedModalUIExtInfoListener()12898 void SceneSessionManager::RegisterConstrainedModalUIExtInfoListener()
12899 {
12900 auto callBack = [this](std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData, uint64_t userid) {
12901 this->UpdateConstrainedModalUIExtInfo(constrainedModalUIExtData, userid);
12902 };
12903 TLOGI(WmsLogTag::WMS_EVENT, "in");
12904 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack, true) != WM_OK) {
12905 TLOGE(WmsLogTag::WMS_EVENT, "failed");
12906 }
12907 }
12908
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)12909 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
12910 const AppForceLandscapeConfig& config)
12911 {
12912 if (bundleName.empty()) {
12913 TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
12914 return WSError::WS_ERROR_NULLPTR;
12915 }
12916 std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
12917 appForceLandscapeMap_[bundleName] = config;
12918 TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
12919 bundleName.c_str(), config.mode_, config.homePage_.c_str());
12920 return WSError::WS_OK;
12921 }
12922
GetAppForceLandscapeConfig(const std::string & bundleName)12923 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
12924 {
12925 if (bundleName.empty()) {
12926 return {};
12927 }
12928 std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
12929 if (appForceLandscapeMap_.empty() ||
12930 appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
12931 TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
12932 return {};
12933 }
12934 return appForceLandscapeMap_[bundleName];
12935 }
12936
TerminateSessionByPersistentId(int32_t persistentId)12937 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
12938 {
12939 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
12940 TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
12941 return WMError::WM_ERROR_INVALID_PERMISSION;
12942 }
12943 if (!SessionPermission::IsSystemAppCall()) {
12944 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
12945 return WMError::WM_ERROR_NOT_SYSTEM_APP;
12946 }
12947 auto sceneSession = GetSceneSession(persistentId);
12948 if (sceneSession == nullptr) {
12949 TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
12950 return WMError::WM_ERROR_INVALID_PARAM;
12951 }
12952 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
12953 TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
12954 return WMError::WM_ERROR_INVALID_PARAM;
12955 }
12956 sceneSession->Clear(true);
12957 TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
12958 return WMError::WM_OK;
12959 }
12960
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)12961 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
12962 {
12963 rootSceneProcessBackEventFunc_ = processBackEventFunc;
12964 TLOGI(WmsLogTag::WMS_EVENT, "end");
12965 }
12966
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)12967 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
12968 const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
12969 {
12970 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
12971 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The caller has no permission granted.");
12972 return WMError::WM_ERROR_INVALID_PERMISSION;
12973 }
12974
12975 surfaceNodeIds.clear();
12976 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
12977 for (auto persistentId : persistentIds) {
12978 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "convert wid:%{public}d", persistentId);
12979 auto sceneSession = GetSceneSession(persistentId);
12980 if (sceneSession == nullptr) {
12981 continue;
12982 }
12983 auto callingPid = sceneSession->GetCallingPid();
12984 auto surfaceNode = sceneSession->GetSurfaceNode();
12985 if (surfaceNode != nullptr && callingPid == pid) {
12986 surfaceNodeIds.push_back(surfaceNode->GetId());
12987 auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
12988 if (leashWinSurfaceNode != nullptr) {
12989 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
12990 surfaceNodeIds.push_back(persistentId);
12991 }
12992 }
12993 }
12994
12995 return WMError::WM_OK;
12996 }
12997
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)12998 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
12999 {
13000 TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
13001 auto task = [this, func] {
13002 closeTargetFloatWindowFunc_ = func;
13003 };
13004 taskScheduler_->PostTask(task, __func__);
13005 }
13006
CloseTargetFloatWindow(const std::string & bundleName)13007 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
13008 {
13009 if (!SessionPermission::IsSystemServiceCalling(false)) {
13010 TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
13011 return WMError::WM_ERROR_INVALID_PERMISSION;
13012 }
13013 auto task = [this, bundleName] {
13014 if (closeTargetFloatWindowFunc_) {
13015 TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
13016 closeTargetFloatWindowFunc_(bundleName);
13017 }
13018 };
13019 taskScheduler_->PostTask(task, __func__);
13020 return WMError::WM_OK;
13021 }
13022
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)13023 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
13024 {
13025 SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
13026 }
13027
CloseTargetPiPWindow(const std::string & bundleName)13028 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
13029 {
13030 if (!SessionPermission::IsSystemServiceCalling(false)) {
13031 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
13032 return WMError::WM_ERROR_INVALID_PERMISSION;
13033 }
13034 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13035 for (const auto& iter : sceneSessionMap_) {
13036 auto& session = iter.second;
13037 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
13038 session->GetSessionInfo().bundleName_ == bundleName) {
13039 session->NotifyCloseExistPipWindow();
13040 break;
13041 }
13042 }
13043 return WMError::WM_OK;
13044 }
13045
GetCurrentPiPWindowInfo(std::string & bundleName)13046 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
13047 {
13048 if (!SessionPermission::IsSystemServiceCalling(false)) {
13049 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
13050 return WMError::WM_ERROR_INVALID_PERMISSION;
13051 }
13052 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13053 for (const auto& iter : sceneSessionMap_) {
13054 auto& session = iter.second;
13055 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
13056 bundleName = session->GetSessionInfo().bundleName_;
13057 return WMError::WM_OK;
13058 }
13059 }
13060 TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
13061 return WMError::WM_OK;
13062 }
13063
RefreshPcZOrderList(uint32_t startZOrder,std::vector<int32_t> && persistentIds)13064 void SceneSessionManager::RefreshPcZOrderList(uint32_t startZOrder, std::vector<int32_t>&& persistentIds)
13065 {
13066 const char* const where = __func__;
13067 auto task = [this, startZOrder, persistentIds = std::move(persistentIds), where] {
13068 std::ostringstream oss;
13069 oss << "[";
13070 for (size_t i = 0; i < persistentIds.size(); i++) {
13071 int32_t persistentId = persistentIds[i];
13072 oss << persistentId;
13073 if (i < persistentIds.size() - 1) {
13074 oss << ",";
13075 }
13076 auto sceneSession = GetSceneSession(persistentId);
13077 if (sceneSession == nullptr) {
13078 TLOGNE(WmsLogTag::WMS_LAYOUT, "sceneSession is nullptr persistentId=%{public}d", persistentId);
13079 continue;
13080 }
13081 if (i > UINT32_MAX - startZOrder) {
13082 TLOGNE(WmsLogTag::WMS_LAYOUT, "Z order overflow, stop refresh");
13083 break;
13084 }
13085 sceneSession->SetPcScenePanel(true);
13086 sceneSession->UpdatePCZOrderAndMarkDirty(i + startZOrder);
13087 }
13088 oss << "]";
13089 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: %{public}s", where, oss.str().c_str());
13090 return WSError::WS_OK;
13091 };
13092 taskScheduler_->PostTask(task, __func__);
13093 }
13094
SkipSnapshotForAppProcess(int32_t pid,bool skip)13095 WMError SceneSessionManager::SkipSnapshotForAppProcess(int32_t pid, bool skip)
13096 {
13097 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13098 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13099 return WMError::WM_ERROR_INVALID_PERMISSION;
13100 }
13101 if (pid < 0) {
13102 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid pid!");
13103 return WMError::WM_ERROR_INVALID_PARAM;
13104 }
13105 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d, skip:%{public}u", pid, skip);
13106 auto task = [this, pid, skip]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
13107 if (skip) {
13108 snapshotSkipPidSet_.insert(pid);
13109 } else {
13110 snapshotSkipPidSet_.erase(pid);
13111 }
13112 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13113 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
13114 if (sceneSession == nullptr) {
13115 continue;
13116 }
13117 if (pid == sceneSession->GetCallingPid()) {
13118 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "send rs set snapshot skip, persistentId:%{public}d, skip:%{public}u",
13119 persistentId, skip);
13120 sceneSession->SetSnapshotSkip(skip);
13121 }
13122 }
13123 };
13124 taskScheduler_->PostTask(task, "SkipSnapshotForAppProcess");
13125 return WMError::WM_OK;
13126 }
13127
RemoveProcessSnapshotSkip(int32_t pid)13128 void SceneSessionManager::RemoveProcessSnapshotSkip(int32_t pid)
13129 {
13130 if (snapshotSkipPidSet_.erase(pid) != 0) {
13131 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "process died, delete pid from snapshot skip pid set. pid:%{public}d", pid);
13132 }
13133 }
13134
SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession> & sceneSession)13135 void SceneSessionManager::SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession>& sceneSession)
13136 {
13137 auto callingPid = sceneSession->GetCallingPid();
13138 if (snapshotSkipPidSet_.find(callingPid) != snapshotSkipPidSet_.end()) {
13139 sceneSession->SetSnapshotSkip(true);
13140 }
13141 }
13142
SkipSnapshotByUserIdAndBundleNames(int32_t userId,const std::vector<std::string> & bundleNameList)13143 WMError SceneSessionManager::SkipSnapshotByUserIdAndBundleNames(int32_t userId,
13144 const std::vector<std::string>& bundleNameList)
13145 {
13146 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13147 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The caller has no permission granted.");
13148 return WMError::WM_ERROR_INVALID_PERMISSION;
13149 }
13150 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "userId:%{public}d", userId);
13151 auto task = [this, userId, bundleNameList]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
13152 snapshotSkipBundleNameSet_.clear();
13153 for (auto& bundleName : bundleNameList) {
13154 snapshotSkipBundleNameSet_.insert(std::move(bundleName));
13155 }
13156 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13157 for (const auto& [_, sceneSession] : sceneSessionMap_) {
13158 if (sceneSession == nullptr) {
13159 continue;
13160 }
13161 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
13162 if (snapshotSkipBundleNameSet_.find(bundleName) != snapshotSkipBundleNameSet_.end()) {
13163 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "set RS snapshot skip true, name:%{public}s",
13164 bundleName.c_str());
13165 sceneSession->SetSnapshotSkip(true);
13166 continue;
13167 }
13168 sceneSession->SetSnapshotSkip(false);
13169 }
13170 };
13171 taskScheduler_->PostTask(task, __func__);
13172 return WMError::WM_OK;
13173 }
13174
SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession> & sceneSession)13175 void SceneSessionManager::SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession>& sceneSession)
13176 {
13177 const std::string& name = sceneSession->GetSessionInfo().bundleName_;
13178 if (snapshotSkipBundleNameSet_.find(name) != snapshotSkipBundleNameSet_.end()) {
13179 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "set RS snapshot skip true, name:%{public}s",
13180 name.c_str());
13181 sceneSession->SetSnapshotSkip(true);
13182 }
13183 }
13184
SetProcessWatermark(int32_t pid,const std::string & watermarkName,bool isEnabled)13185 WMError SceneSessionManager::SetProcessWatermark(int32_t pid, const std::string& watermarkName, bool isEnabled)
13186 {
13187 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13188 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13189 return WMError::WM_ERROR_INVALID_PERMISSION;
13190 }
13191 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "pid:%{public}d, watermarkName:%{public}s, isEnabled:%{public}u",
13192 pid, watermarkName.c_str(), isEnabled);
13193 if (isEnabled && watermarkName.empty()) {
13194 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "watermarkName is empty!");
13195 return WMError::WM_ERROR_INVALID_PARAM;
13196 }
13197 auto task = [this, pid, watermarkName, isEnabled] {
13198 if (isEnabled) {
13199 processWatermarkPidMap_.insert_or_assign(pid, watermarkName);
13200 } else {
13201 processWatermarkPidMap_.erase(pid);
13202 }
13203
13204 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13205 for (const auto& [_, sceneSession] : sceneSessionMap_) {
13206 if (sceneSession == nullptr) {
13207 continue;
13208 }
13209 if (pid == sceneSession->GetCallingPid()) {
13210 sceneSession->SetWatermarkEnabled(watermarkName, isEnabled);
13211 }
13212 }
13213 };
13214 taskScheduler_->PostTask(task, __func__);
13215 return WMError::WM_OK;
13216 }
13217
SetSessionWatermarkForAppProcess(const sptr<SceneSession> & sceneSession)13218 bool SceneSessionManager::SetSessionWatermarkForAppProcess(const sptr<SceneSession>& sceneSession)
13219 {
13220 if (auto iter = processWatermarkPidMap_.find(sceneSession->GetCallingPid());
13221 iter != processWatermarkPidMap_.end()) {
13222 sceneSession->SetWatermarkEnabled(iter->second, true);
13223 return true;
13224 }
13225 return false;
13226 }
13227
RemoveProcessWatermarkPid(int32_t pid)13228 void SceneSessionManager::RemoveProcessWatermarkPid(int32_t pid)
13229 {
13230 if (processWatermarkPidMap_.find(pid) != processWatermarkPidMap_.end()) {
13231 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "process died, delete pid from watermark pid map. pid:%{public}d", pid);
13232 processWatermarkPidMap_.erase(pid);
13233 }
13234 }
13235
GetRootMainWindowId(int32_t persistentId,int32_t & hostWindowId)13236 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
13237 {
13238 if (!SessionPermission::IsSystemServiceCalling()) {
13239 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
13240 return WMError::WM_ERROR_INVALID_PERMISSION;
13241 }
13242 const char* const where = __func__;
13243 auto task = [this, persistentId, &hostWindowId, where]() {
13244 hostWindowId = INVALID_WINDOW_ID;
13245 sptr<Session> session = GetSceneSession(persistentId);
13246 while (session && SessionHelper::IsSubWindow(session->GetWindowType())) {
13247 session = session->GetParentSession();
13248 }
13249 if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
13250 hostWindowId = session->GetPersistentId();
13251 }
13252 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
13253 where, persistentId, hostWindowId);
13254 return WMError::WM_OK;
13255 };
13256 return taskScheduler_->PostSyncTask(task, where);
13257 }
13258
GetMaxInstanceCount(const std::string & bundleName)13259 int32_t SceneSessionManager::GetMaxInstanceCount(const std::string& bundleName)
13260 {
13261 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
13262 return MultiInstanceManager::GetInstance().GetMaxInstanceCount(bundleName);
13263 } else {
13264 return 0;
13265 }
13266 }
13267
GetInstanceCount(const std::string & bundleName)13268 int32_t SceneSessionManager::GetInstanceCount(const std::string& bundleName)
13269 {
13270 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
13271 return MultiInstanceManager::GetInstance().GetInstanceCount(bundleName);
13272 } else {
13273 return 0;
13274 }
13275 }
13276
GetLastInstanceKey(const std::string & bundleName)13277 std::string SceneSessionManager::GetLastInstanceKey(const std::string& bundleName)
13278 {
13279 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
13280 return MultiInstanceManager::GetInstance().GetLastInstanceKey(bundleName);
13281 } else {
13282 return "";
13283 }
13284 }
13285
RefreshAppInfo(const std::string & bundleName)13286 void SceneSessionManager::RefreshAppInfo(const std::string& bundleName)
13287 {
13288 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
13289 MultiInstanceManager::GetInstance().RefreshAppInfo(bundleName);
13290 }
13291 AbilityInfoManager::GetInstance().RemoveAppInfo(bundleName);
13292 }
13293
UpdateScreenLockStatusForApp(const std::string & bundleName,bool isRelease)13294 WMError SceneSessionManager::UpdateScreenLockStatusForApp(const std::string& bundleName, bool isRelease)
13295 {
13296 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13297 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13298 return WMError::WM_ERROR_INVALID_PERMISSION;
13299 }
13300 #ifdef POWER_MANAGER_ENABLE
13301 if (isRelease) {
13302 return ReleaseScreenLockForApp(bundleName);
13303 } else {
13304 return RelockScreenLockForApp(bundleName);
13305 }
13306 #else
13307 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Can not find the sub system of PowerMgr");
13308 return WMError::WM_OK;
13309 #endif
13310 }
13311
ReleaseScreenLockForApp(const std::string & bundleName)13312 WMError SceneSessionManager::ReleaseScreenLockForApp(const std::string& bundleName)
13313 {
13314 std::vector<sptr<SceneSession>> sessionsToReleaseScreenLock;
13315 GetAllSessionsToReleaseScreenLock(sessionsToReleaseScreenLock, bundleName);
13316 auto task = [this, bundleName, sessionsToReleaseScreenLock] {
13317 for (const auto& sceneSession : sessionsToReleaseScreenLock) {
13318 if (sceneSession->keepScreenLock_ == nullptr || !sceneSession->keepScreenLock_->IsUsed()) {
13319 continue;
13320 }
13321 auto res = sceneSession->keepScreenLock_->UnLock();
13322 if (res != ERR_OK) {
13323 TLOGNE(WmsLogTag::WMS_ATTRIBUTE,
13324 "release screenlock failed, window:[%{public}d, %{public}s], err:%{public}d",
13325 sceneSession->GetPersistentId(), sceneSession->GetWindowName().c_str(), res);
13326 continue;
13327 }
13328 auto [iter, emplaced] = releasedScreenLockMap_.try_emplace(bundleName, std::unordered_set<int32_t>{});
13329 iter->second.insert(sceneSession->GetPersistentId());
13330 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "release screenlock success, window:[%{public}d, %{public}s]",
13331 sceneSession->GetPersistentId(), sceneSession->GetWindowName().c_str());
13332 }
13333 return WMError::WM_OK;
13334 };
13335 return taskScheduler_->PostSyncTask(task, __func__);
13336 }
13337
GetAllSessionsToReleaseScreenLock(std::vector<sptr<SceneSession>> & sessionsToReleaseScreenLock,const std::string & bundleName)13338 void SceneSessionManager::GetAllSessionsToReleaseScreenLock(
13339 std::vector<sptr<SceneSession>>& sessionsToReleaseScreenLock, const std::string& bundleName) {
13340 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13341 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
13342 if (sceneSession->GetSessionInfo().bundleName_ == bundleName && sceneSession->keepScreenLock_ != nullptr) {
13343 sessionsToReleaseScreenLock.push_back(sceneSession);
13344 }
13345 }
13346 }
13347
RelockScreenLockForApp(const std::string & bundleName)13348 WMError SceneSessionManager::RelockScreenLockForApp(const std::string& bundleName)
13349 {
13350 auto task = [this, bundleName] {
13351 auto iter = releasedScreenLockMap_.find(bundleName);
13352 if (iter == releasedScreenLockMap_.end()) {
13353 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: not found in map", bundleName.c_str());
13354 return WMError::WM_ERROR_INVALID_OPERATION;
13355 }
13356 const auto& persistentIds = iter->second;
13357 for (const int32_t persistentId : persistentIds) {
13358 sptr<SceneSession> sceneSession = GetSceneSession(static_cast<int32_t>(persistentId));
13359 if (sceneSession == nullptr) {
13360 continue;
13361 }
13362 auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
13363 auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(
13364 sceneSession->GetScreenId());
13365 if (screenSession) {
13366 sourceMode = screenSession->GetSourceMode();
13367 }
13368 if (sceneSession->IsKeepScreenOn() && IsSessionVisibleForeground(sceneSession) &&
13369 sourceMode != ScreenSourceMode::SCREEN_UNIQUE && sceneSession->keepScreenLock_ != nullptr) {
13370 auto res = sceneSession->keepScreenLock_->Lock();
13371 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "relock screenlock, window: [%{public}d, %{public}s], res:%{public}d",
13372 persistentId, sceneSession->GetWindowName().c_str(), res);
13373 }
13374 }
13375 releasedScreenLockMap_.erase(bundleName);
13376 return WMError::WM_OK;
13377 };
13378 return taskScheduler_->PostSyncTask(task, __func__);
13379 }
13380
IsPcWindow(bool & isPcWindow)13381 WMError SceneSessionManager::IsPcWindow(bool& isPcWindow)
13382 {
13383 isPcWindow = systemConfig_.IsPcWindow();
13384 return WMError::WM_OK;
13385 }
13386
IsPcOrPadFreeMultiWindowMode(bool & isPcOrPadFreeMultiWindowMode)13387 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
13388 {
13389 isPcOrPadFreeMultiWindowMode = (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode());
13390 return WMError::WM_OK;
13391 }
13392
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)13393 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
13394 std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
13395 {
13396 if (!SessionPermission::IsSystemCalling()) {
13397 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13398 return WMError::WM_ERROR_INVALID_PERMISSION;
13399 }
13400
13401 auto task = [this, windowIds, &windowDisplayIdMap] {
13402 for (const uint64_t windowId : windowIds) {
13403 sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
13404 if (session == nullptr) {
13405 continue;
13406 }
13407 DisplayId displayId = session->GetSessionProperty()->GetDisplayId();
13408 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
13409 windowId, displayId);
13410 windowDisplayIdMap.insert({windowId, displayId});
13411 }
13412 return WMError::WM_OK;
13413 };
13414 return taskScheduler_->PostSyncTask(task, __func__);
13415 }
13416
IsLastFrameLayoutFinished(bool & isLayoutFinished)13417 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
13418 {
13419 if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
13420 TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
13421 return WSError::WS_ERROR_NULLPTR;
13422 }
13423 isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
13424 return WSError::WS_OK;
13425 }
13426
IsWindowRectAutoSave(const std::string & key,bool & enabled,int persistentId)13427 WMError SceneSessionManager::IsWindowRectAutoSave(const std::string& key, bool& enabled, int persistentId)
13428 {
13429 auto sceneSession = GetSceneSession(persistentId);
13430 if (sceneSession == nullptr) {
13431 TLOGE(WmsLogTag::WMS_MAIN, "sceneSession %{public}d is nullptr", persistentId);
13432 return WMError::WM_ERROR_INVALID_SESSION;
13433 }
13434 std::string specifiedKey = key;
13435 if (sceneSession->GetSessionProperty()->GetIsSaveBySpecifiedFlag()) {
13436 specifiedKey = key + sceneSession->GetSessionInfo().specifiedFlag_;
13437 }
13438 TLOGD(WmsLogTag::WMS_MAIN, "windowId: %{public}d, specifiedKey: %{public}s", persistentId, specifiedKey.c_str());
13439 std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
13440 if (auto iter = isWindowRectAutoSaveMap_.find(specifiedKey); iter != isWindowRectAutoSaveMap_.end()) {
13441 enabled = iter->second;
13442 } else {
13443 enabled = false;
13444 }
13445 return WMError::WM_OK;
13446 }
13447
SetIsWindowRectAutoSave(const std::string & key,bool enabled)13448 void SceneSessionManager::SetIsWindowRectAutoSave(const std::string& key, bool enabled)
13449 {
13450 std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
13451 if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
13452 if (!enabled) {
13453 isWindowRectAutoSaveMap_.erase(key);
13454 } else {
13455 iter->second = enabled;
13456 }
13457 } else {
13458 if (enabled) {
13459 isWindowRectAutoSaveMap_.insert({key, enabled});
13460 }
13461 }
13462 }
13463
MinimizeMainSession(const std::string & bundleName,int32_t appIndex,int32_t userId)13464 WMError SceneSessionManager::MinimizeMainSession(const std::string& bundleName, int32_t appIndex, int32_t userId)
13465 {
13466 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13467 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13468 return WMError::WM_ERROR_INVALID_PERMISSION;
13469 }
13470 if ((currentUserId_ != userId && currentUserId_ != DEFAULT_USERID) ||
13471 (currentUserId_ == DEFAULT_USERID && userId != GetUserIdByUid(getuid()))) {
13472 TLOGW(WmsLogTag::WMS_LIFE, "currentUserId:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
13473 currentUserId_.load(), userId, GetUserIdByUid(getuid()));
13474 return WMError::WM_ERROR_INVALID_OPERATION;
13475 }
13476 const char* const where = __func__;
13477 taskScheduler_->PostAsyncTask([this, bundleName, appIndex, where] {
13478 std::vector<sptr<SceneSession>> mainSessions;
13479 GetMainSessionByBundleNameAndAppIndex(bundleName, appIndex, mainSessions);
13480 if (mainSessions.empty()) {
13481 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, not found any main session", where);
13482 return;
13483 }
13484 for (const auto& session : mainSessions) {
13485 session->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
13486 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, id:%{public}d.", where, session->GetPersistentId());
13487 }
13488 }, __func__);
13489 return WMError::WM_OK;
13490 }
13491
ShiftAppWindowPointerEvent(int32_t sourcePersistentId,int32_t targetPersistentId)13492 WMError SceneSessionManager::ShiftAppWindowPointerEvent(int32_t sourcePersistentId, int32_t targetPersistentId)
13493 {
13494 TLOGD(WmsLogTag::WMS_PC, "sourcePersistentId %{public}d targetPersistentId %{public}d",
13495 sourcePersistentId, targetPersistentId);
13496 if (!(systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode())) {
13497 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
13498 }
13499 if (sourcePersistentId == targetPersistentId) {
13500 return WMError::WM_ERROR_INVALID_CALLING;
13501 }
13502 sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
13503 if (sourceSession == nullptr) {
13504 TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is nullptr", sourcePersistentId);
13505 return WMError::WM_ERROR_INVALID_SESSION;
13506 }
13507 if (!WindowHelper::IsAppWindow(sourceSession->GetWindowType())) {
13508 TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is not app window", sourcePersistentId);
13509 return WMError::WM_ERROR_INVALID_CALLING;
13510 }
13511 sptr<SceneSession> targetSession = GetSceneSession(targetPersistentId);
13512 if (targetSession == nullptr) {
13513 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is nullptr", targetPersistentId);
13514 return WMError::WM_ERROR_INVALID_SESSION;
13515 }
13516 if (!WindowHelper::IsAppWindow(targetSession->GetWindowType())) {
13517 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not app window", targetPersistentId);
13518 return WMError::WM_ERROR_INVALID_CALLING;
13519 }
13520 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
13521 TLOGE(WmsLogTag::WMS_PC, "verify bundle failed, source name is %{public}s but target name is %{public}s",
13522 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
13523 return WMError::WM_ERROR_INVALID_CALLING;
13524 }
13525 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
13526 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not same bundle as calling", targetPersistentId);
13527 return WMError::WM_ERROR_INVALID_CALLING;
13528 }
13529 int32_t callingPid = IPCSkeleton::GetCallingPid();
13530 if (callingPid != targetSession->GetCallingPid()) {
13531 TLOGE(WmsLogTag::WMS_PC, "permission denied, not call by the same process");
13532 return WMError::WM_ERROR_INVALID_CALLING;
13533 }
13534 return ShiftAppWindowPointerEventInner(sourcePersistentId, targetPersistentId,
13535 targetSession->GetSessionProperty()->GetDisplayId());
13536 }
13537
ShiftAppWindowPointerEventInner(int32_t sourceWindowId,int32_t targetWindowId,DisplayId targetDisplayId)13538 WMError SceneSessionManager::ShiftAppWindowPointerEventInner(
13539 int32_t sourceWindowId, int32_t targetWindowId, DisplayId targetDisplayId)
13540 {
13541 return taskScheduler_->PostSyncTask([sourceWindowId, targetWindowId, targetDisplayId] {
13542 auto display = DisplayManager::GetInstance().GetDisplayById(targetDisplayId);
13543 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
13544 if (display) {
13545 vpr = display->GetVirtualPixelRatio();
13546 }
13547 int32_t outside = static_cast<int32_t>(HOTZONE_TOUCH * vpr * 2); // double touch hotzone
13548 MMI::ShiftWindowParam param;
13549 param.sourceWindowId = sourceWindowId;
13550 param.targetWindowId = targetWindowId;
13551 param.x = -outside;
13552 param.y = -outside;
13553 int ret = MMI::InputManager::GetInstance()->ShiftAppPointerEvent(param, true);
13554 TLOGNI(WmsLogTag::WMS_PC, "sourceWindowId %{public}d targetWindowId %{public}d ret %{public}d",
13555 param.sourceWindowId, param.targetWindowId, ret);
13556 return ret == 0 ? WMError::WM_OK : WMError::WM_ERROR_INVALID_CALLING;
13557 }, __func__);
13558 }
13559
LockSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,bool isLock)13560 WMError SceneSessionManager::LockSessionByAbilityInfo(const AbilityInfoBase& abilityInfo, bool isLock)
13561 {
13562 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13563 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13564 return WMError::WM_ERROR_INVALID_PERMISSION;
13565 }
13566 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
13567 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
13568 return WMError::WM_ERROR_INVALID_PERMISSION;
13569 }
13570 TLOGI(WmsLogTag::WMS_LIFE,
13571 "bundleName:%{public}s moduleName:%{public}s abilityName:%{public}s appIndex:%{public}d isLock:%{public}d",
13572 abilityInfo.bundleName.c_str(), abilityInfo.moduleName.c_str(), abilityInfo.abilityName.c_str(),
13573 abilityInfo.appIndex, isLock);
13574 if (!abilityInfo.IsValid()) {
13575 TLOGE(WmsLogTag::WMS_LIFE, "abilityInfo not valid");
13576 return WMError::WM_ERROR_INVALID_PARAM;
13577 }
13578 taskScheduler_->PostAsyncTask([this, abilityInfo, isLock, where = __func__] {
13579 std::vector<sptr<SceneSession>> mainSessions;
13580 GetMainSessionByAbilityInfo(abilityInfo, mainSessions);
13581 if (!mainSessions.empty()) {
13582 for (const auto& mainSession : mainSessions) {
13583 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, set isLockedState true, persistentId:%{public}d",
13584 where, mainSession->GetPersistentId());
13585 mainSession->NotifySessionLockStateChange(isLock);
13586 }
13587 if (isLock) {
13588 return;
13589 }
13590 }
13591 if (isLock) {
13592 if (sessionLockedStateCacheSet_.size() > MAX_LOCK_STATUS_CACHE_SIZE) {
13593 auto iter = sessionLockedStateCacheSet_.begin();
13594 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, reach max erase begin:%{public}s", where, (*iter).c_str());
13595 sessionLockedStateCacheSet_.erase(iter);
13596 }
13597 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, update isLockedState into cache set", where);
13598 sessionLockedStateCacheSet_.insert(abilityInfo.ToKeyString());
13599 } else {
13600 sessionLockedStateCacheSet_.erase(abilityInfo.ToKeyString());
13601 }
13602 }, __func__);
13603 return WMError::WM_OK;
13604 }
13605
HasFloatingWindowForeground(const sptr<IRemoteObject> & abilityToken,bool & hasOrNot)13606 WMError SceneSessionManager::HasFloatingWindowForeground(const sptr<IRemoteObject>& abilityToken, bool& hasOrNot)
13607 {
13608 if (!abilityToken) {
13609 TLOGE(WmsLogTag::WMS_SYSTEM, "AbilityToken is null");
13610 return WMError::WM_ERROR_NULLPTR;
13611 }
13612 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
13613 TLOGE(WmsLogTag::WMS_SYSTEM, "Permission denied, only for SA");
13614 return WMError::WM_ERROR_INVALID_PERMISSION;
13615 }
13616
13617 return taskScheduler_->PostSyncTask([this, &abilityToken, &hasOrNot, where = __func__] {
13618 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13619 for (const auto& [_, session] : sceneSessionMap_) {
13620 if (session && session->GetAbilityToken() == abilityToken &&
13621 session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT && session->IsSessionForeground()) {
13622 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s found", where);
13623 hasOrNot = true;
13624 return WMError::WM_OK;
13625 }
13626 }
13627 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s not found", where);
13628 hasOrNot = false;
13629 return WMError::WM_OK;
13630 }, __func__);
13631 }
13632
SetStatusBarAvoidHeight(int32_t height)13633 void SceneSessionManager::SetStatusBarAvoidHeight(int32_t height)
13634 {
13635 const char* const where = __func__;
13636 auto task = [this, where, height] {
13637 statusBarAvoidHeight_ = height >= 0 ? height : INVALID_STATUS_BAR_AVOID_HEIGHT;
13638 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s, height %{public}d", where, statusBarAvoidHeight_);
13639 return WMError::WM_OK;
13640 };
13641 taskScheduler_->PostSyncTask(task, where);
13642 }
13643
GetStatusBarAvoidHeight(WSRect & barArea)13644 void SceneSessionManager::GetStatusBarAvoidHeight(WSRect& barArea)
13645 {
13646 barArea.height_ = statusBarAvoidHeight_ == INVALID_STATUS_BAR_AVOID_HEIGHT ?
13647 barArea.height_ : statusBarAvoidHeight_;
13648 }
13649
CloneWindow(int32_t fromPersistentId,int32_t toPersistentId)13650 WSError SceneSessionManager::CloneWindow(int32_t fromPersistentId, int32_t toPersistentId)
13651 {
13652 return taskScheduler_->PostSyncTask([this, fromPersistentId, toPersistentId]() {
13653 auto toSceneSession = GetSceneSession(toPersistentId);
13654 if (toSceneSession == nullptr) {
13655 TLOGNE(WmsLogTag::WMS_PC, "Session is nullptr, id: %{public}d", toPersistentId);
13656 return WSError::WS_ERROR_NULLPTR;
13657 }
13658 NodeId nodeId = INVALID_NODEID;
13659 if (fromPersistentId >= 0) { // if fromPersistentId < 0, excute CloneWindow(0) to cancel cloneWindow
13660 if (auto fromSceneSession = GetSceneSession(fromPersistentId)) {
13661 if (auto surfaceNode = fromSceneSession->GetSurfaceNode()) {
13662 nodeId = surfaceNode->GetId();
13663 }
13664 } else {
13665 TLOGNE(WmsLogTag::WMS_PC, "Session is nullptr, id: %{public}d", fromPersistentId);
13666 return WSError::WS_ERROR_NULLPTR;
13667 }
13668 }
13669 toSceneSession->CloneWindow(nodeId);
13670 TLOGNI(WmsLogTag::WMS_PC, "fromSurfaceId: %{public}" PRIu64, nodeId);
13671 return WSError::WS_OK;
13672 }, __func__);
13673 }
13674
UpdateSpecificSessionClientDisplayId(const sptr<WindowSessionProperty> & property)13675 DisplayId SceneSessionManager::UpdateSpecificSessionClientDisplayId(const sptr<WindowSessionProperty>& property)
13676 {
13677 auto initClientDisplayId = DEFAULT_DISPLAY_ID;
13678 // SubWindow
13679 if (auto parentSession = GetSceneSession(property->GetParentPersistentId())) {
13680 if (property->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
13681 property->SetDisplayId(DEFAULT_DISPLAY_ID);
13682 initClientDisplayId = parentSession->GetClientDisplayId();
13683 }
13684 }
13685 // SystemWindow
13686 if (property->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
13687 property->SetDisplayId(DEFAULT_DISPLAY_ID);
13688 initClientDisplayId = VIRTUAL_DISPLAY_ID;
13689 }
13690 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winName:%{public}s, type:%{public}u, displayId:%{public}" PRIu64
13691 ", clientDisplayId: %{public}" PRIu64, property->GetWindowName().c_str(), property->GetWindowType(),
13692 property->GetDisplayId(), initClientDisplayId);
13693 return initClientDisplayId;
13694 }
13695
UpdateSessionDisplayIdBySessionInfo(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)13696 void SceneSessionManager::UpdateSessionDisplayIdBySessionInfo(
13697 sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
13698 {
13699 if (sceneSession->GetScreenId() == VIRTUAL_DISPLAY_ID &&
13700 sceneSession->GetSessionProperty()->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
13701 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s move display %{public}" PRIu64 " from %{public}" PRIu64,
13702 sessionInfo.bundleName_.c_str(), sessionInfo.screenId_, VIRTUAL_DISPLAY_ID);
13703 sceneSession->SetScreenId(sessionInfo.screenId_);
13704 sceneSession->GetSessionProperty()->SetDisplayId(sessionInfo.screenId_);
13705 }
13706 }
13707
RemoveLifeCycleTaskByPersistentId(int32_t persistentId,const LifeCycleTaskType taskType)13708 void SceneSessionManager::RemoveLifeCycleTaskByPersistentId(int32_t persistentId,
13709 const LifeCycleTaskType taskType)
13710 {
13711 auto sceneSession = GetSceneSession(persistentId);
13712 if (sceneSession == nullptr) {
13713 TLOGE(WmsLogTag::WMS_LIFE, "session:%{public}d is nullptr", persistentId);
13714 return;
13715 }
13716 sceneSession->RemoveLifeCycleTask(taskType);
13717 }
13718
RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener,const std::vector<int32_t> & persistentIdList)13719 WMError SceneSessionManager::RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener,
13720 const std::vector<int32_t>& persistentIdList)
13721 {
13722 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13723 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13724 return WMError::WM_ERROR_INVALID_PERMISSION;
13725 }
13726 if (persistentIdList.empty()) {
13727 TLOGE(WmsLogTag::WMS_LIFE, "persistentIdList is empty!");
13728 return WMError::WM_ERROR_INVALID_PARAM;
13729 }
13730 if (listener == nullptr) {
13731 TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
13732 return WMError::WM_ERROR_INVALID_PARAM;
13733 }
13734 taskScheduler_->PostAsyncTask([this, listener, persistentIdList, where = __func__] {
13735 WMError ret = listenerController_->RegisterSessionLifecycleListener(listener, persistentIdList);
13736 TLOGI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
13737 }, __func__);
13738 return WMError::WM_OK;
13739 }
13740
RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener,const std::vector<std::string> & bundleNameList)13741 WMError SceneSessionManager::RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener,
13742 const std::vector<std::string>& bundleNameList)
13743 {
13744 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13745 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13746 return WMError::WM_ERROR_INVALID_PERMISSION;
13747 }
13748 if (listener == nullptr) {
13749 TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
13750 return WMError::WM_ERROR_INVALID_PARAM;
13751 }
13752 taskScheduler_->PostAsyncTask([this, listener, bundleNameList, where = __func__] {
13753 WMError ret = listenerController_->RegisterSessionLifecycleListener(listener, bundleNameList);
13754 TLOGI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
13755 }, __func__);
13756 return WMError::WM_OK;
13757 }
13758
UnregisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener)13759 WMError SceneSessionManager::UnregisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener)
13760 {
13761 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
13762 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
13763 return WMError::WM_ERROR_INVALID_PERMISSION;
13764 }
13765 if (listener == nullptr) {
13766 TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
13767 return WMError::WM_ERROR_INVALID_PARAM;
13768 }
13769 taskScheduler_->PostAsyncTask([this, listener, where = __func__] {
13770 WMError ret = listenerController_->UnregisterSessionLifecycleListener(listener);
13771 TLOGI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
13772 }, __func__);
13773 return WMError::WM_OK;
13774 }
13775
SetParentWindowInner(const sptr<SceneSession> & subSession,const sptr<SceneSession> & oldParentSession,const sptr<SceneSession> & newParentSession)13776 WMError SceneSessionManager::SetParentWindowInner(const sptr<SceneSession>& subSession,
13777 const sptr<SceneSession>& oldParentSession, const sptr<SceneSession>& newParentSession)
13778 {
13779 uint32_t oldSubWindowLevel = oldParentSession->GetSessionProperty()->GetSubWindowLevel();
13780 uint32_t newSubWindowLevel = newParentSession->GetSessionProperty()->GetSubWindowLevel();
13781 if (oldSubWindowLevel < newSubWindowLevel &&
13782 subSession->GetMaxSubWindowLevel() + newSubWindowLevel > MAX_SUB_WINDOW_LEVEL) {
13783 TLOGE(WmsLogTag::WMS_SUB, "newParentSession sub level limit");
13784 return WMError::WM_ERROR_INVALID_PARENT;
13785 }
13786 int32_t oldParentWindowId = oldParentSession->GetPersistentId();
13787 int32_t newParentWindowId = newParentSession->GetPersistentId();
13788 subSession->NotifySetParentSession(oldParentWindowId, newParentWindowId);
13789 int32_t subWindowId = subSession->GetPersistentId();
13790 oldParentSession->RemoveSubSession(subWindowId);
13791 newParentSession->AddSubSession(subSession);
13792 subSession->SetParentSession(newParentSession);
13793 subSession->SetParentPersistentId(newParentWindowId);
13794 subSession->UpdateSubWindowLevel(newSubWindowLevel + 1);
13795 if (oldSubWindowLevel == 0) {
13796 oldParentSession->UnregisterNotifySurfaceBoundsChangeFunc(subWindowId);
13797 if (newSubWindowLevel == 0 && subSession->GetIsFollowParentLayout()) {
13798 subSession->SetFollowParentWindowLayoutEnabled(true);
13799 }
13800 }
13801 return WMError::WM_OK;
13802 }
13803
SetParentWindow(int32_t subWindowId,int32_t newParentWindowId)13804 WMError SceneSessionManager::SetParentWindow(int32_t subWindowId, int32_t newParentWindowId)
13805 {
13806 return taskScheduler_->PostSyncTask([this, subWindowId, newParentWindowId, where = __func__] {
13807 auto subSession = GetSceneSession(subWindowId);
13808 if (!subSession || !WindowHelper::IsSubWindow(subSession->GetWindowType())) {
13809 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s subSession is nullptr or type invalid", where);
13810 return WMError::WM_ERROR_INVALID_WINDOW;
13811 }
13812 int32_t oldParentWindowId = subSession->GetParentPersistentId();
13813 auto oldParentSession = GetSceneSession(oldParentWindowId);
13814 if (oldParentSession == nullptr) {
13815 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s oldParentSession is nullptr", where);
13816 return WMError::WM_ERROR_INVALID_PARENT;
13817 }
13818 auto oldWindowType = oldParentSession->GetWindowType();
13819 if (!WindowHelper::IsMainWindow(oldWindowType) && !WindowHelper::IsFloatOrSubWindow(oldWindowType)) {
13820 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s oldParentSession window type invalid", where);
13821 return WMError::WM_ERROR_INVALID_PARENT;
13822 }
13823 auto newParentSession = GetSceneSession(newParentWindowId);
13824 if (newParentSession == nullptr) {
13825 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession is nullptr", where);
13826 return WMError::WM_ERROR_INVALID_PARENT;
13827 }
13828 TLOGND(WmsLogTag::WMS_SUB, "%{public}s subWindowId: %{public}d oldParentWindowId: %{public}d "
13829 "newParentWindowId: %{public}d", where, subWindowId, oldParentWindowId, newParentWindowId);
13830 auto newWindowType = newParentSession->GetWindowType();
13831 if (!WindowHelper::IsMainWindow(newWindowType) && !WindowHelper::IsFloatOrSubWindow(newWindowType)) {
13832 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession window type invalid", where);
13833 return WMError::WM_ERROR_INVALID_PARENT;
13834 }
13835 if (oldParentSession->GetCallingPid() != newParentSession->GetCallingPid()) {
13836 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s callingPid not same", where);
13837 return WMError::WM_ERROR_INVALID_PARENT;
13838 }
13839 if (newParentSession->IsAncestorsSession(subWindowId)) {
13840 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession is subsession ancestor", where);
13841 return WMError::WM_ERROR_INVALID_PARENT;
13842 }
13843 return SetParentWindowInner(subSession, oldParentSession, newParentSession);
13844 });
13845 }
13846
MinimizeByWindowId(const std::vector<int32_t> & windowIds)13847 WMError SceneSessionManager::MinimizeByWindowId(const std::vector<int32_t>& windowIds)
13848 {
13849 if (!SessionPermission::IsSystemServiceCalling()) {
13850 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system service.");
13851 return WMError::WM_ERROR_INVALID_PERMISSION;
13852 }
13853 if (windowIds.empty()) {
13854 TLOGE(WmsLogTag::WMS_LIFE, "The vector of windowids is empty.");
13855 return WMError::WM_ERROR_INVALID_PARAM;
13856 }
13857 taskScheduler_->PostAsyncTask([this, windowIds, where = __func__]() {
13858 for (const auto& persistentId : windowIds) {
13859 auto sceneSession = GetSceneSession(persistentId);
13860 if (sceneSession == nullptr) {
13861 TLOGE(WmsLogTag::WMS_LIFE, "could not find the window, persistentId:%{public}d", persistentId);
13862 continue;
13863 } else {
13864 sceneSession->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
13865 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, id:%{public}d", where, persistentId);
13866 }
13867 }
13868 }, __func__);
13869 return WMError::WM_OK;
13870 }
13871 } // namespace OHOS::Rosen
13872