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 #include <sys/stat.h>
20
21 #include <ability_context.h>
22 #include <ability_manager_client.h>
23 #include <application_context.h>
24 #include <bundlemgr/launcher_service.h>
25 #include <common/rs_common_def.h>
26 #include <hisysevent.h>
27 #include <parameters.h>
28 #include <hitrace_meter.h>
29 #include "hitrace/hitracechain.h"
30 #include "parameter.h"
31 #include "resource_manager.h"
32 #include "session/host/include/pc_fold_screen_manager.h"
33 #include "publish/scb_dump_subscriber.h"
34 #include <ui/rs_node.h>
35
36 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
37 #include <display_power_mgr_client.h>
38 #endif
39
40 #ifdef POWER_MANAGER_ENABLE
41 #include <power_mgr_client.h>
42 #endif
43
44 #ifdef RES_SCHED_ENABLE
45 #include "res_type.h"
46 #include "res_sched_client.h"
47 #endif
48
49 #include "anomaly_detection.h"
50 #include "color_parser.h"
51 #include "common/include/fold_screen_state_internel.h"
52 #include "common/include/session_permission.h"
53 #include "display_manager.h"
54 #include "distributed_client.h"
55 #include "dms_reporter.h"
56 #include "hidump_controller.h"
57 #include "image_source.h"
58 #include "perform_reporter.h"
59 #include "rdb/starting_window_rdb_manager.h"
60 #include "res_sched_client.h"
61 #include "rs_adapter.h"
62 #include "scene_input_manager.h"
63 #include "scene_screen_change_listener.h"
64 #include "scene_system_ability_listener.h"
65 #include "screen_session_manager_client/include/screen_session_manager_client.h"
66 #include "session/host/include/ability_info_manager.h"
67 #include "session/host/include/main_session.h"
68 #include "session/host/include/multi_instance_manager.h"
69 #include "session/host/include/scb_system_session.h"
70 #include "session/host/include/scene_persistent_storage.h"
71 #include "session/host/include/session_change_recorder.h"
72 #include "session/host/include/session_utils.h"
73 #include "session/host/include/sub_session.h"
74 #include "session_helper.h"
75 #include "session_manager_agent_controller.h"
76 #include "singleton_container.h"
77 #include "softbus_bus_center.h"
78 #include "user_switch_reporter.h"
79 #include "window_helper.h"
80 #include "xcollie/watchdog.h"
81 #include "xcollie/xcollie.h"
82 #include "xcollie/xcollie_define.h"
83 #include "session_permission.h"
84
85 #include "ui_effect_manager.h"
86 #ifdef MEMMGR_WINDOW_ENABLE
87 #include "mem_mgr_client.h"
88 #include "mem_mgr_window_info.h"
89 #endif
90
91 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
92 #include "sec_comp_enhance_kit.h"
93 #endif
94
95 #ifdef IMF_ENABLE
96 #include <input_method_controller.h>
97 #endif // IMF_ENABLE
98
99 namespace OHOS::Rosen {
100 namespace {
101 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
102 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
103 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
104 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
105 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
106 constexpr const char* ATOMIC_SERVICE_SESSION_ID = "com.ohos.param.sessionId";
107 constexpr uint32_t MAX_BRIGHTNESS = 255;
108 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
109 constexpr int32_t SCALE_DIMENSION = 2;
110 constexpr int32_t TRANSLATE_DIMENSION = 2;
111 constexpr int32_t ROTAION_DIMENSION = 4;
112 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
113 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
114 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
115 const std::string EMPTY_DEVICE_ID = "";
116 const std::string STARTWINDOW_TYPE = "startWindowType";
117 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
118
119 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
120 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
121 constexpr int VALUE_MAX_WIDTH = 5;
122 constexpr int MAX_RESEND_TIMES = 6;
123 constexpr int ORIEN_MAX_WIDTH = 12;
124 constexpr int OFFSET_MAX_WIDTH = 8;
125 constexpr int SCALE_MAX_WIDTH = 8;
126 constexpr int PID_MAX_WIDTH = 8;
127 constexpr int PARENT_ID_MAX_WIDTH = 6;
128 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
129 constexpr int32_t CANCEL_POINTER_ID = 99999999;
130 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
131 const std::string ARG_DUMP_ALL = "-a";
132 const std::string ARG_DUMP_WINDOW = "-w";
133 const std::string ARG_DUMP_SCREEN = "-s";
134 const std::string ARG_DUMP_DISPLAY = "-d";
135 const std::string ARG_DUMP_PIPLINE = "-p";
136 const std::string ARG_DUMP_SCB = "-b";
137 const std::string ARG_DUMP_DETAIL = "-c";
138 const std::string ARG_DUMP_RECORD = "-v";
139 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
140 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
141 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
142 constexpr char SMALL_FOLD_PRODUCT_TYPE = '2';
143 constexpr uint32_t MAX_SUB_WINDOW_LEVEL = 10;
144 constexpr uint64_t VIRTUAL_DISPLAY_ID = 999;
145 constexpr uint32_t DEFAULT_LOCK_SCREEN_ZORDER = 2000;
146 constexpr int32_t MAX_LOCK_STATUS_CACHE_SIZE = 1000;
147 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PC = 50;
148 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PAD = 8;
149 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PHONE = 3;
150 constexpr uint64_t NOTIFY_START_ABILITY_TIMEOUT = 4000;
151 constexpr uint64_t START_UI_ABILITY_TIMEOUT = 5000;
152 constexpr int32_t FORCE_SPLIT_MODE = 5;
153 constexpr int32_t NAV_FORCE_SPLIT_MODE = 6;
154 const std::string FB_PANEL_NAME = "Fb_panel";
155
156 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
157 {"unspecified", OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
158 {"landscape", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
159 {"portrait", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
160 {"follow_recent", OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
161 {"landscape_inverted", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
162 {"portrait_inverted", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
163 {"auto_rotation", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
164 {"auto_rotation_landscape", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
165 {"auto_rotation_portrait", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
166 {"auto_rotation_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
167 {"auto_rotation_landscape_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
168 {"auto_rotation_portrait_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
169 {"locked", OHOS::AppExecFwk::DisplayOrientation::LOCKED},
170 {"auto_rotation_unspecified", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
171 {"follow_desktop", OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
172 };
173
174 const std::map<std::string, StartWindowType> CONVERT_STRING_TO_START_WINDOW_TYPE_MAP = {
175 {"REQUIRED_SHOW", StartWindowType::DEFAULT},
176 {"REQUIRED_HIDE", StartWindowType::RETAIN_AND_INVISIBLE},
177 {"OPTIONAL_SHOW", StartWindowType::DEFAULT},
178 };
179
180 const std::unordered_set<std::string> LAYOUT_INFO_WHITELIST = {
181 "SCBSmartDock",
182 "SCBExtScreenDock",
183 "status_bar_tray",
184 "status_bar_personal",
185 "status_bar_sound_panel",
186 "status_bar_notification_panel",
187 "status_bar_input_panel",
188 "status_bar_control_center",
189 "status_bar_wifi_panel",
190 "status_bar_input_method",
191 "status_bar_assistant_translate",
192 "status_bar_quick_note",
193 "status_bar_bluetooth_panel",
194 "status_bar_battery_panel",
195 "status_bar_focus_mode_paddle",
196 "SCBStatusBar"
197 };
198
199 const std::chrono::milliseconds WAIT_TIME(3 * 1000); // 3 * 1000 wait for 3s
200
GetCurrentTime()201 std::string GetCurrentTime()
202 {
203 struct timespec tn;
204 clock_gettime(CLOCK_REALTIME, &tn);
205 uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
206 static_cast<uint64_t>(tn.tv_nsec);
207 return std::to_string(uTime);
208 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)209 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
210 {
211 return a.first < b.first;
212 }
213
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)214 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
215 {
216 if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
217 value = (*item.intsValue_)[0];
218 return true;
219 }
220 return false;
221 }
222
GetPid()223 int32_t GetPid()
224 {
225 static int32_t pid = static_cast<int32_t>(getpid());
226 return pid;
227 }
228
GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)229 bool GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
230 {
231 auto& metadata = abilityInfo->metadata;
232 for (const auto& item : metadata) {
233 if (item.name == "enable.remove.starting.window") {
234 TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "enable.remove.starting.window=%{public}s", item.value.c_str());
235 return item.value == "true";
236 }
237 }
238 TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "enable.remove.starting.window default false");
239 return false;
240 }
241
IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName & element,uint32_t callingTokenId,AppExecFwk::ExtensionAbilityType extensionAbilityType)242 bool IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName& element, uint32_t callingTokenId,
243 AppExecFwk::ExtensionAbilityType extensionAbilityType)
244 {
245 TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: bundleName: %{public}s, moduleName: %{public}s, ablilityName: %{public}s",
246 element.GetBundleName().c_str(), element.GetModuleName().c_str(), element.GetAbilityName().c_str());
247 static const std::unordered_set<AppExecFwk::ExtensionAbilityType> extensionAbilityTypeWhitelist = {
248 AppExecFwk::ExtensionAbilityType::LIVEVIEW_LOCKSCREEN
249 };
250 static const std::vector<std::tuple<std::string, std::string, std::string>> elementNameWhitelist = {
251 std::make_tuple("com.huawei.hmos.settings", "AccessibilityReConfirmDialog", "phone_settings"),
252 std::make_tuple("com.huawei.hmos.settings", "AccessibilityShortKeyDialog", "phone_settings"),
253 std::make_tuple("com.huawei.hmos.settings", "DefaultIntentUiExtensionAbility", "phone_settings"),
254 std::make_tuple("com.ohos.sceneboard", "ScbIntentUIExtensionAbility", "phone_sceneboard"),
255 std::make_tuple("com.ohos.sceneboard", "PoweroffAbility", "phone_sceneboard"),
256 std::make_tuple("com.ohos.sceneboard", "com.ohos.sceneboard.MetaBallsAbility", "metaBallsTurbo"),
257 std::make_tuple("com.huawei.hmos.motiongesture", "IntentUIExtensionAbility", "entry"),
258 std::make_tuple("com.ohos.useriam.authwidget", "userauthuiextensionability", "entry"),
259 std::make_tuple("com.ohos.sceneboard", "AodStyleAbility", "phone_sceneboard"),
260 std::make_tuple("com.ohos.sceneboard", "HomeThemeComponentExtAbility", "themecomponent"),
261 std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedResourceAbility", "engineservice"),
262 std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedEditingAbility", "engineservice"),
263 std::make_tuple("com.ohos.sceneboard", "CoverExtensionAbility", "coverthemecomponent"),
264 std::make_tuple("com.huawei.hmos.findservice", "SystemDialogAbility", "entry"),
265 std::make_tuple("com.huawei.hmos.mediacontroller", "UIExtAbility", "phone_deviceswitch"),
266 std::make_tuple("com.huawei.hmos.mediacontroller", "AnahsDialogAbility", "phone_deviceswitch"),
267 std::make_tuple("com.huawei.hmos.security.privacycenter", "SuperPrivacyProtectedAbility", "superprivacy"),
268 std::make_tuple("com.huawei.hmos.security.privacycenter", "PermDisabledReminderAbility", "superprivacy"),
269 std::make_tuple("com.huawei.hmos.audioaccessorymanager", "NearbyAbility", "phone"),
270 std::make_tuple("com.huawei.hmos.wallet", "WalletDialogUIExtensionAbility", "entry"),
271 std::make_tuple("com.huawei.hmos.settings", "WifiWindowSettingsAbility", "pc_settings"),
272 std::make_tuple("com.ohos.mms", "DeskDialogExtensionAbility", "entry"),
273 std::make_tuple("com.ohos.sceneboard", "ThemeChargingAbility", "engineservice"),
274 std::make_tuple("com.ohos.commondialog", "FoldStatusAbility", "phone_commondialog"),
275 std::make_tuple("com.ohos.commondialog", "SecondaryReflexionAbility", "phone_commondialog"),
276 };
277
278 if (extensionAbilityTypeWhitelist.find(extensionAbilityType) != extensionAbilityTypeWhitelist.end()) {
279 TLOGI(WmsLogTag::WMS_UIEXT, "ability in white list");
280 return true;
281 }
282
283 auto it = std::find_if(elementNameWhitelist.begin(), elementNameWhitelist.end(), [&element](const auto& item) {
284 auto& [bundleName, abilityName, _] = item;
285 return (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName);
286 });
287 if (it != elementNameWhitelist.end()) {
288 return true;
289 }
290
291 TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in white list");
292 return SessionPermission::VerifyPermissionByCallerToken(callingTokenId,
293 PermissionConstants::PERMISSION_CALLED_EXTENSION_ON_LOCK_SCREEN);
294 }
295
296 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
297 public:
298 BundleStatusCallback() = default;
299 virtual ~BundleStatusCallback() = default;
300
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)301 void OnBundleStateChanged(const uint8_t installType,
302 const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
303
OnBundleAdded(const std::string & bundleName,const int userId)304 void OnBundleAdded(const std::string& bundleName, const int userId) override
305 {
306 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
307 }
308
OnBundleUpdated(const std::string & bundleName,const int userId)309 void OnBundleUpdated(const std::string& bundleName, const int userId) override
310 {
311 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
312 }
313
OnBundleRemoved(const std::string & bundleName,const int userId)314 void OnBundleRemoved(const std::string& bundleName, const int userId) override
315 {
316 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
317 }
318 };
319
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)320 bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
321 {
322 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
323 !avoidArea.rightRect_.IsUninitializedRect()) {
324 return false;
325 }
326 if (avoidArea.bottomRect_.IsUninitializedRect()) {
327 return true;
328 }
329 auto diff =
330 std::abs(avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) - sessionBottom);
331 return isVisible && diff <= 1;
332 }
333
334 enum class UpdateStartingWindowColorCacheResult : uint32_t {
335 SUCCESS = 0,
336 COLOR_MAP_BUNDLE_NOT_FOUND,
337 COLOR_MAP_KEY_PAIR_NOT_FOUND,
338 INFO_MAP_BUNDLE_NOT_FOUND,
339 INFO_MAP_KEY_PAIR_NOT_FOUND,
340 };
341 } // namespace
342
CreateInstance()343 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
344 {
345 sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
346 sessionManager->Init();
347 return sessionManager;
348 }
349
GetInstance()350 SceneSessionManager& SceneSessionManager::GetInstance()
351 {
352 static sptr<SceneSessionManager> instance = CreateInstance();
353 return *instance;
354 }
355
SceneSessionManager()356 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
357 {
358 taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
359 if (!mainHandler_) {
360 auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
361 mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
362 }
363 currentUserId_ = DEFAULT_USERID;
364 launcherService_ = sptr<AppExecFwk::LauncherService>::MakeSptr();
365 if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
366 TLOGE(WmsLogTag::DEFAULT, "Failed to register bundle status callback.");
367 }
368
369 collaboratorDeathRecipient_ = sptr<AgentDeathRecipient>::MakeSptr(
370 [this](const sptr<IRemoteObject>& remoteObject) { this->ClearAllCollaboratorSessions(); });
371
372 scbDumpSubscriber_ = ScbDumpSubscriber::Subscribe();
373
374 listenerController_ = std::make_shared<SessionListenerController>(taskScheduler_);
375 windowFocusController_ = sptr<WindowFocusController>::MakeSptr();
376 ffrtQueueHelper_ = std::make_shared<FfrtQueueHelper>();
377 }
378
~SceneSessionManager()379 SceneSessionManager::~SceneSessionManager()
380 {
381 ScbDumpSubscriber::UnSubscribe(scbDumpSubscriber_);
382 SessionChangeRecorder::GetInstance().stopLogFlag_.store(true);
383 }
384
Init()385 void SceneSessionManager::Init()
386 {
387 bool isScbCoreEnabled = system::GetParameter("persist.window.scbcore.enable", "1") == "1";
388 Session::SetScbCoreEnabled(isScbCoreEnabled);
389 bool isBackgroundWindowNotifyEnabled = system::GetParameter("persist.window.background.notify.enable", "0") == "1";
390 Session::SetBackgroundUpdateRectNotifyEnabled(isBackgroundWindowNotifyEnabled);
391
392 constexpr uint64_t interval = 5 * 1000; // 5 second
393 if (HiviewDFX::Watchdog::GetInstance().AddThread(
394 SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
395 TLOGW(WmsLogTag::DEFAULT, "Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
396 }
397
398 bundleMgr_ = GetBundleManager();
399
400 // Parse configuration.
401 LoadWindowSceneXml();
402 LoadWindowParameter();
403 InitPrepareTerminateConfig();
404
405 ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(sptr<DisplayChangeListener>::MakeSptr());
406 ScreenSessionManagerClient::GetInstance().RegisterScreenConnectionChangeListener(
407 sptr<ScreenConnectionChangeListener>::MakeSptr());
408
409 // create handler for inner command at server
410 eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
411 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
412 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
413 if (ret != 0) {
414 TLOGW(WmsLogTag::DEFAULT, "Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
415 }
416 taskScheduler_->SetExportHandler(eventHandler_);
417
418 scbSessionHandler_ = sptr<ScbSessionHandler>::MakeSptr();
419 AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
420 StartWindowInfoReportLoop();
421 TLOGI(WmsLogTag::DEFAULT, "SSM init success.");
422
423 RegisterAppListener();
424 openDebugTrace_ = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
425 isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1") == "1";
426
427 // window recover
428 RegisterSessionRecoverStateChangeListener();
429 RegisterRecoverStateChangeListener();
430
431 // Input init.
432 SceneInputManager::GetInstance().Init();
433 RegisterFlushWindowInfoCallback();
434
435 // DFX
436 SessionChangeRecorder::GetInstance().Init();
437
438 // MMI window state error check
439 int32_t retCode = MMI::InputManager::GetInstance()->
440 RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
441 this->NotifyWindowStateErrorFromMMI(pid, persistentId);
442 });
443 TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
444
445 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
446 MultiInstanceManager::GetInstance().Init(bundleMgr_, taskScheduler_);
447 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
448 }
449 AbilityInfoManager::GetInstance().Init(bundleMgr_);
450 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
451
452 InitVsyncStation();
453 UpdateDarkColorModeToRS();
454 CreateRootSceneSession();
455 foldChangeCallback_ = std::make_shared<FoldScreenStatusChangeCallback>(
456 std::bind(&SceneSessionManager::UpdateSessionWithFoldStateChange, this, std::placeholders::_1,
457 std::placeholders::_2, std::placeholders::_3));
458 PcFoldScreenManager::GetInstance().RegisterFoldScreenStatusChangeCallback(0, foldChangeCallback_);
459
460 InitSnapshotCache();
461 }
462
RegisterSessionRecoverStateChangeListener()463 void SceneSessionManager::RegisterSessionRecoverStateChangeListener()
464 {
465 sessionRecoverStateChangeFunc_ = [this](const SessionRecoverState& state,
466 const sptr<WindowSessionProperty>& property) THREAD_SAFETY_GUARD(SCENE_GUARD) {
467 this->OnSessionRecoverStateChange(state, property);
468 };
469 }
470
OnSessionRecoverStateChange(const SessionRecoverState & state,const sptr<WindowSessionProperty> & property)471 void SceneSessionManager::OnSessionRecoverStateChange(const SessionRecoverState& state,
472 const sptr<WindowSessionProperty>& property)
473 {
474 TLOGI(WmsLogTag::WMS_RECOVER, "id: %{public}d, state:%{public}u", property->GetPersistentId(), state);
475 switch (state) {
476 case SessionRecoverState::SESSION_START_RECONNECT:
477 // The server session has not request yet.
478 UpdateRecoverPropertyForSuperFold(property);
479 RecoverSessionInfo(property);
480 break;
481 case SessionRecoverState::SESSION_FINISH_RECONNECT: {
482 // The server session has been request.
483 auto sessionInfo = property->GetSessionInfo();
484 auto persistentId = sessionInfo.persistentId_;
485 auto sceneSession = GetSceneSession(persistentId);
486 if (sceneSession == nullptr) {
487 break;
488 }
489 if (SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
490 sceneSession->SetRecovered(true);
491 recoverSceneSessionFunc_(sceneSession, sessionInfo);
492 sceneSession->SetWindowShadowEnabled(property->GetWindowShadowEnabled());
493 } else {
494 sceneSession->NotifyFollowParentMultiScreenPolicy(sessionInfo.isFollowParentMultiScreenPolicy);
495 NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
496 CacheSpecificSessionForRecovering(sceneSession, property);
497 sceneSession->SetWindowAnchorInfo(property->GetWindowAnchorInfo());
498 }
499 NotifySessionUnfocusedToClient(persistentId);
500 break;
501 }
502 default:
503 break;
504 }
505 }
506
RegisterRecoverStateChangeListener()507 void SceneSessionManager::RegisterRecoverStateChangeListener()
508 {
509 recoverStateChangeFunc_ = [this](const RecoverState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
510 OnRecoverStateChange(state);
511 };
512 }
513
OnRecoverStateChange(const RecoverState & state)514 void SceneSessionManager::OnRecoverStateChange(const RecoverState& state)
515 {
516 TLOGI(WmsLogTag::WMS_RECOVER, "state: %{public}u", state);
517 switch(state) {
518 case RecoverState::RECOVER_INITIAL:
519 break;
520 case RecoverState::RECOVER_ENABLE_INPUT:
521 SetDisplayBrightness(INVALID_BRIGHTNESS);
522 break;
523 default:
524 break;
525 }
526 }
527
RegisterFlushWindowInfoCallback()528 void SceneSessionManager::RegisterFlushWindowInfoCallback()
529 {
530 SceneInputManager::GetInstance().
531 RegisterFlushWindowInfoCallback([this]() { FlushWindowInfoToMMI(); });
532 }
533
InitVsyncStation()534 void SceneSessionManager::InitVsyncStation()
535 {
536 NodeId nodeId = 0;
537 vsyncStation_ = std::make_shared<VsyncStation>(nodeId);
538 }
539
InitScheduleUtils()540 void SceneSessionManager::InitScheduleUtils()
541 {
542 #ifdef RES_SCHED_ENABLE
543 SCBThreadInfo threadInfo = {
544 .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
545 .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
546 };
547 std::unordered_map<std::string, std::string> payload {
548 { "pid", threadInfo.scbPid_ },
549 { "tid", threadInfo.scbTid_ },
550 { "uid", threadInfo.scbUid_ },
551 { "bundleName", threadInfo.scbBundleName_ },
552 };
553 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
554 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
555 auto task = [threadInfo = std::move(threadInfo)]() mutable {
556 threadInfo.ssmThreadName_ = "OS_SceneSession";
557 threadInfo.ssmTid_ = std::to_string(gettid());
558 const int32_t userInteraction = 2;
559 std::unordered_map<std::string, std::string> payload{
560 { "pid", threadInfo.scbPid_ },
561 { "tid", threadInfo.ssmTid_ },
562 { "uid", threadInfo.scbUid_ },
563 { "extType", "10002" },
564 { "cgroupPrio", "1" },
565 { "isSa", "0" },
566 { "threadName", threadInfo.ssmThreadName_ }
567 };
568 uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
569 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
570 TLOGNI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
571 sptr<ISystemAbilityManager> systemAbilityManager =
572 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
573 if (!systemAbilityManager) {
574 TLOGNE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
575 return;
576 }
577 auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
578 int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
579 if (ret != ERR_OK) {
580 TLOGNI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
581 }
582 };
583 taskScheduler_->PostAsyncTask(task, "changeQosTask");
584 #endif
585 }
586
UpdateSessionWithFoldStateChange(DisplayId displayId,SuperFoldStatus status,SuperFoldStatus prevStatus)587 void SceneSessionManager::UpdateSessionWithFoldStateChange(DisplayId displayId, SuperFoldStatus status,
588 SuperFoldStatus prevStatus)
589 {
590 auto task = [this, displayId, status, where = __func__]() {
591 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: status=%{public}u, display=%{public}" PRIu64,
592 where, static_cast<uint32_t>(status), displayId);
593 if (status == SuperFoldStatus::HALF_FOLDED) {
594 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
595 if (display != nullptr) {
596 UpdateDisplayRegion(display->GetDisplayInfo());
597 }
598 }
599 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
600 for (const auto& [_, sceneSession] : sceneSessionMap_) {
601 if (sceneSession == nullptr) {
602 TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
603 continue;
604 }
605 sceneSession->UpdateCrossAxis();
606 }
607 };
608 taskScheduler_->PostAsyncTask(task, __func__);
609 }
610
SetBehindWindowFilterEnabled(bool enabled)611 void SceneSessionManager::SetBehindWindowFilterEnabled(bool enabled)
612 {
613 bool isSuccessful = RSInterfaces::GetInstance().SetBehindWindowFilterEnabled(enabled);
614 TLOGI(WmsLogTag::WMS_PC, "is successful: %{public}d", isSuccessful);
615 }
616
RegisterAppListener()617 void SceneSessionManager::RegisterAppListener()
618 {
619 appAnrListener_ = sptr<AppAnrListener>::MakeSptr();
620 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
621 if (appMgrClient == nullptr) {
622 TLOGE(WmsLogTag::DEFAULT, "appMgrClient is nullptr.");
623 } else {
624 auto ret = static_cast<int32_t>(appMgrClient->RegisterAppDebugListener(appAnrListener_));
625 TLOGI(WmsLogTag::DEFAULT, "Register app debug listener, %{public}d.", ret);
626 }
627 }
628
LoadWindowParameter()629 void SceneSessionManager::LoadWindowParameter()
630 {
631 const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "HandsetSmartWindow");
632 const bool isPcMode = system::GetBoolParameter("persist.sceneboard.ispcmode", false);
633 if (multiWindowUIType == "HandsetSmartWindow") {
634 systemConfig_.windowUIType_ = WindowUIType::PHONE_WINDOW;
635 } else if (multiWindowUIType == "FreeFormMultiWindow" || isPcMode) {
636 systemConfig_.windowUIType_ = WindowUIType::PC_WINDOW;
637 } else if (multiWindowUIType == "TabletSmartWindow") {
638 systemConfig_.windowUIType_ = WindowUIType::PAD_WINDOW;
639 } else {
640 TLOGE(WmsLogTag::DEFAULT, "unknown multiWindowUIType:%{public}s.", multiWindowUIType.c_str());
641 }
642 appWindowSceneConfig_.multiWindowUIType_ = multiWindowUIType;
643 }
644
LoadWindowSceneXml()645 void SceneSessionManager::LoadWindowSceneXml()
646 {
647 if (WindowSceneConfig::LoadConfigXml()) {
648 if (WindowSceneConfig::GetConfig().IsMap()) {
649 WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
650 }
651 ConfigWindowSceneXml();
652 } else {
653 TLOGE(WmsLogTag::DEFAULT, "Load window scene xml failed");
654 }
655 ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
656 appWindowSceneConfig_.keyboardAnimationOut_);
657 }
658
InitPrepareTerminateConfig()659 void SceneSessionManager::InitPrepareTerminateConfig()
660 {
661 char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
662 int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
663 PREPARE_TERMINATE_ENABLE_SIZE);
664 TLOGI(WmsLogTag::DEFAULT, "%{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
665 if (retSysParam > 0 && !std::strcmp(value, "true")) {
666 isPrepareTerminateEnable_ = true;
667 }
668 }
669
ConfigWindowSceneXml()670 void SceneSessionManager::ConfigWindowSceneXml()
671 {
672 const auto& config = WindowSceneConfig::GetConfig();
673 WindowSceneConfig::ConfigItem item = config["windowEffect"];
674 if (item.IsMap()) {
675 ConfigWindowEffect(item);
676 }
677
678 item = config["decor"];
679 if (item.IsMap()) {
680 ConfigDecor(item);
681 }
682
683 item = config["backgroundswitch"];
684 int32_t param = -1;
685 systemConfig_.backgroundswitch = GetSingleIntItem(item, param) && param == 1;
686 TLOGD(WmsLogTag::DEFAULT, "Load backgroundswitch %{public}d", systemConfig_.backgroundswitch);
687 item = config["defaultWindowMode"];
688 if (GetSingleIntItem(item, param) &&
689 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
690 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
691 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
692 }
693 item = config["defaultMaximizeMode"];
694 if (GetSingleIntItem(item, param) &&
695 (param == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
696 param == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
697 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(param);
698 }
699 item = config["keyboardAnimation"];
700 if (item.IsMap()) {
701 ConfigKeyboardAnimation(item);
702 }
703 item = config["maxFloatingWindowSize"];
704 if (GetSingleIntItem(item, param)) {
705 systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(param);
706 }
707 item = config["windowAnimation"];
708 if (item.IsMap()) {
709 ConfigWindowAnimation(item);
710 }
711 item = config["startWindowTransitionAnimation"];
712 if (item.IsMap()) {
713 ConfigStartingWindowAnimation(item);
714 }
715 item = config["maxMidSceneNum"];
716 if (GetSingleIntItem(item, param)) {
717 systemConfig_.maxMidSceneNum_ = static_cast<uint32_t>(param);
718 }
719 ConfigFreeMultiWindow();
720 ConfigWindowSizeLimits();
721 ConfigAppsWithDeduplicatedWindowStatus();
722 ConfigSnapshotScale();
723 ConfigWindowSceneXml(config);
724 }
725
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)726 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
727 {
728 WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
729 if (item.IsMap()) {
730 ConfigSystemUIStatusBar(item);
731 }
732 item = config["backgroundScreenLock"].GetProp("enable");
733 if (item.IsBool()) {
734 appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
735 }
736 item = config["rotationMode"];
737 if (item.IsString()) {
738 appWindowSceneConfig_.rotationMode_ = item.stringValue_;
739 }
740 item = config["immersive"];
741 if (item.IsMap()) {
742 ConfigWindowImmersive(item);
743 }
744 item = config["supportTypeFloatWindow"].GetProp("enable");
745 if (item.IsBool()) {
746 systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
747 }
748 item = config["singleHandCompatibleMode"];
749 if (item.IsMap()) {
750 ConfigSingleHandCompatibleMode(item);
751 }
752 }
753
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)754 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
755 {
756 AppWindowSceneConfig config;
757 WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
758 if (item.IsMap()) {
759 if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
760 appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
761 config.windowImmersive_.desktopStatusBarConfig_;
762 }
763 }
764 item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
765 if (item.IsMap()) {
766 if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
767 appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
768 config.windowImmersive_.upDownStatusBarConfig_;
769 }
770 }
771 item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
772 if (item.IsMap()) {
773 if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
774 appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
775 config.windowImmersive_.leftRightStatusBarConfig_;
776 }
777 }
778 }
779
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)780 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
781 StatusBarConfig& statusBarConfig)
782 {
783 WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
784 if (item.IsBool()) {
785 statusBarConfig.showHide_ = item.boolValue_;
786 }
787 item = config["contentColor"];
788 if (item.IsString()) {
789 statusBarConfig.contentColor_ = item.stringValue_;
790 }
791 item = config["backgroundColor"];
792 if (item.IsString()) {
793 statusBarConfig.backgroundColor_ = item.stringValue_;
794 }
795 return true;
796 }
797
ConfigFreeMultiWindow()798 void SceneSessionManager::ConfigFreeMultiWindow()
799 {
800 const auto& config = WindowSceneConfig::GetConfig();
801 WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
802 if (freeMultiWindowConfig.IsMap()) {
803 auto supportItem = freeMultiWindowConfig.GetProp("enable");
804 if (supportItem.IsBool()) {
805 systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
806 }
807 auto item = freeMultiWindowConfig["decor"];
808 if (item.IsMap()) {
809 ConfigDecor(item, false);
810 }
811 int32_t param = -1;
812 item = freeMultiWindowConfig["defaultWindowMode"];
813 if (GetSingleIntItem(item, param) &&
814 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
815 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
816 systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
817 static_cast<WindowMode>(static_cast<uint32_t>(param));
818 }
819 item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
820 if (GetSingleIntItem(item, param) && (param > 0)) {
821 systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
822 }
823 param = -1;
824 item = freeMultiWindowConfig["defaultDragResizeType"];
825 if (GetSingleIntItem(item, param) && param >= 0 &&
826 param < static_cast<int32_t>(DragResizeType::RESIZE_MAX_VALUE)) {
827 systemConfig_.freeMultiWindowConfig_.defaultDragResizeType_ =
828 static_cast<DragResizeType>(static_cast<uint32_t>(param));
829 }
830 }
831 }
832
LoadFreeMultiWindowConfig(bool enable)833 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
834 {
835 FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
836 if (enable) {
837 systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
838 systemConfig_.decorWindowModeSupportType_ = freeMultiWindowConfig.decorWindowModeSupportType_;
839 systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
840 } else {
841 const auto& config = WindowSceneConfig::GetConfig();
842 auto item = config["decor"];
843 if (item.IsMap()) {
844 ConfigDecor(item, true);
845 }
846 int32_t param = -1;
847 item = config["defaultWindowMode"];
848 if (GetSingleIntItem(item, param) &&
849 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
850 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
851 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
852 }
853 }
854 systemConfig_.freeMultiWindowEnable_ = enable;
855 rsInterface_.SetFreeMultiWindowStatus(enable);
856 }
857
GetSystemSessionConfig() const858 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
859 {
860 return systemConfig_;
861 }
862
SwitchFreeMultiWindow(bool enable)863 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
864 {
865 if (!systemConfig_.freeMultiWindowSupport_) {
866 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "device not support");
867 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
868 }
869 LoadFreeMultiWindowConfig(enable);
870 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
871 for (const auto& [_, sceneSession] : sceneSessionMap_) {
872 if (sceneSession == nullptr) {
873 continue;
874 }
875 sceneSession->SwitchFreeMultiWindow(systemConfig_);
876 }
877 UpdateAppHookWindowInfoWhenSwitchFreeMultiWindow(enable);
878 WindowStyleType type = enable ?
879 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
880 SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
881 return WSError::WS_OK;
882 }
883
GetFreeMultiWindowEnableState(bool & enable)884 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
885 {
886 enable = systemConfig_.freeMultiWindowEnable_;
887 return WSError::WS_OK;
888 }
889
SetForegroundWindowNum(uint32_t windowNum)890 WMError SceneSessionManager::SetForegroundWindowNum(uint32_t windowNum)
891 {
892 if (!SessionPermission::IsSystemServiceCalling()) {
893 TLOGE(WmsLogTag::WMS_PC, "The caller is not system service.");
894 return WMError::WM_ERROR_INVALID_PERMISSION;
895 }
896 if (!systemConfig_.freeMultiWindowSupport_) {
897 TLOGE(WmsLogTag::WMS_PC, "device not support");
898 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
899 }
900 taskScheduler_->PostAsyncTask([this, windowNum]() {
901 if (setForegroundWindowNumFunc_) {
902 TLOGNI(WmsLogTag::WMS_PC, "max foreground windowNum: %{public}d", windowNum);
903 setForegroundWindowNumFunc_(windowNum);
904 }
905 }, __func__);
906 return WMError::WM_OK;
907 }
908
RegisterSetForegroundWindowNumCallback(SetForegroundWindowNumFunc && func)909 void SceneSessionManager::RegisterSetForegroundWindowNumCallback(SetForegroundWindowNumFunc&& func)
910 {
911 setForegroundWindowNumFunc_ = std::move(func);
912 }
913
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)914 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject>& token,
915 const ContinueState& continueState)
916 {
917 TLOGI(WmsLogTag::WMS_LIFE, "in");
918 int32_t callingUid = IPCSkeleton::GetCallingUid();
919 return taskScheduler_->PostSyncTask([this, token, continueState, callingUid, where = __func__] {
920 sptr <SceneSession> sceneSession = FindSessionByToken(token);
921 if (sceneSession == nullptr) {
922 TLOGNE(WmsLogTag::DEFAULT, "fail to find session by token.");
923 return WSError::WS_ERROR_INVALID_PARAM;
924 }
925 sceneSession->SetSessionInfoContinueState(continueState);
926 DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
927 static_cast<AAFwk::ContinueState>(continueState), callingUid);
928 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: id:%{public}d, continueState:%{public}d",
929 where, sceneSession->GetPersistentId(), continueState);
930 return WSError::WS_OK;
931 }, __func__);
932 }
933
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)934 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
935 {
936 WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
937 if (item.IsBool()) {
938 if (mainConfig) {
939 systemConfig_.isSystemDecorEnable_ = item.boolValue_;
940 } else {
941 systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
942 }
943 bool decorEnable = item.boolValue_;
944 uint32_t support = 0;
945 std::vector<std::string> supportedModes;
946 item = decorConfig["supportedMode"];
947 if (item.IsStrings()) {
948 supportedModes = *item.stringsValue_;
949 }
950 for (auto mode : supportedModes) {
951 if (mode == "fullscreen") {
952 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
953 } else if (mode == "floating") {
954 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
955 } else if (mode == "pip") {
956 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
957 } else if (mode == "split") {
958 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
959 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
960 } else if (mode == "fb") {
961 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FB;
962 } else {
963 TLOGW(WmsLogTag::DEFAULT, "Invalid supporedMode");
964 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
965 break;
966 }
967 }
968 if (mainConfig && item.IsStrings()) {
969 systemConfig_.decorWindowModeSupportType_ = support;
970 }
971 if (!mainConfig && item.IsStrings()) {
972 systemConfig_.freeMultiWindowConfig_.decorWindowModeSupportType_ = support;
973 }
974 }
975 }
976
AddAlphaToColor(float alpha,std::string & color)977 static void AddAlphaToColor(float alpha, std::string& color)
978 {
979 if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
980 return;
981 }
982
983 uint32_t alphaValue = 0xFF * alpha;
984 std::ostringstream ss;
985 ss << std::hex << alphaValue;
986 std::string strAlpha = ss.str();
987 if (strAlpha.size() == 1) {
988 strAlpha.append(1, '0');
989 }
990
991 color.insert(1, strAlpha);
992 }
993
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)994 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
995 {
996 return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
997 (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) == AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
998 }
999
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)1000 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
1001 {
1002 AppWindowSceneConfig config;
1003 // config corner radius
1004 WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
1005 if (item.IsMap()) {
1006 if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
1007 appWindowSceneConfig_ = config;
1008 // set default corner radius of window by system config
1009 systemConfig_.defaultCornerRadius_ = config.floatCornerRadius_;
1010 }
1011 }
1012
1013 // config shadow
1014 item = effectConfig["appWindows"]["shadow"]["focused"];
1015 if (item.IsMap()) {
1016 if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
1017 appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
1018 }
1019 }
1020 item = effectConfig["appWindows"]["shadow"]["unfocused"];
1021 if (item.IsMap()) {
1022 if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
1023 appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
1024 }
1025 }
1026 AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
1027 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
1028
1029 // config shadow in dark mode
1030 item = effectConfig["appWindows"]["shadowDark"]["focused"];
1031 if (item.IsMap()) {
1032 if (ConfigAppWindowShadow(item, config.focusedShadowDark_)) {
1033 appWindowSceneConfig_.focusedShadowDark_ = config.focusedShadowDark_;
1034 }
1035 }
1036 item = effectConfig["appWindows"]["shadowDark"]["unfocused"];
1037 if (item.IsMap()) {
1038 if (ConfigAppWindowShadow(item, config.unfocusedShadowDark_)) {
1039 appWindowSceneConfig_.unfocusedShadowDark_ = config.unfocusedShadowDark_;
1040 }
1041 }
1042 AddAlphaToColor(appWindowSceneConfig_.focusedShadowDark_.alpha_, appWindowSceneConfig_.focusedShadowDark_.color_);
1043 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadowDark_.alpha_,
1044 appWindowSceneConfig_.unfocusedShadowDark_.color_);
1045
1046 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "successfully");
1047 }
1048
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)1049 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
1050 {
1051 static const std::unordered_map<std::string, float> stringToCornerRadius = {
1052 {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
1053 {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
1054 };
1055
1056 if (item.IsString()) {
1057 auto value = item.stringValue_;
1058 if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
1059 out = stringToCornerRadius.at(value);
1060 return true;
1061 }
1062 }
1063 return false;
1064 }
1065
SetEnableInputEvent(bool enabled)1066 void SceneSessionManager::SetEnableInputEvent(bool enabled)
1067 {
1068 TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
1069 enableInputEvent_ = enabled;
1070
1071 if (recoverStateChangeFunc_ == nullptr) {
1072 return;
1073 }
1074
1075 if (enabled) {
1076 recoverStateChangeFunc_(RecoverState::RECOVER_ENABLE_INPUT);
1077 } else {
1078 recoverStateChangeFunc_(RecoverState::RECOVER_INITIAL);
1079 }
1080
1081 }
1082
IsInputEventEnabled() const1083 bool SceneSessionManager::IsInputEventEnabled() const
1084 {
1085 return enableInputEvent_;
1086 }
1087
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)1088 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
1089 {
1090 for (const auto persistentId : alivePersistentIds_) {
1091 if (std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId) !=
1092 recoveredPersistentIds.end()) {
1093 continue;
1094 }
1095 auto sceneSession = GetSceneSession(persistentId);
1096 if (sceneSession == nullptr) {
1097 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
1098 continue;
1099 }
1100 if (sceneSession->IsRecovered()) {
1101 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
1102 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1103 visibleWindowCountMap_.erase(sceneSession->GetCallingPid());
1104 EraseSceneSessionAndMarkDirtyLocked(persistentId);
1105 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
1106 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
1107 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
1108 }
1109 }
1110 }
1111 }
1112
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)1113 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
1114 {
1115 TLOGI(WmsLogTag::WMS_RECOVER, "persistentIds recovered=%{public}zu. CurrentUserId=%{public}d",
1116 recoveredPersistentIds.size(), currentUserId_.load());
1117
1118 taskScheduler_->PostAsyncTask([this, recoveredPersistentIds]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
1119 ClearUnrecoveredSessions(recoveredPersistentIds);
1120 std::list<AAFwk::SessionInfo> abilitySessionInfos;
1121 for (const auto persistentId : recoveredPersistentIds) {
1122 if (failRecoveredPersistentIdSet_.count(persistentId)) {
1123 TLOGNI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId=%{public}d, continue", persistentId);
1124 continue;
1125 }
1126 auto sceneSession = GetSceneSession(persistentId);
1127 if (sceneSession == nullptr) {
1128 TLOGNE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
1129 continue;
1130 }
1131 const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
1132 TLOGND(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d", persistentId);
1133 abilitySessionInfos.emplace_back(*abilitySessionInfo);
1134 }
1135 std::vector<int32_t> unrecoverableSessionIds;
1136 AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
1137 abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
1138 TLOGNI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds=%{public}zu",
1139 unrecoverableSessionIds.size());
1140 for (const auto sessionId : unrecoverableSessionIds) {
1141 auto sceneSession = GetSceneSession(sessionId);
1142 if (sceneSession == nullptr) {
1143 TLOGNW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId=%{public}d ",
1144 sessionId);
1145 continue;
1146 }
1147 const auto& sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
1148 TLOGNI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId=%{public}d", sessionId);
1149 ExceptionInfo exceptionInfo;
1150 sceneSession->NotifySessionExceptionInner(sceneSessionInfo, exceptionInfo);
1151 }
1152 RemoveFailRecoveredSession();
1153 }, __func__);
1154 }
1155
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)1156 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
1157 WindowShadowConfig& outShadow)
1158 {
1159 WindowSceneConfig::ConfigItem item = shadowConfig["color"];
1160 if (item.IsString()) {
1161 auto color = item.stringValue_;
1162 uint32_t colorValue;
1163 if (!ColorParser::Parse(color, colorValue)) {
1164 return false;
1165 }
1166 outShadow.color_ = color;
1167 }
1168
1169 item = shadowConfig["offsetX"];
1170 if (item.IsFloats()) {
1171 auto offsetX = *item.floatsValue_;
1172 if (offsetX.size() != 1) {
1173 return false;
1174 }
1175 outShadow.offsetX_ = offsetX[0];
1176 }
1177
1178 item = shadowConfig["offsetY"];
1179 if (item.IsFloats()) {
1180 auto offsetY = *item.floatsValue_;
1181 if (offsetY.size() != 1) {
1182 return false;
1183 }
1184 outShadow.offsetY_ = offsetY[0];
1185 }
1186
1187 item = shadowConfig["alpha"];
1188 if (item.IsFloats()) {
1189 auto alpha = *item.floatsValue_;
1190 if (alpha.size() != 1 ||
1191 (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
1192 return false;
1193 }
1194 outShadow.alpha_ = alpha[0];
1195 }
1196
1197 item = shadowConfig["radius"];
1198 if (item.IsFloats()) {
1199 auto radius = *item.floatsValue_;
1200 if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
1201 return false;
1202 }
1203 outShadow.radius_ = radius[0];
1204 }
1205
1206 return true;
1207 }
1208
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)1209 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
1210 KeyboardSceneAnimationConfig& config)
1211 {
1212 if (item.IsMap() && item.mapValue_->count("curve")) {
1213 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1214 config.curveType_ = curveType;
1215 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1216 config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1217 config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1218 config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1219 config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1220 }
1221 }
1222
1223 const WindowSceneConfig::ConfigItem& duration = item["duration"];
1224 if (duration.IsInts()) {
1225 auto numbers = *duration.intsValue_;
1226 if (numbers.size() == 1) {
1227 config.duration_ = static_cast<uint32_t>(numbers[0]);
1228 }
1229 }
1230 }
1231
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)1232 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
1233 {
1234 LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
1235 LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
1236
1237 // config system animation
1238 const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
1239 systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
1240 {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
1241 appConfigIn.duration_);
1242 const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
1243 systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
1244 {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
1245 appConfigOut.duration_);
1246 }
1247
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)1248 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
1249 KeyboardSceneAnimationConfig& animationOut)
1250 {
1251 if (!systemConfig_.animationIn_.curveType_.empty() && !systemConfig_.animationOut_.curveType_.empty()) {
1252 TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
1253 "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
1254 systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
1255 systemConfig_.animationOut_.duration_);
1256 return;
1257 }
1258
1259 // default animation curve params
1260 constexpr char CURVETYPE[] = "interpolatingSpring";
1261 constexpr float IN_CTRLX1 = 0.0f;
1262 constexpr float OUT_CTRLX1 = 4.0f;
1263 constexpr float CTRLY1 = 1.0f;
1264 constexpr float CTRLX2 = 342.0f;
1265 constexpr float CTRLY2 = 37.0f;
1266 constexpr uint32_t DURATION = 150;
1267
1268 if (systemConfig_.animationIn_.curveType_.empty()) {
1269 std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1270 // update system config for client
1271 systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
1272 // update app config for server
1273 animationIn.curveType_ = CURVETYPE;
1274 animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
1275 animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
1276 animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
1277 animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
1278 animationIn.duration_ = DURATION;
1279 TLOGI(WmsLogTag::WMS_KEYBOARD, "config default animationIn");
1280 }
1281
1282 if (systemConfig_.animationOut_.curveType_.empty()) {
1283 std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1284 // update system config for client
1285 systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
1286 // update app config for server
1287 animationOut.curveType_ = CURVETYPE;
1288 animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
1289 animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
1290 animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
1291 animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
1292 animationOut.duration_ = DURATION;
1293 TLOGI(WmsLogTag::WMS_KEYBOARD, "config default animationOut");
1294 }
1295 }
1296
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)1297 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
1298 {
1299 WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
1300 if (item.IsMap() && item.mapValue_->count("curve")) {
1301 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1302 appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
1303 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1304 appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1305 appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1306 appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1307 appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1308 }
1309 }
1310 item = windowAnimationConfig["timing"]["duration"];
1311 if (item.IsInts() && item.intsValue_->size() == 1) {
1312 auto duration = *item.intsValue_;
1313 appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
1314 }
1315 item = windowAnimationConfig["scale"];
1316 if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
1317 auto scales = *item.floatsValue_;
1318 appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
1319 appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
1320 }
1321 item = windowAnimationConfig["rotation"];
1322 if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
1323 auto rotations = *item.floatsValue_;
1324 appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
1325 appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
1326 appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
1327 appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1328 }
1329 item = windowAnimationConfig["translate"];
1330 if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1331 auto translates = *item.floatsValue_;
1332 appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1333 appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1334 }
1335 item = windowAnimationConfig["opacity"];
1336 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1337 auto opacity = *item.floatsValue_;
1338 appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1339 }
1340 }
1341
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)1342 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1343 {
1344 auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1345 auto item = configItem.GetProp("enable");
1346 if (item.IsBool()) {
1347 config.enabled_ = item.boolValue_;
1348 }
1349 item = configItem["timing"];
1350 if (item.IsMap() && item.mapValue_->count("curve")) {
1351 config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1352 }
1353 item = configItem["timing"]["duration"];
1354 if (item.IsInts() && item.intsValue_->size() == 1) {
1355 config.duration_ = (*item.intsValue_)[0];
1356 }
1357 item = configItem["opacityStart"];
1358 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1359 config.opacityStart_ = (*item.floatsValue_)[0];
1360 }
1361 item = configItem["opacityEnd"];
1362 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1363 config.opacityEnd_ = (*item.floatsValue_)[0];
1364 }
1365 }
1366
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)1367 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1368 const WindowSceneConfig::ConfigItem& curveConfig)
1369 {
1370 static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1371 "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1372 static std::unordered_set<std::string> paramCurveSet = {
1373 "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1374
1375 std::string curveName = "easeOut";
1376 const auto& nameItem = curveConfig.GetProp("name");
1377 if (!nameItem.IsString()) {
1378 return {curveName, {}};
1379 }
1380
1381 std::string name = nameItem.stringValue_;
1382 std::vector<float> curveParams;
1383
1384 if (paramCurveSet.find(name) != paramCurveSet.end()) {
1385 curveName = name;
1386 curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1387 if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1388 std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1389 curveParams.begin());
1390 }
1391 } else {
1392 auto iter = curveSet.find(name);
1393 if (iter != curveSet.end()) {
1394 curveName = name;
1395 }
1396 }
1397
1398 return {curveName, curveParams};
1399 }
1400
1401
ConfigSingleHandCompatibleMode(const WindowSceneConfig::ConfigItem & configItem)1402 void SceneSessionManager::ConfigSingleHandCompatibleMode(const WindowSceneConfig::ConfigItem& configItem)
1403 {
1404 auto& config = singleHandCompatibleModeConfig_;
1405 auto item = configItem.GetProp("enable");
1406 if (item.IsBool()) {
1407 config.enabled = item.boolValue_;
1408 }
1409 item = configItem["singleHandScale"];
1410 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1411 config.singleHandScale = (*item.floatsValue_)[0];
1412 }
1413 item = configItem["heightChangeRatio"];
1414 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1415 config.heightChangeRatio = (*item.floatsValue_)[0];
1416 }
1417 item = configItem["widthChangeRatio"];
1418 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1419 config.widthChangeRatio = (*item.floatsValue_)[0];
1420 }
1421 }
1422
ConfigAppsWithDeduplicatedWindowStatus()1423 void SceneSessionManager::ConfigAppsWithDeduplicatedWindowStatus()
1424 {
1425 const auto& config = WindowSceneConfig::GetConfig();
1426 WindowSceneConfig::ConfigItem item = config["appsWithDeduplicatedWindowStatus"];
1427 std::vector<std::string> appsWithDeduplicatedWindowStatus;
1428 if (item.IsStrings()) {
1429 appsWithDeduplicatedWindowStatus = *item.stringsValue_;
1430 }
1431 for (auto&& app : appsWithDeduplicatedWindowStatus) {
1432 if (!app.empty()) {
1433 TLOGI(WmsLogTag::WMS_LAYOUT, "app:%{public}s", app.c_str());
1434 appsWithDeduplicatedWindowStatus_.insert(std::move(app));
1435 }
1436 }
1437 }
1438
SetWindowStatusDeduplicationBySystemConfig(const SessionInfo & sessionInfo,SystemSessionConfig & systemConfig)1439 void SceneSessionManager::SetWindowStatusDeduplicationBySystemConfig(const SessionInfo& sessionInfo,
1440 SystemSessionConfig& systemConfig)
1441 {
1442 std::string bundleName = sessionInfo.bundleName_;
1443 bool deduplicationEnabled = false;
1444 if (appsWithDeduplicatedWindowStatus_.find(bundleName) != appsWithDeduplicatedWindowStatus_.end()) {
1445 TLOGI(WmsLogTag::WMS_LAYOUT, "need skip redundant windowStatus notifications, name:%{public}s",
1446 bundleName.c_str());
1447 deduplicationEnabled = true;
1448 }
1449 systemConfig.skipRedundantWindowStatusNotifications_ = deduplicationEnabled;
1450 }
1451
ConfigWindowSizeLimits()1452 void SceneSessionManager::ConfigWindowSizeLimits()
1453 {
1454 const auto& config = WindowSceneConfig::GetConfig();
1455 WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1456 if (item.IsMap()) {
1457 ConfigMainWindowSizeLimits(item);
1458 }
1459
1460 item = config["subWindowSizeLimits"];
1461 if (item.IsMap()) {
1462 ConfigSubWindowSizeLimits(item);
1463 }
1464
1465 item = config["dialogWindowSizeLimits"];
1466 if (item.IsMap()) {
1467 ConfigDialogWindowSizeLimits(item);
1468 }
1469 }
1470
ConfigDialogWindowSizeLimits(const WindowSceneConfig::ConfigItem & dialogWindowSizeConifg)1471 void SceneSessionManager::ConfigDialogWindowSizeLimits(const WindowSceneConfig::ConfigItem& dialogWindowSizeConifg)
1472 {
1473 auto item = dialogWindowSizeConifg["miniWidth"];
1474 if (item.IsInts()) {
1475 auto numbers = *item.intsValue_;
1476 if (numbers.size() == 1) {
1477 systemConfig_.miniWidthOfDialogWindow_ = static_cast<uint32_t>(numbers[0]);
1478 }
1479 }
1480
1481 item = dialogWindowSizeConifg["miniHeight"];
1482 if (item.IsInts()) {
1483 auto numbers = *item.intsValue_;
1484 if (numbers.size() == 1) {
1485 systemConfig_.miniHeightOfDialogWindow_ = static_cast<uint32_t>(numbers[0]);
1486 }
1487 }
1488 }
1489
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1490 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1491 {
1492 auto item = mainWindowSizeConifg["miniWidth"];
1493 if (item.IsInts()) {
1494 auto numbers = *item.intsValue_;
1495 if (numbers.size() == 1) {
1496 systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1497 }
1498 }
1499
1500 item = mainWindowSizeConifg["miniHeight"];
1501 if (item.IsInts()) {
1502 auto numbers = *item.intsValue_;
1503 if (numbers.size() == 1) {
1504 systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1505 }
1506 }
1507 }
1508
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1509 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1510 {
1511 auto item = subWindowSizeConifg["miniWidth"];
1512 if (item.IsInts()) {
1513 auto numbers = *item.intsValue_;
1514 if (numbers.size() == 1) {
1515 systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1516 }
1517 }
1518
1519 item = subWindowSizeConifg["miniHeight"];
1520 if (item.IsInts()) {
1521 auto numbers = *item.intsValue_;
1522 if (numbers.size() == 1) {
1523 systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1524 }
1525 }
1526 }
1527
ConfigSnapshotScale()1528 void SceneSessionManager::ConfigSnapshotScale()
1529 {
1530 const auto& config = WindowSceneConfig::GetConfig();
1531 WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1532 if (item.IsFloats()) {
1533 auto snapshotScale = *item.floatsValue_;
1534 if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1535 return;
1536 }
1537 snapshotScale_ = snapshotScale[0];
1538 }
1539 }
1540
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1541 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1542 {
1543 TLOGI(WmsLogTag::WMS_IMMS, "load");
1544 WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1545 if (item.IsInts() && item.intsValue_->size() == 1) {
1546 bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1547 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1548 TLOGI(WmsLogTag::WMS_IMMS, "showInLandscapeMode %{public}d",
1549 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1550 }
1551
1552 item = statusBarConfig["immersiveStatusBarBgColor"];
1553 if (item.IsString()) {
1554 auto color = item.stringValue_;
1555 uint32_t colorValue;
1556 if (!ColorParser::Parse(color, colorValue)) {
1557 return;
1558 }
1559 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1560 TLOGI(WmsLogTag::WMS_IMMS, "immersiveStatusBarBgColor %{public}s",
1561 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1562 }
1563
1564 item = statusBarConfig["immersiveStatusBarContentColor"];
1565 if (item.IsString()) {
1566 auto color = item.stringValue_;
1567 uint32_t colorValue;
1568 if (!ColorParser::Parse(color, colorValue)) {
1569 return;
1570 }
1571 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1572 TLOGI(WmsLogTag::WMS_IMMS, "immersiveStatusBarContentColor %{public}s",
1573 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1574 }
1575 }
1576
ConfigSupportFollowParentWindowLayout()1577 void SceneSessionManager::ConfigSupportFollowParentWindowLayout()
1578 {
1579 TLOGI(WmsLogTag::WMS_SUB, "support");
1580 auto task = [this] {
1581 systemConfig_.supportFollowParentWindowLayout_ = true;
1582 };
1583 taskScheduler_->PostAsyncTask(task, "ConfigSupportFollowParentWindowLayout");
1584 }
1585
ConfigSupportFollowRelativePositionToParent()1586 void SceneSessionManager::ConfigSupportFollowRelativePositionToParent()
1587 {
1588 TLOGI(WmsLogTag::WMS_SUB, "support");
1589 auto task = [this] {
1590 systemConfig_.supportFollowRelativePositionToParent_ = true;
1591 };
1592 taskScheduler_->PostAsyncTask(task, "ConfigSupportFollowRelativePositionToParent");
1593 }
1594
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1595 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1596 {
1597 rootSceneContextWeak_ = contextWeak;
1598 }
1599
CreateRootSceneSession()1600 void SceneSessionManager::CreateRootSceneSession()
1601 {
1602 system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1603 auto specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1604 specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1605 return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1606 };
1607 specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1608 return this->GetSceneSessionVectorByType(type);
1609 };
1610 specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1611 return this->GetAINavigationBarArea(displayId);
1612 };
1613 specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1614 this->UpdateAvoidArea(persistentId);
1615 };
1616 specificCb->onNotifyAvoidAreaChange_ = [this](const sptr<AvoidArea>& avoidArea, AvoidAreaType type) {
1617 onNotifyAvoidAreaChangeForRootFunc_(avoidArea, type, nullptr);
1618 };
1619 rootSceneSession_ = sptr<RootSceneSession>::MakeSptr(specificCb);
1620 rootSceneSession_->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1621 rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1622 rootSceneSession_->SetSystemConfig(systemConfig_);
1623
1624 AppExecFwk::RunningProcessInfo info;
1625 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(getpid(), info);
1626 TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d processName: %{public}s", getpid(), info.processName_.c_str());
1627
1628 if (SCENE_BOARD_BUNDLE_NAME == info.processName_) {
1629 AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1630 TLOGI(WmsLogTag::WMS_LIFE, "SetRootSceneSession success.");
1631 }
1632
1633 rootSceneSession_->RegisterGetStatusBarAvoidHeightFunc([this](DisplayId displayId, WSRect& barArea) {
1634 return this->GetStatusBarAvoidHeight(displayId, barArea);
1635 });
1636 rootSceneSession_->RegisterGetStatusBarConstantlyShowFunc([this](DisplayId displayId, bool& isVisible) {
1637 return this->GetStatusBarConstantlyShow(displayId, isVisible);
1638 });
1639 }
1640
GetRootSceneSession()1641 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1642 {
1643 return rootSceneSession_;
1644 }
1645
UpdateRootSceneAvoidArea()1646 void SceneSessionManager::UpdateRootSceneAvoidArea()
1647 {
1648 UpdateAvoidArea(rootSceneSession_->GetPersistentId());
1649 }
1650
RegisterNotifyRootSceneAvoidAreaChangeFunc(NotifyRootSceneAvoidAreaChangeFunc && func)1651 void SceneSessionManager::RegisterNotifyRootSceneAvoidAreaChangeFunc(NotifyRootSceneAvoidAreaChangeFunc&& func)
1652 {
1653 onNotifyAvoidAreaChangeForRootFunc_ = std::move(func);
1654 }
1655
GetRootSessionAvoidAreaByType(AvoidAreaType type)1656 AvoidArea SceneSessionManager::GetRootSessionAvoidAreaByType(AvoidAreaType type)
1657 {
1658 if (auto rootSession = GetRootSceneSession()) {
1659 return rootSession->GetAvoidAreaByType(type);
1660 }
1661 return {};
1662 }
1663
GetRootSceneStatusBarHeight() const1664 uint32_t SceneSessionManager::GetRootSceneStatusBarHeight() const
1665 {
1666 return static_cast<uint32_t>(rootSceneSession_->GetStatusBarHeight());
1667 }
1668
GetSceneSession(int32_t persistentId)1669 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1670 {
1671 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1672 if (auto it = sceneSessionMap_.find(persistentId); it != sceneSessionMap_.end()) {
1673 return it->second;
1674 }
1675 TLOGD(WmsLogTag::DEFAULT, "Not found scene session with id: %{public}d", persistentId);
1676 return nullptr;
1677 }
1678
IsMainWindowByPersistentId(int32_t persistentId)1679 bool SceneSessionManager::IsMainWindowByPersistentId(int32_t persistentId)
1680 {
1681 if (persistentId <= INVALID_SESSION_ID) {
1682 return false;
1683 }
1684 if (auto sceneSession = GetSceneSession(persistentId)) {
1685 return SessionHelper::IsMainWindow(sceneSession->GetWindowType());
1686 }
1687 return false;
1688 }
1689
GetMainSessionByPersistentId(int32_t persistentId) const1690 sptr<SceneSession> SceneSessionManager::GetMainSessionByPersistentId(int32_t persistentId) const
1691 {
1692 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1693 auto it = sceneSessionMap_.find(persistentId);
1694 if (it != sceneSessionMap_.end() && it->second && SessionHelper::IsMainWindow(it->second->GetWindowType())) {
1695 return it->second;
1696 }
1697 return nullptr;
1698 }
1699
GetMainSessionByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::vector<sptr<SceneSession>> & mainSessions)1700 void SceneSessionManager::GetMainSessionByBundleNameAndAppIndex(
1701 const std::string& bundleName, int32_t appIndex, std::vector<sptr<SceneSession>>& mainSessions)
1702 {
1703 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1704 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1705 if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName &&
1706 sceneSession->GetSessionInfo().appIndex_ == appIndex &&
1707 SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1708 mainSessions.push_back(sceneSession);
1709 }
1710 }
1711 }
1712
GetMainSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,std::vector<sptr<SceneSession>> & mainSessions) const1713 void SceneSessionManager::GetMainSessionByAbilityInfo(const AbilityInfoBase& abilityInfo,
1714 std::vector<sptr<SceneSession>>& mainSessions) const
1715 {
1716 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1717 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1718 if (!sceneSession || !SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1719 continue;
1720 }
1721 if (sceneSession->GetSessionInfo().bundleName_ == abilityInfo.bundleName &&
1722 sceneSession->GetSessionInfo().moduleName_ == abilityInfo.moduleName &&
1723 sceneSession->GetSessionInfo().abilityName_ == abilityInfo.abilityName &&
1724 sceneSession->GetSessionInfo().appIndex_ == abilityInfo.appIndex) {
1725 mainSessions.push_back(sceneSession);
1726 }
1727 }
1728 }
1729
GetSceneSessionByIdentityInfo(const SessionIdentityInfo & info)1730 sptr<SceneSession> SceneSessionManager::GetSceneSessionByIdentityInfo(const SessionIdentityInfo& info)
1731 {
1732 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1733 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1734 if (!sceneSession) {
1735 return nullptr;
1736 }
1737 if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1738 sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1739 sceneSession->GetSessionInfo().appInstanceKey_ != info.instanceKey_ ||
1740 sceneSession->GetSessionInfo().specifiedFlag_ != info.specifiedFlag_ ||
1741 sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1742 continue;
1743 }
1744 const auto& sessionModuleName = sceneSession->GetSessionInfo().moduleName_;
1745 const auto& sessionAbilityName = sceneSession->GetSessionInfo().abilityName_;
1746 if (info.isAtomicService_) {
1747 if ((sessionModuleName.empty() || sessionModuleName == info.moduleName_) &&
1748 (sessionAbilityName.empty() || sessionAbilityName == info.abilityName_)) {
1749 return sceneSession;
1750 }
1751 } else if (sessionModuleName == info.moduleName_ && sessionAbilityName == info.abilityName_) {
1752 return sceneSession;
1753 }
1754 }
1755 return nullptr;
1756 }
1757
GetSceneSessionByType(WindowType type)1758 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1759 {
1760 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1761 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1762 if (sceneSession && sceneSession->GetWindowType() == type) {
1763 return sceneSession;
1764 }
1765 }
1766 return nullptr;
1767 }
1768
GetSceneSessionByBundleName(const std::string & bundleName)1769 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionByBundleName(const std::string& bundleName)
1770 {
1771 std::vector<sptr<SceneSession>> sceneSessionVector;
1772 if (bundleName.empty()) {
1773 return sceneSessionVector;
1774 }
1775 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1776 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1777 if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName) {
1778 sceneSessionVector.emplace_back(sceneSession);
1779 }
1780 }
1781 return sceneSessionVector;
1782 }
1783
GetSceneSessionVectorByTypeAndDisplayId(WindowType type,uint64_t displayId)1784 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByTypeAndDisplayId(
1785 WindowType type, uint64_t displayId)
1786 {
1787 if (displayId == DISPLAY_ID_INVALID) {
1788 TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1789 return {};
1790 }
1791 std::vector<sptr<SceneSession>> sceneSessionVector;
1792 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1793 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1794 if (sceneSession->GetWindowType() == type &&
1795 sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1796 sceneSessionVector.emplace_back(sceneSession);
1797 }
1798 }
1799 return sceneSessionVector;
1800 }
1801
GetSceneSessionVectorByType(WindowType type)1802 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
1803 {
1804 std::vector<sptr<SceneSession>> sceneSessionVector;
1805 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1806 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1807 if (sceneSession->GetWindowType() == type) {
1808 sceneSessionVector.emplace_back(sceneSession);
1809 }
1810 }
1811 return sceneSessionVector;
1812 }
1813
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1814 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1815 sptr<WindowSessionProperty> property)
1816 {
1817 if (sceneSession == nullptr || property == nullptr) {
1818 TLOGD(WmsLogTag::WMS_DIALOG, "Session or property is null");
1819 return WSError::WS_ERROR_NULLPTR;
1820 }
1821 auto parentPersistentId = property->GetParentPersistentId();
1822 sceneSession->SetParentPersistentId(parentPersistentId);
1823 if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1824 auto parentSession = GetSceneSession(parentPersistentId);
1825 if (parentSession == nullptr) {
1826 TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1827 return WSError::WS_ERROR_NULLPTR;
1828 }
1829 sceneSession->GetSessionProperty()->SetSubWindowZLevel(property->GetSubWindowZLevel());
1830 parentSession->BindDialogSessionTarget(sceneSession);
1831 parentSession->BindDialogToParentSession(sceneSession);
1832 sceneSession->SetParentSession(parentSession);
1833 TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1834 sceneSession->GetPersistentId(), parentPersistentId);
1835 }
1836 return WSError::WS_OK;
1837 }
1838
CreateSpecificSessionCallback()1839 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1840 {
1841 sptr<SceneSession::SpecificSessionCallback> specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1842 specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1843 return this->RequestSceneSession(sessionInfo, property);
1844 };
1845 specificCb->onDestroy_ = [this](const int32_t persistentId) {
1846 return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1847 };
1848 specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1849 this->ClearDisplayStatusBarTemporarilyFlags();
1850 };
1851 specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1852 this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1853 };
1854 specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1855 return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1856 };
1857 specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1858 return this->GetSceneSessionVectorByType(type);
1859 };
1860 specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1861 this->UpdateAvoidArea(persistentId);
1862 };
1863 specificCb->onGetStatusBarDefaultVisibilityByDisplayId_ = [this](DisplayId displayId) {
1864 return this->GetStatusBarDefaultVisibilityByDisplayId(displayId);
1865 };
1866 specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1867 this->NotifyWindowInfoChange(persistentId, type);
1868 };
1869 specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1870 this->NotifyMMIWindowPidChange(windowId, startMoving);
1871 };
1872 specificCb->onSessionTouchOutside_ = [this](int32_t persistentId, DisplayId displayId) {
1873 this->NotifySessionTouchOutside(persistentId, displayId);
1874 };
1875 specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1876 return this->GetAINavigationBarArea(displayId);
1877 };
1878 specificCb->onGetNextAvoidAreaRectInfo_ = [this](
1879 DisplayId displayId, AvoidAreaType type, std::pair<WSRect, WSRect>& nextSystemBarAvoidAreaRectInfo) {
1880 return this->GetNextAvoidRectInfo(displayId, type, nextSystemBarAvoidAreaRectInfo);
1881 };
1882 specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1883 this->OnOutsideDownEvent(x, y);
1884 };
1885 specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1886 return this->HandleSecureSessionShouldHide(sceneSession);
1887 };
1888 specificCb->onNotifyWindowSystemBarPropertyChangeFunc_ = [this](
1889 WindowType type, const SystemBarProperty& systemBarProperty) {
1890 return this->NotifyWindowSystemBarPropertyChange(type, systemBarProperty);
1891 };
1892 specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1893 this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1894 };
1895 specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1896 this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1897 };
1898 specificCb->onSetSkipEventOnCastPlus_ = [this](int32_t windowId, bool isSkip) {
1899 this->SetSkipEventOnCastPlusInner(windowId, isSkip);
1900 };
1901 specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1902 this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1903 };
1904 specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1905 this->UpdateGestureBackEnabled(persistentId);
1906 };
1907 specificCb->onKeyboardRotationChange_ = [this](int32_t persistentId, Rotation rotation,
1908 std::vector<std::pair<bool, WSRect>>& avoidAreas) {
1909 this->GetKeyboardOccupiedAreaWithRotation(persistentId, rotation, avoidAreas);
1910 };
1911 specificCb->onGetSceneSessionByIdCallback_ = [this](int32_t persistentId) {
1912 return this->GetSceneSession(persistentId);
1913 };
1914 return specificCb;
1915 }
1916
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1917 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1918 {
1919 TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1920 auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1921 if (isSkip) {
1922 if (it == skipSurfaceNodeIds_.end()) {
1923 skipSurfaceNodeIds_.push_back(surfaceNodeId);
1924 } else {
1925 return;
1926 }
1927 } else {
1928 if (it != skipSurfaceNodeIds_.end()) {
1929 skipSurfaceNodeIds_.erase(it);
1930 } else {
1931 return;
1932 }
1933 }
1934 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1935 }
1936
AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)1937 WMError SceneSessionManager::AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
1938 {
1939 if (!SessionPermission::IsSystemCalling()) {
1940 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
1941 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1942 }
1943 auto task = [this, &persistentIds] {
1944 for (const auto persistentId : persistentIds) {
1945 auto session = GetSceneSession(persistentId);
1946 if (!session || SessionHelper::IsSubWindow(session->GetWindowType())) {
1947 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] not found or is sub window", persistentId);
1948 continue;
1949 }
1950 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] add to virtual screen black list", persistentId);
1951 auto surfaceNode = session->GetSurfaceNode();
1952 if (surfaceNode) {
1953 auto surfaceNodeId = surfaceNode->GetId();
1954 if (std::count(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId) == 0) {
1955 skipSurfaceNodeIds_.push_back(surfaceNodeId);
1956 }
1957 }
1958 auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
1959 if (leashWinSurfaceNode) {
1960 auto leashWinSurfaceNodeId = leashWinSurfaceNode->GetId();
1961 if (std::count(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), leashWinSurfaceNodeId) == 0) {
1962 skipSurfaceNodeIds_.push_back(leashWinSurfaceNodeId);
1963 }
1964 }
1965 SetSkipEventOnCastPlusInner(persistentId, true);
1966 }
1967 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1968 return WMError::WM_OK;
1969 };
1970 return taskScheduler_->PostSyncTask(task, __func__);
1971 }
1972
RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)1973 WMError SceneSessionManager::RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
1974 {
1975 if (!SessionPermission::IsSystemCalling()) {
1976 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
1977 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1978 }
1979 auto task = [this, &persistentIds] {
1980 for (const auto persistentId : persistentIds) {
1981 auto session = GetSceneSession(persistentId);
1982 if (!session || SessionHelper::IsSubWindow(session->GetWindowType())) {
1983 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] not found or is sub window", persistentId);
1984 continue;
1985 }
1986 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] remove from virtual screen black list", persistentId);
1987 auto surfaceNode = session->GetSurfaceNode();
1988 if (surfaceNode) {
1989 auto surfaceNodeId = surfaceNode->GetId();
1990 auto iter = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1991 if (iter != skipSurfaceNodeIds_.end()) {
1992 skipSurfaceNodeIds_.erase(iter);
1993 }
1994 }
1995 auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
1996 if (leashWinSurfaceNode) {
1997 auto leashWinSurfaceNodeId = leashWinSurfaceNode->GetId();
1998 auto iter = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), leashWinSurfaceNodeId);
1999 if (iter != skipSurfaceNodeIds_.end()) {
2000 skipSurfaceNodeIds_.erase(iter);
2001 }
2002 }
2003 SetSkipEventOnCastPlusInner(persistentId, false);
2004 }
2005 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
2006 return WMError::WM_OK;
2007 };
2008 return taskScheduler_->PostSyncTask(task, __func__);
2009 }
2010
SetScreenPrivacyWindowTagSwitch(uint64_t screenId,const std::vector<std::string> & privacyWindowTags,bool enable)2011 WMError SceneSessionManager::SetScreenPrivacyWindowTagSwitch(
2012 uint64_t screenId, const std::vector<std::string>& privacyWindowTags, bool enable)
2013 {
2014 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "screenId: %{public}" PRIu64 ", tagsize: %{public}zu, enable: %{public}d",
2015 screenId, privacyWindowTags.size(), enable);
2016 if (!SessionPermission::IsSACalling()) {
2017 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
2018 return WMError::WM_ERROR_INVALID_PERMISSION;
2019 }
2020 if (enable) {
2021 for (const auto& privacyWindowTag : privacyWindowTags) {
2022 screenRSBlackListConfigMap_[screenId].insert({ .privacyWindowTag = privacyWindowTag });
2023 }
2024 FlushSessionBlackListInfoMapWhenAdd(screenId);
2025 } else {
2026 for (const auto& privacyWindowTag : privacyWindowTags) {
2027 screenRSBlackListConfigMap_[screenId].erase({ .privacyWindowTag = privacyWindowTag });
2028 if (screenRSBlackListConfigMap_[screenId].empty()) {
2029 screenRSBlackListConfigMap_.erase(screenId);
2030 break;
2031 }
2032 }
2033 FlushSessionBlackListInfoMapWhenRemove(screenId);
2034 }
2035 return WMError::WM_OK;
2036 }
2037
SetSkipEventOnCastPlusInner(int32_t windowId,bool isSkip)2038 void SceneSessionManager::SetSkipEventOnCastPlusInner(int32_t windowId, bool isSkip)
2039 {
2040 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Wid: %{public}d, isSkip: %{public}d", windowId, isSkip);
2041 auto sceneSession = GetSceneSession(windowId);
2042 if(sceneSession == nullptr) {
2043 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "SceneSession is nullptr, Wid: %{public}d", windowId);
2044 return;
2045 }
2046 sceneSession->GetSessionProperty()->SetSkipEventOnCastPlus(isSkip);
2047 FlushWindowInfoToMMI(true);
2048 }
2049
CreateKeyboardSessionCallback()2050 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
2051 {
2052 auto keyboardCb = sptr<KeyboardSession::KeyboardSessionCallback>::MakeSptr();
2053 keyboardCb->onGetSceneSession = [this](int32_t persistentId) {
2054 return this->GetSceneSession(persistentId);
2055 };
2056 keyboardCb->onGetFocusedSessionId = [this] {
2057 return this->GetFocusedSessionId();
2058 };
2059 keyboardCb->onCallingSessionIdChange = callingSessionIdChangeFunc_;
2060 keyboardCb->onSystemKeyboardAvoidChange = [this](DisplayId displayId, SystemKeyboardAvoidChangeReason reason) {
2061 this->HandleKeyboardAvoidChange(nullptr, displayId, reason);
2062 };
2063 keyboardCb->onNotifyOccupiedAreaChange = [this](const sptr<OccupiedAreaChangeInfo>& info) {
2064 this->onNotifyAvoidAreaChangeForRootFunc_(nullptr, AvoidAreaType::TYPE_KEYBOARD, info);
2065 };
2066 keyboardCb->isLastFrameLayoutFinished = [this]() {
2067 if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
2068 TLOGE(WmsLogTag::WMS_KEYBOARD, "isRootSceneLastFrameLayoutFinishedFunc_ is nullptr");
2069 return true;
2070 }
2071 return isRootSceneLastFrameLayoutFinishedFunc_();
2072 };
2073 return keyboardCb;
2074 }
2075
CheckWindowId(int32_t windowId,int32_t & pid)2076 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
2077 {
2078 if (!SessionPermission::IsSystemCalling()) {
2079 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
2080 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2081 }
2082
2083 auto task = [this, windowId, &pid] {
2084 pid = INVALID_PID;
2085 auto sceneSession = GetSceneSession(windowId);
2086 if (sceneSession == nullptr) {
2087 TLOGNE(WmsLogTag::WMS_EVENT, "sceneSession(%{public}d) is nullptr", windowId);
2088 return WMError::WM_ERROR_INVALID_WINDOW;
2089 }
2090 pid = sceneSession->GetCallingPid();
2091 TLOGND(WmsLogTag::WMS_EVENT, "Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
2092 return WMError::WM_OK;
2093 };
2094 return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
2095 }
2096
GetWindowLimits(int32_t windowId,WindowLimits & windowLimits)2097 WMError SceneSessionManager::GetWindowLimits(int32_t windowId, WindowLimits& windowLimits)
2098 {
2099 if (!(systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode())) {
2100 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "not pc device, return.");
2101 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2102 }
2103 if (!SessionPermission::IsSystemCalling()) {
2104 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "permission denied!");
2105 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2106 }
2107 auto sceneSession = GetSceneSession(windowId);
2108 if (!sceneSession) {
2109 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sceneSession(%{public}d) is nullptr", windowId);
2110 return WMError::WM_ERROR_INVALID_WINDOW;
2111 }
2112 auto sessionProperty = sceneSession->GetSessionProperty();
2113 if (!sessionProperty) {
2114 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sessionProperty(%{public}d) is nullptr", windowId);
2115 return WMError::WM_ERROR_INVALID_WINDOW;
2116 }
2117 windowLimits = sessionProperty->GetWindowLimits();
2118 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "GetWindowLimits minWidth:%{public}u, minHeight:%{public}u, "
2119 "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", windowLimits.minWidth_,
2120 windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
2121 return WMError::WM_OK;
2122 }
2123
GetLockScreenZOrder()2124 uint32_t SceneSessionManager::GetLockScreenZOrder()
2125 {
2126 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2127 for (const auto& [persistentId, session] : sceneSessionMap_) {
2128 if (session && session->IsScreenLockWindow()) {
2129 TLOGI(WmsLogTag::WMS_UIEXT, "window %{public}d-%{public}d", persistentId,
2130 session->GetZOrder());
2131 return session->GetZOrder() < DEFAULT_LOCK_SCREEN_ZORDER ? DEFAULT_LOCK_SCREEN_ZORDER :
2132 session->GetZOrder();
2133 }
2134 }
2135 TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not found");
2136 return DEFAULT_LOCK_SCREEN_ZORDER;
2137 }
2138
CheckUIExtensionCreation(int32_t windowId,uint32_t callingTokenId,const AppExecFwk::ElementName & element,AppExecFwk::ExtensionAbilityType extensionAbilityType,int32_t & pid)2139 WMError SceneSessionManager::CheckUIExtensionCreation(int32_t windowId, uint32_t callingTokenId,
2140 const AppExecFwk::ElementName& element, AppExecFwk::ExtensionAbilityType extensionAbilityType, int32_t& pid)
2141 {
2142 if (!SessionPermission::IsSystemCalling()) {
2143 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
2144 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2145 }
2146 auto task = [this, windowId, callingTokenId, &element, extensionAbilityType, &pid] {
2147 pid = INVALID_PID;
2148 auto sceneSession = GetSceneSession(windowId);
2149 if (sceneSession == nullptr) {
2150 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sceneSession(%{public}d) is nullptr", windowId);
2151 return WMError::WM_ERROR_INVALID_WINDOW;
2152 }
2153 pid = sceneSession->GetCallingPid();
2154 if (!IsScreenLocked()) {
2155 TLOGND(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in lock screen");
2156 return WMError::WM_OK;
2157 }
2158 if (IsUserAuthPassed()) {
2159 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: auth passed");
2160 return WMError::WM_OK;
2161 }
2162 // 1. check window whether can show on main window
2163 if (!sceneSession->IsShowOnLockScreen(GetLockScreenZOrder())) {
2164 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not called on lock screen");
2165 return WMError::WM_OK;
2166 }
2167 // 2. check permission
2168 if (!IsUIExtCanShowOnLockScreen(element, callingTokenId, extensionAbilityType)) {
2169 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: no permisson, window id %{public}d, %{public}d", windowId,
2170 callingTokenId);
2171 return WMError::WM_ERROR_INVALID_PERMISSION;
2172 }
2173 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: pass");
2174 return WMError::WM_OK;
2175 };
2176
2177 std::ostringstream ss;
2178 ss << "UIExtOnLockCheck" << "_" << windowId << "_" << callingTokenId;
2179 return taskScheduler_->PostSyncTask(task, ss.str());
2180 }
2181
2182 // windowIds are all main window
OnNotifyAboveLockScreen(const std::vector<int32_t> & windowIds)2183 void SceneSessionManager::OnNotifyAboveLockScreen(const std::vector<int32_t>& windowIds)
2184 {
2185 taskScheduler_->PostSyncTask([this, &windowIds] {
2186 // check every window
2187 for (auto windowId : windowIds) {
2188 auto sceneSession = GetSceneSession(windowId);
2189 if (!sceneSession) {
2190 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sesssion is null for %{public}d", windowId);
2191 continue;
2192 }
2193 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: check for %{public}d", windowId);
2194 sceneSession->OnNotifyAboveLockScreen();
2195 }
2196 return WMError::WM_OK;
2197 }, __func__);
2198 }
2199
GetKeyboardSession(DisplayId displayId,bool isSystemKeyboard)2200 sptr<SceneSession> SceneSessionManager::GetKeyboardSession(DisplayId displayId, bool isSystemKeyboard)
2201 {
2202 if (displayId == DISPLAY_ID_INVALID) {
2203 TLOGE(WmsLogTag::WMS_KEYBOARD, "displayId is invalid.");
2204 return nullptr;
2205 }
2206 sptr<SceneSession> keyboardSession = nullptr;
2207 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2208 for (const auto& [_, sceneSession] : sceneSessionMap_) {
2209 if (sceneSession && sceneSession->GetScreenId() == displayId &&
2210 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
2211 sceneSession->IsSystemKeyboard() == isSystemKeyboard) {
2212 keyboardSession = sceneSession;
2213 break;
2214 }
2215 }
2216 return keyboardSession;
2217 }
2218
HandleKeyboardAvoidChange(const sptr<SceneSession> & sceneSession,DisplayId displayId,SystemKeyboardAvoidChangeReason reason)2219 void SceneSessionManager::HandleKeyboardAvoidChange(const sptr<SceneSession>& sceneSession, DisplayId displayId,
2220 SystemKeyboardAvoidChangeReason reason)
2221 {
2222 if (!systemConfig_.IsPcWindow()) {
2223 TLOGI(WmsLogTag::WMS_KEYBOARD, "this device is not pc.");
2224 return;
2225 }
2226 switch (reason) {
2227 // if the system keyboard's avoid area is active first, deactivate the other keyboard's avoid area
2228 case SystemKeyboardAvoidChangeReason::KEYBOARD_CREATED: {
2229 if (!sceneSession || sceneSession->IsSystemKeyboard()) {
2230 return;
2231 }
2232 sptr<SceneSession> systemKeyboardSession = GetKeyboardSession(displayId, true);
2233 if (systemKeyboardSession && systemKeyboardSession->IsSessionForeground() &&
2234 systemKeyboardSession->GetKeyboardGravity() == SessionGravity::SESSION_GRAVITY_BOTTOM) {
2235 sceneSession->ActivateKeyboardAvoidArea(false, false);
2236 }
2237 break;
2238 }
2239 /*
2240 * activate the system keyboard's avoid area, while it is showing or it's gravity is bottom
2241 * and deactivate other keyboard's avoid area
2242 */
2243 case SystemKeyboardAvoidChangeReason::KEYBOARD_SHOW:
2244 case SystemKeyboardAvoidChangeReason::KEYBOARD_GRAVITY_BOTTOM: {
2245 UpdateKeyboardAvoidAreaActive(true);
2246 break;
2247 }
2248 /*
2249 * when the system keyboard is hiden, disconnect or it's gravity is float
2250 * check for whether other keyboard can be avoided: if yes, avoids the other keyboard
2251 * if no, restores the system keyboard
2252 */
2253 case SystemKeyboardAvoidChangeReason::KEYBOARD_HIDE:
2254 case SystemKeyboardAvoidChangeReason::KEYBOARD_DISCONNECT:
2255 case SystemKeyboardAvoidChangeReason::KEYBOARD_GRAVITY_FLOAT: {
2256 bool keyboardRecalculate = false;
2257 if (auto keyboardSession = GetKeyboardSession(displayId, false)) {
2258 if (keyboardSession->IsSessionForeground() &&
2259 keyboardSession->GetKeyboardGravity() == SessionGravity::SESSION_GRAVITY_BOTTOM) {
2260 keyboardRecalculate = true;
2261 }
2262 keyboardSession->ActivateKeyboardAvoidArea(true, keyboardRecalculate);
2263 }
2264 if (auto sysKeyboardSession = GetKeyboardSession(displayId, true)) {
2265 sysKeyboardSession->ActivateKeyboardAvoidArea(false, !keyboardRecalculate);
2266 }
2267 break;
2268 }
2269 default:
2270 break;
2271 }
2272 }
2273
UpdateKeyboardAvoidAreaActive(bool systemKeyboardAvoidAreaActive)2274 void SceneSessionManager::UpdateKeyboardAvoidAreaActive(bool systemKeyboardAvoidAreaActive)
2275 {
2276 const auto& keyboardSessionVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
2277 if (keyboardSessionVec.empty()) {
2278 TLOGI(WmsLogTag::WMS_KEYBOARD, "there is no keyboard window in the map");
2279 return;
2280 }
2281 for (const auto& keyboardSession : keyboardSessionVec) {
2282 if (!keyboardSession) {
2283 continue;
2284 }
2285 if (keyboardSession->IsSystemKeyboard()) {
2286 keyboardSession->ActivateKeyboardAvoidArea(systemKeyboardAvoidAreaActive, false);
2287 } else {
2288 keyboardSession->ActivateKeyboardAvoidArea(!systemKeyboardAvoidAreaActive, false);
2289 }
2290 }
2291 }
2292
RequestKeyboardPanelSession(const std::string & panelName,uint64_t displayId)2293 sptr<SceneSession> SceneSessionManager::RequestKeyboardPanelSession(const std::string& panelName, uint64_t displayId)
2294 {
2295 SessionInfo panelInfo = {
2296 .bundleName_ = panelName,
2297 .moduleName_ = panelName,
2298 .abilityName_ = panelName,
2299 .isSystem_ = true,
2300 .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
2301 .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
2302 .screenId_ = displayId,
2303 .isRotable_ = true,
2304 };
2305 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
2306 return RequestSceneSession(panelInfo, nullptr);
2307 }
2308
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)2309 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
2310 {
2311 if (!isKeyboardPanelEnabled_) {
2312 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
2313 return;
2314 }
2315 if (keyboardSession == nullptr) {
2316 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
2317 return;
2318 }
2319 const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL);
2320 sptr<SceneSession> panelSession;
2321 for (const auto& session : panelVec) {
2322 if (session && session->IsSystemKeyboard() == keyboardSession->IsSystemKeyboard()) {
2323 panelSession = session;
2324 break;
2325 }
2326 }
2327 /*
2328 * Only 2 scenarios of panelSession is nullptr:
2329 * 1: neither keyboard panel session nor system keyboard panel session is created.
2330 * 2: a panel session has been created already, but it's isSystemKeyboard is not match with the keyboardSesion's
2331 */
2332 if (panelSession == nullptr) {
2333 if (panelVec.size() >= 2) { // 2 is max number of keyboard panel, one input method and one system keyboard
2334 TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
2335 ReportKeyboardCreateException(keyboardSession);
2336 return;
2337 }
2338 std::string panelName = keyboardSession->IsSystemKeyboard() ? "SCBSystemKeyboardPanel" : "SCBKeyboardPanel";
2339 panelSession = RequestKeyboardPanelSession(panelName,
2340 static_cast<uint64_t>(keyboardSession->GetSessionProperty()->GetDisplayId()));
2341 if (panelSession == nullptr) {
2342 TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
2343 return;
2344 }
2345 } else {
2346 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId: %{public}d",
2347 panelSession->GetPersistentId());
2348 }
2349 panelSession->SetIsSystemKeyboard(keyboardSession->IsSystemKeyboard());
2350 keyboardSession->BindKeyboardPanelSession(panelSession);
2351 panelSession->BindKeyboardSession(keyboardSession);
2352 TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
2353 panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
2354 }
2355
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)2356 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
2357 sptr<WindowSessionProperty> property)
2358 {
2359 sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
2360 sptr<SceneSession> sceneSession = nullptr;
2361 if (sessionInfo.isSystem_) {
2362 sceneSession = new SCBSystemSession(sessionInfo, specificCb);
2363 TLOGI(WmsLogTag::DEFAULT, "[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
2364 } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
2365 sceneSession = new MainSession(sessionInfo, specificCb);
2366 TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
2367 } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
2368 sceneSession = new SubSession(sessionInfo, specificCb);
2369 TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
2370 } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2371 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
2372 sceneSession = new KeyboardSession(sessionInfo, specificCb, keyboardCb);
2373 sceneSession->SetIsSystemKeyboard(property->IsSystemKeyboard());
2374 CreateKeyboardPanelSession(sceneSession);
2375 HandleKeyboardAvoidChange(sceneSession, sceneSession->GetScreenId(),
2376 SystemKeyboardAvoidChangeReason::KEYBOARD_CREATED);
2377 TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
2378 } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
2379 sceneSession = new SystemSession(sessionInfo, specificCb);
2380 TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
2381 } else {
2382 TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
2383 }
2384 if (sceneSession != nullptr) {
2385 sceneSession->SetWindowAnimationDuration(appWindowSceneConfig_.windowAnimation_.duration_);
2386 sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
2387 sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
2388 sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
2389 return this->GetAppForceLandscapeConfig(bundleName);
2390 });
2391 sceneSession->RegisterAppHookWindowInfoFunc([this](const std::string& bundleName) {
2392 return this->GetAppHookWindowInfo(bundleName);
2393 });
2394 sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
2395 this->UpdatePrivateStateAndNotify(persistentId);
2396 });
2397 sceneSession->SetNotifyScreenshotAppEventRegisteredFunc([this](int32_t persistentId, bool isRegister) {
2398 this->UpdateSessionScreenshotAppEventListener(persistentId, isRegister);
2399 });
2400 sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
2401 this->NotifyVisibleChange(persistentId);
2402 });
2403 sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
2404 return this->IsLastFrameLayoutFinished(isLayoutFinished);
2405 });
2406 sceneSession->SetIsAINavigationBarAvoidAreaValidFunc([this](const AvoidArea& avoidArea, int32_t sessionBottom) {
2407 return CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea, sessionBottom);
2408 });
2409 sceneSession->RegisterGetStatusBarAvoidHeightFunc([this](DisplayId displayId, WSRect& barArea) {
2410 return this->GetStatusBarAvoidHeight(displayId, barArea);
2411 });
2412 sceneSession->RegisterGetStatusBarConstantlyShowFunc([this](DisplayId displayId, bool& isVisible) {
2413 return this->GetStatusBarConstantlyShow(displayId, isVisible);
2414 });
2415 sceneSession->SetHasRequestedVsyncFunc([this](bool& hasRequestedVsync) {
2416 return this->HasRootSceneRequestedVsync(hasRequestedVsync);
2417 });
2418 sceneSession->SetRequestNextVsyncWhenModeChangeFunc(
2419 [this](const std::shared_ptr<VsyncCallback>& vsyncCallback) {
2420 return this->RequestVsyncByRootSceneWhenModeChange(vsyncCallback);
2421 });
2422 sceneSession->SetGetAllAppUseControlMapFunc([this]() ->
2423 std::unordered_map<std::string, std::unordered_map<ControlAppType, ControlInfo>>& {
2424 return allAppUseControlMap_;
2425 });
2426 sceneSession->RegisterGetFbPanelWindowIdFunc([this](uint32_t& windowId) {
2427 return this->GetFbPanelWindowId(windowId);
2428 });
2429 DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2430 GetAppDragResizeType(sessionInfo.bundleName_, dragResizeType);
2431 sceneSession->SetAppDragResizeType(dragResizeType);
2432 sceneSession->SetKeyFramePolicy(GetAppKeyFramePolicy(sessionInfo.bundleName_));
2433 sceneSession->SetSingleHandTransform(singleHandTransform_);
2434 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, displayId: %{public}" PRIu64,
2435 sceneSession->GetPersistentId(), sceneSession->GetSessionProperty()->GetDisplayId());
2436 }
2437 return sceneSession;
2438 }
2439
GetEffectiveDragResizeType(DragResizeType & dragResizeType)2440 void SceneSessionManager::GetEffectiveDragResizeType(DragResizeType& dragResizeType)
2441 {
2442 if (dragResizeType != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2443 return;
2444 }
2445 if (systemConfig_.freeMultiWindowSupport_) {
2446 if (systemConfig_.freeMultiWindowConfig_.defaultDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2447 dragResizeType = systemConfig_.freeMultiWindowConfig_.defaultDragResizeType_;
2448 return;
2449 }
2450 dragResizeType = DragResizeType::RESIZE_WHEN_DRAG_END;
2451 } else {
2452 dragResizeType = DragResizeType::RESIZE_EACH_FRAME;
2453 }
2454 }
2455
SetGlobalDragResizeType(DragResizeType dragResizeType)2456 WMError SceneSessionManager::SetGlobalDragResizeType(DragResizeType dragResizeType)
2457 {
2458 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
2459 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2460 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2461 return WMError::WM_ERROR_INVALID_PERMISSION;
2462 }
2463 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2464 globalDragResizeType_ = dragResizeType;
2465 taskScheduler_->PostAsyncTask([this] {
2466 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2467 for (const auto& [_, sceneSession] : sceneSessionMap_) {
2468 if (sceneSession != nullptr && WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2469 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
2470 DragResizeType appDragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2471 GetAppDragResizeType(bundleName, appDragResizeType);
2472 TLOGND(WmsLogTag::WMS_LAYOUT, "SetGlobalDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
2473 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), appDragResizeType);
2474 sceneSession->SetAppDragResizeType(appDragResizeType);
2475 }
2476 }
2477 }, __func__);
2478 return WMError::WM_OK;
2479 }
2480
GetGlobalDragResizeType(DragResizeType & dragResizeType)2481 WMError SceneSessionManager::GetGlobalDragResizeType(DragResizeType& dragResizeType)
2482 {
2483 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2484 dragResizeType = globalDragResizeType_;
2485 GetEffectiveDragResizeType(dragResizeType);
2486 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
2487 return WMError::WM_OK;
2488 }
2489
SetAppDragResizeType(const std::string & bundleName,DragResizeType dragResizeType)2490 WMError SceneSessionManager::SetAppDragResizeType(const std::string& bundleName, DragResizeType dragResizeType)
2491 {
2492 TLOGD(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2493 dragResizeType, bundleName.c_str());
2494 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2495 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2496 return WMError::WM_ERROR_INVALID_PERMISSION;
2497 }
2498 return SetAppDragResizeTypeInner(bundleName, dragResizeType);
2499 }
2500
SetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType dragResizeType)2501 WMError SceneSessionManager::SetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType dragResizeType)
2502 {
2503 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2504 dragResizeType, bundleName.c_str());
2505 if (bundleName.empty()) {
2506 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2507 return WMError::WM_ERROR_INVALID_PARAM;
2508 }
2509 std::lock_guard<std::mutex> dragResizeTypeLock(dragResizeTypeMutex_);
2510 appDragResizeTypeMap_[bundleName] = dragResizeType;
2511 GetAppDragResizeTypeInner(bundleName, dragResizeType);
2512 taskScheduler_->PostAsyncTask([this, bundleName, dragResizeType] {
2513 auto allMatchSession = GetSceneSessionByBundleName(bundleName);
2514 for (const auto& sceneSession : allMatchSession) {
2515 if (sceneSession != nullptr) {
2516 TLOGNI(WmsLogTag::WMS_LAYOUT, "SetAppDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
2517 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), dragResizeType);
2518 sceneSession->SetAppDragResizeType(dragResizeType);
2519 }
2520 }
2521 }, __func__);
2522 return WMError::WM_OK;
2523 }
2524
GetAppDragResizeType(const std::string & bundleName,DragResizeType & dragResizeType)2525 WMError SceneSessionManager::GetAppDragResizeType(const std::string& bundleName, DragResizeType& dragResizeType)
2526 {
2527 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2528 return GetAppDragResizeTypeInner(bundleName, dragResizeType);
2529 }
2530
GetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType & dragResizeType)2531 WMError SceneSessionManager::GetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType& dragResizeType)
2532 {
2533 if (bundleName.empty()) {
2534 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2535 return WMError::WM_ERROR_INVALID_PARAM;
2536 }
2537 if (globalDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2538 TLOGI(WmsLogTag::WMS_LAYOUT, "use global value");
2539 dragResizeType = globalDragResizeType_;
2540 return WMError::WM_OK;
2541 }
2542 dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2543 if (auto iter = appDragResizeTypeMap_.find(bundleName); iter != appDragResizeTypeMap_.end()) {
2544 dragResizeType = iter->second;
2545 }
2546 GetEffectiveDragResizeType(dragResizeType);
2547 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2548 dragResizeType, bundleName.c_str());
2549 return WMError::WM_OK;
2550 }
2551
SetAppKeyFramePolicy(const std::string & bundleName,const KeyFramePolicy & keyFramePolicy)2552 WMError SceneSessionManager::SetAppKeyFramePolicy(const std::string& bundleName,
2553 const KeyFramePolicy& keyFramePolicy)
2554 {
2555 TLOGI(WmsLogTag::WMS_LAYOUT, "keyFramePolicy enabled: %{public}d, bundleName: %{public}s",
2556 keyFramePolicy.enabled(), bundleName.c_str());
2557 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2558 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2559 return WMError::WM_ERROR_INVALID_PERMISSION;
2560 }
2561 if (bundleName.empty()) {
2562 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2563 return WMError::WM_ERROR_INVALID_PARAM;
2564 }
2565 {
2566 std::lock_guard<std::mutex> lock(keyFrameMutex_);
2567 appKeyFramePolicyMap_[bundleName] = keyFramePolicy;
2568 }
2569 taskScheduler_->PostAsyncTask([this, bundleName, keyFramePolicy, where = __func__] {
2570 auto allMatchSession = GetSceneSessionByBundleName(bundleName);
2571 for (const auto& sceneSession : allMatchSession) {
2572 if (sceneSession != nullptr && systemConfig_.IsPcWindow() &&
2573 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2574 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: pc main window id: %{public}d, bundleName: %{public}s",
2575 where, sceneSession->GetPersistentId(), bundleName.c_str());
2576 sceneSession->SetKeyFramePolicy(keyFramePolicy);
2577 }
2578 }
2579 }, __func__);
2580 return WMError::WM_OK;
2581 }
2582
GetAppKeyFramePolicy(const std::string & bundleName)2583 KeyFramePolicy SceneSessionManager::GetAppKeyFramePolicy(const std::string& bundleName)
2584 {
2585 {
2586 std::lock_guard<std::mutex> lock(keyFrameMutex_);
2587 if (auto iter = appKeyFramePolicyMap_.find(bundleName); iter != appKeyFramePolicyMap_.end()) {
2588 return iter->second;
2589 }
2590 }
2591 return KeyFramePolicy();
2592 }
2593
GetSceneSessionBySessionInfo(const SessionInfo & sessionInfo)2594 sptr<SceneSession> SceneSessionManager::GetSceneSessionBySessionInfo(const SessionInfo& sessionInfo)
2595 {
2596 if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
2597 if (auto session = GetSceneSession(sessionInfo.persistentId_)) {
2598 TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
2599 return session;
2600 }
2601
2602 if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
2603 TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
2604 "abilityName: %{public}s, appIndex: %{public}d",
2605 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
2606 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
2607 SessionIdentityInfo identityInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_,
2608 sessionInfo.abilityName_, sessionInfo.appIndex_, sessionInfo.appInstanceKey_, sessionInfo.windowType_,
2609 sessionInfo.isAtomicService_ };
2610 auto sceneSession = GetSceneSessionByIdentityInfo(identityInfo);
2611 bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
2612 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
2613 if (isSingleStart) {
2614 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
2615 sessionInfo.persistentId_);
2616 return sceneSession;
2617 }
2618 }
2619 }
2620 return nullptr;
2621 }
2622
GetHookedSessionByModuleName(const SessionInfo & sessionInfo)2623 sptr<SceneSession> SceneSessionManager::GetHookedSessionByModuleName(const SessionInfo& sessionInfo)
2624 {
2625 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2626 sptr<SceneSession> session = nullptr;
2627 for (const auto &[_, sceneSession] : sceneSessionMap_) {
2628 if (!sceneSession || !SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
2629 continue;
2630 }
2631 if (sceneSession->GetSessionInfo().bundleName_ != sessionInfo.bundleName_ ||
2632 sceneSession->GetSessionInfo().moduleName_ != sessionInfo.moduleName_ ||
2633 sceneSession->GetSessionInfo().appIndex_ != sessionInfo.appIndex_ ||
2634 sceneSession->GetSessionInfo().appInstanceKey_ != sessionInfo.appInstanceKey_) {
2635 continue;
2636 }
2637 if (sceneSession->GetSessionInfo().disableDelegator) {
2638 return nullptr;
2639 } else {
2640 session = sceneSession;
2641 }
2642 }
2643 return session;
2644 }
2645
UpdateAbilityHookState(sptr<SceneSession> & sceneSession,bool isAbilityHook)2646 void SceneSessionManager::UpdateAbilityHookState(sptr<SceneSession>& sceneSession, bool isAbilityHook)
2647 {
2648 if (!sceneSession || !isAbilityHook) {
2649 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null or isAbilityHook is false");
2650 return;
2651 }
2652 sceneSession->EditSessionInfo().isAbilityHook_ = isAbilityHook;
2653 RegisterHookSceneSessionActivationFunc(sceneSession);
2654 }
2655
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)2656 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
2657 sptr<WindowSessionProperty> property)
2658 {
2659 auto task = [this, sessionInfo, property, where = __func__] {
2660 if (auto session = GetSceneSessionBySessionInfo(sessionInfo)) {
2661 UpdateSessionDisplayIdBySessionInfo(session, sessionInfo);
2662 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
2663 UpdateAbilityHookState(session, sessionInfo.isAbilityHook_);
2664 return session;
2665 }
2666 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: appName: [%{public}s %{public}s %{public}s] "
2667 "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
2668 where, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
2669 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
2670 static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
2671 sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
2672 if (sceneSession == nullptr) {
2673 TLOGNE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
2674 return sceneSession;
2675 }
2676 if (sessionInfo.isAbilityHook_) {
2677 auto session = GetHookedSessionByModuleName(sessionInfo);
2678 if (session) {
2679 TLOGNW(WmsLogTag::WMS_LIFE, "session disableDelegator %{public}d is still hook, return hook session",
2680 session->GetSessionInfo().disableDelegator);
2681 return session;
2682 }
2683 RegisterHookSceneSessionActivationFunc(sceneSession);
2684 }
2685 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2686 WindowHelper::IsMainWindow(sceneSession->GetWindowType()) &&
2687 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2688 MultiInstanceManager::GetInstance().FillInstanceKeyIfNeed(sceneSession);
2689 }
2690 LOCK_GUARD_EXPR(SCENE_GUARD, InitSceneSession(sceneSession, sessionInfo, property));
2691 PreLoadStartingWindow(sceneSession);
2692 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2693 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
2694 where, sceneSession->GetSessionInfo().ancoSceneState);
2695 bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
2696 const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
2697 if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
2698 TLOGNI(WmsLogTag::WMS_LIFE,
2699 "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
2700 where, reusedSceneSession->GetPersistentId(),
2701 reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
2702 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
2703 return reusedSceneSession;
2704 }
2705 if (isPreHandleSuccess) {
2706 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
2707 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
2708 }
2709 }
2710 {
2711 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2712 sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
2713 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2714 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2715 MultiInstanceManager::GetInstance().IncreaseInstanceKeyRefCount(sceneSession);
2716 }
2717 }
2718 PerformRegisterInRequestSceneSession(sceneSession);
2719 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
2720 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: id: %{public}d, type: %{public}d, instanceKey: %{public}s, "
2721 "displayId: %{public}" PRIu64, where, sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
2722 sceneSession->GetAppInstanceKey().c_str(), sceneSession->GetSessionProperty()->GetDisplayId());
2723 return sceneSession;
2724 };
2725 return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
2726 }
2727
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)2728 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
2729 const sptr<WindowSessionProperty>& property)
2730 {
2731 auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
2732 DisplayId currDisplayId = DISPLAY_ID_INVALID;
2733 if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
2734 currDisplayId = sessionInfo.screenId_;
2735 } else if (callerSession) {
2736 currDisplayId = callerSession->GetSessionProperty()->GetDisplayId();
2737 }
2738 sceneSession->GetSessionProperty()->SetDisplayId(currDisplayId);
2739 sceneSession->SetScreenId(currDisplayId);
2740 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "synchronous screenId with displayId %{public}" PRIu64, currDisplayId);
2741
2742 sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
2743 sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
2744 if (sessionInfo.isSystem_) {
2745 sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
2746 sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
2747 auto rootContext = rootSceneContextWeak_.lock();
2748 sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
2749 } else {
2750 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
2751 "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
2752 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2753 sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
2754 }
2755 RegisterSessionExceptionFunc(sceneSession);
2756 RegisterVisibilityChangedDetectFunc(sceneSession);
2757 RegisterSaveSnapshotFunc(sceneSession);
2758 if (systemConfig_.IsPcOrPcMode()) {
2759 RegisterGetStartWindowConfigCallback(sceneSession);
2760 }
2761 if (systemConfig_.windowUIType_ == WindowUIType::PAD_WINDOW) {
2762 RegisterRemoveSnapshotFunc(sceneSession);
2763 }
2764 // Skip FillSessionInfo when atomicService free-install start.
2765 if (!IsAtomicServiceFreeInstall(sessionInfo)) {
2766 FillSessionInfo(sceneSession);
2767 }
2768 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
2769 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2770 WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
2771 }
2772 if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
2773 sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
2774 }
2775 InitFbWindow(sceneSession, property);
2776 auto systemConfig = systemConfig_;
2777 SetWindowStatusDeduplicationBySystemConfig(sessionInfo, systemConfig);
2778 sceneSession->SetSystemConfig(systemConfig);
2779 sceneSession->InitSnapshotCapacity();
2780 sceneSession->SetSnapshotScale(snapshotScale_);
2781 UpdateParentSessionForDialog(sceneSession, property);
2782 std::string key = sessionInfo.bundleName_ + "_" + sessionInfo.moduleName_ + "_" + sessionInfo.abilityName_ + "_" +
2783 std::to_string(sessionInfo.appIndex_);
2784 if (sessionLockedStateCacheSet_.find(key) != sessionLockedStateCacheSet_.end()) {
2785 sceneSession->NotifySessionLockStateChange(true);
2786 }
2787 }
2788
InitFbWindow(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)2789 void SceneSessionManager::InitFbWindow(const sptr<SceneSession>& sceneSession,
2790 const sptr<WindowSessionProperty>& property)
2791 {
2792 if (property != nullptr && WindowHelper::IsFbWindow(property->GetWindowType())) {
2793 sceneSession->SetFbTemplateInfo(property->GetFbTemplateInfo());
2794 }
2795 }
2796
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)2797 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
2798 {
2799 taskScheduler_->PostAsyncTask([abilityName = sessionInfo.abilityName_,
2800 bundleName = sessionInfo.bundleName_, toScreenId = sessionInfo.screenId_, action, fromScreenId] {
2801 sptr<DisplayChangeInfo> info = sptr<DisplayChangeInfo>::MakeSptr();
2802 info->action_ = action;
2803 info->abilityName_ = std::move(abilityName);
2804 info->bundleName_ = std::move(bundleName);
2805 info->toScreenId_ = toScreenId;
2806 info->fromScreenId_ = fromScreenId;
2807 ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
2808 TLOGNI(WmsLogTag::DMS, "Notify ability %{public}s bundle %{public}s update toScreen id: %{public}" PRIu64,
2809 info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
2810 }, __func__);
2811 }
2812
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)2813 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
2814 {
2815 RegisterSessionSnapshotFunc(sceneSession);
2816 RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
2817 RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
2818 RegisterDisplayIdChangedNotifyManagerFunc(sceneSession);
2819 RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
2820 RegisterGetStateFromManagerFunc(sceneSession);
2821 RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
2822 RegisterAcquireRotateAnimationConfigFunc(sceneSession);
2823 RegisterRequestVsyncFunc(sceneSession);
2824 RegisterSceneSessionDestructNotifyManagerFunc(sceneSession);
2825 RegisterSessionPropertyChangeNotifyManagerFunc(sceneSession);
2826 }
2827
UpdateSceneSessionWant(const SessionInfo & sessionInfo)2828 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
2829 {
2830 if (sessionInfo.persistentId_ != 0) {
2831 auto session = GetSceneSession(sessionInfo.persistentId_);
2832 if (session != nullptr && sessionInfo.want != nullptr) {
2833 TLOGI(WmsLogTag::WMS_MAIN, "Get session id:%{public}d", sessionInfo.persistentId_);
2834 if (!CheckCollaboratorType(session->GetCollaboratorType())) {
2835 session->SetSessionInfoWant(sessionInfo.want);
2836 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
2837 } else {
2838 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
2839 }
2840 } else {
2841 TLOGI(WmsLogTag::WMS_MAIN, "Get session fail(%{public}d), id:%{public}d",
2842 session == nullptr, sessionInfo.persistentId_);
2843 }
2844 } else {
2845 TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
2846 }
2847 }
2848
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)2849 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
2850 {
2851 if (session != nullptr && session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2852 FillSessionInfo(session);
2853 if (CheckCollaboratorType(session->GetCollaboratorType())) {
2854 PreHandleCollaborator(session, persistentId);
2855 }
2856 }
2857 }
2858
SetAbilitySessionInfo(const sptr<SceneSession> & sceneSession,int32_t requestId)2859 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& sceneSession,
2860 int32_t requestId)
2861 {
2862 const auto& sessionInfo = sceneSession->GetSessionInfo();
2863 auto abilitySessionInfo = sptr<AAFwk::SessionInfo>::MakeSptr();
2864 abilitySessionInfo->sessionToken = sptr<ISession>(sceneSession)->AsObject();
2865 abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
2866 std::chrono::system_clock::now()).time_since_epoch().count());
2867 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
2868 abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
2869 sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
2870 abilitySessionInfo->persistentId = sceneSession->GetPersistentId();
2871 abilitySessionInfo->requestCode = sessionInfo.requestCode;
2872 abilitySessionInfo->resultCode = sessionInfo.resultCode;
2873 abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
2874 abilitySessionInfo->startSetting = sessionInfo.startSetting;
2875 abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
2876 abilitySessionInfo->userId = currentUserId_;
2877 abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
2878 abilitySessionInfo->processOptions = sessionInfo.processOptions;
2879 abilitySessionInfo->requestId = sessionInfo.requestId;
2880 abilitySessionInfo->reuseDelegatorWindow = sessionInfo.reuseDelegatorWindow;
2881 abilitySessionInfo->specifiedFlag = sessionInfo.specifiedFlag_;
2882 if (sessionInfo.want != nullptr) {
2883 abilitySessionInfo->want = sessionInfo.GetWantSafely();
2884 } else {
2885 abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
2886 sessionInfo.moduleName_);
2887 }
2888 int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
2889 bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
2890 if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
2891 TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
2892 appIndex, sessionInfo.appIndex_);
2893 }
2894 if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
2895 TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
2896 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
2897 }
2898 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
2899 static_cast<int>(sceneSession->GetSessionProperty()->GetDisplayId()));
2900 abilitySessionInfo->instanceKey = sessionInfo.appInstanceKey_;
2901 if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
2902 sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2903 abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
2904 } else {
2905 TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
2906 }
2907 abilitySessionInfo->scenarios = sessionInfo.scenarios;
2908 TLOGI(WmsLogTag::WMS_LIFE, "Is SCB Call, set flag:%{public}d, persistentId:%{public}d, requestId:%{public}d",
2909 requestId == DEFAULT_REQUEST_FROM_SCB_ID, abilitySessionInfo->persistentId, requestId);
2910 return abilitySessionInfo;
2911 }
2912
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)2913 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
2914 {
2915 if (!isPrepareTerminateEnable_) { // not support prepareTerminate
2916 isPrepareTerminate = false;
2917 TLOGE(WmsLogTag::WMS_MAIN, "not support prepareTerminate, Id:%{public}d", persistentId);
2918 return WSError::WS_OK;
2919 }
2920 auto sceneSession = GetSceneSession(persistentId);
2921 if (sceneSession == nullptr) {
2922 TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is null, Id:%{public}d", persistentId);
2923 isPrepareTerminate = false;
2924 return WSError::WS_ERROR_NULLPTR;
2925 }
2926 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2927 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
2928 PrepareTerminateAbilityBySCB(sceneSessionInfo, isPrepareTerminate);
2929 TLOGI(WmsLogTag::WMS_MAIN, "Id:%{public}d isPrepareTerminate:%{public}d "
2930 "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
2931 return WSError::WS_OK;
2932 }
2933
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive,int32_t requestId)2934 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive,
2935 int32_t requestId)
2936 {
2937 auto task = [this, weakSceneSession = wptr(sceneSession), isNewActive,
2938 requestId]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
2939 OHOS::HiviewDFX::HiTraceId hiTraceId = OHOS::HiviewDFX::HiTraceChain::GetId();
2940 bool isValid = hiTraceId.IsValid();
2941 if (!isValid) {
2942 hiTraceId = OHOS::HiviewDFX::HiTraceChain::Begin("WindowCreateOnCall",
2943 HiTraceFlag::HITRACE_FLAG_INCLUDE_ASYNC | HiTraceFlag::HITRACE_FLAG_NO_BE_INFO |
2944 HiTraceFlag::HITRACE_FLAG_DONOT_CREATE_SPAN);
2945 }
2946 sptr<SceneSession> sceneSession = weakSceneSession.promote();
2947 if (sceneSession == nullptr) {
2948 TLOGNE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
2949 if (!isValid) {
2950 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
2951 }
2952 return WSError::WS_ERROR_NULLPTR;
2953 }
2954 if (!Session::IsScbCoreEnabled()) {
2955 sceneSession->SetForegroundInteractiveStatus(true);
2956 }
2957 auto persistentId = sceneSession->GetPersistentId();
2958 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
2959 TLOGNI(WmsLogTag::WMS_MAIN,
2960 "Request active id:%{public}d, system:%{public}d, isNewActive:%{public}d, requestId:%{public}d",
2961 persistentId, sceneSession->GetSessionInfo().isSystem_,
2962 isNewActive, sceneSession->GetSessionInfo().requestId);
2963 if (!GetSceneSession(persistentId)) {
2964 TLOGNE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
2965 if (!isValid) {
2966 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
2967 }
2968 return WSError::WS_ERROR_INVALID_SESSION;
2969 }
2970 auto ret = RequestSceneSessionActivationInner(sceneSession, isNewActive, requestId);
2971 if (ret == WSError::WS_OK) {
2972 sceneSession->SetExitSplitOnBackground(false);
2973 }
2974 abilityInfoMap_.clear(); // clear cache after terminate
2975 if (!isValid) {
2976 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
2977 }
2978 return ret;
2979 };
2980 std::string taskName = "RequestSceneSessionActivation:PID:" +
2981 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2982 taskScheduler_->PostAsyncTask(task, taskName);
2983 return WSError::WS_OK;
2984 }
2985
NotifyAmsPendingSessionWhenFail(uint32_t resultCode,std::string resultMessage,int32_t requestId)2986 void SceneSessionManager::NotifyAmsPendingSessionWhenFail(uint32_t resultCode, std::string resultMessage,
2987 int32_t requestId)
2988 {
2989 TLOGE(WmsLogTag::WMS_LIFE, "failed, requestId:%{public}d", requestId);
2990 ffrtQueueHelper_->SubmitTask([requestId]{
2991 AAFwk::AbilityManagerClient::GetInstance()->NotifyStartupExceptionBySCB(requestId);
2992 });
2993 }
2994
IsKeyboardForeground()2995 bool SceneSessionManager::IsKeyboardForeground()
2996 {
2997 bool isKeyboardForeground = false;
2998 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2999 for (const auto& [_, sceneSession] : sceneSessionMap_) {
3000 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3001 isKeyboardForeground = sceneSession->IsSessionForeground();
3002 break;
3003 }
3004 }
3005 return isKeyboardForeground;
3006 }
3007
RequestInputMethodCloseKeyboard(const int32_t persistentId)3008 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
3009 {
3010 auto sceneSession = GetSceneSession(persistentId);
3011 if (sceneSession == nullptr) {
3012 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
3013 return;
3014 }
3015 // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
3016 if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
3017 !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
3018 TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
3019 persistentId, sceneSession->GetSessionState());
3020 sceneSession->RequestHideKeyboard(true);
3021 }
3022 }
3023
ResetSceneMissionInfo(const sptr<AAFwk::SessionInfo> & abilitySessionInfo)3024 void SceneSessionManager::ResetSceneMissionInfo(const sptr<AAFwk::SessionInfo>& abilitySessionInfo)
3025 {
3026 abilitySessionInfo->scenarios = 0; // 0 after app started, scenarios reset to initial value
3027 }
3028
StartUIAbilityBySCBTimeoutCheck(const sptr<SceneSession> & sceneSession,const sptr<AAFwk::SessionInfo> & abilitySessionInfo,const uint32_t & windowStateChangeReason,bool & isColdStart)3029 int32_t SceneSessionManager::StartUIAbilityBySCBTimeoutCheck(const sptr<SceneSession>& sceneSession,
3030 const sptr<AAFwk::SessionInfo>& abilitySessionInfo, const uint32_t& windowStateChangeReason, bool& isColdStart)
3031 {
3032 std::shared_ptr<int32_t> retCode = std::make_shared<int32_t>(0);
3033 std::shared_ptr<bool> coldStartFlag = std::make_shared<bool>(false);
3034 bool isTimeout = ffrtQueueHelper_->SubmitTaskAndWait([this, sceneSession, abilitySessionInfo,
3035 coldStartFlag, retCode, windowStateChangeReason] {
3036 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("WMS:SSM:StartUIAbilityBySCB",
3037 START_UI_ABILITY_TIMEOUT/1000, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
3038 auto result = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo,
3039 *coldStartFlag, windowStateChangeReason);
3040 CloseAllFd(sceneSession->GetSessionInfo().want);
3041 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
3042 *retCode = static_cast<int32_t>(result);
3043 TLOGNI(WmsLogTag::WMS_LIFE, "start ui ability retCode: %{public}d", *retCode);
3044 }, START_UI_ABILITY_TIMEOUT);
3045
3046 if (isTimeout) {
3047 TLOGE(WmsLogTag::WMS_LIFE, "start ui ability timeout, currentUserId: %{public}d", currentUserId_.load());
3048 return static_cast<int32_t>(WSError::WS_ERROR_START_UI_ABILITY_TIMEOUT);
3049 }
3050 ResetSceneMissionInfo(abilitySessionInfo);
3051 isColdStart = *coldStartFlag;
3052 return *retCode;
3053 }
3054
CloseAllFd(std::shared_ptr<AAFwk::Want> & want)3055 void SceneSessionManager::CloseAllFd(std::shared_ptr<AAFwk::Want>& want)
3056 {
3057 if (want) {
3058 want->CloseAllFd();
3059 }
3060 }
3061
StartUIAbilityBySCB(sptr<SceneSession> & sceneSession)3062 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& sceneSession)
3063 {
3064 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
3065 return StartUIAbilityBySCB(abilitySessionInfo, sceneSession);
3066 }
3067
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo,sptr<SceneSession> & sceneSession)3068 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo,
3069 sptr<SceneSession>& sceneSession)
3070 {
3071 bool isColdStart = false;
3072 return StartUIAbilityBySCBTimeoutCheck(sceneSession, abilitySessionInfo,
3073 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
3074 }
3075
ChangeUIAbilityVisibilityBySCB(const sptr<SceneSession> & sceneSession,bool visibility,bool isNewWant,bool isFromClient)3076 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(const sptr<SceneSession>& sceneSession,
3077 bool visibility, bool isNewWant, bool isFromClient)
3078 {
3079 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
3080 if (!isFromClient) {
3081 sceneSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
3082 }
3083 if(visibility) {
3084 abilitySessionInfo->isNewWant = isNewWant;
3085 TLOGI(WmsLogTag::WMS_MAIN, "ChangUIAbilityVisibility isNewActive:%{public}d, isVisibility: %{public}d",
3086 abilitySessionInfo->isNewWant, visibility);
3087 }
3088 return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
3089 }
3090
RequestSceneSessionActivationInner(sptr<SceneSession> & sceneSession,bool isNewActive,int32_t requestId)3091 WSError SceneSessionManager::RequestSceneSessionActivationInner(
3092 sptr<SceneSession>& sceneSession, bool isNewActive, int32_t requestId)
3093 {
3094 auto persistentId = sceneSession->GetPersistentId();
3095 RequestInputMethodCloseKeyboard(persistentId);
3096 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3097 sceneSession->SetIsStarting(true);
3098 sceneSession->SetStartingBeforeVisible(true);
3099 }
3100 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) && sceneSession->IsFocusedOnShow()) {
3101 if (Session::IsScbCoreEnabled()) {
3102 if (sceneSession->IsVisibleForeground()) {
3103 RequestSessionFocusImmediately(persistentId);
3104 } else {
3105 PostProcessFocusState state = { true, true, true, FocusChangeReason::SCB_START_APP };
3106 sceneSession->SetPostProcessFocusState(state);
3107 }
3108 } else {
3109 RequestSessionFocusImmediately(persistentId);
3110 }
3111 }
3112 if (sceneSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
3113 FillSessionInfo(sceneSession);
3114 if (CheckCollaboratorType(sceneSession->GetCollaboratorType()) &&
3115 !PreHandleCollaborator(sceneSession, persistentId)) {
3116 TLOGE(WmsLogTag::WMS_LIFE, "[id: %{public}d] ancoSceneState: %{public}d",
3117 persistentId, sceneSession->GetSessionInfo().ancoSceneState);
3118 ExceptionInfo exceptionInfo;
3119 exceptionInfo.needRemoveSession = true;
3120 sceneSession->NotifySessionExceptionInner(SetAbilitySessionInfo(sceneSession), exceptionInfo);
3121 NotifyAmsPendingSessionWhenFail(static_cast<uint32_t>(RequestResultCode::FAIL),
3122 "", sceneSession->GetSessionInfo().requestId);
3123 return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
3124 }
3125 }
3126 sceneSession->NotifyActivation();
3127 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession, requestId);
3128 sceneSessionInfo->isNewWant = isNewActive;
3129 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3130 sceneSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, sceneSessionInfo->persistentId);
3131 sceneSessionInfo->collaboratorType = sceneSession->GetCollaboratorType();
3132 }
3133 TLOGI(WmsLogTag::WMS_LIFE, "[id: %{public}d] want-ability: %{public}s, bundle: %{public}s, "
3134 "module: %{public}s, uri: %{public}s, appIndex: %{public}d, requestId:%{public}d", persistentId,
3135 sceneSessionInfo->want.GetElement().GetAbilityName().c_str(),
3136 sceneSessionInfo->want.GetElement().GetBundleName().c_str(),
3137 sceneSessionInfo->want.GetElement().GetModuleName().c_str(),
3138 sceneSessionInfo->want.GetElement().GetURI().c_str(),
3139 sceneSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0),
3140 sceneSessionInfo->requestId);
3141 int32_t errCode = ERR_OK;
3142 bool isColdStart = false;
3143 if (!sceneSession->IsSessionForeground()) {
3144 listenerController_->NotifySessionLifecycleEvent(ISessionLifecycleListener::SessionLifecycleEvent::FOREGROUND,
3145 sceneSession->GetSessionInfo());
3146 }
3147 if (!systemConfig_.backgroundswitch || sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc()) {
3148 TLOGI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Begin StartUIAbility, system: %{public}u", persistentId,
3149 static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
3150 errCode = StartUIAbilityBySCBTimeoutCheck(sceneSession, sceneSessionInfo,
3151 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
3152 } else {
3153 TLOGI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Background switch on, isNewActive %{public}d state %{public}u "
3154 "reuseDelegatorWindow %{public}d", persistentId,
3155 isNewActive, sceneSession->GetSessionState(), sceneSession->GetSessionInfo().reuseDelegatorWindow);
3156 if (isNewActive || sceneSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
3157 sceneSession->GetSessionState() == SessionState::STATE_END ||
3158 sceneSession->GetSessionInfo().reuseDelegatorWindow) {
3159 TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
3160 static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
3161 errCode = StartUIAbilityBySCBTimeoutCheck(sceneSession, sceneSessionInfo,
3162 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
3163 } else {
3164 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
3165 sceneSession->NotifySessionForeground(1, true);
3166 }
3167 }
3168 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3169 WindowInfoReporter::GetInstance().InsertShowReportInfo(sceneSession->GetSessionInfo().bundleName_);
3170 }
3171 NotifyCollaboratorAfterStart(sceneSession, sceneSessionInfo);
3172 if (errCode != ERR_OK) {
3173 TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
3174 ExceptionInfo exceptionInfo;
3175 exceptionInfo.needRemoveSession = true;
3176 sceneSession->NotifySessionExceptionInner(sceneSessionInfo, exceptionInfo, false, true);
3177 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
3178 startUIAbilityErrorFunc_(
3179 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
3180 }
3181 }
3182 if (isColdStart) {
3183 TLOGI(WmsLogTag::WMS_MAIN, "Cold start, identityToken:%{public}s, bundleName:%{public}s",
3184 sceneSessionInfo->identityToken.c_str(), sceneSession->GetSessionInfo().bundleName_.c_str());
3185 sceneSession->SetClientIdentityToken(sceneSessionInfo->identityToken);
3186 sceneSession->ResetSessionConnectState();
3187 sceneSession->ResetIsActive();
3188 sceneSession->UpdatePrivacyModeControlInfo();
3189 }
3190 return WSError::WS_OK;
3191 }
3192
NotifyCollaboratorAfterStart(sptr<SceneSession> & sceneSession,sptr<AAFwk::SessionInfo> & sceneSessionInfo)3193 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& sceneSession,
3194 sptr<AAFwk::SessionInfo>& sceneSessionInfo)
3195 {
3196 if (sceneSession == nullptr || sceneSessionInfo == nullptr) {
3197 return;
3198 }
3199 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3200 NotifyLoadAbility(sceneSession->GetCollaboratorType(),
3201 sceneSessionInfo, sceneSession->GetSessionInfo().abilityInfo);
3202 NotifyUpdateSessionInfo(sceneSession);
3203 NotifyMoveSessionToForeground(sceneSession->GetCollaboratorType(), sceneSessionInfo->persistentId);
3204 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
3205 }
3206 }
3207
IsPcSceneSessionLifecycle(const sptr<SceneSession> & sceneSession)3208 bool SceneSessionManager::IsPcSceneSessionLifecycle(const sptr<SceneSession>& sceneSession)
3209 {
3210 bool isPcAppInLargeScreenDevice = sceneSession->GetSessionProperty()->GetIsPcAppInPad();
3211 bool isAppSupportPhoneInPc = sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc();
3212 return (systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) ||
3213 (isPcAppInLargeScreenDevice && !IsScreenLocked() && !systemConfig_.IsPhoneWindow());
3214 }
3215
InitSnapshotCache()3216 void SceneSessionManager::InitSnapshotCache()
3217 {
3218 const static std::unordered_map<WindowUIType, std::size_t> SNAPSHOT_CACHE_CAPACITY_MAP = {
3219 {WindowUIType::PC_WINDOW, MAX_SNAPSHOT_IN_RECENT_PC},
3220 {WindowUIType::PAD_WINDOW, MAX_SNAPSHOT_IN_RECENT_PAD},
3221 {WindowUIType::PHONE_WINDOW, MAX_SNAPSHOT_IN_RECENT_PHONE},
3222 {WindowUIType::INVALID_WINDOW, MAX_SNAPSHOT_IN_RECENT_PHONE},
3223 };
3224
3225 snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(WindowUIType::INVALID_WINDOW);
3226 auto uiType = systemConfig_.windowUIType_;
3227 if (SNAPSHOT_CACHE_CAPACITY_MAP.find(uiType) != SNAPSHOT_CACHE_CAPACITY_MAP.end()) {
3228 snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(uiType);
3229 }
3230 TLOGI(WmsLogTag::WMS_PATTERN, "type: %{public}hhu", uiType);
3231 snapshotLruCache_ = std::make_unique<LruCache>(snapshotCapacity_);
3232 }
3233
PutSnapshotToCache(int32_t persistentId)3234 void SceneSessionManager::PutSnapshotToCache(int32_t persistentId)
3235 {
3236 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
3237 if (int32_t removedCacheId = snapshotLruCache_->Put(persistentId);
3238 removedCacheId != UNDEFINED_REMOVED_KEY) {
3239 if (auto removedCacheSession = GetSceneSession(removedCacheId)) {
3240 removedCacheSession->ResetSnapshot();
3241 } else {
3242 TLOGW(WmsLogTag::WMS_PATTERN, "removedCacheSession:%{public}d nullptr", removedCacheId);
3243 }
3244 }
3245 }
3246
VisitSnapshotFromCache(int32_t persistentId)3247 void SceneSessionManager::VisitSnapshotFromCache(int32_t persistentId)
3248 {
3249 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
3250 if (!snapshotLruCache_->Visit(persistentId)) {
3251 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d not in cache", persistentId);
3252 }
3253 }
3254
RemoveSnapshotFromCache(int32_t persistentId)3255 void SceneSessionManager::RemoveSnapshotFromCache(int32_t persistentId)
3256 {
3257 TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
3258 snapshotLruCache_->Remove(persistentId);
3259 if (auto sceneSession = GetSceneSession(persistentId)) {
3260 sceneSession->ResetSnapshot();
3261 }
3262 }
3263
RegisterSaveSnapshotFunc(const sptr<SceneSession> & sceneSession)3264 WSError SceneSessionManager::RegisterSaveSnapshotFunc(const sptr<SceneSession>& sceneSession)
3265 {
3266 if (sceneSession == nullptr) {
3267 TLOGE(WmsLogTag::WMS_PATTERN, "session is nullptr");
3268 return WSError::WS_ERROR_NULLPTR;
3269 }
3270 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3271 return WSError::WS_ERROR_INVALID_WINDOW;
3272 }
3273 auto persistentId = sceneSession->GetPersistentId();
3274 sceneSession->SetSaveSnapshotCallback([this, persistentId]() {
3275 this->PutSnapshotToCache(persistentId);
3276 });
3277 return WSError::WS_OK;
3278 }
3279
RegisterRemoveSnapshotFunc(const sptr<SceneSession> & sceneSession)3280 WSError SceneSessionManager::RegisterRemoveSnapshotFunc(const sptr<SceneSession>& sceneSession)
3281 {
3282 if (sceneSession == nullptr) {
3283 TLOGE(WmsLogTag::WMS_PATTERN, "session is nullptr");
3284 return WSError::WS_ERROR_NULLPTR;
3285 }
3286 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3287 return WSError::WS_ERROR_INVALID_WINDOW;
3288 }
3289 auto persistentId = sceneSession->GetPersistentId();
3290 sceneSession->SetRemoveSnapshotCallback([this, persistentId]() {
3291 this->RemoveSnapshotFromCache(persistentId);
3292 });
3293 return WSError::WS_OK;
3294 }
3295
ConfigSupportSnapshotAllSessionStatus()3296 void SceneSessionManager::ConfigSupportSnapshotAllSessionStatus()
3297 {
3298 TLOGI(WmsLogTag::WMS_PATTERN, "support");
3299 auto task = [this] {
3300 systemConfig_.supportSnapshotAllSessionStatus_ = true;
3301 };
3302 taskScheduler_->PostAsyncTask(task, "ConfigSupportSnapshotAllSessionStatus");
3303 }
3304
CreateUIEffectController(const sptr<IUIEffectControllerClient> & controllerClient,sptr<IUIEffectController> & controller,int32_t & controllerId)3305 WMError SceneSessionManager::CreateUIEffectController(const sptr<IUIEffectControllerClient>& controllerClient,
3306 sptr<IUIEffectController>& controller, int32_t& controllerId)
3307 {
3308 if (!SessionPermission::IsSystemCalling()) {
3309 TLOGE(WmsLogTag::WMS_ANIMATION, "not system calling, permission denied!");
3310 return WMError::WM_ERROR_NOT_SYSTEM_APP;
3311 }
3312 if (!systemConfig_.IsPhoneWindow() && (!systemConfig_.IsPadWindow() || systemConfig_.IsFreeMultiWindowMode())) {
3313 TLOGE(WmsLogTag::WMS_ANIMATION, "device not support!");
3314 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3315 }
3316 return UIEffectManager::GetInstance().CreateUIEffectController(controllerClient, controller, controllerId);
3317 }
3318
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot,ScreenLockReason reason)3319 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
3320 const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot, ScreenLockReason reason)
3321 {
3322 auto task = [this, weakSceneSession = wptr(sceneSession), isDelegator, isToDesktop, isSaveSnapshot, reason] {
3323 auto sceneSession = weakSceneSession.promote();
3324 if (sceneSession == nullptr) {
3325 TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr");
3326 return WSError::WS_ERROR_NULLPTR;
3327 }
3328 auto persistentId = sceneSession->GetPersistentId();
3329 TLOGNI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Request background, isDelegator:%{public}d "
3330 "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
3331 persistentId, isDelegator, isToDesktop, isSaveSnapshot);
3332 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
3333 TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id: %{public}d paused", sceneSession->GetPersistentId());
3334 sceneSession->UpdateLifecyclePausedInner();
3335 sceneSession->SetActive(false);
3336 sceneSession->UpdatePrivacyModeControlInfo();
3337
3338 if (isToDesktop) {
3339 sceneSession->EditSessionInfo().callerToken_ = nullptr;
3340 sceneSession->EditSessionInfo().callingTokenId_ = 0;
3341 }
3342
3343 sceneSession->BackgroundTask(isSaveSnapshot, reason);
3344 listenerController_->NotifySessionLifecycleEvent(
3345 ISessionLifecycleListener::SessionLifecycleEvent::BACKGROUND, sceneSession->GetSessionInfo());
3346 if (!GetSceneSession(persistentId)) {
3347 TLOGNE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
3348 return WSError::WS_ERROR_INVALID_SESSION;
3349 }
3350 if (persistentId == brightnessSessionId_) {
3351 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
3352 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
3353 UpdateBrightness(focusedSessionId);
3354 }
3355 if (IsPcSceneSessionLifecycle(sceneSession)) {
3356 TLOGNI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Notify session background", persistentId);
3357 sceneSession->NotifySessionBackground(1, true, true);
3358 } else {
3359 TLOGNI(WmsLogTag::WMS_MAIN, "[id: %{public}d] begin MinimzeUIAbility, system: %{public}u",
3360 persistentId, static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
3361 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
3362 if (!isDelegator) {
3363 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, false,
3364 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3365 } else {
3366 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, true,
3367 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3368 }
3369 }
3370
3371 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3372 WindowInfoReporter::GetInstance().InsertHideReportInfo(sceneSession->GetSessionInfo().bundleName_);
3373 }
3374 return WSError::WS_OK;
3375 };
3376 std::string taskName = "RequestSceneSessionBackground:PID:" +
3377 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
3378 taskScheduler_->PostAsyncTask(task, taskName);
3379 return WSError::WS_OK;
3380 }
3381
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)3382 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
3383 {
3384 taskScheduler_->PostAsyncTask([this, weakSceneSession = wptr(sceneSession), interactive] {
3385 auto sceneSession = weakSceneSession.promote();
3386 if (sceneSession == nullptr) {
3387 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
3388 return;
3389 }
3390 auto persistentId = sceneSession->GetPersistentId();
3391 TLOGNI(WmsLogTag::WMS_LIFE, "NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
3392 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
3393 if (!GetSceneSession(persistentId)) {
3394 TLOGNE(WmsLogTag::WMS_LIFE, "session is invalid with %{public}d", persistentId);
3395 return;
3396 }
3397 sceneSession->NotifyForegroundInteractiveStatus(interactive);
3398 }, __func__);
3399 }
3400
DestroyDialogWithMainWindow(const sptr<SceneSession> & sceneSession)3401 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& sceneSession)
3402 {
3403 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
3404 if (sceneSession == nullptr) {
3405 TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
3406 return WSError::WS_ERROR_NULLPTR;
3407 }
3408 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3409 TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", sceneSession->GetPersistentId());
3410 const auto& dialogVec = sceneSession->GetDialogVector();
3411 for (const auto& dialog : dialogVec) {
3412 if (dialog == nullptr) {
3413 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
3414 continue;
3415 }
3416 auto sceneSession = GetSceneSession(dialog->GetPersistentId());
3417 if (sceneSession == nullptr) {
3418 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
3419 return WSError::WS_ERROR_INVALID_SESSION;
3420 }
3421 WindowDestroyNotifyVisibility(sceneSession);
3422 dialog->NotifyDestroy();
3423 dialog->Disconnect();
3424
3425 auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
3426 if (dialogSceneSession != nullptr) {
3427 dialogSceneSession->ClearSpecificSessionCbMap();
3428 }
3429 {
3430 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3431 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
3432 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
3433 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
3434 }
3435 }
3436 sceneSession->ClearDialogVector();
3437 return WSError::WS_OK;
3438 }
3439 return WSError::WS_ERROR_INVALID_SESSION;
3440 }
3441
DestroySubSession(const sptr<SceneSession> & sceneSession)3442 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
3443 {
3444 if (sceneSession == nullptr) {
3445 TLOGW(WmsLogTag::WMS_SUB, "sceneSession is nullptr");
3446 return;
3447 }
3448 for (const auto& subSession : sceneSession->GetSubSession()) {
3449 if (subSession != nullptr) {
3450 const auto persistentId = subSession->GetPersistentId();
3451 TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
3452 DestroyAndDisconnectSpecificSessionInner(persistentId);
3453 }
3454 }
3455 }
3456
DestroyToastSession(const sptr<SceneSession> & sceneSession)3457 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
3458 {
3459 if (sceneSession == nullptr) {
3460 TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
3461 return;
3462 }
3463 for (const auto& toastSession : sceneSession->GetToastSession()) {
3464 if (toastSession != nullptr) {
3465 const auto persistentId = toastSession->GetPersistentId();
3466 TLOGI(WmsLogTag::WMS_TOAST, "id: %{public}d", persistentId);
3467 DestroyAndDisconnectSpecificSessionInner(persistentId);
3468 }
3469 }
3470 }
3471
BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,int32_t fingerId,int32_t action,int32_t wid)3472 void SceneSessionManager::BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
3473 int32_t fingerId, int32_t action, int32_t wid)
3474 {
3475 if (pointerEvent == nullptr) {
3476 TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null, wid:%{public}d fingerId:%{public}d action:%{public}d",
3477 wid, fingerId, action);
3478 return;
3479 }
3480 pointerEvent->SetId(CANCEL_POINTER_ID);
3481 pointerEvent->SetTargetWindowId(wid);
3482 pointerEvent->SetPointerId(fingerId);
3483 pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
3484 MMI::PointerEvent::PointerItem item;
3485 item.SetPointerId(fingerId);
3486 pointerEvent->AddPointerItem(item);
3487 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN) {
3488 pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
3489 } else {
3490 pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_MOUSE);
3491 }
3492 }
3493
SendCancelEventBeforeEraseSession(const sptr<SceneSession> & sceneSession)3494 void SceneSessionManager::SendCancelEventBeforeEraseSession(const sptr<SceneSession>& sceneSession)
3495 {
3496 auto task = [this, needCancelEventSceneSession = sceneSession] {
3497 if (needCancelEventSceneSession == nullptr) {
3498 TLOGI(WmsLogTag::WMS_EVENT, "scenesession is nullptr, needn't send cancel event");
3499 return;
3500 }
3501 auto wid = needCancelEventSceneSession->GetPersistentId();
3502 if (needCancelEventSceneSession->GetMousePointerDownEventStatus()) {
3503 std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
3504 BuildCancelPointerEvent(pointerEvent, 1, MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN, wid);
3505 TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send mouse cancel. wid:%{public}d", wid);
3506 needCancelEventSceneSession->SetMousePointerDownEventStatus(false);
3507 needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
3508 }
3509 std::unordered_set<int32_t> fingerPointerDownStatusList = needCancelEventSceneSession->GetFingerPointerDownStatusList();
3510 if (fingerPointerDownStatusList.empty()) {
3511 return;
3512 }
3513 for (auto fingerId : fingerPointerDownStatusList) {
3514 std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
3515 BuildCancelPointerEvent(pointerEvent, fingerId, MMI::PointerEvent::POINTER_ACTION_DOWN, wid);
3516 TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send touch cancel. wid:%{public}d fingerId:%{public}d",
3517 wid, fingerId);
3518 needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
3519 needCancelEventSceneSession->RemoveFingerPointerDownStatus(fingerId);
3520 }
3521 };
3522 mainHandler_->PostTask(std::move(task), "wms:sendCancelBeforeEraseSession", 0, AppExecFwk::EventQueue::Priority::VIP);
3523 }
3524
EraseSceneSessionMapById(int32_t persistentId)3525 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
3526 {
3527 auto sceneSession = GetSceneSession(persistentId);
3528 if (sceneSession != nullptr) {
3529 RemovePreLoadStartingWindowFromMap(sceneSession->GetSessionInfo());
3530 } else {
3531 TLOGW(WmsLogTag::WMS_PATTERN, "session is nullptr id: %{public}d", persistentId);
3532 }
3533 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3534 EraseSceneSessionAndMarkDirtyLocked(persistentId);
3535 systemTopSceneSessionMap_.erase(persistentId);
3536 nonSystemFloatSceneSessionMap_.erase(persistentId);
3537 SendCancelEventBeforeEraseSession(sceneSession);
3538 if (sceneSession && MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
3539 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
3540 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
3541 }
3542 }
3543
3544 /**
3545 * if visible session is erased, mark dirty
3546 * lock-free
3547 */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)3548 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
3549 {
3550 // get scene session lock-free
3551 auto iter = sceneSessionMap_.find(persistentId);
3552 if (iter == sceneSessionMap_.end()) {
3553 TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
3554 return;
3555 }
3556 const auto& sceneSession = iter->second;
3557 if (sceneSession != nullptr && sceneSession->IsVisible()) {
3558 sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
3559 }
3560 sceneSessionMap_.erase(persistentId);
3561 }
3562
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean,bool isUserRequestedExit)3563 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
3564 bool needRemoveSession, bool isSaveSnapshot, bool isForceClean, bool isUserRequestedExit)
3565 {
3566 auto task = [this, weakSceneSession = wptr(sceneSession), needRemoveSession, isSaveSnapshot, isForceClean,
3567 isUserRequestedExit]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
3568 auto sceneSession = weakSceneSession.promote();
3569 if (sceneSession == nullptr) {
3570 TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
3571 return WSError::WS_ERROR_NULLPTR;
3572 }
3573 auto persistentId = sceneSession->GetPersistentId();
3574 TLOGNI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Destruct session, remove:%{public}d isSaveSnapshot:%{public}d "
3575 "isForceClean:%{public}d isUserRequestedExit:%{public}d", persistentId, needRemoveSession, isSaveSnapshot,
3576 isForceClean, isUserRequestedExit);
3577 RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
3578 avoidAreaListenerSessionSet_.erase(persistentId);
3579 screenshotAppEventListenerSessionSet_.erase(persistentId);
3580 RemoveSessionFromBlackList(sceneSession);
3581 DestroyDialogWithMainWindow(sceneSession);
3582 DestroyToastSession(sceneSession);
3583 DestroySubSession(sceneSession); // destroy sub session by destruction
3584 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
3585 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3586 WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sceneSession->GetSessionInfo().bundleName_);
3587 }
3588 WindowDestroyNotifyVisibility(sceneSession);
3589 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
3590 sceneSession->SetRemoveSnapshotCallback([this, persistentId]() {
3591 this->RemoveSnapshotFromCache(persistentId);
3592 });
3593 sceneSession->DisconnectTask(false, isSaveSnapshot);
3594 if (!GetSceneSession(persistentId)) {
3595 TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
3596 return WSError::WS_ERROR_INVALID_SESSION;
3597 }
3598 startingWindowRdbMgr_->ClearRdbStore();
3599 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
3600 sceneSession->GetCloseAbilityWantAndClean(sceneSessionInfo->want);
3601 ResetSceneSessionInfoWant(sceneSessionInfo);
3602 return RequestSceneSessionDestructionInner(
3603 sceneSession, sceneSessionInfo, needRemoveSession, isForceClean, isUserRequestedExit);
3604 };
3605 std::string taskName = "RequestSceneSessionDestruction:PID:" +
3606 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
3607 taskScheduler_->PostAsyncTask(task, taskName);
3608 return WSError::WS_OK;
3609 }
3610
ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo> & sceneSessionInfo)3611 void SceneSessionManager::ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo>& sceneSessionInfo)
3612 {
3613 if (sceneSessionInfo->resultCode == -1) {
3614 AAFwk::Want want;
3615 std::string keySessionId = sceneSessionInfo->want.GetStringParam(ATOMIC_SERVICE_SESSION_ID);
3616 want.SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
3617 sceneSessionInfo->want = std::move(want);
3618 TLOGI(WmsLogTag::WMS_MAIN, "keySessionId: %{public}s", keySessionId.c_str());
3619 }
3620 }
3621
ResetWantInfo(const sptr<SceneSession> & sceneSession)3622 void SceneSessionManager::ResetWantInfo(const sptr<SceneSession>& sceneSession)
3623 {
3624 if (const auto sessionInfoWant = sceneSession->GetSessionInfo().want) {
3625 const auto& bundleName = sessionInfoWant->GetElement().GetBundleName();
3626 const auto& abilityName = sessionInfoWant->GetElement().GetAbilityName();
3627 const auto& keySessionId = sessionInfoWant->GetStringParam(ATOMIC_SERVICE_SESSION_ID);
3628 AppExecFwk::ElementName element;
3629 element.SetBundleName(bundleName);
3630 element.SetAbilityName(abilityName);
3631 auto want = std::make_shared<AAFwk::Want>();
3632 want->SetElement(element);
3633 want->SetBundle(bundleName);
3634 if (!keySessionId.empty()) {
3635 want->SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
3636 }
3637 sceneSession->SetSessionInfoWant(want);
3638 }
3639 }
3640
RequestSceneSessionDestructionInner(sptr<SceneSession> & sceneSession,sptr<AAFwk::SessionInfo> sceneSessionInfo,const bool needRemoveSession,const bool isForceClean,bool isUserRequestedExit)3641 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& sceneSession,
3642 sptr<AAFwk::SessionInfo> sceneSessionInfo, const bool needRemoveSession, const bool isForceClean,
3643 bool isUserRequestedExit)
3644 {
3645 auto persistentId = sceneSession->GetPersistentId();
3646 TLOGI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Begin CloseUIAbility, system: %{public}d",
3647 persistentId, sceneSession->GetSessionInfo().isSystem_);
3648 if (isForceClean) {
3649 AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit,
3650 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3651 } else {
3652 ffrtQueueHelper_->SubmitTask([sceneSessionInfo, persistentId, isUserRequestedExit, where = __func__] {
3653 auto ret = AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(sceneSessionInfo,
3654 isUserRequestedExit, static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3655 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s close ability ret:%{public}d, persistentId:%{public}d",
3656 where, static_cast<int32_t>(ret), persistentId);
3657 });
3658 }
3659 sceneSession->SetIsUserRequestedExit(isUserRequestedExit);
3660 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
3661 if (needRemoveSession) {
3662 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3663 NotifyClearSession(sceneSession->GetCollaboratorType(), sceneSessionInfo->persistentId);
3664 }
3665 EraseSceneSessionMapById(persistentId);
3666 } else {
3667 // if terminate, reset want. so start from recent, start a new one.
3668 TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
3669 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3670 sceneSession->SetSessionInfoWant(nullptr);
3671 }
3672 ResetWantInfo(sceneSession);
3673 sceneSession->ResetSessionInfoResultCode();
3674 sceneSession->EditSessionInfo().isSetStartWindowType_ = false;
3675 }
3676 NotifySessionForCallback(sceneSession, needRemoveSession);
3677 // Clear js cb map if needed.
3678 sceneSession->ClearJsSceneSessionCbMap(needRemoveSession);
3679 return WSError::WS_OK;
3680 }
3681
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)3682 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
3683 const sptr<SceneSession>& sceneSession)
3684 {
3685 if (sceneSession == nullptr || sessionStage == nullptr) {
3686 TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
3687 return;
3688 }
3689
3690 auto remoteObject = sessionStage->AsObject();
3691 remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
3692 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
3693 TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
3694 return;
3695 }
3696 TLOGD(WmsLogTag::WMS_LIFE, "Id: %{public}d", sceneSession->GetPersistentId());
3697 }
3698
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)3699 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
3700 {
3701 taskScheduler_->PostAsyncTask([this, remoteObject] {
3702 auto iter = remoteObjectMap_.find(remoteObject);
3703 if (iter == remoteObjectMap_.end()) {
3704 TLOGNE(WmsLogTag::WMS_DIALOG, "Invalid remoteObject");
3705 return;
3706 }
3707 TLOGND(WmsLogTag::WMS_DIALOG, "Remote died, id: %{public}d", iter->second);
3708 auto sceneSession = GetSceneSession(iter->second);
3709 if (sceneSession == nullptr) {
3710 TLOGNW(WmsLogTag::WMS_DIALOG, "Remote died, session is nullptr, id: %{public}d", iter->second);
3711 return;
3712 }
3713 DestroyAndDisconnectSpecificSessionInner(iter->second);
3714 }, __func__);
3715 }
3716
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)3717 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
3718 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3719 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
3720 SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
3721 {
3722 if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
3723 TLOGE(WmsLogTag::WMS_LIFE, "create system window or modal subwindow permission denied!");
3724 return WSError::WS_ERROR_NOT_SYSTEM_APP;
3725 }
3726 auto parentSession = GetSceneSession(property->GetParentPersistentId());
3727 if (parentSession) {
3728 auto parentProperty = parentSession->GetSessionProperty();
3729 if (parentProperty->GetSubWindowLevel() >= MAX_SUB_WINDOW_LEVEL) {
3730 TLOGE(WmsLogTag::WMS_SUB, "sub window level exceeds limit");
3731 return WSError::WS_ERROR_INVALID_WINDOW;
3732 }
3733 property->SetSubWindowLevel(parentProperty->GetSubWindowLevel() + 1);
3734 }
3735 auto initClientDisplayId = UpdateSpecificSessionClientDisplayId(property);
3736 bool shouldBlock = false;
3737 bool isSystemCalling = SessionPermission::IsSystemCalling();
3738 if (!isSystemCalling) {
3739 if (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT && !systemConfig_.IsPcWindow()) {
3740 shouldBlock = property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load();
3741 } else if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && parentSession) {
3742 shouldBlock = parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
3743 }
3744 }
3745 if (shouldBlock) {
3746 TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
3747 return WSError::WS_ERROR_INVALID_OPERATION;
3748 }
3749 bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
3750 if (!isPhoneOrPad && property->GetWindowType() == WindowType::WINDOW_TYPE_MUTISCREEN_COLLABORATION) {
3751 TLOGE(WmsLogTag::WMS_LIFE, "only phone or pad can create mutiScreen collaboration window");
3752 return WSError::WS_ERROR_INVALID_OPERATION;
3753 }
3754
3755 if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
3756 WSError err = CheckSubSessionStartedByExtensionAndSetDisplayId(token, property, sessionStage);
3757 if (err != WSError::WS_OK) {
3758 return err;
3759 }
3760 }
3761 // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
3762 if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
3763 TLOGE(WmsLogTag::DEFAULT, "The alarm window has been deprecated!");
3764 return WSError::WS_ERROR_INVALID_WINDOW;
3765 }
3766
3767 if (property->GetWindowType() == WindowType::WINDOW_TYPE_FB) {
3768 auto ret = IsFloatingBallValid(parentSession);
3769 if (ret != WSError::WS_OK) {
3770 return ret;
3771 }
3772 }
3773
3774 TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
3775 property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
3776
3777 // Get pid and uid before posting task.
3778 auto pid = IPCSkeleton::GetCallingRealPid();
3779 auto uid = IPCSkeleton::GetCallingUid();
3780 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &persistentId, &session, &systemConfig, token,
3781 pid, uid, isSystemCalling, initClientDisplayId]() {
3782 if (property == nullptr) {
3783 TLOGNE(WmsLogTag::WMS_LIFE, "property is nullptr");
3784 return WSError::WS_ERROR_NULLPTR;
3785 }
3786 if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !IsEnablePiPCreate(property)) {
3787 TLOGNE(WmsLogTag::WMS_PIP, "pip window is not enable to create.");
3788 return WSError::WS_DO_NOTHING;
3789 }
3790 const auto type = property->GetWindowType();
3791 // create specific session
3792 SessionInfo info;
3793 info.windowType_ = static_cast<uint32_t>(type);
3794 info.bundleName_ = property->GetSessionInfo().bundleName_;
3795 info.abilityName_ = property->GetSessionInfo().abilityName_;
3796 info.moduleName_ = property->GetSessionInfo().moduleName_;
3797 info.screenId_ = property->GetDisplayId();
3798
3799 if (IsPiPForbidden(property, type)) {
3800 TLOGNE(WmsLogTag::WMS_PIP, "forbid pip");
3801 return WSError::WS_ERROR_INVALID_PERMISSION;
3802 }
3803 ClosePipWindowIfExist(type);
3804 sptr<SceneSession> newSession = RequestSceneSession(info, property);
3805 if (newSession == nullptr) {
3806 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
3807 return WSError::WS_ERROR_NULLPTR;
3808 }
3809 newSession->SetClientDisplayId(initClientDisplayId);
3810 property->SetSystemCalling(isSystemCalling);
3811 auto errCode = newSession->ConnectInner(
3812 sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
3813 newSession->SetIsSystemSpecificSession(isSystemCalling);
3814 systemConfig = systemConfig_;
3815 persistentId = property->GetPersistentId();
3816
3817 NotifyCreateSpecificSession(newSession, property, type);
3818 session = newSession;
3819 AddClientDeathRecipient(sessionStage, newSession);
3820
3821 if (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
3822 CheckFloatWindowIsAnco(pid, newSession);
3823 }
3824
3825 UpdateSubSessionBlackList(newSession);
3826 TLOGNI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
3827 "parentId: %{public}d, type: %{public}d",
3828 newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
3829 return errCode;
3830 };
3831
3832 return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
3833 }
3834
CheckSubSessionStartedByExtensionAndSetDisplayId(const sptr<IRemoteObject> & token,const sptr<WindowSessionProperty> & property,const sptr<ISessionStage> & sessionStage)3835 WSError SceneSessionManager::CheckSubSessionStartedByExtensionAndSetDisplayId(const sptr<IRemoteObject>& token,
3836 const sptr<WindowSessionProperty>& property, const sptr<ISessionStage>& sessionStage)
3837 {
3838 sptr<SceneSession> extensionParentSession = GetSceneSession(property->GetParentPersistentId());
3839 if (extensionParentSession == nullptr) {
3840 TLOGE(WmsLogTag::WMS_UIEXT, "extensionParentSession is invalid with %{public}d",
3841 property->GetParentPersistentId());
3842 return WSError::WS_ERROR_NULLPTR;
3843 }
3844 auto pid = IPCSkeleton::GetCallingRealPid();
3845 auto parentPid = extensionParentSession->GetCallingPid();
3846 WSError result = WSError::WS_ERROR_INVALID_WINDOW;
3847 if (pid == parentPid) { // Determine Whether to create a sub window in the same process.
3848 TLOGI(WmsLogTag::WMS_UIEXT, "pid == parentPid");
3849 result = WSError::WS_OK;
3850 }
3851 AAFwk::UIExtensionSessionInfo info;
3852 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
3853 if (info.persistentId != INVALID_SESSION_ID && info.hostWindowId != INVALID_SESSION_ID) {
3854 int32_t parentId = static_cast<int32_t>(info.hostWindowId);
3855 // Check the parent ids are the same in cross-process scenarios.
3856 if (parentId == property->GetParentPersistentId()) {
3857 TLOGD(WmsLogTag::WMS_UIEXT, "parentId == property->GetParentPersistentId(parentId:%{public}d)", parentId);
3858 result = WSError::WS_OK;
3859 }
3860 }
3861 if (SessionPermission::IsSystemCalling()) { // Fallback strategy.
3862 TLOGD(WmsLogTag::WMS_UIEXT, "is system app");
3863 result = WSError::WS_OK;
3864 }
3865 if (property->GetIsUIExtensionAbilityProcess() && SessionPermission::IsStartedByUIExtension()) {
3866 AAFwk::UIExtensionHostInfo hostInfo;
3867 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
3868 const auto& sessionInfo = extensionParentSession->GetSessionInfo();
3869 auto hostBundleName = extensionParentSession->IsAnco()?
3870 SessionUtils::GetBundleNameBySessionName(hostInfo.sessionName) : hostInfo.elementName_.GetBundleName();
3871 if (sessionInfo.bundleName_ != hostBundleName &&
3872 sessionInfo.bundleName_ != info.hostElementName.GetBundleName()) {
3873 TLOGE(WmsLogTag::WMS_UIEXT, "The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s,"
3874 " hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(), hostBundleName.c_str());
3875 ReportSubWindowCreationFailure(pid, info.elementName.GetAbilityName(), sessionInfo.bundleName_,
3876 hostBundleName);
3877 return WSError::WS_ERROR_INVALID_WINDOW;
3878 }
3879 result = WSError::WS_OK;
3880 }
3881 if (result == WSError::WS_OK) {
3882 sptr<WindowSessionProperty> parentProperty = extensionParentSession->GetSessionProperty();
3883 if (sessionStage && property->GetIsUIExtFirstSubWindow()) {
3884 sessionStage->UpdateDisplayId(extensionParentSession->GetClientDisplayId() == VIRTUAL_DISPLAY_ID
3885 ? VIRTUAL_DISPLAY_ID
3886 : parentProperty->GetDisplayId());
3887 property->SetDisplayId(parentProperty->GetDisplayId());
3888 }
3889 } else {
3890 TLOGE(WmsLogTag::WMS_UIEXT, "can't create sub window: persistentId %{public}d", property->GetPersistentId());
3891 }
3892 return result;
3893 }
3894
ReportSubWindowCreationFailure(const int32_t & pid,const std::string & abilityName,const std::string & parentBundleName,const std::string & hostBundleName)3895 void SceneSessionManager::ReportSubWindowCreationFailure(const int32_t& pid, const std::string& abilityName,
3896 const std::string& parentBundleName, const std::string& hostBundleName)
3897 {
3898 taskScheduler_->PostAsyncTask([pid, abilityName, parentBundleName, hostBundleName]() {
3899 std::ostringstream oss;
3900 oss << "The hostWindow is not this parentwindow ! parentwindow bundleName: " << parentBundleName;
3901 oss << ", hostwindow bundleName: " << hostBundleName;
3902 oss << ", abilityName: " << abilityName;
3903 SingletonContainer::Get<WindowInfoReporter>().ReportWindowException(
3904 static_cast<int32_t>(WindowDFXHelperType::WINDOW_CREATE_SUB_WINDOW_FAILED), pid, oss.str());
3905 }, __func__);
3906 }
3907
CheckFloatWindowIsAnco(pid_t pid,const sptr<SceneSession> & newSession)3908 void SceneSessionManager::CheckFloatWindowIsAnco(pid_t pid, const sptr<SceneSession>& newSession)
3909 {
3910 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
3911 {
3912 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3913 sceneSessionMapCopy = sceneSessionMap_;
3914 }
3915 for (const auto& [_, session] : sceneSessionMapCopy) {
3916 if (session && session->GetCallingPid() == pid &&
3917 session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3918 auto sessionInfo = session->GetSessionInfo();
3919 if (AbilityInfoManager::GetInstance().IsAnco(sessionInfo.bundleName_,
3920 sessionInfo.abilityName_, sessionInfo.moduleName_)) {
3921 newSession->SetIsAncoForFloatingWindow(true);
3922 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Set float window is anco, wid: %{public}d", newSession->GetWindowId());
3923 break;
3924 }
3925 }
3926 }
3927 }
3928
ClosePipWindowIfExist(WindowType type)3929 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
3930 {
3931 if (type != WindowType::WINDOW_TYPE_PIP) {
3932 return;
3933 }
3934 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3935 for (const auto& [_, session] : sceneSessionMap_) {
3936 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
3937 session->NotifyCloseExistPipWindow();
3938 break;
3939 }
3940 }
3941 }
3942
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo,DisplayId displayId)3943 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo, DisplayId displayId)
3944 {
3945 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3946 for (const auto& [_, session] : sceneSessionMap_) {
3947 if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
3948 pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
3949 session->IsSessionForeground()) {
3950 if (startPiPFailedFunc_) {
3951 startPiPFailedFunc_(displayId);
3952 }
3953 TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
3954 return false;
3955 }
3956 }
3957 return true;
3958 }
3959
IsEnablePiPCreate(const sptr<WindowSessionProperty> & property)3960 bool SceneSessionManager::IsEnablePiPCreate(const sptr<WindowSessionProperty>& property)
3961 {
3962 if (isScreenLocked_) {
3963 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
3964 return false;
3965 }
3966 Rect pipRect = property->GetRequestRect();
3967 if (pipRect.width_ == 0 || pipRect.height_ == 0) {
3968 TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
3969 return false;
3970 }
3971 if (!CheckPiPPriority(property->GetPiPTemplateInfo(), property->GetDisplayId())) {
3972 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
3973 return false;
3974 }
3975 auto parentSession = GetSceneSession(property->GetParentPersistentId());
3976 if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
3977 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
3978 return false;
3979 }
3980 return true;
3981 }
3982
IsPiPForbidden(const sptr<WindowSessionProperty> & property,const WindowType & type)3983 bool SceneSessionManager::IsPiPForbidden(const sptr<WindowSessionProperty>& property, const WindowType& type)
3984 {
3985 sptr<SceneSession> parentSession = GetSceneSession(property->GetParentPersistentId());
3986 if (parentSession == nullptr) {
3987 TLOGE(WmsLogTag::WMS_PIP, "invalid parentSession");
3988 return false;
3989 }
3990 sptr<WindowSessionProperty> parentProperty = parentSession->GetSessionProperty();
3991 if (parentProperty == nullptr) {
3992 TLOGE(WmsLogTag::WMS_PIP, "invalid parentProperty");
3993 return false;
3994 }
3995 DisplayId screenId = parentProperty->GetDisplayId();
3996 if (screenId == SCREEN_ID_INVALID) {
3997 TLOGE(WmsLogTag::WMS_PIP, "invalid screenId");
3998 return false;
3999 }
4000 sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(screenId);
4001 if (screenSession == nullptr) {
4002 TLOGE(WmsLogTag::WMS_PIP, "invalid screenSession");
4003 return false;
4004 }
4005 std::string screenName = screenSession->GetName();
4006 if (type == WindowType::WINDOW_TYPE_PIP &&
4007 (screenName == "HiCar" || screenName == "SuperLauncher" || screenName == "PadWithCar")) {
4008 TLOGI(WmsLogTag::WMS_PIP, "screen name %{public}s", screenName.c_str());
4009 return true;
4010 }
4011 return false;
4012 }
4013
IsFloatingBallValid(const sptr<SceneSession> & parentSession)4014 WSError SceneSessionManager::IsFloatingBallValid(const sptr<SceneSession>& parentSession)
4015 {
4016 if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
4017 parentSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
4018 TLOGE(WmsLogTag::WMS_LIFE, "Parent is null or state invalid");
4019 return WSError::WS_ERROR_INVALID_PARENT;
4020 }
4021 return WSError::WS_OK;
4022 }
4023
NotifyPiPWindowVisibleChange(bool screenLocked)4024 void SceneSessionManager::NotifyPiPWindowVisibleChange(bool screenLocked) {
4025 sptr<SceneSession> session = SelectSesssionFromMap(pipWindowSurfaceId_);
4026 if (session != nullptr) {
4027 std::vector<std::pair<uint64_t, WindowVisibilityState>> pipVisibilityChangeInfos;
4028 if (screenLocked) {
4029 pipVisibilityChangeInfos.emplace_back(pipWindowSurfaceId_, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
4030 } else {
4031 pipVisibilityChangeInfos.emplace_back(pipWindowSurfaceId_, WINDOW_VISIBILITY_STATE_NO_OCCLUSION);
4032 }
4033 DealwithVisibilityChange(pipVisibilityChangeInfos, lastVisibleData_);
4034 }
4035 }
4036
IsLastPiPWindowVisible(uint64_t surfaceId,WindowVisibilityState lastVisibilityState)4037 bool SceneSessionManager::IsLastPiPWindowVisible(uint64_t surfaceId, WindowVisibilityState lastVisibilityState) {
4038 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
4039 if (session == nullptr || session->GetWindowMode() != WindowMode::WINDOW_MODE_PIP) {
4040 TLOGD(WmsLogTag::WMS_PIP, "session is null or windowMode is not PIP");
4041 return false;
4042 }
4043 if (isScreenLocked_) {
4044 TLOGD(WmsLogTag::WMS_PIP, "pipWindow occlusion because of screen locked");
4045 return false;
4046 }
4047 if (lastVisibilityState != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
4048 // no visibility notification processing after pip is occlusion
4049 TLOGI(WmsLogTag::WMS_PIP, "pipWindow occlusion success. pipWindowSurfaceId: %{public}" PRIu64, surfaceId);
4050 pipWindowSurfaceId_ = surfaceId;
4051 return true;
4052 }
4053 return false;
4054 }
4055
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)4056 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
4057 {
4058 WindowType type = property->GetWindowType();
4059 if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
4060 return true;
4061 }
4062
4063 if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
4064 TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
4065 return false;
4066 }
4067
4068 if (!SessionPermission::IsSystemCalling()) {
4069 TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
4070 return false;
4071 }
4072
4073 return true;
4074 }
4075
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)4076 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
4077 {
4078 WindowType type = property->GetWindowType();
4079 if (WindowHelper::IsUIExtensionWindow(type)) {
4080 // UIExtension window disallowed.
4081 return false;
4082 }
4083 if (!WindowHelper::IsSystemWindow(type)) {
4084 // type is not system
4085 return true;
4086 }
4087 if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && property->IsSystemKeyboard()) {
4088 // system keyboard window can only be created by virtual keyboard service
4089 if (SessionPermission::VerifyCallingPermission("ohos.permission.VIRTUAL_KEYBOARD_WINDOW")) {
4090 TLOGD(WmsLogTag::WMS_KEYBOARD, "create system keyboard, permission check sucess.");
4091 return true;
4092 }
4093 TLOGE(WmsLogTag::WMS_KEYBOARD, "create system keyboard, permission check failed.");
4094 return false;
4095 }
4096 if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
4097 type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR) && SessionPermission::IsStartedByInputMethod()) {
4098 // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
4099 TLOGD(WmsLogTag::WMS_KEYBOARD, "check create permission success, input method app create input method window.");
4100 return true;
4101 }
4102 if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
4103 // some system types could be created by normal app
4104 return true;
4105 }
4106 if (type == WindowType::WINDOW_TYPE_FB) {
4107 return SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_FLOATING_BALL);
4108 }
4109 if (type == WindowType::WINDOW_TYPE_FLOAT) {
4110 // WINDOW_TYPE_FLOAT could be created with the corresponding permission
4111 if (SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW") &&
4112 (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd() ||
4113 systemConfig_.supportTypeFloatWindow_)) {
4114 TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission success.");
4115 return true;
4116 } else if (SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW") &&
4117 systemConfig_.supportCreateFloatWindow_) {
4118 TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission success. SupportCreateFloatWindow.");
4119 return true;
4120 } else {
4121 TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission failed.");
4122 return false;
4123 }
4124 }
4125 if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
4126 int32_t parentId = property->GetParentPersistentId();
4127 auto parentSession = GetSceneSession(parentId);
4128 if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
4129 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
4130 TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
4131 return true;
4132 } else {
4133 TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
4134 }
4135 }
4136 if (SessionHelper::IsNeedSACalling(type)) {
4137 if (SessionPermission::IsSACalling()) {
4138 TLOGI(WmsLogTag::WMS_SYSTEM, "check sa permission success, create with SA calling.");
4139 return true;
4140 }
4141 TLOGE(WmsLogTag::WMS_SYSTEM, "check sa permission failed");
4142 return false;
4143 }
4144 if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
4145 TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
4146 return true;
4147 }
4148 TLOGE(WmsLogTag::WMS_SYSTEM, "finally check permission failed.");
4149 return false;
4150 }
4151
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)4152 void SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
4153 {
4154 if (property == nullptr) {
4155 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
4156 return;
4157 }
4158 SessionInfo& sessionInfo = property->EditSessionInfo();
4159 sessionInfo.persistentId_ = property->GetPersistentId();
4160 sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
4161 sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
4162 sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
4163 sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
4164 ? SessionState::STATE_ACTIVE
4165 : SessionState::STATE_BACKGROUND;
4166 sessionInfo.isPersistentRecover_ = true;
4167 sessionInfo.appInstanceKey_ = property->GetAppInstanceKey();
4168 sessionInfo.screenId_ = property->GetDisplayId();
4169 sessionInfo.isAbilityHook_ = property->GetIsAbilityHook();
4170 sessionInfo.supportedWindowModes =
4171 WindowHelper::ConvertSupportTypeToSupportModes(property->GetWindowModeSupportType());
4172 TLOGI(WmsLogTag::WMS_RECOVER,
4173 "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
4174 "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
4175 "windowState=%{public}u, appInstanceKey=%{public}s, isFollowParentMultiScreenPolicy=%{public}d, "
4176 "screenId=%{public}" PRIu64 ", isAbilityHook=%{public}d",
4177 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
4178 sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_,
4179 sessionInfo.appInstanceKey_.c_str(), sessionInfo.isFollowParentMultiScreenPolicy,
4180 sessionInfo.screenId_, sessionInfo.isAbilityHook_);
4181 }
4182
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)4183 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
4184 {
4185 TLOGI(WmsLogTag::WMS_RECOVER, "Size of PersistentIds need to be recovered=%{public}zu, CurrentUserId=%{public}d",
4186 alivePersistentIds.size(), currentUserId_.load());
4187 alivePersistentIds_ = alivePersistentIds;
4188 }
4189
IsNeedRecover(const int32_t persistentId)4190 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
4191 {
4192 if (auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
4193 it == alivePersistentIds_.end()) {
4194 TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
4195 return false;
4196 }
4197 return true;
4198 }
4199
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)4200 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
4201 bool isSpecificSession)
4202 {
4203 if (property == nullptr) {
4204 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
4205 return WSError::WS_ERROR_NULLPTR;
4206 }
4207 if (!CheckSystemWindowPermission(property)) {
4208 TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
4209 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4210 }
4211 if (isSpecificSession) {
4212 if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
4213 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
4214 return WSError::WS_ERROR_INVALID_PARAM;
4215 }
4216 } else {
4217 if (property->GetPersistentId() > 0 && !IsNeedRecover(property->GetPersistentId())) {
4218 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
4219 return WSError::WS_ERROR_INVALID_PARAM;
4220 }
4221 }
4222 return WSError::WS_OK;
4223 }
4224
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)4225 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
4226 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
4227 sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
4228 {
4229 auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
4230 if (propCheckRet != WSError::WS_OK) {
4231 return propCheckRet;
4232 }
4233 auto pid = IPCSkeleton::GetCallingRealPid();
4234 auto uid = IPCSkeleton::GetCallingUid();
4235 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
4236 if (recoveringFinished_ || sessionRecoverStateChangeFunc_ == nullptr) {
4237 TLOGNW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
4238 return WSError::WS_ERROR_INVALID_OPERATION;
4239 }
4240 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_START_RECONNECT, property);
4241 SessionInfo info = property->GetSessionInfo();
4242 TLOGNI(WmsLogTag::WMS_RECOVER, "callingWindowId=%{public}" PRIu32, property->GetCallingSessionId());
4243 ClosePipWindowIfExist(property->GetWindowType());
4244 sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
4245 if (sceneSession == nullptr) {
4246 TLOGNE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
4247 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4248 return WSError::WS_ERROR_NULLPTR;
4249 }
4250
4251 auto persistentId = sceneSession->GetPersistentId();
4252 if (persistentId != info.persistentId_) {
4253 TLOGNE(WmsLogTag::WMS_RECOVER,
4254 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
4255 info.persistentId_, persistentId, property->GetParentPersistentId());
4256 failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
4257 EraseSceneSessionMapById(persistentId);
4258 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4259 return WSError::WS_ERROR_INVALID_SESSION;
4260 }
4261
4262 auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
4263 if (errCode != WSError::WS_OK) {
4264 TLOGNE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
4265 EraseSceneSessionMapById(persistentId);
4266 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4267 return errCode;
4268 }
4269 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_FINISH_RECONNECT, property);
4270 AddClientDeathRecipient(sessionStage, sceneSession);
4271 session = sceneSession;
4272 return errCode;
4273 };
4274 return taskScheduler_->PostSyncTask(task, __func__);
4275 }
4276
NotifyRecoveringFinished()4277 void SceneSessionManager::NotifyRecoveringFinished()
4278 {
4279 taskScheduler_->PostAsyncTask([this]() {
4280 TLOGNI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
4281 recoveringFinished_ = true;
4282 recoverSubSessionCacheMap_.clear();
4283 recoverDialogSessionCacheMap_.clear();
4284 }, __func__);
4285 }
4286
CacheSpecificSessionForRecovering(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)4287 void SceneSessionManager::CacheSpecificSessionForRecovering(
4288 const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)
4289 {
4290 if (!IsWindowSupportCacheForRecovering(sceneSession, property)) {
4291 return;
4292 }
4293
4294 auto windowType = property->GetWindowType();
4295 auto parentId = property->GetParentPersistentId();
4296 TLOGI(WmsLogTag::WMS_RECOVER, "Cache specific session persistentId=%{public}d, parent persistentId="
4297 "%{public}d, window type=%{public}d", sceneSession->GetPersistentId(), parentId, windowType);
4298
4299 if (WindowHelper::IsSubWindow(windowType)) {
4300 recoverSubSessionCacheMap_[parentId].emplace_back(sceneSession);
4301 } else if (WindowHelper::IsDialogWindow(windowType)) {
4302 recoverDialogSessionCacheMap_[parentId].emplace_back(sceneSession);
4303 }
4304 }
4305
IsWindowSupportCacheForRecovering(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)4306 bool SceneSessionManager::IsWindowSupportCacheForRecovering(
4307 const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)
4308 {
4309 if (recoveringFinished_) {
4310 TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
4311 return false;
4312 }
4313
4314 if (sceneSession == nullptr || property == nullptr) {
4315 TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
4316 return false;
4317 }
4318
4319 auto windowType = property->GetWindowType();
4320 if (!WindowHelper::IsSubWindow(windowType) && !WindowHelper::IsDialogWindow(windowType)) {
4321 return false;
4322 }
4323
4324 auto parentId = property->GetParentPersistentId();
4325 if ((WindowHelper::IsSubWindow(windowType) &&
4326 createSubSessionFuncMap_.find(parentId) != createSubSessionFuncMap_.end()) ||
4327 (WindowHelper::IsDialogWindow(windowType) &&
4328 bindDialogTargetFuncMap_.find(parentId) != bindDialogTargetFuncMap_.end())) {
4329 return false;
4330 }
4331
4332 return true;
4333 }
4334
RecoverCachedSubSession(int32_t persistentId)4335 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
4336 {
4337 auto iter = recoverSubSessionCacheMap_.find(persistentId);
4338 if (iter == recoverSubSessionCacheMap_.end()) {
4339 return;
4340 }
4341 TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
4342 for (auto& sceneSession : iter->second) {
4343 NotifyCreateSubSession(persistentId, sceneSession);
4344 }
4345 recoverSubSessionCacheMap_.erase(iter);
4346 }
4347
RecoverCachedDialogSession(int32_t persistentId)4348 void SceneSessionManager::RecoverCachedDialogSession(int32_t persistentId)
4349 {
4350 auto iter = recoverDialogSessionCacheMap_.find(persistentId);
4351 if (iter == recoverDialogSessionCacheMap_.end()) {
4352 return;
4353 }
4354 TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
4355 for (auto& sceneSession : iter->second) {
4356 UpdateParentSessionForDialog(sceneSession, sceneSession->GetSessionProperty());
4357 }
4358 recoverDialogSessionCacheMap_.erase(iter);
4359 }
4360
NotifySessionUnfocusedToClient(int32_t persistentId)4361 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
4362 {
4363 TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
4364 listenerController_->NotifySessionUnfocused(persistentId);
4365 }
4366
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)4367 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
4368 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
4369 sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
4370 {
4371 auto result = CheckSessionPropertyOnRecovery(property, false);
4372 if (result != WSError::WS_OK) {
4373 return result;
4374 }
4375 auto pid = IPCSkeleton::GetCallingRealPid();
4376 auto uid = IPCSkeleton::GetCallingUid();
4377 auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
4378 if (recoveringFinished_ || sessionRecoverStateChangeFunc_ == nullptr) {
4379 TLOGNW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
4380 return WSError::WS_ERROR_INVALID_OPERATION;
4381 }
4382 if (recoverSceneSessionFunc_ == nullptr) {
4383 TLOGNE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
4384 return WSError::WS_ERROR_NULLPTR;
4385 }
4386 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_START_RECONNECT, property);
4387 SessionInfo sessionInfo = property->GetSessionInfo();
4388 sptr<SceneSession> sceneSession = RequestSceneSession(sessionInfo, nullptr);
4389 if (sceneSession == nullptr) {
4390 TLOGNE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
4391 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4392 return WSError::WS_ERROR_NULLPTR;
4393 }
4394 int32_t persistentId = sceneSession->GetPersistentId();
4395 if (persistentId != sessionInfo.persistentId_) {
4396 TLOGNE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
4397 sessionInfo.persistentId_, persistentId);
4398 EraseSceneSessionMapById(persistentId);
4399 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4400 return WSError::WS_ERROR_INVALID_SESSION;
4401 }
4402 auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
4403 if (ret != WSError::WS_OK) {
4404 TLOGNE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
4405 EraseSceneSessionMapById(sessionInfo.persistentId_);
4406 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4407 return ret;
4408 }
4409 sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_FINISH_RECONNECT, property);
4410 session = sceneSession;
4411 return WSError::WS_OK;
4412 };
4413 return taskScheduler_->PostSyncTask(task, __func__);
4414 }
4415
UpdateRecoverPropertyForSuperFold(const sptr<WindowSessionProperty> & property)4416 void SceneSessionManager::UpdateRecoverPropertyForSuperFold(const sptr<WindowSessionProperty>& property)
4417 {
4418 if (property->GetDisplayId() != VIRTUAL_DISPLAY_ID) {
4419 return;
4420 }
4421 static auto foldCreaseRegion = SingletonContainer::Get<DisplayManager>().GetCurrentFoldCreaseRegion();
4422 if (foldCreaseRegion == nullptr) {
4423 return;
4424 }
4425 Rect recoverWindowRect = property->GetWindowRect();
4426 Rect recoverRequestRect = property->GetRequestRect();
4427 TLOGD(WmsLogTag::WMS_RECOVER,
4428 "WindowRect: %{public}s, RequestRect: %{public}s, DisplayId: %{public}d",
4429 recoverWindowRect.ToString().c_str(), recoverRequestRect.ToString().c_str(),
4430 static_cast<uint32_t>(property->GetDisplayId()));
4431
4432 auto foldCrease = foldCreaseRegion->GetCreaseRects().front();
4433 recoverWindowRect.posY_ += foldCrease.posY_ + static_cast<int32_t>(foldCrease.height_);
4434 recoverRequestRect.posY_ += foldCrease.posY_ + static_cast<int32_t>(foldCrease.height_);
4435 property->SetWindowRect(recoverWindowRect);
4436 property->SetRequestRect(recoverRequestRect);
4437 property->SetDisplayId(0);
4438 TLOGD(WmsLogTag::WMS_RECOVER,
4439 "WindowRect: %{public}s, RequestRect: %{public}s, DisplayId: %{public}d",
4440 recoverWindowRect.ToString().c_str(), recoverRequestRect.ToString().c_str(),
4441 static_cast<uint32_t>(property->GetDisplayId()));
4442 }
4443
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)4444 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
4445 {
4446 TLOGI(WmsLogTag::WMS_RECOVER, "in");
4447 recoverSceneSessionFunc_ = func;
4448 }
4449
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)4450 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
4451 {
4452 createSystemSessionFunc_ = func;
4453 }
4454
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)4455 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
4456 {
4457 createKeyboardSessionFunc_ = func;
4458 }
4459
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)4460 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
4461 {
4462 startPiPFailedFunc_ = std::move(func);
4463 }
4464
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)4465 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
4466 const NotifyCreateSubSessionFunc& func)
4467 {
4468 TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
4469 taskScheduler_->PostSyncTask([this, persistentId, func]() {
4470 createSubSessionFuncMap_[persistentId] = func;
4471 RecoverCachedSubSession(persistentId);
4472 return WMError::WM_OK;
4473 }, __func__);
4474 }
4475
RegisterBindDialogTargetListener(const sptr<SceneSession> & session,NotifyBindDialogSessionFunc && func)4476 void SceneSessionManager::RegisterBindDialogTargetListener(const sptr<SceneSession>& session,
4477 NotifyBindDialogSessionFunc&& func)
4478 {
4479 int32_t persistentId = session->GetPersistentId();
4480 TLOGI(WmsLogTag::WMS_DIALOG, "Id: %{public}d", persistentId);
4481 taskScheduler_->PostTask([this, session, persistentId, func = std::move(func)] {
4482 session->RegisterBindDialogSessionCallback(func);
4483 bindDialogTargetFuncMap_[persistentId] = std::move(func);
4484 RecoverCachedDialogSession(persistentId);
4485 }, __func__);
4486 }
4487
SetFocusedSessionDisplayIdIfNeeded(sptr<SceneSession> & newSession)4488 void SceneSessionManager::SetFocusedSessionDisplayIdIfNeeded(sptr<SceneSession>& newSession)
4489 {
4490 if (newSession->GetSessionProperty()->GetDisplayId() == DISPLAY_ID_INVALID) {
4491 uint64_t defaultDisplayId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
4492 int32_t focusSessionId = windowFocusController_->GetFocusedSessionId(defaultDisplayId);
4493 auto focusedSession = GetSceneSession(focusSessionId);
4494 DisplayId displayId = defaultDisplayId;
4495 if (focusedSession != nullptr && focusedSession->GetSessionProperty()->GetDisplayId() != DISPLAY_ID_INVALID) {
4496 displayId = focusedSession->GetSessionProperty()->GetDisplayId();
4497 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, focus id %{public}d, display id: %{public}" PRIu64,
4498 newSession->GetPersistentId(), focusedSession->GetPersistentId(), displayId);
4499 } else {
4500 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "get focus id failed, use default displayId %{public}" PRIu64, displayId);
4501 }
4502 newSession->SetScreenId(displayId);
4503 newSession->GetSessionProperty()->SetDisplayId(displayId);
4504 }
4505 }
4506
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)4507 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
4508 sptr<WindowSessionProperty> property, const WindowType& type)
4509 {
4510 if (newSession == nullptr || property == nullptr) {
4511 TLOGE(WmsLogTag::WMS_LIFE, "newSession or property is nullptr");
4512 return;
4513 }
4514 if (SessionHelper::IsSystemWindow(type)) {
4515 if (type == WindowType::WINDOW_TYPE_FLOAT) {
4516 auto parentSession = GetSceneSession(property->GetParentPersistentId());
4517 if (parentSession != nullptr) {
4518 newSession->SetParentSession(parentSession);
4519 }
4520 }
4521 if (type == WindowType::WINDOW_TYPE_TOAST) {
4522 NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
4523 }
4524 if (type != WindowType::WINDOW_TYPE_DIALOG) {
4525 if (WindowHelper::IsSystemSubWindow(type)) {
4526 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
4527 } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
4528 && createKeyboardSessionFunc_) {
4529 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
4530 } else if (createSystemSessionFunc_) {
4531 SetFocusedSessionDisplayIdIfNeeded(newSession);
4532 property->SetDisplayId(newSession->GetSessionProperty()->GetDisplayId());
4533 createSystemSessionFunc_(newSession);
4534 }
4535 TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
4536 newSession->GetPersistentId(), type);
4537 } else {
4538 TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, "
4539 "type:%{public}d", newSession->GetPersistentId(), type);
4540 return;
4541 }
4542 } else if (SessionHelper::IsSubWindow(type)) {
4543 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
4544 TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
4545 newSession->GetPersistentId(), property->GetParentPersistentId(), type);
4546 } else {
4547 TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
4548 newSession->GetPersistentId(), type);
4549 }
4550 }
4551
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)4552 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
4553 {
4554 if (session == nullptr) {
4555 TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
4556 return;
4557 }
4558 auto iter = createSubSessionFuncMap_.find(persistentId);
4559 if (iter == createSubSessionFuncMap_.end()) {
4560 recoverSubSessionCacheMap_[persistentId].push_back(session);
4561 TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
4562 return;
4563 }
4564 const auto& createSubSessionFunc = iter->second;
4565 sptr<SceneSession> parentSession = nullptr;
4566 if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
4567 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4568 parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
4569 } else {
4570 parentSession = GetSceneSession(persistentId);
4571 }
4572 if (parentSession == nullptr) {
4573 TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
4574 persistentId, session->GetPersistentId());
4575 return;
4576 }
4577 parentSession->AddSubSession(session);
4578 session->SetParentSession(parentSession);
4579 if (createSubSessionFunc) {
4580 createSubSessionFunc(session);
4581 }
4582 TLOGD(WmsLogTag::WMS_LIFE, "Notify success, parentId: %{public}d, subId: %{public}d",
4583 persistentId, session->GetPersistentId());
4584 }
4585
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)4586 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
4587 const std::map<int32_t, sptr<SceneSession>>& sessionMap)
4588 {
4589 if (persistentId == INVALID_SESSION_ID) {
4590 TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
4591 return nullptr;
4592 }
4593 auto iter = sessionMap.find(persistentId);
4594 if (iter == sessionMap.end()) {
4595 TLOGD(WmsLogTag::WMS_LIFE, "Error found scene session with id: %{public}d", persistentId);
4596 return nullptr;
4597 }
4598 sptr<SceneSession> parentSession = iter->second;
4599 if (parentSession == nullptr) {
4600 TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
4601 return nullptr;
4602 }
4603 bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
4604 parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
4605 if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
4606 TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
4607 return parentSession;
4608 }
4609 return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
4610 }
4611
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)4612 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
4613 {
4614 if (session == nullptr) {
4615 TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
4616 return;
4617 }
4618
4619 auto parentSession = GetSceneSession(persistentId);
4620 if (parentSession == nullptr) {
4621 TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
4622 persistentId, session->GetPersistentId());
4623 return;
4624 }
4625 parentSession->AddToastSession(session);
4626 session->SetParentSession(parentSession);
4627 TLOGD(WmsLogTag::WMS_LIFE, "Notify success, parentId: %{public}d, toastId: %{public}d",
4628 persistentId, session->GetPersistentId());
4629 }
4630
UnregisterSpecificSessionCreateListener(int32_t persistentId)4631 void SceneSessionManager::UnregisterSpecificSessionCreateListener(int32_t persistentId)
4632 {
4633 TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
4634 taskScheduler_->PostSyncTask([this, persistentId]() {
4635 if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
4636 createSubSessionFuncMap_.erase(persistentId);
4637 }
4638 if (bindDialogTargetFuncMap_.find(persistentId) != bindDialogTargetFuncMap_.end()) {
4639 bindDialogTargetFuncMap_.erase(persistentId);
4640 }
4641 return WMError::WM_OK;
4642 }, __func__);
4643 }
4644
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)4645 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
4646 {
4647 if (!func) {
4648 TLOGD(WmsLogTag::WMS_EVENT, "set func is null");
4649 }
4650 statusBarEnabledChangeFunc_ = func;
4651 }
4652
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)4653 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
4654 const ProcessGestureNavigationEnabledChangeFunc& func)
4655 {
4656 if (!func) {
4657 TLOGD(WmsLogTag::WMS_EVENT, "set func is null");
4658 }
4659 gestureNavigationEnabledChangeFunc_ = func;
4660 }
4661
OnOutsideDownEvent(int32_t x,int32_t y)4662 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
4663 {
4664 TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
4665 if (outsideDownEventFunc_) {
4666 outsideDownEventFunc_(x, y);
4667 }
4668 }
4669
GetDisplayGroupIdFromSceneSession(const sptr<SceneSession> & session,DisplayId & displayGroupId) const4670 WSError SceneSessionManager::GetDisplayGroupIdFromSceneSession(const sptr<SceneSession>& session,
4671 DisplayId& displayGroupId) const
4672 {
4673 if (session == nullptr) {
4674 return WSError::WS_ERROR_NULLPTR;
4675 }
4676 displayGroupId = GetDisplayGroupId(session->GetDisplayId());
4677 return WSError::WS_OK;
4678 }
4679
IsSameDisplayGroupId(const sptr<SceneSession> & session,const DisplayId touchDisplayGroupId) const4680 bool SceneSessionManager::IsSameDisplayGroupId(const sptr<SceneSession>& session,
4681 const DisplayId touchDisplayGroupId) const
4682 {
4683 DisplayId displayGroupId = 0;
4684 if (GetDisplayGroupIdFromSceneSession(session, displayGroupId) != WSError::WS_OK) {
4685 TLOGD(WmsLogTag::WMS_EVENT, "session is null.");
4686 return false;
4687 }
4688 return displayGroupId == touchDisplayGroupId;
4689 }
4690
NotifySessionTouchOutside(int32_t persistentId,DisplayId displayId)4691 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId, DisplayId displayId)
4692 {
4693 auto task = [this, persistentId, displayId]() {
4694 int32_t callingSessionId = INVALID_WINDOW_ID;
4695 auto sceneSession = GetSceneSession(persistentId);
4696 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
4697 callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
4698 TLOGND(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
4699 persistentId, callingSessionId);
4700 }
4701 DisplayId touchDisplayGroupId = GetDisplayGroupId(displayId);
4702 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4703 for (const auto& [_, sceneSession] : sceneSessionMap_) {
4704 if (sceneSession == nullptr) {
4705 continue;
4706 }
4707 if (!(sceneSession->IsVisible() ||
4708 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4709 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
4710 continue;
4711 }
4712 if (!IsSameDisplayGroupId(sceneSession, touchDisplayGroupId)) {
4713 continue;
4714 }
4715 auto sessionId = sceneSession->GetPersistentId();
4716 if (!sceneSession->CheckTouchOutsideCallbackRegistered() &&
4717 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
4718 TLOGND(WmsLogTag::WMS_KEYBOARD, "id: %{public}d is not in touchOutsideListenerNodes, don't notify.",
4719 sessionId);
4720 continue;
4721 }
4722 if (sessionId == callingSessionId || sessionId == persistentId) {
4723 TLOGND(WmsLogTag::WMS_KEYBOARD, "No need to notify touch window, id: %{public}d", sessionId);
4724 continue;
4725 }
4726 sceneSession->NotifyTouchOutside();
4727 }
4728 };
4729
4730 taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
4731 return;
4732 }
4733
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)4734 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
4735 {
4736 TLOGD(WmsLogTag::WMS_EVENT, "in");
4737 outsideDownEventFunc_ = func;
4738 }
4739
NotifyWatchGestureConsumeResult(int32_t keyCode,bool isConsumed)4740 WMError SceneSessionManager::NotifyWatchGestureConsumeResult(int32_t keyCode, bool isConsumed)
4741 {
4742 TLOGD(WmsLogTag::WMS_EVENT, "keyCode:%{public}d isConsumed:%{public}d", keyCode, isConsumed);
4743 if (onWatchGestureConsumeResultFunc_) {
4744 onWatchGestureConsumeResultFunc_(keyCode, isConsumed);
4745 } else {
4746 TLOGE(WmsLogTag::WMS_EVENT, "onWatchGestureConsumeResultFunc is null");
4747 return WMError::WM_ERROR_INVALID_PARAM;
4748 }
4749 return WMError::WM_OK;
4750 }
4751
RegisterWatchGestureConsumeResultCallback(NotifyWatchGestureConsumeResultFunc && func)4752 void SceneSessionManager::RegisterWatchGestureConsumeResultCallback(NotifyWatchGestureConsumeResultFunc&& func)
4753 {
4754 TLOGD(WmsLogTag::WMS_EVENT, "in");
4755 onWatchGestureConsumeResultFunc_ = std::move(func);
4756 }
4757
NotifyWatchFocusActiveChange(bool isActive)4758 WMError SceneSessionManager::NotifyWatchFocusActiveChange(bool isActive)
4759 {
4760 TLOGD(WmsLogTag::WMS_EVENT, "isActive:%{public}d", isActive);
4761 if (onWatchFocusActiveChangeFunc_) {
4762 onWatchFocusActiveChangeFunc_(isActive);
4763 } else {
4764 TLOGE(WmsLogTag::WMS_EVENT, "onWatchFocusActiveChangeFunc is null");
4765 return WMError::WM_ERROR_INVALID_PARAM;
4766 }
4767 return WMError::WM_OK;
4768 }
4769
RegisterWatchFocusActiveChangeCallback(NotifyWatchFocusActiveChangeFunc && func)4770 void SceneSessionManager::RegisterWatchFocusActiveChangeCallback(NotifyWatchFocusActiveChangeFunc&& func)
4771 {
4772 TLOGD(WmsLogTag::WMS_EVENT, "in");
4773 onWatchFocusActiveChangeFunc_ = std::move(func);
4774 }
4775
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)4776 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
4777 {
4778 for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
4779 if (iter->second != persistentId) {
4780 continue;
4781 }
4782 if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
4783 TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
4784 }
4785 remoteObjectMap_.erase(iter);
4786 break;
4787 }
4788 }
4789
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)4790 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
4791 {
4792 auto sceneSession = GetSceneSession(persistentId);
4793 if (sceneSession == nullptr) {
4794 return WSError::WS_ERROR_NULLPTR;
4795 }
4796 auto ret = sceneSession->UpdateActiveStatus(false);
4797 RemoveSessionFromBlackList(sceneSession);
4798 WindowDestroyNotifyVisibility(sceneSession);
4799 auto windowType = sceneSession->GetWindowType();
4800 if (windowType == WindowType::WINDOW_TYPE_DIALOG) {
4801 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4802 if (parentSession == nullptr) {
4803 TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
4804 } else {
4805 parentSession->RemoveDialogToParentSession(sceneSession);
4806 parentSession->UnregisterNotifySurfaceBoundsChangeFunc(persistentId);
4807 }
4808 } else if (windowType == WindowType::WINDOW_TYPE_TOAST) {
4809 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4810 if (parentSession != nullptr) {
4811 TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
4812 parentSession->RemoveToastSession(persistentId);
4813 } else {
4814 TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
4815 }
4816 } else if (windowType == WindowType::WINDOW_TYPE_FLOAT) {
4817 DestroySubSession(sceneSession);
4818 }
4819 ret = sceneSession->Disconnect();
4820 sceneSession->ClearSpecificSessionCbMap();
4821 if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
4822 DestroySubSession(sceneSession);
4823 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4824 if (parentSession != nullptr) {
4825 TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
4826 parentSession->RemoveSubSession(sceneSession->GetPersistentId());
4827 parentSession->UnregisterNotifySurfaceBoundsChangeFunc(persistentId);
4828 } else {
4829 TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
4830 }
4831 DestroyUIServiceExtensionSubWindow(sceneSession);
4832 }
4833 {
4834 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4835 EraseSceneSessionAndMarkDirtyLocked(persistentId);
4836 systemTopSceneSessionMap_.erase(persistentId);
4837 nonSystemFloatSceneSessionMap_.erase(persistentId);
4838 UnregisterSpecificSessionCreateListener(persistentId);
4839 }
4840 ClearSpecificSessionRemoteObjectMap(persistentId);
4841 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
4842 return ret;
4843 }
4844
DestroyAndDisconnectSpecificSession(const int32_t persistentId)4845 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
4846 {
4847 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
4848 auto task = [this, persistentId, callingPid]() {
4849 TLOGNI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
4850 auto sceneSession = GetSceneSession(persistentId);
4851 if (sceneSession == nullptr) {
4852 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
4853 return WSError::WS_ERROR_NULLPTR;
4854 }
4855
4856 if (callingPid != sceneSession->GetCallingPid()) {
4857 TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
4858 return WSError::WS_ERROR_INVALID_PERMISSION;
4859 }
4860 return DestroyAndDisconnectSpecificSessionInner(persistentId);
4861 };
4862
4863 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
4864 }
4865
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)4866 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
4867 const sptr<IRemoteObject>& callback)
4868 {
4869 if (callback == nullptr) {
4870 return WSError::WS_ERROR_NULLPTR;
4871 }
4872 const auto callingPid = IPCSkeleton::GetCallingRealPid();
4873 auto task = [this, persistentId, callingPid, callback]() {
4874 TLOGNI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
4875 auto sceneSession = GetSceneSession(persistentId);
4876 if (sceneSession == nullptr) {
4877 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
4878 return WSError::WS_ERROR_NULLPTR;
4879 }
4880
4881 if (callingPid != sceneSession->GetCallingPid()) {
4882 TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
4883 return WSError::WS_ERROR_INVALID_PERMISSION;
4884 }
4885 sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
4886 return DestroyAndDisconnectSpecificSessionInner(persistentId);
4887 };
4888
4889 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
4890 }
4891
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession> & sceneSession)4892 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
4893 {
4894 if (!sceneSession) {
4895 TLOGE(WmsLogTag::WMS_SUB, "sceneSession is null");
4896 return;
4897 }
4898 auto sessionProperty = sceneSession->GetSessionProperty();
4899 if (sessionProperty->GetIsUIExtFirstSubWindow() &&
4900 !sessionProperty->GetIsUIExtensionAbilityProcess()) {
4901 sceneSession->NotifyDestroy();
4902 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
4903 TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
4904 TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
4905 sceneSession->GetPersistentId(), errCode);
4906 }
4907 }
4908
GetWindowSceneConfig() const4909 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
4910 {
4911 return appWindowSceneConfig_;
4912 }
4913
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)4914 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
4915 {
4916 taskScheduler_->PostAsyncTask([this, config] {
4917 TLOGNI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
4918 rotateAnimationConfig_.duration_ = config.duration_;
4919 }, __func__);
4920 }
4921
ProcessBackEvent()4922 WSError SceneSessionManager::ProcessBackEvent()
4923 {
4924 taskScheduler_->PostAsyncTask([this]() {
4925 auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
4926 if (focusGroup == nullptr) {
4927 TLOGNE(WmsLogTag::WMS_MAIN, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
4928 return WSError::WS_ERROR_NULLPTR;
4929 }
4930 auto focusedSessionId = focusGroup->GetFocusedSessionId();
4931 auto needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
4932 auto session = GetSceneSession(focusedSessionId);
4933 if (!session) {
4934 TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId);
4935 return WSError::WS_ERROR_INVALID_SESSION;
4936 }
4937 TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
4938 focusedSessionId, needBlockNotifyFocusStatusUntilForeground);
4939 if (needBlockNotifyFocusStatusUntilForeground ||
4940 (!session->IsSessionValid() && !session->IsSystemSession())) {
4941 TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
4942 if (session->GetSessionInfo().abilityInfo != nullptr &&
4943 session->GetSessionInfo().abilityInfo->unclearableMission) {
4944 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
4945 return WSError::WS_OK;
4946 }
4947 session->RequestSessionBack(true);
4948 return WSError::WS_OK;
4949 }
4950 if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
4951 rootSceneProcessBackEventFunc_();
4952 } else {
4953 session->ProcessBackEvent();
4954 }
4955 return WSError::WS_OK;
4956 }, __func__);
4957 return WSError::WS_OK;
4958 }
4959
InitUserInfo(int32_t userId,std::string & fileDir)4960 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
4961 {
4962 if (userId == DEFAULT_USERID || fileDir.empty()) {
4963 TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
4964 return WSError::WS_DO_NOTHING;
4965 }
4966 TLOGI(WmsLogTag::WMS_MAIN, "userId: %{public}d, path: %{public}s", userId, fileDir.c_str());
4967 InitStartingWindowRdb(fileDir + "/StartingWindowRdb/");
4968 return taskScheduler_->PostSyncTask([this, userId, &fileDir]() {
4969 if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
4970 TLOGND(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
4971 }
4972 if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
4973 TLOGND(WmsLogTag::WMS_MAIN, "Create icon directory failed");
4974 }
4975 currentUserId_ = userId;
4976 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
4977 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
4978 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
4979 }
4980 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
4981 RegisterSecSurfaceInfoListener();
4982 RegisterConstrainedModalUIExtInfoListener();
4983 return WSError::WS_OK;
4984 }, __func__);
4985 }
4986
IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession> & sceneSession,int32_t pid)4987 bool SceneSessionManager::IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession>& sceneSession, int32_t pid)
4988 {
4989 auto sessionState = sceneSession->GetSessionState();
4990 auto isInvalidMainSession = !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
4991 sessionState == SessionState::STATE_DISCONNECT ||
4992 sessionState == SessionState::STATE_END;
4993 if (isInvalidMainSession) {
4994 TLOGD(WmsLogTag::WMS_MULTI_USER, "persistentId: %{public}d, type: %{public}d, state: %{public}d",
4995 sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState());
4996 }
4997 return sceneSession->GetCallingPid() != pid && IsPcSceneSessionLifecycle(sceneSession) && !isInvalidMainSession;
4998 }
4999
StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession> & sceneSession,bool isUserActive)5000 WSError SceneSessionManager::StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession>& sceneSession, bool isUserActive)
5001 {
5002 auto persistentId = sceneSession->GetPersistentId();
5003 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
5004 if (!isUserActive) {
5005 TLOGI(WmsLogTag::WMS_MULTI_USER,
5006 "MinimizeUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
5007 sceneSession->GetWindowType(), sceneSession->GetSessionState());
5008 bool isFromUser = false;
5009 TLOGNI(WmsLogTag::WMS_LIFE, "MinimizeUIAbilityBySCB, Notify scene session id: %{public}d paused", persistentId);
5010 sceneSession->UpdateLifecyclePausedInner();
5011 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(
5012 abilitySessionInfo, isFromUser, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH));
5013 if (errCode == ERR_OK) {
5014 sceneSession->SetMinimizedFlagByUserSwitch(true);
5015 } else {
5016 TLOGE(WmsLogTag::WMS_MULTI_USER, "minimize failed! errCode: %{public}d", errCode);
5017 }
5018 } else if (sceneSession->IsMinimizedByUserSwitch()) {
5019 TLOGI(WmsLogTag::WMS_MULTI_USER,
5020 "StartUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
5021 sceneSession->GetWindowType(), sceneSession->GetSessionState());
5022 sceneSession->SetMinimizedFlagByUserSwitch(false);
5023 bool isColdStart = false;
5024 abilitySessionInfo->isNewWant = false;
5025 int32_t errCode = StartUIAbilityBySCBTimeoutCheck(sceneSession,
5026 abilitySessionInfo, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH), isColdStart);
5027 if (errCode != ERR_OK) {
5028 TLOGE(WmsLogTag::WMS_MULTI_USER, "start failed! errCode: %{public}d", errCode);
5029 ExceptionInfo exceptionInfo;
5030 exceptionInfo.needRemoveSession = true;
5031 sceneSession->NotifySessionExceptionInner(abilitySessionInfo, exceptionInfo, false, true);
5032 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
5033 startUIAbilityErrorFunc_(
5034 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
5035 }
5036 }
5037 }
5038 return WSError::WS_OK;
5039 }
5040
ProcessUIAbilityOnUserSwitch(bool isUserActive)5041 void SceneSessionManager::ProcessUIAbilityOnUserSwitch(bool isUserActive)
5042 {
5043 int32_t pid = GetPid();
5044 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5045 for (const auto& [_, sceneSession] : sceneSessionMap_) {
5046 if (sceneSession == nullptr) {
5047 TLOGE(WmsLogTag::WMS_MULTI_USER, "session is null");
5048 continue;
5049 }
5050 // Change app life cycle in pc when user switch, do app freeze or unfreeze
5051 if (IsNeedChangeLifeCycleOnUserSwitch(sceneSession, pid)) {
5052 StartOrMinimizeUIAbilityBySCB(sceneSession, isUserActive);
5053 }
5054 }
5055 }
5056
HandleUserSwitching(bool isUserActive)5057 void SceneSessionManager::HandleUserSwitching(bool isUserActive)
5058 {
5059 // A brief screen freeze may occur when handling a switching event.
5060 // Record the duration and report it to HiSysEvent for troubleshooting.
5061 UserSwitchReporter reporter(isUserActive);
5062
5063 isUserBackground_ = !isUserActive;
5064 SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
5065 if (isUserActive) { // switch to current user
5066 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
5067 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
5068 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
5069 }
5070 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
5071 // notify screenSessionManager to recover current user
5072 ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
5073 FlushWindowInfoToMMI(true);
5074 NotifyAllAccessibilityInfo();
5075 rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
5076 UpdatePrivateStateAndNotifyForAllScreens();
5077 } else { // switch to another user
5078 SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
5079 // minimized UI abilities when the user is switching and inactive
5080 ProcessUIAbilityOnUserSwitch(isUserActive);
5081 }
5082 }
5083
HandleUserSwitched(bool isUserActive)5084 void SceneSessionManager::HandleUserSwitched(bool isUserActive)
5085 {
5086 if (isUserActive) {
5087 // start UI abilities only after the user has switched and become active
5088 ProcessUIAbilityOnUserSwitch(isUserActive);
5089 } else {
5090 rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
5091 }
5092 }
5093
HandleUserSwitch(const UserSwitchEventType type,const bool isUserActive)5094 void SceneSessionManager::HandleUserSwitch(const UserSwitchEventType type, const bool isUserActive)
5095 {
5096 if (type == UserSwitchEventType::SWITCHING && !isUserActive) {
5097 ScreenSessionManagerClient::GetInstance().DisconnectAllExternalScreen();
5098 }
5099
5100 taskScheduler_->PostSyncTask([this, type, isUserActive, where = __func__] {
5101 TLOGNI(WmsLogTag::WMS_MULTI_USER,
5102 "%{public}s: currentUserId: %{public}d, switchEventType: %{public}u, isUserActive: %{public}u",
5103 where, currentUserId_.load(), type, isUserActive);
5104 switch (type) {
5105 case UserSwitchEventType::SWITCHING: {
5106 HandleUserSwitching(isUserActive);
5107 break;
5108 }
5109 case UserSwitchEventType::SWITCHED: {
5110 HandleUserSwitched(isUserActive);
5111 break;
5112 }
5113 default: {
5114 TLOGNW(WmsLogTag::WMS_MULTI_USER, "%{public}s: Invalid switchEventType: %{public}u", where, type);
5115 break;
5116 }
5117 }
5118 return WSError::WS_OK;
5119 }, __func__);
5120 }
5121
GetBundleManager()5122 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
5123 {
5124 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
5125 if (systemAbilityMgr == nullptr) {
5126 TLOGE(WmsLogTag::DEFAULT, "Failed to get SystemAbilityManager.");
5127 return nullptr;
5128 }
5129 auto bmsProxy = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
5130 if (bmsProxy == nullptr) {
5131 TLOGE(WmsLogTag::DEFAULT, "Failed to get BundleManagerService.");
5132 return nullptr;
5133 }
5134 return iface_cast<AppExecFwk::IBundleMgr>(bmsProxy);
5135 }
5136
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)5137 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
5138 const AppExecFwk::AbilityInfo& abilityInfo)
5139 {
5140 auto context = rootSceneContextWeak_.lock();
5141 if (!context) {
5142 TLOGE(WmsLogTag::DEFAULT, "context is nullptr.");
5143 return nullptr;
5144 }
5145 auto resourceMgr = context->GetResourceManager();
5146 if (!resourceMgr) {
5147 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
5148 return nullptr;
5149 }
5150 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
5151 if (!resConfig) {
5152 TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
5153 return nullptr;
5154 }
5155 resourceMgr->GetResConfig(*resConfig);
5156 resourceMgr = Global::Resource::CreateResourceManager(
5157 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
5158 if (!resourceMgr) {
5159 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
5160 return nullptr;
5161 }
5162 resourceMgr->UpdateResConfig(*resConfig);
5163
5164 std::string loadPath;
5165 if (!abilityInfo.hapPath.empty()) { // zipped hap
5166 loadPath = abilityInfo.hapPath;
5167 } else {
5168 loadPath = abilityInfo.resourcePath;
5169 }
5170
5171 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA |
5172 Global::Resource::SELECT_PROF)) {
5173 TLOGW(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
5174 }
5175 return resourceMgr;
5176 }
5177
GetPathInfoFromResource(const std::shared_ptr<Global::Resource::ResourceManager> resourceMgr,bool hapPathEmpty,uint32_t resourceId,std::string & path)5178 bool SceneSessionManager::GetPathInfoFromResource(const std::shared_ptr<Global::Resource::ResourceManager> resourceMgr,
5179 bool hapPathEmpty, uint32_t resourceId, std::string& path)
5180 {
5181 if (resourceId == 0) {
5182 TLOGD(WmsLogTag::WMS_PATTERN, "resource invalid:%{public}u", resourceId);
5183 return false;
5184 }
5185 if (resourceMgr->GetMediaById(resourceId, path) != Global::Resource::RState::SUCCESS) {
5186 TLOGE(WmsLogTag::WMS_PATTERN, "failed id:%{public}u", resourceId);
5187 return false;
5188 }
5189 if (!hapPathEmpty) {
5190 auto pos = path.find_last_of('.');
5191 if (pos == std::string::npos) {
5192 TLOGE(WmsLogTag::WMS_PATTERN, "Format error, path %{private}s", path.c_str());
5193 return false;
5194 }
5195 path = "resource:///" + std::to_string(resourceId) + path.substr(pos);
5196 }
5197 return true;
5198 }
5199
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,StartingWindowInfo & startingWindowInfo)5200 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
5201 StartingWindowInfo& startingWindowInfo)
5202 {
5203 const std::map<std::string, std::string> START_WINDOW_KEY_AND_DEFAULT_MAP = {
5204 {STARTWINDOW_TYPE, "REQUIRED_SHOW"},
5205 };
5206
5207 auto resourceMgr = GetResourceManager(abilityInfo);
5208 if (!resourceMgr) {
5209 TLOGE(WmsLogTag::WMS_PATTERN, "resourceMgr is nullptr.");
5210 return false;
5211 }
5212 bool hapPathEmpty = abilityInfo.hapPath.empty();
5213 if (hapPathEmpty) {
5214 TLOGD(WmsLogTag::WMS_PATTERN, "hapPath empty:%{public}s", abilityInfo.bundleName.c_str());
5215 }
5216
5217 const auto startWindowType = START_WINDOW_KEY_AND_DEFAULT_MAP.find(STARTWINDOW_TYPE);
5218 if (startWindowType != START_WINDOW_KEY_AND_DEFAULT_MAP.end()) {
5219 startingWindowInfo.startWindowType_ = startingWindowRdbMgr_->GetStartWindowValFromProfile(
5220 abilityInfo, resourceMgr, startWindowType->first, startWindowType->second);
5221 }
5222
5223 if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId,
5224 startingWindowInfo.backgroundColorEarlyVersion_) != Global::Resource::RState::SUCCESS ||
5225 !GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5226 abilityInfo.startWindowIconId, startingWindowInfo.iconPathEarlyVersion_)) {
5227 if (!emptyStartupResource_.count(abilityInfo.bundleName)) {
5228 emptyStartupResource_.insert(abilityInfo.bundleName);
5229 TLOGE(WmsLogTag::WMS_PATTERN, "failed:%{public}s.", abilityInfo.bundleName.c_str());
5230 }
5231 return false;
5232 }
5233 // check start_window.json enabled by required field
5234 startingWindowInfo.configFileEnabled_ = abilityInfo.startWindowResource.startWindowBackgroundColorId != 0;
5235 if (!startingWindowInfo.configFileEnabled_) {
5236 return true;
5237 }
5238 if (resourceMgr->GetColorById(abilityInfo.startWindowResource.startWindowBackgroundColorId,
5239 startingWindowInfo.backgroundColor_) != Global::Resource::RState::SUCCESS) {
5240 TLOGE(WmsLogTag::WMS_PATTERN, "failed:%{public}s.", abilityInfo.bundleName.c_str());
5241 return false;
5242 }
5243 auto res = GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5244 abilityInfo.startWindowResource.startWindowAppIconId, startingWindowInfo.iconPath_);
5245 res = GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5246 abilityInfo.startWindowResource.startWindowIllustrationId, startingWindowInfo.illustrationPath_) && res;
5247 res = GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5248 abilityInfo.startWindowResource.startWindowBackgroundImageId, startingWindowInfo.backgroundImagePath_) && res;
5249 res = GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5250 abilityInfo.startWindowResource.startWindowBrandingImageId, startingWindowInfo.brandingPath_) && res;
5251 TLOGD(WmsLogTag::WMS_PATTERN, "all image configured:%{public}s, %{public}d", abilityInfo.bundleName.c_str(), res);
5252 startingWindowInfo.backgroundImageFit_ = abilityInfo.startWindowResource.startWindowBackgroundImageFit;
5253 return true;
5254 }
5255
GetIsDarkFromConfiguration()5256 bool SceneSessionManager::GetIsDarkFromConfiguration()
5257 {
5258 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
5259 if (appContext == nullptr) {
5260 TLOGE(WmsLogTag::WMS_PATTERN, "app context is nullptr");
5261 return false;
5262 }
5263 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
5264 if (config == nullptr) {
5265 TLOGE(WmsLogTag::WMS_PATTERN, "app configuration is nullptr");
5266 return false;
5267 }
5268 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
5269 TLOGI(WmsLogTag::WMS_PATTERN, "colorMode: %{public}s", colorMode.c_str());
5270 return (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
5271 }
5272
GetBundleStartingWindowInfos(bool isDark,const AppExecFwk::BundleInfo & bundleInfo,std::vector<std::pair<StartingWindowRdbItemKey,StartingWindowInfo>> & outValues)5273 void SceneSessionManager::GetBundleStartingWindowInfos(bool isDark, const AppExecFwk::BundleInfo& bundleInfo,
5274 std::vector<std::pair<StartingWindowRdbItemKey, StartingWindowInfo>>& outValues)
5275 {
5276 for (const auto& moduleInfo : bundleInfo.hapModuleInfos) {
5277 for (const auto& abilityInfo : moduleInfo.abilityInfos) {
5278 StartingWindowRdbItemKey itemKey = {
5279 .bundleName = abilityInfo.bundleName,
5280 .moduleName = abilityInfo.moduleName,
5281 .abilityName = abilityInfo.name,
5282 .darkMode = isDark,
5283 };
5284 StartingWindowInfo startingWindowInfo;
5285 if (!GetStartupPageFromResource(abilityInfo, startingWindowInfo)) {
5286 continue;
5287 }
5288 outValues.emplace_back(std::make_pair(itemKey, startingWindowInfo));
5289 }
5290 }
5291 }
5292
GetIconFromDesk(const SessionInfo & sessionInfo,std::string & startupPagePath) const5293 bool SceneSessionManager::GetIconFromDesk(const SessionInfo& sessionInfo, std::string& startupPagePath) const
5294 {
5295 auto& want = sessionInfo.want;
5296 if (want == nullptr) {
5297 TLOGI(WmsLogTag::WMS_PATTERN, "want is nullPtr");
5298 return false;
5299 }
5300 startupPagePath = want->GetStringParam("realAppIcon");
5301 if (startupPagePath.empty()) {
5302 return false;
5303 }
5304 return true;
5305 }
5306
InitStartingWindowRdb(const std::string & rdbPath)5307 void SceneSessionManager::InitStartingWindowRdb(const std::string& rdbPath)
5308 {
5309 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:InitStartingWindowRdb");
5310 WmsRdbConfig config;
5311 config.dbPath = rdbPath;
5312 if (mkdir(rdbPath.c_str(), S_IRWXU)) {
5313 TLOGW(WmsLogTag::WMS_PATTERN, "mkdir failed or already exists");
5314 }
5315 startingWindowRdbMgr_ = std::make_unique<StartingWindowRdbManager>(config);
5316 if (startingWindowRdbMgr_ == nullptr) {
5317 TLOGE(WmsLogTag::WMS_PATTERN, "create rdb manager fail");
5318 return;
5319 }
5320 if (!startingWindowRdbMgr_->Init()) {
5321 TLOGE(WmsLogTag::WMS_PATTERN, "init fail %{private}s", config.dbPath.c_str());
5322 return;
5323 }
5324 bool deleteAllDataRes = startingWindowRdbMgr_->DeleteAllData();
5325 TLOGI(WmsLogTag::WMS_PATTERN, "delete all data res: %{public}d", deleteAllDataRes);
5326 }
5327
UpdateAllStartingWindowRdb()5328 void SceneSessionManager::UpdateAllStartingWindowRdb()
5329 {
5330 const char* const where = __func__;
5331 auto loadTask = [this, where]() {
5332 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:UpdateAllStartingWindowRdb");
5333 if (bundleMgr_ == nullptr) {
5334 TLOGNE(WmsLogTag::WMS_PATTERN, "bundleMgr is nullptr");
5335 return;
5336 }
5337 std::vector<AppExecFwk::BundleInfo> bundleInfos;
5338 int32_t ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(
5339 static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE) |
5340 static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
5341 static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
5342 static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_ONLY_WITH_LAUNCHER_ABILITY),
5343 bundleInfos, currentUserId_));
5344 if (ret != 0) {
5345 TLOGNE(WmsLogTag::WMS_PATTERN, "GetBundleInfosV9 error:%{public}d", ret);
5346 return;
5347 }
5348 std::vector<std::pair<StartingWindowRdbItemKey, StartingWindowInfo>> inputValues;
5349 bool isDark = GetIsDarkFromConfiguration();
5350 for (const auto& bundleInfo : bundleInfos) {
5351 GetBundleStartingWindowInfos(isDark, bundleInfo, inputValues);
5352 }
5353 int64_t outInsertNum = -1;
5354 auto batchInsertRes = startingWindowRdbMgr_->BatchInsert(outInsertNum, inputValues);
5355 TLOGNI(WmsLogTag::WMS_PATTERN, "res: %{public}d, bundles: %{public}zu, insert: %{public}" PRId64,
5356 batchInsertRes, bundleInfos.size(), outInsertNum);
5357 startingWindowRdbMgr_->ClearRdbStore();
5358 };
5359 ffrtQueueHelper_->SubmitTask(loadTask);
5360 }
5361
GetStartupPage(const SessionInfo & sessionInfo,StartingWindowInfo & startingWindowInfo)5362 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, StartingWindowInfo& startingWindowInfo)
5363 {
5364 if (GetIconFromDesk(sessionInfo, startingWindowInfo.iconPathEarlyVersion_)) {
5365 TLOGI(WmsLogTag::WMS_PATTERN, "get icon from desk success");
5366 return;
5367 }
5368 if (!bundleMgr_) {
5369 TLOGE(WmsLogTag::WMS_PATTERN, "bundleMgr_ is nullptr.");
5370 return;
5371 }
5372 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
5373 if (GetStartingWindowInfoFromCache(sessionInfo, startingWindowInfo)) {
5374 return;
5375 }
5376 if (GetStartingWindowInfoFromRdb(sessionInfo, startingWindowInfo)) {
5377 CacheStartingWindowInfo(
5378 sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_, startingWindowInfo);
5379 uint32_t updateRes = UpdateCachedColorToAppSet(
5380 sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_, startingWindowInfo);
5381 TLOGI(WmsLogTag::WMS_PATTERN, "updateRes %{public}u, %{public}x",
5382 updateRes, startingWindowInfo.backgroundColor_);
5383 return;
5384 }
5385 AAFwk::Want want;
5386 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
5387 AppExecFwk::AbilityInfo abilityInfo;
5388 if (!bundleMgr_->QueryAbilityInfo(
5389 want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
5390 TLOGE(WmsLogTag::WMS_PATTERN, "Get ability info from BMS failed!");
5391 return;
5392 }
5393 if (GetStartupPageFromResource(abilityInfo, startingWindowInfo)) {
5394 CacheStartingWindowInfo(
5395 sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_, startingWindowInfo);
5396 if (startingWindowRdbMgr_ != nullptr) {
5397 StartingWindowRdbItemKey itemKey = {
5398 .bundleName = sessionInfo.bundleName_,
5399 .moduleName = sessionInfo.moduleName_,
5400 .abilityName = sessionInfo.abilityName_,
5401 .darkMode = GetIsDarkFromConfiguration(),
5402 };
5403 if (!startingWindowRdbMgr_->InsertData(itemKey, startingWindowInfo)) {
5404 TLOGW(WmsLogTag::WMS_PATTERN, "rdb insert faild");
5405 }
5406 }
5407 uint32_t updateRes = UpdateCachedColorToAppSet(
5408 sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_, startingWindowInfo);
5409 TLOGI(WmsLogTag::WMS_PATTERN, "updateRes %{public}u, %{public}x",
5410 updateRes, startingWindowInfo.backgroundColor_);
5411 }
5412 TLOGW(WmsLogTag::WMS_PATTERN, "%{public}d, %{public}x", startingWindowInfo.configFileEnabled_,
5413 startingWindowInfo.configFileEnabled_ ? startingWindowInfo.backgroundColor_ :
5414 startingWindowInfo.backgroundColorEarlyVersion_);
5415 }
5416
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,StartingWindowInfo & startingWindowInfo)5417 bool SceneSessionManager::GetStartingWindowInfoFromCache(
5418 const SessionInfo& sessionInfo, StartingWindowInfo& startingWindowInfo)
5419 {
5420 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
5421 std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5422 auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
5423 if (iter == startingWindowMap_.end()) {
5424 return false;
5425 }
5426 auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
5427 const auto& infoMap = iter->second;
5428 auto infoMapIter = infoMap.find(key);
5429 if (infoMapIter == infoMap.end()) {
5430 return false;
5431 }
5432 startingWindowInfo = infoMapIter->second;
5433 TLOGW(WmsLogTag::WMS_PATTERN, "%{public}x, %{public}s, %{public}x, %{public}s",
5434 startingWindowInfo.backgroundColorEarlyVersion_, startingWindowInfo.iconPathEarlyVersion_.c_str(),
5435 startingWindowInfo.backgroundColor_, startingWindowInfo.iconPath_.c_str());
5436 return true;
5437 }
5438
GetStartingWindowInfoFromRdb(const SessionInfo & sessionInfo,StartingWindowInfo & startingWindowInfo)5439 bool SceneSessionManager::GetStartingWindowInfoFromRdb(
5440 const SessionInfo& sessionInfo, StartingWindowInfo& startingWindowInfo)
5441 {
5442 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromRdb");
5443 if (startingWindowRdbMgr_ == nullptr) {
5444 TLOGE(WmsLogTag::WMS_PATTERN, "rdb is nullptr");
5445 return false;
5446 }
5447 StartingWindowRdbItemKey itemKey = {
5448 .bundleName = sessionInfo.bundleName_,
5449 .moduleName = sessionInfo.moduleName_,
5450 .abilityName = sessionInfo.abilityName_,
5451 .darkMode = GetIsDarkFromConfiguration(),
5452 };
5453 bool res = startingWindowRdbMgr_->QueryData(itemKey, startingWindowInfo);
5454 TLOGW(WmsLogTag::WMS_PATTERN, "%{public}x, %{public}s, %{public}x, %{public}s, %{public}d",
5455 startingWindowInfo.backgroundColorEarlyVersion_, startingWindowInfo.iconPathEarlyVersion_.c_str(),
5456 startingWindowInfo.backgroundColor_, startingWindowInfo.iconPath_.c_str(), res);
5457 return res;
5458 }
5459
UpdateCachedColorToAppSet(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,StartingWindowInfo & info)5460 uint32_t SceneSessionManager::UpdateCachedColorToAppSet(const std::string& bundleName, const std::string& moduleName,
5461 const std::string& abilityName, StartingWindowInfo& info)
5462 {
5463 auto key = moduleName + abilityName;
5464 uint32_t color = 0;
5465 std::unordered_map<std::string, std::unordered_map<std::string, uint32_t>> colorFromAppMap;
5466 {
5467 std::shared_lock<std::shared_mutex> lock(startingWindowColorFromAppMapMutex_);
5468 colorFromAppMap = startingWindowColorFromAppMap_;
5469 }
5470 auto colorMapIter = colorFromAppMap.find(bundleName);
5471 if (colorMapIter == colorFromAppMap.end()) {
5472 return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::COLOR_MAP_BUNDLE_NOT_FOUND);
5473 }
5474 auto& colorMap = colorMapIter->second;
5475 auto colorIter = colorMap.find(key);
5476 if (colorIter == colorMap.end()) {
5477 return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::COLOR_MAP_KEY_PAIR_NOT_FOUND);
5478 }
5479 color = colorIter->second;
5480 info.backgroundColor_ = color;
5481 info.backgroundColorEarlyVersion_ = color;
5482 {
5483 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5484 auto iter = startingWindowMap_.find(bundleName);
5485 if (iter == startingWindowMap_.end()) {
5486 return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::INFO_MAP_BUNDLE_NOT_FOUND);
5487 }
5488 auto& infoMap = iter->second;
5489 auto infoIter = infoMap.find(key);
5490 if (infoIter == infoMap.end()) {
5491 return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::INFO_MAP_BUNDLE_NOT_FOUND);
5492 }
5493 infoIter->second.backgroundColorEarlyVersion_ = color;
5494 infoIter->second.backgroundColor_ = color;
5495 }
5496 return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::SUCCESS);
5497 }
5498
CacheStartingWindowInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,const StartingWindowInfo & startingWindowInfo)5499 void SceneSessionManager::CacheStartingWindowInfo(const std::string& bundleName, const std::string& moduleName,
5500 const std::string& abilityName, const StartingWindowInfo& startingWindowInfo)
5501 {
5502 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
5503 auto key = moduleName + abilityName;
5504 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5505 auto iter = startingWindowMap_.find(bundleName);
5506 if (iter != startingWindowMap_.end()) {
5507 auto& infoMap = iter->second;
5508 infoMap.emplace(key, startingWindowInfo);
5509 return;
5510 }
5511 if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
5512 startingWindowMap_.erase(startingWindowMap_.begin());
5513 }
5514 std::map<std::string, StartingWindowInfo> infoMap({{ key, startingWindowInfo }});
5515 startingWindowMap_.emplace(bundleName, infoMap);
5516 }
5517
GetPreLoadStartingWindow(const SessionInfo & sessionInfo)5518 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetPreLoadStartingWindow(const SessionInfo& sessionInfo)
5519 {
5520 std::unordered_map<std::string, std::shared_ptr<Media::PixelMap>> preLoadMap;
5521 {
5522 std::shared_lock<std::shared_mutex> lock(preLoadstartingWindowMapMutex_);
5523 preLoadMap = preLoadStartingWindowMap_;
5524 }
5525 std::string key = sessionInfo.bundleName_ + '_' + sessionInfo.moduleName_ + '_' +sessionInfo.abilityName_;
5526 auto iter = preLoadMap.find(key);
5527 if (iter == preLoadMap.end()) {
5528 TLOGI(WmsLogTag::WMS_PATTERN, "%{public}s not found", key.c_str());
5529 return nullptr;
5530 }
5531 return iter->second;
5532 }
5533
RemovePreLoadStartingWindowFromMap(const SessionInfo & sessionInfo)5534 void SceneSessionManager::RemovePreLoadStartingWindowFromMap(const SessionInfo& sessionInfo)
5535 {
5536 std::string key = sessionInfo.bundleName_ + '_' + sessionInfo.moduleName_ + '_' +sessionInfo.abilityName_;
5537 std::unique_lock<std::shared_mutex> lock(preLoadstartingWindowMapMutex_);
5538 auto iter = preLoadStartingWindowMap_.find(key);
5539 if (iter != preLoadStartingWindowMap_.end()) {
5540 preLoadStartingWindowMap_.erase(iter);
5541 TLOGI(WmsLogTag::WMS_PATTERN, "%{public}s", key.c_str());
5542 }
5543 }
5544
PreLoadStartingWindow(sptr<SceneSession> sceneSession)5545 void SceneSessionManager::PreLoadStartingWindow(sptr<SceneSession> sceneSession)
5546 {
5547 const char* const where = __func__;
5548 auto loadTask = [this, weakSceneSession = wptr(sceneSession), where]() {
5549 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:PreLoadStartingWindow");
5550 sptr<SceneSession> sceneSession = weakSceneSession.promote();
5551 if (sceneSession == nullptr) {
5552 TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s session is nullptr", where);
5553 return;
5554 }
5555 auto sessionInfo = sceneSession->GetSessionInfo();
5556 if (!SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
5557 TLOGND(WmsLogTag::WMS_PATTERN, "%{public}s id: %{public}d is not main window",
5558 where, sceneSession->GetPersistentId());
5559 return;
5560 }
5561 if (sessionInfo.isPersistentRecover_) {
5562 TLOGNI(WmsLogTag::WMS_PATTERN, "%{public}s skip id: %{public}d for recover",
5563 where, sceneSession->GetPersistentId());
5564 return;
5565 }
5566 StartingWindowInfo startingWindowInfo;
5567 GetStartupPage(sessionInfo, startingWindowInfo);
5568 uint32_t resId = 0;
5569 if (!CheckAndGetPreLoadResourceId(startingWindowInfo, resId)) {
5570 TLOGND(WmsLogTag::WMS_PATTERN, "%{public}s check no need preLoad", where);
5571 return;
5572 }
5573 if (sessionInfo.abilityInfo == nullptr) {
5574 TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s id: %{public}d abilityInfo is nullptr",
5575 where, sceneSession->GetPersistentId());
5576 return;
5577 }
5578 auto pixelMap = GetPixelMap(resId, sessionInfo.abilityInfo);
5579 if (pixelMap == nullptr) {
5580 TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s pixelMap is nullptr", where);
5581 return;
5582 }
5583 std::string key = sessionInfo.bundleName_ + '_' + sessionInfo.moduleName_ + '_' +sessionInfo.abilityName_;
5584 {
5585 std::unique_lock<std::shared_mutex> lock(preLoadstartingWindowMapMutex_);
5586 preLoadStartingWindowMap_[key] = pixelMap;
5587 }
5588 sceneSession->NotifyPreLoadStartingWindowFinished();
5589 };
5590 ffrtQueueHelper_->SubmitTask(loadTask);
5591 if (needUpdateRdb_) {
5592 UpdateAllStartingWindowRdb();
5593 needUpdateRdb_ = false;
5594 }
5595 }
5596
CheckAndGetPreLoadResourceId(const StartingWindowInfo & startingWindowInfo,uint32_t & resId)5597 bool SceneSessionManager::CheckAndGetPreLoadResourceId(const StartingWindowInfo& startingWindowInfo, uint32_t& resId)
5598 {
5599 if (startingWindowInfo.configFileEnabled_) {
5600 TLOGD(WmsLogTag::WMS_PATTERN, "config file enabled");
5601 return false;
5602 }
5603 const auto& iconPath= startingWindowInfo.iconPathEarlyVersion_;
5604 auto pos = iconPath.find_last_of('.');
5605 constexpr uint32_t RESOURCE_PATH_HEAD_LENGTH = 12;
5606 if (pos == std::string::npos || pos <= RESOURCE_PATH_HEAD_LENGTH) {
5607 TLOGE(WmsLogTag::WMS_PATTERN, "format error: %{private}s", iconPath.c_str());
5608 return false;
5609 }
5610 const auto& extName = iconPath.substr(pos);
5611 if (extName != ".png" && extName != ".jpg") {
5612 TLOGI(WmsLogTag::WMS_PATTERN, "format not need preLoad: %{private}s", iconPath.c_str());
5613 return false;
5614 }
5615 const auto& resIdStr = iconPath.substr(RESOURCE_PATH_HEAD_LENGTH, pos - RESOURCE_PATH_HEAD_LENGTH);
5616 if (!WindowHelper::IsNumber(resIdStr)) {
5617 TLOGE(WmsLogTag::WMS_PATTERN, "number format error: %{public}s", resIdStr.c_str());
5618 return false;
5619 }
5620 resId = std::stoul(resIdStr);
5621 return true;
5622 }
5623
OnBundleUpdated(const std::string & bundleName,int userId)5624 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
5625 {
5626 taskScheduler_->PostAsyncTask([this, bundleName, where = __func__]() {
5627 if (startingWindowRdbMgr_ == nullptr || bundleMgr_ == nullptr) {
5628 TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s: rdb or bms is nullptr", where);
5629 return;
5630 }
5631 startingWindowRdbMgr_->DeleteDataByBundleName(bundleName);
5632 AppExecFwk::BundleInfo bundleInfo;
5633 bool ret = bundleMgr_->GetBundleInfoV9(bundleName,
5634 static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE) |
5635 static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
5636 static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY),
5637 bundleInfo, currentUserId_);
5638 if (ret == 0) {
5639 std::vector<std::pair<StartingWindowRdbItemKey, StartingWindowInfo>> inputValues;
5640 GetBundleStartingWindowInfos(GetIsDarkFromConfiguration() ,bundleInfo, inputValues);
5641 int64_t outInsertNum = -1;
5642 auto batchInsertRes = startingWindowRdbMgr_->BatchInsert(outInsertNum, inputValues);
5643 TLOGNI(WmsLogTag::WMS_PATTERN, "res:%{public}d, insert num:%{public}" PRId64, batchInsertRes, outInsertNum);
5644 }
5645 }, __func__);
5646 taskScheduler_->PostAsyncTask([this, bundleName]() {
5647 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5648 if (auto iter = startingWindowMap_.find(bundleName); iter != startingWindowMap_.end()) {
5649 startingWindowMap_.erase(iter);
5650 }
5651 }, __func__);
5652 }
5653
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)5654 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
5655 {
5656 taskScheduler_->PostAsyncTask([this]() {
5657 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5658 startingWindowMap_.clear();
5659 }, __func__);
5660 }
5661
ExtractSupportWindowModeFromMetaData(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)5662 std::vector<AppExecFwk::SupportWindowMode> SceneSessionManager::ExtractSupportWindowModeFromMetaData(
5663 const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
5664 {
5665 std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
5666 if (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode()) {
5667 auto metadata = abilityInfo->metadata;
5668 for (auto item : metadata) {
5669 if (item.name == "ohos.ability.window.supportWindowModeInFreeMultiWindow") {
5670 updateWindowModes = ParseWindowModeFromMetaData(item.value);
5671 }
5672 }
5673 }
5674 if (updateWindowModes.empty()) {
5675 updateWindowModes = abilityInfo->windowModes;
5676 }
5677 return updateWindowModes;
5678 }
5679
ParseWindowModeFromMetaData(const std::string & supportModesInFreeMultiWindow)5680 std::vector<AppExecFwk::SupportWindowMode> SceneSessionManager::ParseWindowModeFromMetaData(
5681 const std::string& supportModesInFreeMultiWindow)
5682 {
5683 std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
5684 std::stringstream supportModes(supportModesInFreeMultiWindow);
5685 std::string supportWindowMode;
5686 while (getline(supportModes, supportWindowMode, ',')) {
5687 if (supportWindowMode == "fullscreen") {
5688 updateWindowModes.push_back(AppExecFwk::SupportWindowMode::FULLSCREEN);
5689 } else if (supportWindowMode == "split") {
5690 updateWindowModes.push_back(AppExecFwk::SupportWindowMode::SPLIT);
5691 } else if (supportWindowMode == "floating") {
5692 updateWindowModes.push_back(AppExecFwk::SupportWindowMode::FLOATING);
5693 }
5694 }
5695 return updateWindowModes;
5696 }
5697
5698
FillSessionInfo(sptr<SceneSession> & sceneSession)5699 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
5700 {
5701 const auto& sessionInfo = sceneSession->GetSessionInfo();
5702 if (sessionInfo.bundleName_.empty()) {
5703 TLOGE(WmsLogTag::DEFAULT, "bundleName_ is empty");
5704 return;
5705 }
5706 if (sessionInfo.isSystem_) {
5707 TLOGD(WmsLogTag::DEFAULT, "is system scene!");
5708 return;
5709 }
5710 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
5711 sessionInfo.moduleName_, IsAtomicServiceFreeInstall(sessionInfo));
5712 if (abilityInfo == nullptr) {
5713 TLOGE(WmsLogTag::DEFAULT, "Null");
5714 return;
5715 }
5716 if (sessionInfo.supportedWindowModes.empty()) {
5717 sceneSession->SetSessionInfoSupportedWindowModes(ExtractSupportWindowModeFromMetaData(abilityInfo));
5718 }
5719 sceneSession->SetEnableRemoveStartingWindow(GetEnableRemoveStartingWindowFromBMS(abilityInfo));
5720 sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
5721 sceneSession->SetSessionInfoTime(GetCurrentTime());
5722 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
5723 sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
5724 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
5725 sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
5726 }
5727 SetSessionInfoStartWindowType(sceneSession);
5728 TLOGI(WmsLogTag::WMS_MAIN, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
5729 "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
5730 abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
5731 abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
5732 }
5733
SetSessionInfoStartWindowType(const sptr<SceneSession> & sceneSession)5734 void SceneSessionManager::SetSessionInfoStartWindowType(const sptr<SceneSession>& sceneSession)
5735 {
5736 if (systemConfig_.IsPcOrPcMode() && !sceneSession->GetSessionInfo().isSetStartWindowType_) {
5737 StartingWindowInfo startingWindowInfo;
5738 GetStartupPage(sceneSession->GetSessionInfo(), startingWindowInfo);
5739 TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, startWindowType from rdb:%{public}s",
5740 sceneSession->GetPersistentId(), startingWindowInfo.startWindowType_.c_str());
5741 if (CONVERT_STRING_TO_START_WINDOW_TYPE_MAP.count(startingWindowInfo.startWindowType_) > 0) {
5742 sceneSession->EditSessionInfo().startWindowType_ =
5743 CONVERT_STRING_TO_START_WINDOW_TYPE_MAP.at(startingWindowInfo.startWindowType_);
5744 }
5745 if (sceneSession->GetSessionInfo().startWindowType_ == StartWindowType::RETAIN_AND_INVISIBLE) {
5746 sceneSession->SetHidingStartingWindow(true);
5747 }
5748 TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, startWindowType:%{public}d",
5749 sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().startWindowType_);
5750 }
5751 }
5752
RegisterGetStartWindowConfigCallback(const sptr<SceneSession> & sceneSession)5753 void SceneSessionManager::RegisterGetStartWindowConfigCallback(const sptr<SceneSession>& sceneSession)
5754 {
5755 if (sceneSession == nullptr) {
5756 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
5757 return;
5758 }
5759 sceneSession->RegisterGetStartWindowConfigFunc([this](const SessionInfo& sessionInfo, std::string& startWindowType) {
5760 StartingWindowInfo startingWindowInfo;
5761 GetStartupPage(sessionInfo, startingWindowInfo);
5762 startWindowType = startingWindowInfo.startWindowType_;
5763 TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, startWindowType:%{public}s",
5764 sessionInfo.persistentId_, startWindowType.c_str());
5765 });
5766 }
5767
5768
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName,bool isAtomicServiceFreeInstall)5769 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
5770 const std::string& bundleName, const std::string& abilityName, const std::string& moduleName,
5771 bool isAtomicServiceFreeInstall)
5772 {
5773 if (!bundleMgr_) {
5774 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
5775 return nullptr;
5776 }
5777 SessionInfoList list = {
5778 .uid_ = uId, .bundleName_ = bundleName, .abilityName_ = abilityName, .moduleName_ = moduleName
5779 };
5780 if (abilityInfoMap_.count(list)) {
5781 return abilityInfoMap_[list];
5782 }
5783 if (isAtomicServiceFreeInstall) {
5784 AppExecFwk::BundleInfo bundleInfo;
5785 auto flag = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
5786 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
5787 bool ret = bundleMgr_->GetBundleInfoV9(bundleName, flag, bundleInfo, currentUserId_);
5788 if (ret) {
5789 TLOGE(WmsLogTag::WMS_LIFE, "Get bundle:%{public}s info from BMS failed!", bundleName.c_str());
5790 return nullptr;
5791 }
5792 for (const auto& hapModuleInfo : bundleInfo.hapModuleInfos) {
5793 if (!hapModuleInfo.abilityInfos.empty()) {
5794 TLOGI(WmsLogTag::WMS_LIFE, "Get abilityInfo success in AtomicFreeInstall, bundle:%{public}s.",
5795 bundleName.c_str());
5796
5797 // Atomic services only have one ability.
5798 return std::make_shared<AppExecFwk::AbilityInfo>(hapModuleInfo.abilityInfos[0]);
5799 }
5800 }
5801 TLOGE(WmsLogTag::WMS_LIFE, "Get abilityInfo failed, bundleName:%{public}s.", bundleName.c_str());
5802 return nullptr;
5803 }
5804
5805 AAFwk::Want want;
5806 want.SetElementName("", bundleName, abilityName, moduleName);
5807 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
5808 if (abilityInfo == nullptr) {
5809 TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
5810 return nullptr;
5811 }
5812 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
5813 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
5814 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
5815 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
5816 if (!ret) {
5817 TLOGE(WmsLogTag::DEFAULT, "Failed");
5818 return nullptr;
5819 }
5820 abilityInfoMap_[list] = abilityInfo;
5821 return abilityInfo;
5822 }
5823
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)5824 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
5825 uint32_t& topWinId, uint32_t& zOrder)
5826 {
5827 const auto& subVec = session->GetSubSession();
5828 for (const auto& subSession : subVec) {
5829 if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
5830 TLOGW(WmsLogTag::WMS_SUB,
5831 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
5832 continue;
5833 }
5834 if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
5835 subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
5836 subSession->GetZOrder() > zOrder) {
5837 topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
5838 zOrder = subSession->GetZOrder();
5839 TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
5840 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
5841 }
5842 if (subSession->GetSubSession().size() > 0) {
5843 GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
5844 }
5845 }
5846 }
5847
5848 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)5849 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
5850 {
5851 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
5852 auto task = [this, mainWinId, &topWinId, callingPid]() {
5853 const auto& mainSession = GetSceneSession(mainWinId);
5854 if (mainSession == nullptr) {
5855 return WMError::WM_ERROR_INVALID_WINDOW;
5856 }
5857
5858 if (callingPid != mainSession->GetCallingPid()) {
5859 TLOGNE(WmsLogTag::WMS_HIERARCHY, "Permission denied, not destroy by the same process");
5860 return WMError::WM_ERROR_INVALID_PERMISSION;
5861 }
5862 uint32_t zOrder = mainSession->GetZOrder();
5863 topWinId = mainWinId;
5864 GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
5865 TLOGNI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
5866 "zOrder: %{public}d", mainWinId, topWinId, zOrder);
5867 return WMError::WM_OK;
5868 };
5869
5870 if (!Session::IsScbCoreEnabled()) {
5871 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
5872 }
5873 bool postNow = false;
5874 auto mainSession = GetSceneSession(mainWinId);
5875 if (mainSession != nullptr) {
5876 postNow = !(mainSession->GetUIStateDirty());
5877 }
5878 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
5879 if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
5880 taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
5881 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
5882 }
5883 TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
5884 {
5885 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
5886 if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
5887 std::cv_status::timeout) {
5888 TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
5889 }
5890 }
5891 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
5892 }
5893
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)5894 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
5895 int32_t windowId, int32_t& mainWindowId)
5896 {
5897 auto iter = sceneSessionMap.find(windowId);
5898 if (iter == sceneSessionMap.end()) {
5899 TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
5900 return WMError::WM_ERROR_NULLPTR;
5901 }
5902 sptr<SceneSession> sceneSession = iter->second;
5903 if (sceneSession == nullptr) {
5904 TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
5905 return WMError::WM_ERROR_NULLPTR;
5906 }
5907 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
5908 mainWindowId = sceneSession->GetPersistentId();
5909 return WMError::WM_OK;
5910 }
5911 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
5912 WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
5913 return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
5914 }
5915 // not sub window, dialog, return invalid id
5916 mainWindowId = INVALID_SESSION_ID;
5917 return WMError::WM_OK;
5918 }
5919
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)5920 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
5921 {
5922 if (windowId == INVALID_SESSION_ID) {
5923 TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
5924 return WMError::WM_ERROR_INVALID_PARAM;
5925 }
5926 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5927 return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
5928 }
5929
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)5930 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
5931 const sptr<SceneSession>& sceneSession)
5932 {
5933 auto systemBarProperties = property->GetSystemBarProperty();
5934 for (auto iter : systemBarProperties) {
5935 if (iter.first == type) {
5936 sceneSession->SetSystemBarProperty(iter.first, iter.second);
5937 TLOGD(WmsLogTag::WMS_IMMS, "type %{public}d enable %{public}d",
5938 static_cast<int32_t>(iter.first), iter.second.enable_);
5939 }
5940 }
5941 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5942 }
5943
5944 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)5945 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
5946 const sptr<SceneSession>& sceneSession)
5947 {
5948 if (!SessionPermission::IsSystemCalling()) {
5949 TLOGE(WmsLogTag::WMS_HIERARCHY, "UpdateTopmostProperty permission denied!");
5950 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5951 }
5952
5953 sceneSession->SetTopmost(property->IsTopmost());
5954 return WMError::WM_OK;
5955 }
5956
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)5957 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
5958 const sptr<SceneSession>& sceneSession)
5959 {
5960 auto propertyOld = sceneSession->GetSessionProperty();
5961 bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
5962 bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
5963 if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
5964 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "property hideNonSystemFloatingWindows not change");
5965 return;
5966 }
5967
5968 if (IsSessionVisibleForeground(sceneSession)) {
5969 if (hideNonSystemFloatingWindowsOld) {
5970 UpdateForceHideState(sceneSession, propertyOld, false);
5971 } else {
5972 UpdateForceHideState(sceneSession, property, true);
5973 }
5974 }
5975 }
5976
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)5977 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
5978 const sptr<WindowSessionProperty>& property, bool add)
5979 {
5980 if (systemConfig_.IsPcWindow()) {
5981 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "IsPcWindow, ineffective");
5982 return;
5983 }
5984 if (property == nullptr) {
5985 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "property is null");
5986 return;
5987 }
5988 auto persistentId = sceneSession->GetPersistentId();
5989 bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
5990 bool notifyAll = false;
5991 if (add) {
5992 if (property->GetHideNonSystemFloatingWindows()) {
5993 systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
5994 notifyAll = !forceHideFloatOld;
5995 } else if ((property->IsFloatingWindowAppType() && !property->GetSystemCalling()) ||
5996 sceneSession->GetIsAncoForFloatingWindow()) {
5997 nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
5998 if (forceHideFloatOld) {
5999 sceneSession->NotifyForceHideChange(true);
6000 }
6001 }
6002 } else {
6003 if (property->GetHideNonSystemFloatingWindows()) {
6004 systemTopSceneSessionMap_.erase(persistentId);
6005 notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
6006 } else if ((property->IsFloatingWindowAppType() && !property->GetSystemCalling()) ||
6007 sceneSession->GetIsAncoForFloatingWindow()) {
6008 nonSystemFloatSceneSessionMap_.erase(persistentId);
6009 if (property->GetForceHide()) {
6010 sceneSession->NotifyForceHideChange(false);
6011 }
6012 }
6013 }
6014 if (notifyAll) {
6015 bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
6016 for (const auto& item : nonSystemFloatSceneSessionMap_) {
6017 auto forceHideSceneSession = item.second;
6018 if (forceHideFloatNew != forceHideSceneSession->GetSessionProperty()->GetForceHide()) {
6019 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
6020 }
6021 }
6022 }
6023 }
6024
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)6025 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
6026 {
6027 #ifdef POWER_MANAGER_ENABLE
6028 auto task = [this, sceneSession]() {
6029 if (sceneSession == nullptr) {
6030 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
6031 return;
6032 }
6033 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "Win: %{public}s, is turn on%{public}d",
6034 sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
6035 std::string identity = IPCSkeleton::ResetCallingIdentity();
6036 if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
6037 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "turn screen on");
6038 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
6039 }
6040 // set ipc identity to raw
6041 IPCSkeleton::SetCallingIdentity(identity);
6042 };
6043 taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
6044
6045 #else
6046 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
6047 #endif
6048 }
6049
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock,const std::string & screenLockPrefix,std::shared_ptr<PowerMgr::RunningLock> & screenLock)6050 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock,
6051 const std::string& screenLockPrefix, std::shared_ptr<PowerMgr::RunningLock>& screenLock)
6052 {
6053 #ifdef POWER_MANAGER_ENABLE
6054 wptr<SceneSession> weakSceneSession(sceneSession);
6055 auto task = [this, weakSceneSession, requireLock, &screenLockPrefix, &screenLock]() {
6056 auto sceneSession = weakSceneSession.promote();
6057 if (sceneSession == nullptr) {
6058 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
6059 return;
6060 }
6061 if (requireLock && screenLock == nullptr) {
6062 // reset ipc identity
6063 std::string identity = IPCSkeleton::ResetCallingIdentity();
6064 screenLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(
6065 screenLockPrefix + std::to_string(sceneSession->GetPersistentId()),
6066 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
6067 // set ipc identity to raw
6068 IPCSkeleton::SetCallingIdentity(identity);
6069 }
6070 if (screenLock == nullptr) {
6071 return;
6072 }
6073 auto currScreenId = sceneSession->GetSessionInfo().screenId_;
6074 auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
6075 if (auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(currScreenId)) {
6076 sourceMode = screenSession->GetSourceMode();
6077 }
6078 bool shouldLock = requireLock && IsSessionVisibleForeground(sceneSession) && sourceMode != ScreenSourceMode::SCREEN_UNIQUE;
6079 TLOGNI(WmsLogTag::WMS_ATTRIBUTE,
6080 "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d]",
6081 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionState(),
6082 sceneSession->IsVisible(), requireLock, shouldLock, currScreenId, sourceMode);
6083 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
6084 ErrCode res;
6085 std::string identity = IPCSkeleton::ResetCallingIdentity();
6086 if (shouldLock) {
6087 res = screenLock->Lock();
6088 } else {
6089 res = screenLock->UnLock();
6090 }
6091 // set ipc identity to raw
6092 IPCSkeleton::SetCallingIdentity(identity);
6093 if (res != ERR_OK) {
6094 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "handle keep screen running lock failed: [operation: %{public}d, "
6095 "err: %{public}d]", requireLock, res);
6096 }
6097 };
6098 taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
6099 #else
6100 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
6101 #endif
6102 }
6103
NotifyVisibleChange(int32_t persistentId)6104 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
6105 {
6106 auto sceneSession = GetSceneSession(persistentId);
6107 if (sceneSession == nullptr) {
6108 return false;
6109 }
6110 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
6111 sceneSession->keepScreenLock_);
6112 HandleKeepScreenOn(sceneSession, sceneSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
6113 sceneSession->viewKeepScreenLock_);
6114 return true;
6115 }
6116
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)6117 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
6118 {
6119 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
6120 if (GetDisplayBrightness() != brightness &&
6121 GetFocusedSessionId() == sceneSession->GetPersistentId()) {
6122 PostBrightnessTask(brightness);
6123 }
6124 #else
6125 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of DisplayPowerMgr");
6126 #endif
6127 brightnessSessionId_ = sceneSession->GetPersistentId();
6128 return WSError::WS_OK;
6129 }
6130
PostBrightnessTask(float brightness)6131 void SceneSessionManager::PostBrightnessTask(float brightness)
6132 {
6133 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
6134 bool postTaskRet = true;
6135 bool isPC = systemConfig_.IsPcWindow();
6136 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
6137 if (!isPC) {
6138 auto task = [] {
6139 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
6140 };
6141 postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
6142 }
6143 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
6144 } else {
6145 auto task = [brightness, isPC] {
6146 if (isPC) {
6147 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
6148 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
6149 } else {
6150 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
6151 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
6152 }
6153 };
6154 postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
6155 SetDisplayBrightness(brightness);
6156 }
6157 if (!postTaskRet) {
6158 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "post task failed. task is SetBrightness");
6159 }
6160 #endif
6161 }
6162
UpdateBrightness(int32_t persistentId)6163 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
6164 {
6165 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
6166 if (systemConfig_.IsPcWindow()) {
6167 return WSError::WS_OK;
6168 }
6169 auto sceneSession = GetSceneSession(persistentId);
6170 if (sceneSession == nullptr) {
6171 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
6172 return WSError::WS_ERROR_NULLPTR;
6173 }
6174 if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
6175 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLET_SWIPE_CARD ||
6176 sceneSession->GetSessionInfo().isSystem_)) {
6177 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window or wallet swipe card can set brightness");
6178 return WSError::WS_DO_NOTHING;
6179 }
6180 auto brightness = sceneSession->GetBrightness();
6181 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
6182 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
6183 if (IsNeedUpdateBrightness(persistentId, brightness)) {
6184 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with default value");
6185 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
6186 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
6187 brightnessSessionId_ = INVALID_WINDOW_ID;
6188 }
6189 } else {
6190 if (std::fabs(brightness - GetDisplayBrightness()) > std::numeric_limits<float>::min()) {
6191 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with value");
6192 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
6193 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
6194 SetDisplayBrightness(brightness);
6195 }
6196 brightnessSessionId_ = sceneSession->GetPersistentId();
6197 }
6198 #else
6199 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of DisplayPowerMgr");
6200 #endif
6201 return WSError::WS_OK;
6202 }
6203
IsNeedUpdateBrightness(int32_t persistentId,float brightness)6204 bool SceneSessionManager::IsNeedUpdateBrightness(int32_t persistentId, float brightness)
6205 {
6206 if (std::fabs(brightness - GetDisplayBrightness()) < std::numeric_limits<float>::min()) {
6207 return false;
6208 }
6209 if (brightnessSessionId_ == persistentId) {
6210 return true;
6211 }
6212 auto brightnessSession = GetSceneSession(brightnessSessionId_);
6213 if (brightnessSession != nullptr && brightnessSession->IsSessionForeground()) {
6214 return false;
6215 }
6216 return true;
6217 }
6218
GetCurrentUserId() const6219 int32_t SceneSessionManager::GetCurrentUserId() const
6220 {
6221 return currentUserId_;
6222 }
6223
SetDisplayBrightness(float brightness)6224 void SceneSessionManager::SetDisplayBrightness(float brightness)
6225 {
6226 displayBrightness_ = brightness;
6227 }
6228
GetDisplayBrightness() const6229 float SceneSessionManager::GetDisplayBrightness() const
6230 {
6231 return displayBrightness_;
6232 }
6233
SetGestureNavigationEnabled(bool enable)6234 WMError SceneSessionManager::SetGestureNavigationEnabled(bool enable)
6235 {
6236 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6237 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
6238 return WMError::WM_ERROR_NOT_SYSTEM_APP;
6239 }
6240 std::string callerBundleName = SessionPermission::GetCallingBundleName();
6241 TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
6242 auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
6243 SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
6244 if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
6245 TLOGNE(WmsLogTag::WMS_EVENT, "callback func is null");
6246 return WMError::WM_OK;
6247 }
6248 if (gestureNavigationEnabledChangeFunc_) {
6249 gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
6250 }
6251 if (statusBarEnabledChangeFunc_) {
6252 statusBarEnabledChangeFunc_(enable, bundleName);
6253 }
6254 return WMError::WM_OK;
6255 };
6256 return taskScheduler_->PostSyncTask(task, "SetGestureNavigationEnabled");
6257 }
6258
SetFocusedSessionId(const int32_t persistentId,const DisplayId displayId)6259 WSError SceneSessionManager::SetFocusedSessionId(const int32_t persistentId, const DisplayId displayId)
6260 {
6261 return windowFocusController_->UpdateFocusedSessionId(displayId, persistentId);
6262 }
6263
GetFocusedSessionId(DisplayId displayId) const6264 int32_t SceneSessionManager::GetFocusedSessionId(DisplayId displayId) const
6265 {
6266 return windowFocusController_->GetFocusedSessionId(displayId);
6267 }
6268
GetDisplayGroupId(DisplayId displayId) const6269 DisplayId SceneSessionManager::GetDisplayGroupId(DisplayId displayId) const
6270 {
6271 return windowFocusController_->GetDisplayGroupId(displayId);
6272 }
6273
GetAllFocusedSessionList() const6274 std::vector<std::pair<DisplayId, int32_t>> SceneSessionManager::GetAllFocusedSessionList() const
6275 {
6276 return windowFocusController_->GetAllFocusedSessionList();
6277 }
6278
GetFocusWindowInfo(FocusChangeInfo & focusInfo,DisplayId displayId)6279 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo, DisplayId displayId)
6280 {
6281 if (!SessionPermission::IsSACalling()) {
6282 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
6283 return;
6284 }
6285 taskScheduler_->PostSyncTask([this, &focusInfo, displayId] {
6286 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6287 if (focusGroup == nullptr) {
6288 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6289 return WSError::WS_ERROR_DESTROYED_OBJECT;
6290 }
6291 if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
6292 focusInfo.windowId_ = sceneSession->GetWindowId();
6293 focusInfo.displayId_ = focusGroup->GetDisplayGroupId() == DEFAULT_DISPLAY_ID
6294 ? DEFAULT_DISPLAY_ID
6295 : sceneSession->GetDisplayId();
6296 focusInfo.pid_ = sceneSession->GetCallingPid();
6297 focusInfo.uid_ = sceneSession->GetCallingUid();
6298 focusInfo.windowType_ = sceneSession->GetWindowType();
6299 focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
6300 TLOGND(WmsLogTag::WMS_FOCUS, "Get focus session info success");
6301 return WSError::WS_OK;
6302 }
6303 return WSError::WS_ERROR_DESTROYED_OBJECT;
6304 }, __func__);
6305 }
6306
AddFocusGroup(DisplayGroupId displayGroupId,DisplayId displayId)6307 WSError SceneSessionManager::AddFocusGroup(DisplayGroupId displayGroupId, DisplayId displayId)
6308 {
6309 return windowFocusController_->AddFocusGroup(displayGroupId, displayId);
6310 }
6311
RemoveFocusGroup(DisplayGroupId displayGroupId,DisplayId displayId)6312 WSError SceneSessionManager::RemoveFocusGroup(DisplayGroupId displayGroupId, DisplayId displayId)
6313 {
6314 return windowFocusController_->RemoveFocusGroup(displayGroupId, displayId);
6315 }
6316
SendPointerEventForHover(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)6317 WSError SceneSessionManager::SendPointerEventForHover(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
6318 {
6319 if (!SessionPermission::IsSACalling()) {
6320 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
6321 return WSError::WS_ERROR_INVALID_PERMISSION;
6322 }
6323 if (pointerEvent == nullptr) {
6324 TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is nullptr");
6325 return WSError::WS_ERROR_NULLPTR;
6326 }
6327 bool isHoverDown = pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_HOVER_ENTER &&
6328 pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN;
6329 if (!isHoverDown) {
6330 TLOGE(WmsLogTag::WMS_EVENT, "pointer event is not hover down");
6331 return WSError::WS_ERROR_INVALID_PARAM;
6332 }
6333 return taskScheduler_->PostSyncTask([this, &pointerEvent]() {
6334 int32_t windowId = pointerEvent->GetAgentWindowId();
6335 TLOGNI(WmsLogTag::WMS_EVENT, "windowId: %{public}d", windowId);
6336 auto sceneSession = GetSceneSession(windowId);
6337 if (sceneSession == nullptr) {
6338 TLOGNE(WmsLogTag::WMS_EVENT, "session is nullptr");
6339 return WSError::WS_ERROR_INVALID_SESSION;
6340 }
6341 return sceneSession->SendPointerEventForHover(pointerEvent);
6342 }, __func__);
6343 }
6344
IsValidDigitString(const std::string & windowIdStr)6345 static bool IsValidDigitString(const std::string& windowIdStr)
6346 {
6347 if (windowIdStr.empty()) {
6348 return false;
6349 }
6350 for (char ch : windowIdStr) {
6351 if (ch >= '0' && ch <= '9') {
6352 continue;
6353 }
6354 TLOGE(WmsLogTag::DEFAULT, "invalid window id");
6355 return false;
6356 }
6357 return true;
6358 }
6359
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)6360 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
6361 {
6362 if (sceneSession == nullptr) {
6363 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
6364 return;
6365 }
6366 sceneSession->SetSessionExceptionListener([this, where = __func__](
6367 const SessionInfo& info, const ExceptionInfo& exceptionInfo , bool startFail = false) {
6368 auto task = [this, info, where] {
6369 auto session = GetSceneSession(info.persistentId_);
6370 if (session == nullptr) {
6371 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Not found session, id:%{public}d", where, info.persistentId_);
6372 return;
6373 }
6374 if (session->GetSessionInfo().isSystem_) {
6375 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d is system", where, session->GetPersistentId());
6376 return;
6377 }
6378 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s errorCode: %{public}d, id: %{public}d",
6379 where, info.errorCode, info.persistentId_);
6380 if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
6381 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
6382 TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
6383 "or foreground timeout, id: %{public}d", info.persistentId_);
6384 listenerController_->NotifySessionClosed(session->GetSessionInfo());
6385 }
6386 };
6387 taskScheduler_->PostVoidSyncTask(task, "sessionException");
6388 }, false);
6389 TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
6390 }
6391
RegisterVisibilityChangedDetectFunc(const sptr<SceneSession> & sceneSession)6392 void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr<SceneSession>& sceneSession)
6393 {
6394 if (sceneSession == nullptr) {
6395 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
6396 return;
6397 }
6398 sceneSession->SetVisibilityChangedDetectFunc(
6399 [this](int32_t pid, bool isVisible, bool newIsVisible) THREAD_SAFETY_GUARD(SCENE_GUARD) {
6400 if (isVisible == newIsVisible || pid == -1) {
6401 return;
6402 }
6403 auto windowPidVisibilityInfo = sptr<WindowPidVisibilityInfo>::MakeSptr();
6404 windowPidVisibilityInfo->pid_ = pid;
6405 int32_t currentCount = 0;
6406 int32_t beforeCount = 0;
6407 if (visibleWindowCountMap_.find(pid) != visibleWindowCountMap_.end()) {
6408 beforeCount = visibleWindowCountMap_[pid];
6409 }
6410 currentCount = newIsVisible ? beforeCount + 1 : beforeCount - 1;
6411 visibleWindowCountMap_[pid] = currentCount;
6412 if (visibleWindowCountMap_[pid] == 0) {
6413 visibleWindowCountMap_.erase(pid);
6414 }
6415 if (beforeCount == 0 && currentCount == 1) {
6416 TLOGNI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid);
6417 windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE;
6418 SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
6419 } else if (beforeCount == 1 && currentCount == 0) {
6420 TLOGNI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid);
6421 windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE;
6422 SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
6423 } else if (beforeCount < 0 || currentCount < 0) {
6424 TLOGNE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid);
6425 RecoveryVisibilityPidCount(pid);
6426 }
6427 });
6428 }
6429
RecoveryVisibilityPidCount(int32_t pid)6430 void SceneSessionManager::RecoveryVisibilityPidCount(int32_t pid)
6431 {
6432 int32_t count = 0;
6433 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6434 for (const auto& [_, session] : sceneSessionMap_) {
6435 if (session && session->GetCallingPid() == pid && session->IsVisible()) {
6436 count++;
6437 }
6438 }
6439 if (count > 0) {
6440 visibleWindowCountMap_[pid] = count;
6441 }
6442 }
6443
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)6444 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
6445 {
6446 if (sceneSession == nullptr) {
6447 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
6448 return;
6449 }
6450 NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
6451 auto sceneSession = GetSceneSession(persistentId);
6452 if (sceneSession == nullptr) {
6453 TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
6454 return;
6455 }
6456 if (sceneSession->GetSessionInfo().isSystem_) {
6457 TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, id: %{public}d is system",
6458 sceneSession->GetPersistentId());
6459 return;
6460 }
6461 auto abilityInfo = sceneSession->GetSessionInfo().abilityInfo;
6462 if (abilityInfo == nullptr) {
6463 TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, abilityInfo is nullptr");
6464 return;
6465 }
6466 if (!abilityInfo->excludeFromMissions) {
6467 listenerController_->NotifySessionSnapshotChanged(persistentId);
6468 }
6469 };
6470 sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
6471 TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d", sceneSession->GetPersistentId());
6472 }
6473
RegisterRequestVsyncFunc(const sptr<SceneSession> & sceneSession)6474 void SceneSessionManager::RegisterRequestVsyncFunc(const sptr<SceneSession>& sceneSession)
6475 {
6476 if (sceneSession == nullptr) {
6477 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
6478 return;
6479 }
6480 sceneSession->SetRequestNextVsyncFunc([this](const std::shared_ptr<VsyncCallback>& callback) {
6481 vsyncStation_->RequestVsync(callback);
6482 });
6483 }
6484
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)6485 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
6486 {
6487 if (sceneSession == nullptr) {
6488 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
6489 return;
6490 }
6491 AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
6492 config.duration_ = rotateAnimationConfig_.duration_;
6493 };
6494 sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
6495 TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d",
6496 sceneSession->GetPersistentId());
6497 }
6498
CloseSyncTransaction(std::function<void ()> func)6499 void SceneSessionManager::CloseSyncTransaction(std::function<void()> func)
6500 {
6501 auto task = [this, param = std::move(func), where = __func__] () {
6502 if (!closeSyncFunc_) {
6503 closeSyncFunc_ = std::move(param);
6504 }
6505 bool isLastFrameLayoutFinished = true;
6506 IsLastFrameLayoutFinished(isLastFrameLayoutFinished);
6507 if (isLastFrameLayoutFinished) {
6508 closeSyncFunc_();
6509 } else {
6510 needCloseSync_ = true;
6511 }
6512 };
6513 taskScheduler_->PostAsyncTask(task, __func__);
6514 }
6515
NotifySessionForCallback(const sptr<SceneSession> & sceneSession,const bool needRemoveSession)6516 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
6517 {
6518 if (sceneSession == nullptr) {
6519 TLOGW(WmsLogTag::DEFAULT, "session is null");
6520 return;
6521 }
6522 if (sceneSession->GetSessionInfo().isSystem_) {
6523 TLOGW(WmsLogTag::DEFAULT, "id: %{public}d is system", sceneSession->GetPersistentId());
6524 return;
6525 }
6526 if (sceneSession->GetSessionInfo().appIndex_ != 0) {
6527 TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, appIndex: %{public}d, id: %{public}d",
6528 sceneSession->GetSessionInfo().appIndex_, sceneSession->GetPersistentId());
6529 listenerController_->NotifySessionLifecycleEvent(
6530 ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
6531 return;
6532 }
6533 if (needRemoveSession) {
6534 TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, needRemoveSession, id: %{public}d", sceneSession->GetPersistentId());
6535 listenerController_->NotifySessionLifecycleEvent(
6536 ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
6537 return;
6538 }
6539 if (sceneSession->GetSessionInfo().abilityInfo == nullptr) {
6540 TLOGW(WmsLogTag::DEFAULT, "abilityInfo is null, id: %{public}d", sceneSession->GetPersistentId());
6541 } else if ((sceneSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
6542 (sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6543 TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
6544 sceneSession->GetPersistentId());
6545 listenerController_->NotifySessionLifecycleEvent(
6546 ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
6547 return;
6548 }
6549 TLOGI(WmsLogTag::DEFAULT, "NotifyClosed, id: %{public}d", sceneSession->GetPersistentId());
6550 listenerController_->NotifySessionClosed(sceneSession->GetSessionInfo());
6551 }
6552
NotifyWindowInfoChangeFromSession(int32_t persistentId)6553 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
6554 {
6555 TLOGD(WmsLogTag::DEFAULT, "persistentId=%{public}d", persistentId);
6556 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6557 if (sceneSession == nullptr) {
6558 TLOGE(WmsLogTag::DEFAULT, "sceneSession nullptr");
6559 return;
6560 }
6561
6562 SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
6563 }
6564
IsSessionVisible(const sptr<SceneSession> & session) const6565 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session) const
6566 {
6567 if (session == nullptr) {
6568 return false;
6569 }
6570 if (Session::IsScbCoreEnabled()) {
6571 return session->IsVisible();
6572 }
6573 const auto& state = session->GetSessionState();
6574 if (WindowHelper::IsSubWindow(session->GetWindowType())) {
6575 const auto& mainOrFloatSession = session->GetMainOrFloatSession();
6576 if (mainOrFloatSession == nullptr) {
6577 TLOGE(WmsLogTag::WMS_SUB, "Can not find parent for this sub window, id: %{public}d",
6578 session->GetPersistentId());
6579 return false;
6580 }
6581 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
6582 const auto mainOrFloatSessionState = mainOrFloatSession->GetSessionState();
6583 if (mainOrFloatSessionState == SessionState::STATE_INACTIVE ||
6584 mainOrFloatSessionState == SessionState::STATE_BACKGROUND) {
6585 TLOGD(WmsLogTag::WMS_SUB, "Parent of this sub window is at background, id: %{public}d",
6586 session->GetPersistentId());
6587 return false;
6588 }
6589 TLOGD(WmsLogTag::WMS_SUB, "Sub window is at foreground, id: %{public}d", session->GetPersistentId());
6590 return true;
6591 }
6592 TLOGD(WmsLogTag::WMS_SUB, "Sub window is at background, id: %{public}d", session->GetPersistentId());
6593 return false;
6594 }
6595
6596 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
6597 TLOGD(WmsLogTag::WMS_LIFE, "Window is at foreground, id: %{public}d", session->GetPersistentId());
6598 return true;
6599 }
6600 TLOGD(WmsLogTag::WMS_LIFE, "Window is at background, id: %{public}d", session->GetPersistentId());
6601 return false;
6602 }
6603
IsSessionVisibleForeground(const sptr<SceneSession> & session) const6604 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session) const
6605 {
6606 if (session == nullptr) {
6607 return false;
6608 }
6609 if (Session::IsScbCoreEnabled()) {
6610 return session->IsVisibleForeground();
6611 }
6612 return IsSessionVisible(session);
6613 }
6614
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)6615 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
6616 {
6617 if (session == nullptr) {
6618 return;
6619 }
6620 int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
6621 WSRect rect = session->GetSessionRect();
6622 std::string sName;
6623 if (session->GetSessionInfo().isSystem_) {
6624 sName = session->GetSessionInfo().abilityName_;
6625 } else {
6626 sName = session->GetWindowName();
6627 }
6628 uint32_t flag = session->GetSessionProperty()->GetWindowFlags();
6629 uint64_t displayId = session->GetSessionProperty()->GetDisplayId();
6630 uint32_t orientation = 0;
6631 const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
6632 sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
6633 // std::setw is used to set the output width and different width values are set to keep the format aligned.
6634 oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
6635 << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
6636 << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
6637 << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
6638 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
6639 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
6640 << std::left << std::setw(VALUE_MAX_WIDTH) << flag
6641 << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
6642 << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
6643 << "[ "
6644 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
6645 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
6646 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
6647 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
6648 << "]"
6649 << " [ "
6650 << std::left << std::setw(OFFSET_MAX_WIDTH) << GetFloatWidth(OFFSET_MAX_WIDTH, session->GetOffsetX())
6651 << std::left << std::setw(OFFSET_MAX_WIDTH) << GetFloatWidth(OFFSET_MAX_WIDTH, session->GetOffsetY())
6652 << "]"
6653 << " [ "
6654 << std::left << std::setw(SCALE_MAX_WIDTH) << GetFloatWidth(SCALE_MAX_WIDTH, session->GetScaleX())
6655 << std::left << std::setw(SCALE_MAX_WIDTH) << GetFloatWidth(SCALE_MAX_WIDTH, session->GetScaleY())
6656 << std::left << std::setw(SCALE_MAX_WIDTH) << GetFloatWidth(SCALE_MAX_WIDTH, session->GetPivotX())
6657 << std::left << std::setw(SCALE_MAX_WIDTH) << GetFloatWidth(SCALE_MAX_WIDTH, session->GetPivotY())
6658 << "]"
6659 << std::endl;
6660 }
6661
GetFloatWidth(const int width,float value)6662 std::string SceneSessionManager::GetFloatWidth(const int width, float value)
6663 {
6664 std::ostringstream oss;
6665 oss << value;
6666 std::string strValue = oss.str();
6667 return (strValue.size() > static_cast<size_t>(width)) ? strValue.substr(0, width) : strValue;
6668 }
6669
DumpFocusInfo(std::ostringstream & oss)6670 void SceneSessionManager::DumpFocusInfo(std::ostringstream& oss)
6671 {
6672 auto defaultFocusedSessionId = windowFocusController_->GetFocusedSessionId(DEFAULT_DISPLAY_ID);
6673 oss << "Focus window: " << defaultFocusedSessionId << std::endl;
6674 std::vector<std::pair<DisplayId, int32_t>> allFocusedSessionList =
6675 windowFocusController_->GetAllFocusedSessionList();
6676 oss << "All Focus window: " << std::endl;
6677 if (allFocusedSessionList.size() > 0) {
6678 for (const auto& focusState : allFocusedSessionList) {
6679 oss << "DisplayId: " << focusState.first << " WindowId: " << focusState.second << std::endl;
6680 }
6681 }
6682 }
6683
GetAllSessionDumpInfo(std::string & dumpInfo)6684 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
6685 {
6686 std::ostringstream oss;
6687 oss << "-------------------------------------ScreenGroup 0"
6688 << "-------------------------------------" << std::endl;
6689 oss << "WindowName DisplayId Pid WinId Type Mode Flag ZOrd Orientation [ x y w h ]"
6690 << " [ OffsetX OffsetY ] [ ScaleX ScaleY PivotX PivotY ]" << std::endl;
6691 std::vector<sptr<SceneSession>> allSession;
6692 std::vector<sptr<SceneSession>> backgroundSession;
6693 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
6694 {
6695 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6696 sceneSessionMapCopy = sceneSessionMap_;
6697 }
6698 for (const auto& elem : sceneSessionMapCopy) {
6699 auto curSession = elem.second;
6700 if (curSession == nullptr) {
6701 TLOGD(WmsLogTag::DEFAULT, "nullptr");
6702 continue;
6703 }
6704 if (!curSession->GetSessionInfo().isSystem_ &&
6705 (curSession->GetSessionState() < SessionState::STATE_FOREGROUND ||
6706 curSession->GetSessionState() > SessionState::STATE_BACKGROUND)) {
6707 TLOGW(WmsLogTag::DEFAULT, "id:%{public}d,invalid state:%{public}u",
6708 curSession->GetPersistentId(), curSession->GetSessionState());
6709 continue;
6710 }
6711 if (IsSessionVisibleForeground(curSession)) {
6712 allSession.push_back(curSession);
6713 } else {
6714 backgroundSession.push_back(curSession);
6715 }
6716 }
6717 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
6718 uint32_t count = 0;
6719 for (const auto& session : allSession) {
6720 if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
6721 oss << "---------------------------------------------------------------------------------------"
6722 << std::endl;
6723 }
6724 DumpSessionInfo(session, oss);
6725 count++;
6726 }
6727 DumpFocusInfo(oss);
6728 oss << "SingleHand: X[" << singleHandTransform_.posX << "] Y[" << singleHandTransform_.posY << "] scale["
6729 << singleHandTransform_.scaleX << "]" << std::endl;
6730 oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
6731 oss << "Highlighted windows: " << GetHighlightIdsStr() << std::endl;
6732 dumpInfo.append(oss.str());
6733 return WSError::WS_OK;
6734 }
6735
GetAllSessionDumpDetailInfo(std::string & dumpInfo)6736 WSError SceneSessionManager::GetAllSessionDumpDetailInfo(std::string& dumpInfo)
6737 {
6738 std::ostringstream oss;
6739 std::vector<sptr<SceneSession>> allSession;
6740 std::vector<sptr<SceneSession>> backgroundSession;
6741
6742 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
6743 {
6744 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6745 sceneSessionMapCopy = sceneSessionMap_;
6746 }
6747 for (const auto& elem : sceneSessionMapCopy) {
6748 auto curSession = elem.second;
6749 if (curSession == nullptr) {
6750 continue;
6751 }
6752 if (IsSessionVisibleForeground(curSession)) {
6753 allSession.push_back(curSession);
6754 } else {
6755 backgroundSession.push_back(curSession);
6756 }
6757 }
6758 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
6759 HidumpController::GetInstance().GetAllSessionDumpDetailedInfo(oss, allSession, backgroundSession);
6760 dumpInfo.append(oss.str());
6761 return WSError::WS_OK;
6762 }
6763
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)6764 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
6765 {
6766 dumpRootSceneFunc_ = func;
6767 }
6768
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)6769 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
6770 const std::vector<std::string>& params, std::string& dumpInfo)
6771 {
6772 std::vector<std::string> resetParams;
6773 resetParams.assign(params.begin() + 2, params.end()); // 2: params num
6774 if (resetParams.empty()) {
6775 TLOGND(WmsLogTag::DEFAULT, "do not dump ui info");
6776 return;
6777 }
6778
6779 if (!session->GetSessionInfo().isSystem_) {
6780 TLOGD(WmsLogTag::DEFAULT, "Dump normal session, not system");
6781 dumpInfoFuture_.ResetLock({});
6782 session->DumpSessionElementInfo(resetParams);
6783 std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
6784 for (auto& info: infos) {
6785 dumpInfo.append(info).append("\n");
6786 }
6787 } else {
6788 TLOGD(WmsLogTag::DEFAULT, "Dump system session");
6789 std::vector<std::string> infos;
6790 dumpRootSceneFunc_(session, resetParams, infos);
6791 for (auto& info: infos) {
6792 dumpInfo.append(info).append("\n");
6793 }
6794 }
6795 }
6796
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)6797 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
6798 const std::string& strId)
6799 {
6800 uint64_t persistentId = std::stoull(strId);
6801 auto session = GetSceneSession(persistentId);
6802 if (session == nullptr) {
6803 return WSError::WS_ERROR_INVALID_PARAM;
6804 }
6805 auto sessionProperty = session->GetSessionProperty();
6806 WSRect rect = session->GetSessionRect();
6807 std::string isVisible = session->IsVisible() ? "true" : "false";
6808 std::string focusable = session->GetFocusable() ? "true" : "false";
6809 std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
6810 bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
6811 std::string isPrivacyMode = privacyMode ? "true" : "false";
6812 bool isFirstFrameAvailable = true;
6813 std::ostringstream oss;
6814 oss << "WindowName: " << session->GetWindowName() << std::endl;
6815 oss << "DisplayId: " << session->GetSessionProperty()->GetDisplayId() << std::endl;
6816 oss << "WinId: " << session->GetPersistentId() << std::endl;
6817 oss << "Pid: " << session->GetCallingPid() << std::endl;
6818 oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
6819 oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
6820 oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
6821 oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
6822 oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
6823 oss << "IsVisible: " << isVisible << std::endl;
6824 oss << "isRSVisible: " << (session->GetRSVisible() ? "true" : "false") << std::endl;
6825 oss << "Focusable: " << focusable << std::endl;
6826 oss << "DecoStatus: " << decoStatus << std::endl;
6827 oss << "isPrivacyMode: " << isPrivacyMode << std::endl;
6828 oss << "WindowRect: " << "[ "
6829 << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
6830 << " ]" << std::endl;
6831 oss << "scaleX: " << session->GetScaleX() << std::endl;
6832 oss << "scaleY: " << session->GetScaleY() << std::endl;
6833 oss << "Offset: " << "[ "
6834 << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
6835 oss << "Scale: " << "[ "
6836 << session->GetScaleX() << ", " << session->GetScaleY() << ", "
6837 << session->GetPivotX() << ", " << session->GetPivotY()
6838 << " ]" << std::endl;
6839 oss << "ParentWindowId: " << session->GetParentPersistentId() << std::endl;
6840 dumpInfo.append(oss.str());
6841
6842 DumpSessionElementInfo(session, params, dumpInfo);
6843 return WSError::WS_OK;
6844 }
6845
GetSCBDebugDumpInfo(std::string && cmd,std::string & dumpInfo)6846 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string&& cmd, std::string& dumpInfo)
6847 {
6848 std::string filePath;
6849 {
6850 auto rootContext = rootSceneContextWeak_.lock();
6851 filePath = rootContext != nullptr ? rootContext->GetFilesDir() + "/wms.dump" : "";
6852 }
6853 // publish data
6854 bool ret = eventHandler_->PostSyncTask(
6855 [this, filePath = std::move(filePath), cmd = std::move(cmd)] {
6856 return scbDumpSubscriber_->Publish(cmd, filePath);
6857 }, "PublishSCBDumper");
6858 if (!ret) {
6859 return WSError::WS_ERROR_INVALID_OPERATION;
6860 }
6861 // get response event
6862 auto task = [this, &dumpInfo] {
6863 dumpInfo.append(scbDumpSubscriber_->GetDebugDumpInfo(WAIT_TIME));
6864 return WSError::WS_OK;
6865 };
6866 eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
6867 return WSError::WS_OK;
6868 }
6869
NotifyDumpInfoResult(const std::vector<std::string> & info)6870 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
6871 {
6872 dumpInfoFuture_.SetValue(info);
6873 TLOGD(WmsLogTag::DEFAULT, "NotifyDumpInfoResult");
6874 }
6875
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)6876 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
6877 {
6878 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
6879 TLOGE(WmsLogTag::DEFAULT, "GetSessionDumpInfo permission denied!");
6880 return WSError::WS_ERROR_INVALID_PERMISSION;
6881 }
6882
6883 if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
6884 return GetAllSessionDumpInfo(dumpInfo);
6885 }
6886 if (params.size() == 1 && params[0] == ARG_DUMP_DETAIL) { // 1: params num
6887 return GetAllSessionDumpDetailInfo(dumpInfo);
6888 }
6889 if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
6890 return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
6891 }
6892 if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2: params num
6893 std::string cmd;
6894 std::for_each(params.begin() + 1, params.end(),
6895 [&cmd](const std::string& value) {
6896 cmd += value;
6897 cmd += ' ';
6898 });
6899 return GetSCBDebugDumpInfo(std::move(cmd), dumpInfo);
6900 }
6901 if (params.size() >= 1 && params[0] == ARG_DUMP_PIPLINE) { // 1: params num
6902 return GetTotalUITreeInfo(dumpInfo);
6903 }
6904 if (params.size() >= 2 && params[0] == ARG_DUMP_RECORD) { // 2: params num
6905 std::vector<std::string> resetParams;
6906 resetParams.assign(params.begin() + 1, params.end());
6907 SessionChangeRecorder::GetInstance().GetSceneSessionNeedDumpInfo(resetParams, dumpInfo);
6908 return WSError::WS_OK;
6909 }
6910 return WSError::WS_ERROR_INVALID_OPERATION;
6911 }
6912
GetTotalUITreeInfo(std::string & dumpInfo)6913 WSError SceneSessionManager::GetTotalUITreeInfo(std::string& dumpInfo)
6914 {
6915 TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
6916 if (dumpUITreeFunc_) {
6917 dumpUITreeFunc_(dumpInfo);
6918 } else {
6919 TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
6920 }
6921 return WSError::WS_OK;
6922 }
6923
SetDumpUITreeFunc(const DumpUITreeFunc & func)6924 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
6925 {
6926 dumpUITreeFunc_ = func;
6927 }
6928
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)6929 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
6930 {
6931 onFlushUIParamsFunc_ = std::move(func);
6932 }
6933
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)6934 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
6935 {
6936 isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
6937 }
6938
SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId,bool visible)6939 void SceneSessionManager::SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId, bool visible)
6940 {
6941 taskScheduler_->PostAsyncTask([this, displayId, visible] {
6942 statusBarDefaultVisibilityPerDisplay_[displayId] = visible;
6943 TLOGNI(WmsLogTag::WMS_IMMS, "set default visibility, "
6944 "display id %{public}" PRIu64 " visible %{public}d", displayId, visible);
6945 }, __func__);
6946 }
6947
GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)6948 bool SceneSessionManager::GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)
6949 {
6950 return statusBarDefaultVisibilityPerDisplay_.count(displayId) != 0 ?
6951 statusBarDefaultVisibilityPerDisplay_[displayId] : true;
6952 }
6953
FocusIDChange(int32_t persistentId,const sptr<SceneSession> & sceneSession)6954 void FocusIDChange(int32_t persistentId, const sptr<SceneSession>& sceneSession)
6955 {
6956 // notify RS
6957 TLOGD(WmsLogTag::WMS_FOCUS, "current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s, "
6958 "abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
6959 sceneSession->GetSessionProperty()->GetWindowName().c_str(),
6960 sceneSession->GetSessionInfo().bundleName_.c_str(),
6961 sceneSession->GetSessionInfo().abilityName_.c_str(),
6962 sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
6963 uint64_t focusNodeId = 0; // 0 means invalid
6964 if (sceneSession->GetSurfaceNode() == nullptr) {
6965 TLOGW(WmsLogTag::WMS_FOCUS, "focused window surfaceNode is null");
6966 } else {
6967 focusNodeId = sceneSession->GetSurfaceNode()->GetId();
6968 }
6969 FocusAppInfo appInfo = {
6970 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
6971 sceneSession->GetSessionInfo().bundleName_,
6972 sceneSession->GetSessionInfo().abilityName_, focusNodeId};
6973 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
6974 }
6975
6976 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)6977 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
6978 {
6979 std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
6980 {
6981 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6982 for (auto& iter : sceneSessionMap_) {
6983 ret.push_back(iter);
6984 }
6985 }
6986 std::sort(ret.begin(), ret.end(), cmp);
6987 return ret;
6988 }
6989
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)6990 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
6991 {
6992 if (isFromTopToBottom) {
6993 TraverseSessionTreeFromTopToBottom(func);
6994 } else {
6995 TraverseSessionTreeFromBottomToTop(func);
6996 }
6997 return;
6998 }
6999
TraverseSessionTreeFromTopToBottom(TraverseFunc func)7000 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
7001 {
7002 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
7003 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
7004 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
7005 return lhsZOrder < rhsZOrder;
7006 };
7007 auto sceneSessionVector = GetSceneSessionVector(cmp);
7008
7009 for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
7010 auto session = iter->second;
7011 if (session == nullptr) {
7012 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7013 continue;
7014 }
7015 if (func(session)) {
7016 return;
7017 }
7018 }
7019 return;
7020 }
7021
TraverseSessionTreeFromBottomToTop(TraverseFunc func)7022 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
7023 {
7024 // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7025 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
7026 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
7027 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
7028 return lhsZOrder < rhsZOrder;
7029 };
7030 auto sceneSessionVector = GetSceneSessionVector(cmp);
7031 // std::map<int32_t, sptr<SceneSession>>::iterator iter;
7032 for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
7033 auto session = iter->second;
7034 if (session == nullptr) {
7035 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7036 continue;
7037 }
7038 if (func(session)) {
7039 return;
7040 }
7041 }
7042 return;
7043 }
7044
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)7045 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
7046 FocusChangeReason reason)
7047 {
7048 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
7049 auto sceneSession = GetSceneSession(persistentId);
7050 if (sceneSession == nullptr) {
7051 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7052 return WMError::WM_ERROR_NULLPTR;
7053 }
7054 int32_t callingPid = IPCSkeleton::GetCallingPid();
7055 if (callingPid != sceneSession->GetCallingPid() &&
7056 !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
7057 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
7058 return WMError::WM_ERROR_INVALID_CALLING;
7059 }
7060 auto task = [this, persistentId, isFocused, byForeground, reason]() {
7061 if (isFocused) {
7062 RequestSessionFocus(persistentId, byForeground, reason);
7063 } else {
7064 RequestSessionUnfocus(persistentId, reason);
7065 }
7066 };
7067 taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
7068 focusChangeReason_ = reason;
7069 return WMError::WM_OK;
7070 }
7071
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)7072 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
7073 FocusChangeReason reason)
7074 {
7075 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
7076 auto task = [this, persistentId, isFocused, byForeground, reason]() {
7077 if (isFocused) {
7078 if (reason == FocusChangeReason::FOREGROUND) {
7079 RequestSessionFocusImmediately(persistentId);
7080 return;
7081 }
7082 if (reason == FocusChangeReason::MOVE_UP) {
7083 auto session = GetSceneSession(persistentId);
7084 if (session && !session->IsFocused()) {
7085 PostProcessFocusState state = { true, true, byForeground, reason };
7086 session->SetPostProcessFocusState(state);
7087 }
7088 return;
7089 }
7090 // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
7091 if (reason == FocusChangeReason::CLICK) {
7092 return;
7093 }
7094 if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
7095 auto session = GetSceneSession(persistentId);
7096 if (session && !session->IsFocused()) {
7097 PostProcessFocusState state = { true, true, byForeground, reason };
7098 session->SetPostProcessFocusState(state);
7099 }
7100 }
7101 } else {
7102 RequestSessionUnfocus(persistentId, reason);
7103 }
7104 };
7105 taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
7106 return WMError::WM_OK;
7107 }
7108
RequestFocusStatusBySA(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)7109 WMError SceneSessionManager::RequestFocusStatusBySA(int32_t persistentId, bool isFocused,
7110 bool byForeground, FocusChangeReason reason)
7111 {
7112 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
7113 if (!SessionPermission::IsSACalling()) {
7114 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, only support SA calling.");
7115 return WMError::WM_ERROR_INVALID_PERMISSION;
7116 }
7117 auto sceneSession = GetSceneSession(persistentId);
7118 if (sceneSession == nullptr) {
7119 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7120 return WMError::WM_ERROR_NULLPTR;
7121 }
7122 auto task = [this, persistentId, isFocused, byForeground, reason]() {
7123 if (isFocused) {
7124 RequestSessionFocus(persistentId, byForeground, reason);
7125 } else {
7126 RequestSessionUnfocus(persistentId, reason);
7127 }
7128 };
7129 taskScheduler_->PostAsyncTask(task, "RequestFocusOnPreviousWindow" + std::to_string(persistentId));
7130 return WMError::WM_OK;
7131 }
7132
RequestAllAppSessionUnfocus()7133 void SceneSessionManager::RequestAllAppSessionUnfocus()
7134 {
7135 auto task = [this]() {
7136 RequestAllAppSessionUnfocusInner();
7137 };
7138 taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
7139 return;
7140 }
7141
7142 /**
7143 * request focus and ignore its state
7144 * only used when app main window start before foreground
7145 */
RequestSessionFocusImmediately(int32_t persistentId,bool blockNotifyUntilVisible)7146 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId, bool blockNotifyUntilVisible)
7147 {
7148 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, blockNotify: %{public}d", persistentId, blockNotifyUntilVisible);
7149 auto sceneSession = GetSceneSession(persistentId);
7150 if (sceneSession == nullptr) {
7151 TLOGE(WmsLogTag::WMS_FOCUS, "[WMSComm]session is nullptr");
7152 return WSError::WS_ERROR_INVALID_SESSION;
7153 }
7154 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7155 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7156 if (focusGroup == nullptr) {
7157 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7158 return WSError::WS_ERROR_NULLPTR;
7159 }
7160 // base block
7161 WSError basicCheckRet = RequestFocusBasicCheck(persistentId, focusGroup);
7162 if (basicCheckRet != WSError::WS_OK) {
7163 return basicCheckRet;
7164 }
7165 if (!sceneSession->CheckFocusable()) {
7166 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
7167 return WSError::WS_DO_NOTHING;
7168 }
7169 if (!sceneSession->IsFocusedOnShow()) {
7170 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
7171 return WSError::WS_DO_NOTHING;
7172 }
7173
7174 // specific block
7175 FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
7176 WSError specificCheckRet = RequestFocusSpecificCheck(displayId, sceneSession, true, reason);
7177 if (specificCheckRet != WSError::WS_OK) {
7178 return specificCheckRet;
7179 }
7180 auto needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7181 focusGroup->SetNeedBlockNotifyUnfocusStatus(needBlockNotifyFocusStatusUntilForeground);
7182 if (!sceneSession->GetSessionInfo().isSystem_ && !blockNotifyUntilVisible && systemConfig_.IsPcWindow()) {
7183 if (!sceneSession->IsSessionForeground()) {
7184 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
7185 }
7186 } else if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
7187 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
7188 }
7189 ShiftFocus(displayId, sceneSession, false, reason);
7190 return WSError::WS_OK;
7191 }
7192
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)7193 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
7194 {
7195 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
7196 persistentId, byForeground, reason);
7197 auto sceneSession = GetSceneSession(persistentId);
7198 if (sceneSession == nullptr) {
7199 TLOGE(WmsLogTag::WMS_FOCUS, "[WMSComm]session is nullptr");
7200 return WSError::WS_ERROR_INVALID_SESSION;
7201 }
7202 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7203 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7204 if (focusGroup == nullptr) {
7205 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7206 return WSError::WS_ERROR_NULLPTR;
7207 }
7208 WSError checkRet = RequestSessionFocusCheck(sceneSession, focusGroup, persistentId, byForeground, reason);
7209 if (checkRet != WSError::WS_OK) {
7210 return checkRet;
7211 }
7212 focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
7213 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7214 ShiftFocus(displayId, sceneSession, false, reason);
7215 return WSError::WS_OK;
7216 }
7217
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)7218 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
7219 {
7220 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
7221 if (persistentId == INVALID_SESSION_ID) {
7222 TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid: %{public}d", persistentId);
7223 return WSError::WS_ERROR_INVALID_SESSION;
7224 }
7225 auto sceneSession = GetSceneSession(persistentId);
7226 if (sceneSession == nullptr) {
7227 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr: %{public}d", persistentId);
7228 return WSError::WS_ERROR_INVALID_SESSION;
7229 }
7230 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7231 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7232 if (focusGroup == nullptr) {
7233 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7234 return WSError::WS_ERROR_NULLPTR;
7235 }
7236 auto focusedSession = GetSceneSession(focusGroup->GetFocusedSessionId());
7237 if (persistentId != focusGroup->GetFocusedSessionId() &&
7238 !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
7239 TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
7240 return WSError::WS_DO_NOTHING;
7241 }
7242 // if pop menu created by desktop request unfocus, back to desktop
7243 auto lastSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
7244 if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
7245 lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
7246 RequestSessionFocus(focusGroup->GetLastFocusedSessionId(), false) == WSError::WS_OK) {
7247 TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
7248 return WSError::WS_OK;
7249 }
7250 auto nextSession = GetNextFocusableSession(displayId, persistentId);
7251 if (nextSession == nullptr) {
7252 DumpAllSessionFocusableInfo(persistentId);
7253 }
7254 focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
7255 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7256
7257 if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
7258 return WSError::WS_OK;
7259 }
7260 if (nextSession && !nextSession->IsSessionForeground() && !nextSession->GetSessionInfo().isSystem_) {
7261 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
7262 }
7263 return ShiftFocus(displayId, nextSession, true, reason);
7264 }
7265
RequestAllAppSessionUnfocusInner()7266 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
7267 {
7268 TLOGI(WmsLogTag::WMS_FOCUS, "in");
7269 auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
7270 if (focusGroup == nullptr) {
7271 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
7272 return WSError::WS_ERROR_NULLPTR;
7273 }
7274 auto focusedSession = GetSceneSession(focusGroup->GetFocusedSessionId());
7275 if (!focusedSession) {
7276 TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
7277 return WSError::WS_DO_NOTHING;
7278 }
7279 if (!focusedSession->IsAppSession()) {
7280 TLOGW(WmsLogTag::WMS_FOCUS, "Focused session is non app: %{public}d", focusGroup->GetFocusedSessionId());
7281 return WSError::WS_DO_NOTHING;
7282 }
7283 auto nextSession = GetTopFocusableNonAppSession();
7284
7285 focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
7286 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7287 return ShiftFocus(DEFAULT_DISPLAY_ID, nextSession, true, FocusChangeReason::WIND);
7288 }
7289
RequestSessionFocusCheck(const sptr<SceneSession> & sceneSession,const sptr<FocusGroup> & focusGroup,int32_t persistentId,bool byForeground,FocusChangeReason reason)7290 WSError SceneSessionManager::RequestSessionFocusCheck(const sptr<SceneSession>& sceneSession,
7291 const sptr<FocusGroup>& focusGroup, int32_t persistentId, bool byForeground, FocusChangeReason reason)
7292 {
7293 if (reason == FocusChangeReason::REQUEST_WITH_CHECK_SUB_WINDOW &&
7294 CheckRequestFocusSubWindowImmediately(sceneSession)) {
7295 TLOGD(WmsLogTag::WMS_FOCUS, "sub window focused");
7296 return WSError::WS_DO_NOTHING;
7297 }
7298 WSError basicCheckRet = RequestFocusBasicCheck(persistentId, focusGroup);
7299 if (basicCheckRet != WSError::WS_OK) {
7300 return basicCheckRet;
7301 }
7302 if (!sceneSession->CheckFocusable() || !IsSessionVisibleForeground(sceneSession)) {
7303 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
7304 return WSError::WS_DO_NOTHING;
7305 }
7306 if (!sceneSession->IsFocusedOnShow()) {
7307 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
7308 return WSError::WS_DO_NOTHING;
7309 }
7310 if (!sceneSession->IsFocusableOnShow() &&
7311 (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
7312 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
7313 return WSError::WS_DO_NOTHING;
7314 }
7315 // subwindow/dialog state block
7316 if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
7317 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
7318 GetSceneSession(sceneSession->GetParentPersistentId()) &&
7319 !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
7320 TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
7321 sceneSession->GetParentPersistentId());
7322 return WSError::WS_DO_NOTHING;
7323 }
7324 // specific block
7325 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession->GetSessionProperty()->GetDisplayId(),
7326 sceneSession, byForeground, reason);
7327 if (specificCheckRet != WSError::WS_OK) {
7328 return specificCheckRet;
7329 }
7330 return WSError::WS_OK;
7331 }
7332
RequestFocusBasicCheck(int32_t persistentId,const sptr<FocusGroup> & focusGroup)7333 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId, const sptr<FocusGroup>& focusGroup)
7334 {
7335 // basic focus rule
7336 if (persistentId == INVALID_SESSION_ID) {
7337 TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
7338 return WSError::WS_ERROR_INVALID_SESSION;
7339 }
7340 if (focusGroup == nullptr) {
7341 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr");
7342 return WSError::WS_ERROR_NULLPTR;
7343 }
7344 if (persistentId == focusGroup->GetFocusedSessionId()) {
7345 TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
7346 return WSError::WS_DO_NOTHING;
7347 }
7348 return WSError::WS_OK;
7349 }
7350
7351 /**
7352 * @note @window.focus
7353 * When high zOrder System Session unfocus, check if the last focused app window can focus.
7354 */
CheckLastFocusedAppSessionFocus(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & nextSession)7355 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(const sptr<SceneSession>& focusedSession,
7356 const sptr<SceneSession>& nextSession)
7357 {
7358 if (focusedSession == nullptr || nextSession == nullptr) {
7359 return false;
7360 }
7361 auto displayId = focusedSession->GetSessionProperty()->GetDisplayId();
7362 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7363 if (focusGroup == nullptr) {
7364 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7365 return false;
7366 }
7367 auto lastFocusedAppSessionId = focusGroup->GetLastFocusedAppSessionId();
7368 TLOGI(WmsLogTag::WMS_FOCUS, "last=%{public}d, next=%{public}d",
7369 lastFocusedAppSessionId, nextSession->GetPersistentId());
7370
7371 if (lastFocusedAppSessionId == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId) {
7372 return false;
7373 }
7374
7375 if (!focusedSession->IsSystemSessionAboveApp()) {
7376 return false;
7377 }
7378
7379 auto mode = nextSession->GetWindowMode();
7380 // only when next session is app, and in split or floation
7381 if (nextSession->IsAppSession() &&
7382 (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
7383 mode == WindowMode::WINDOW_MODE_FLOATING)) {
7384 if (RequestSessionFocus(lastFocusedAppSessionId, false, FocusChangeReason::LAST_FOCUSED_APP) ==
7385 WSError::WS_OK) {
7386 return true;
7387 }
7388 focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
7389 }
7390 return false;
7391 }
7392
7393 /**
7394 * When switching focus, check if the blockingType window has been traversed downwards.
7395 *
7396 * @return true: traversed downwards, false: not.
7397 */
CheckFocusIsDownThroughBlockingType(const sptr<SceneSession> & requestSceneSession,const sptr<SceneSession> & focusedSession,bool includingAppSession)7398 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(const sptr<SceneSession>& requestSceneSession,
7399 const sptr<SceneSession>& focusedSession, bool includingAppSession)
7400 {
7401 uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
7402 uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
7403 auto displayId = requestSceneSession->GetSessionProperty()->GetDisplayId();
7404 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
7405 requestSessionZOrder, focusedSessionZOrder);
7406 if (requestSessionZOrder < focusedSessionZOrder) {
7407 auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(displayId, requestSessionZOrder,
7408 includingAppSession);
7409 uint32_t topNearestBlockingZOrder = 0;
7410 if (topNearestBlockingFocusSession) {
7411 topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
7412 TLOGI(WmsLogTag::WMS_FOCUS,
7413 "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\
7414 topNearestBlockingZOrder: %{public}d, topNearestBlockingId: %{public}d",
7415 requestSessionZOrder, focusedSessionZOrder,
7416 topNearestBlockingZOrder, topNearestBlockingFocusSession->GetPersistentId());
7417 }
7418 if (focusedSessionZOrder >= topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder) {
7419 TLOGD(WmsLogTag::WMS_FOCUS, "focus pass through, needs to be intercepted");
7420 return true;
7421 }
7422 }
7423 TLOGD(WmsLogTag::WMS_FOCUS, "not through");
7424 return false;
7425 }
7426
CheckTopmostWindowFocus(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession)7427 bool SceneSessionManager::CheckTopmostWindowFocus(const sptr<SceneSession>& focusedSession,
7428 const sptr<SceneSession>& sceneSession)
7429 {
7430 bool isFocusedMainSessionTopmost =
7431 focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
7432 auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
7433 bool isFocusedSessionParentTopmost = parentSession &&
7434 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
7435 if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
7436 (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
7437 return true;
7438 }
7439 return false;
7440 }
7441
CheckRequestFocusImmediately(const sptr<SceneSession> & sceneSession)7442 bool SceneSessionManager::CheckRequestFocusImmediately(const sptr<SceneSession>& sceneSession)
7443 {
7444 if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
7445 (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
7446 (ProcessModalTopmostRequestFocusImmediately(sceneSession) == WSError::WS_OK ||
7447 ProcessDialogRequestFocusImmediately(sceneSession) == WSError::WS_OK)) {
7448 TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
7449 return true;
7450 }
7451 return false;
7452 }
7453
CheckRequestFocusSubWindowImmediately(const sptr<SceneSession> & sceneSession)7454 bool SceneSessionManager::CheckRequestFocusSubWindowImmediately(const sptr<SceneSession>& sceneSession)
7455 {
7456 if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
7457 SessionHelper::IsSubWindow(sceneSession->GetWindowType())) &&
7458 (ProcessSubWindowRequestFocusImmediately(sceneSession) == WSError::WS_OK ||
7459 ProcessDialogRequestFocusImmediately(sceneSession) == WSError::WS_OK)) {
7460 TLOGD(WmsLogTag::WMS_FOCUS, "dialog or sub window get focused");
7461 return true;
7462 }
7463 return false;
7464 }
7465
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)7466 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
7467 const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
7468 {
7469 if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
7470 focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
7471 return false;
7472 }
7473 if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
7474 return false;
7475 }
7476 return sceneSession->GetZOrder() < focusedSession->GetZOrder();
7477 }
7478
RequestFocusSpecificCheck(DisplayId displayId,const sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)7479 WSError SceneSessionManager::RequestFocusSpecificCheck(DisplayId displayId, const sptr<SceneSession>& sceneSession,
7480 bool byForeground, FocusChangeReason reason)
7481 {
7482 TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
7483 int32_t persistentId = sceneSession->GetPersistentId();
7484 if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
7485 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
7486 return WSError::WS_ERROR_INVALID_OPERATION;
7487 }
7488 // dialog get focus
7489 if (CheckRequestFocusImmediately(sceneSession)) {
7490 return WSError::WS_DO_NOTHING;
7491 }
7492 // blocking-type session will block lower zOrder request focus
7493 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
7494 auto focusedSession = GetSceneSession(focusedSessionId);
7495 if (focusedSession) {
7496 TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d", reason,
7497 byForeground);
7498 if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
7499 // return ok if focused session is topmost
7500 return WSError::WS_OK;
7501 }
7502 if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
7503 sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
7504 TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
7505 byForeground = false;
7506 }
7507 if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, true)) {
7508 TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
7509 return WSError::WS_DO_NOTHING;
7510 }
7511 if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
7512 !byForeground) {
7513 if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
7514 && focusedSession->IsAppSession()) {
7515 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
7516 return WSError::WS_OK;
7517 }
7518 }
7519 bool isBlockingType = focusedSession->IsAppSession() ||
7520 (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
7521 // temp check
7522 if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
7523 sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
7524 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
7525 persistentId);
7526 return WSError::WS_DO_NOTHING;
7527 }
7528 // desktop click temp check
7529 if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
7530 TLOGD(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
7531 return WSError::WS_DO_NOTHING;
7532 }
7533 }
7534 return WSError::WS_OK;
7535 }
7536
IsParentSessionVisible(const sptr<SceneSession> & session)7537 bool SceneSessionManager::IsParentSessionVisible(const sptr<SceneSession>& session)
7538 {
7539 if (WindowHelper::IsSubWindow(session->GetWindowType()) ||
7540 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
7541 auto parentSession = GetSceneSession(session->GetParentPersistentId());
7542 return parentSession == nullptr || IsSessionVisibleForeground(parentSession);
7543 }
7544 return true;
7545 }
7546
DumpAllSessionFocusableInfo(int32_t persistentId)7547 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
7548 {
7549 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
7550 auto func = [this](const sptr<SceneSession>& session) {
7551 if (session == nullptr) {
7552 return false;
7553 }
7554 bool parentVisible = IsParentSessionVisible(session);
7555 bool sessionVisible = IsSessionVisible(session);
7556 TLOGNI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
7557 "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
7558 session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
7559 session->GetFocusable(), sessionVisible, parentVisible);
7560 return false;
7561 };
7562 TraverseSessionTree(func, true);
7563 }
7564
GetNextFocusableSession(DisplayId displayId,int32_t persistentId)7565 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(DisplayId displayId, int32_t persistentId)
7566 {
7567 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
7568 bool previousFocusedSessionFound = false;
7569 DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
7570 sptr<SceneSession> nextFocusableSession = nullptr;
7571 auto func = [this, persistentId, &previousFocusedSessionFound, &nextFocusableSession, displayGroupId](sptr<SceneSession> session) {
7572 if (session == nullptr) {
7573 return false;
7574 }
7575 if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
7576 displayGroupId) {
7577 return false;
7578 }
7579 if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
7580 TLOGND(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
7581 return false;
7582 }
7583 if (previousFocusedSessionFound && session->CheckFocusable() &&
7584 session->IsVisibleNotBackground() && IsParentSessionVisible(session)) {
7585 nextFocusableSession = session;
7586 return true;
7587 }
7588 if (session->GetPersistentId() == persistentId) {
7589 previousFocusedSessionFound = true;
7590 }
7591 return false;
7592 };
7593 TraverseSessionTree(func, true);
7594 sptr<SceneSession> topFloatingSession = GetNextFocusableSessionWhenFloatWindowExist(displayGroupId, persistentId);
7595 if (topFloatingSession != nullptr && nextFocusableSession != nullptr && nextFocusableSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
7596 TLOGI(WmsLogTag::WMS_FOCUS, "topFloatingSessionId: %{public}d", topFloatingSession->GetPersistentId());
7597 return topFloatingSession;
7598 }
7599 return nextFocusableSession;
7600 }
7601
GetNextFocusableSessionWhenFloatWindowExist(DisplayId displayGroupId,int32_t persistentId)7602 sptr<SceneSession> SceneSessionManager::GetNextFocusableSessionWhenFloatWindowExist(DisplayId displayGroupId,
7603 int32_t persistentId)
7604 {
7605 bool isPhoneOrPadWithoutPcMode =
7606 (systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) && !systemConfig_.IsFreeMultiWindowMode();
7607 if (!isPhoneOrPadWithoutPcMode) {
7608 return nullptr;
7609 }
7610 auto topFloatingSession = GetTopFloatingSession(displayGroupId, persistentId);
7611 auto sceneSession = GetSceneSession(persistentId);
7612 if (topFloatingSession != nullptr && SessionHelper::IsMainWindow(sceneSession->GetWindowType()) &&
7613 sceneSession->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) {
7614 return topFloatingSession;
7615 }
7616 return nullptr;
7617 }
7618
GetTopFloatingSession(DisplayId displayGroupId,int32_t persistentId)7619 sptr<SceneSession> SceneSessionManager::GetTopFloatingSession(DisplayId displayGroupId, int32_t persistentId)
7620 {
7621 bool previousFocusedSessionFound = false;
7622 sptr<SceneSession> topFloatingSession = nullptr;
7623 auto func = [this, persistentId, &previousFocusedSessionFound, &topFloatingSession, displayGroupId](sptr<SceneSession> session) {
7624 if (session == nullptr || topFloatingSession != nullptr || previousFocusedSessionFound) {
7625 return false;
7626 }
7627 if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
7628 displayGroupId) {
7629 return false;
7630 }
7631 if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
7632 TLOGND(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
7633 return false;
7634 }
7635 // need to be floating window
7636 if (session->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
7637 return false;
7638 }
7639 // need to be main window
7640 if (!SessionHelper::IsMainWindow(session->GetWindowType())) {
7641 return false;
7642 }
7643
7644 if (session->CheckFocusable() && session->IsVisible()) {
7645 topFloatingSession = session;
7646 return true;
7647 }
7648 if (session->GetPersistentId() == persistentId) {
7649 previousFocusedSessionFound = true;
7650 }
7651 return false;
7652 };
7653 TraverseSessionTree(func, true);
7654 return topFloatingSession;
7655 }
7656
7657 /**
7658 * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
7659 * and it is the closest;
7660 */
GetTopNearestBlockingFocusSession(DisplayId displayId,uint32_t zOrder,bool includingAppSession)7661 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(DisplayId displayId, uint32_t zOrder,
7662 bool includingAppSession)
7663 {
7664 sptr<SceneSession> ret = nullptr;
7665 DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
7666 auto func = [this, &ret, zOrder, includingAppSession, displayGroupId](sptr<SceneSession> session) {
7667 if (session == nullptr) {
7668 return false;
7669 }
7670 if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
7671 displayGroupId) {
7672 return false;
7673 }
7674 uint32_t sessionZOrder = session->GetZOrder();
7675 if (sessionZOrder <= zOrder) { // must be above the target session
7676 return false;
7677 }
7678 if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7679 TLOGND(WmsLogTag::WMS_FOCUS, "topmost window do not block");
7680 return false;
7681 }
7682 auto parentSession = GetSceneSession(session->GetParentPersistentId());
7683 if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
7684 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost()) {
7685 TLOGND(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
7686 return false;
7687 }
7688
7689 if (IsSessionVisibleForeground(session) && CheckBlockingFocus(session, includingAppSession)) {
7690 ret = session;
7691 return true;
7692 }
7693 return false;
7694 };
7695 TraverseSessionTree(func, false);
7696 return ret;
7697 }
7698
CheckBlockingFocus(const sptr<SceneSession> & session,bool includingAppSession)7699 bool SceneSessionManager::CheckBlockingFocus(const sptr<SceneSession>& session, bool includingAppSession)
7700 {
7701 if (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) {
7702 TLOGD(WmsLogTag::WMS_FOCUS, "system window blocked");
7703 return true;
7704 }
7705
7706 bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
7707 if (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION) {
7708 return true;
7709 }
7710 if (includingAppSession && session->IsAppSession()) {
7711 TLOGD(WmsLogTag::WMS_FOCUS,
7712 "id: %{public}d, isFloatType: %{public}d, isFloatMode: %{public}d", session->GetPersistentId(),
7713 session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT,
7714 session->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING);
7715 bool isPcOrPcMode =
7716 systemConfig_.IsPcWindow() || (isPhoneOrPad && systemConfig_.IsFreeMultiWindowMode());
7717 if (isPcOrPcMode && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
7718 return false;
7719 }
7720 bool isPhoneOrPadWithoutPcMode = isPhoneOrPad && !systemConfig_.IsFreeMultiWindowMode();
7721 if (isPhoneOrPadWithoutPcMode && session->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
7722 SessionHelper::IsMainWindow(session->GetWindowType()) && !session->GetIsMidScene()) {
7723 return false;
7724 }
7725 return true;
7726 }
7727 return false;
7728 }
7729
GetTopFocusableNonAppSession()7730 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
7731 {
7732 TLOGD(WmsLogTag::WMS_FOCUS, "in.");
7733 sptr<SceneSession> ret = nullptr;
7734 auto func = [this, &ret](sptr<SceneSession> session) {
7735 if (session == nullptr) {
7736 return false;
7737 }
7738 if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
7739 DEFAULT_DISPLAY_ID) {
7740 return false;
7741 }
7742 if (session->IsAppSession()) {
7743 return session->GetZOrder() == 0 ? false : true;
7744 }
7745 if (session->CheckFocusable() && IsSessionVisibleForeground(session)) {
7746 ret = session;
7747 }
7748 return false;
7749 };
7750 TraverseSessionTree(func, false);
7751 return ret;
7752 }
7753
SetShiftFocusListener(const ProcessShiftFocusFunc & func)7754 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
7755 {
7756 TLOGD(WmsLogTag::WMS_FOCUS, "in");
7757 shiftFocusFunc_ = func;
7758 }
7759
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)7760 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
7761 {
7762 TLOGD(WmsLogTag::WMS_FOCUS, "in");
7763 notifySCBAfterFocusedFunc_ = func;
7764 }
7765
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)7766 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
7767 {
7768 TLOGD(WmsLogTag::WMS_FOCUS, "in");
7769 notifySCBAfterUnfocusedFunc_ = func;
7770 }
7771
SetSCBFocusChangeListener(const NotifyDiffSCBAfterUpdateFocusFunc && func)7772 void SceneSessionManager::SetSCBFocusChangeListener(const NotifyDiffSCBAfterUpdateFocusFunc&& func)
7773 {
7774 TLOGD(WmsLogTag::WMS_FOCUS, "in");
7775 notifyDiffSCBAfterUnfocusedFunc_ = std::move(func);
7776 }
7777
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)7778 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
7779 {
7780 TLOGD(WmsLogTag::DEFAULT, "in");
7781 callingSessionIdChangeFunc_ = func;
7782 }
7783
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)7784 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
7785 {
7786 TLOGD(WmsLogTag::DEFAULT, "in");
7787 startUIAbilityErrorFunc_ = func;
7788 }
7789
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)7790 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
7791 const AbilityManagerCollaboratorRegisteredFunc& func)
7792 {
7793 auto task = [this, func] {
7794 abilityManagerCollaboratorRegisteredFunc_ = func;
7795 };
7796 taskScheduler_->PostAsyncTask(task, __func__);
7797 }
7798
ShiftFocus(DisplayId displayId,const sptr<SceneSession> & nextSession,bool isProactiveUnfocus,FocusChangeReason reason)7799 WSError SceneSessionManager::ShiftFocus(DisplayId displayId, const sptr<SceneSession>& nextSession,
7800 bool isProactiveUnfocus, FocusChangeReason reason)
7801 {
7802 // unfocus
7803 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
7804 int32_t focusedId = focusedSessionId;
7805 auto focusedSession = GetSceneSession(focusedSessionId);
7806 UpdateFocusStatus(displayId, focusedSession, false);
7807 // focus
7808 int32_t nextId = INVALID_SESSION_ID;
7809 if (nextSession == nullptr) {
7810 std::string sessionLog(GetAllSessionFocusInfo());
7811 TLOGW(WmsLogTag::WMS_FOCUS, "next session nullptr! id: %{public}d, info: %{public}s",
7812 focusedSessionId, sessionLog.c_str());
7813 } else {
7814 nextId = nextSession->GetPersistentId();
7815 }
7816 UpdateFocusStatus(displayId, nextSession, true);
7817 UpdateHighlightStatus(displayId, focusedSession, nextSession, isProactiveUnfocus);
7818 if (shiftFocusFunc_ != nullptr) {
7819 auto displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
7820 shiftFocusFunc_(nextId, displayGroupId);
7821 }
7822 bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
7823 bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
7824 if (!scbPrevFocus && scbCurrFocus) {
7825 if (notifySCBAfterFocusedFunc_ != nullptr) {
7826 notifySCBAfterFocusedFunc_(nextSession->GetSessionProperty()->GetDisplayId());
7827 }
7828 } else if (scbPrevFocus && !scbCurrFocus) {
7829 if (notifySCBAfterUnfocusedFunc_ != nullptr) {
7830 notifySCBAfterUnfocusedFunc_(focusedSession->GetSessionProperty()->GetDisplayId());
7831 }
7832 } else if (scbPrevFocus && scbCurrFocus) {
7833 DisplayId focusedSessionDisplayId = focusedSession->GetSessionProperty()->GetDisplayId();
7834 DisplayId nextSessionDisplayId = nextSession->GetSessionProperty()->GetDisplayId();
7835 if (notifyDiffSCBAfterUnfocusedFunc_ != nullptr && focusedSessionDisplayId != nextSessionDisplayId) {
7836 notifyDiffSCBAfterUnfocusedFunc_(focusedSessionDisplayId, nextSessionDisplayId);
7837 }
7838 }
7839 TLOGI(WmsLogTag::WMS_FOCUS, "[%{public}" PRIu64 ",%{public}d,%{public}d,%{public}d",
7840 displayId, focusedId, nextId, reason);
7841 return WSError::WS_OK;
7842 }
7843
UpdateFocusStatus(DisplayId displayId,const sptr<SceneSession> & sceneSession,bool isFocused)7844 void SceneSessionManager::UpdateFocusStatus(DisplayId displayId, const sptr<SceneSession>& sceneSession,
7845 bool isFocused)
7846 {
7847 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7848 if (focusGroup == nullptr) {
7849 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7850 return;
7851 }
7852 bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7853 bool needBlockNotifyUnfocusStatus = focusGroup->GetNeedBlockNotifyUnfocusStatus();
7854 if (sceneSession == nullptr) {
7855 TLOGW(WmsLogTag::WMS_FOCUS, "session is nullptr");
7856 if (isFocused) {
7857 SetFocusedSessionId(INVALID_SESSION_ID, displayId);
7858 focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
7859 auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
7860 NotifyUnFocusedByMission(prevSession);
7861 }
7862 return;
7863 }
7864 TLOGD(WmsLogTag::WMS_FOCUS, "name: %{public}s, id: %{public}d, isFocused: %{public}d, displayId: %{public}" PRIu64,
7865 sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused, displayId);
7866 // set focused
7867 if (isFocused) {
7868 SetFocusedSessionId(sceneSession->GetPersistentId(), displayId);
7869 if (sceneSession->IsAppOrLowerSystemSession()) {
7870 focusGroup->SetLastFocusedAppSessionId(sceneSession->GetPersistentId());
7871 }
7872 }
7873 sceneSession->UpdateFocus(isFocused);
7874 // notify listenerController unfocused
7875 auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
7876 if (isFocused && MissionChanged(prevSession, sceneSession)) {
7877 NotifyUnFocusedByMission(prevSession);
7878 }
7879 if ((isFocused && !needBlockNotifyFocusStatusUntilForeground) || (!isFocused && !needBlockNotifyUnfocusStatus)) {
7880 NotifyFocusStatus(sceneSession, isFocused, focusGroup);
7881 }
7882 }
7883
7884 /** @note @window.focus */
UpdateHighlightStatus(DisplayId displayId,const sptr<SceneSession> & preSceneSession,const sptr<SceneSession> & currSceneSession,bool isProactiveUnfocus)7885 void SceneSessionManager::UpdateHighlightStatus(DisplayId displayId, const sptr<SceneSession>& preSceneSession,
7886 const sptr<SceneSession>& currSceneSession, bool isProactiveUnfocus)
7887 {
7888 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7889 if (focusGroup == nullptr) {
7890 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7891 return;
7892 }
7893 bool needBlockHighlightNotify = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7894 if(isProactiveUnfocus){
7895 TLOGD(WmsLogTag::WMS_FOCUS, "proactiveUnfocus");
7896 RemoveHighlightSessionIds(preSceneSession);
7897 }
7898 if (currSceneSession == nullptr) {
7899 TLOGE(WmsLogTag::WMS_FOCUS, "currSceneSession is nullptr");
7900 return;
7901 }
7902 if(currSceneSession->GetSessionProperty()->GetExclusivelyHighlighted()) {
7903 TLOGD(WmsLogTag::WMS_FOCUS, "exclusively highlighted");
7904 SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
7905 return;
7906 }
7907 if(SessionHelper::IsSystemWindow(currSceneSession->GetWindowType())) {
7908 TLOGD(WmsLogTag::WMS_FOCUS, "system highlighted");
7909 AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
7910 return;
7911 }
7912 if(currSceneSession->IsSameMainSession(preSceneSession)) {
7913 TLOGD(WmsLogTag::WMS_FOCUS, "related highlighted");
7914 AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
7915 return;
7916 }
7917 TLOGD(WmsLogTag::WMS_FOCUS, "highlighted");
7918 SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
7919 }
7920
7921 /** @note @window.focus */
SetHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)7922 void SceneSessionManager::SetHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
7923 {
7924 if (sceneSession == nullptr) {
7925 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7926 return;
7927 }
7928 {
7929 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
7930 for (auto persistentId : highlightIds_) {
7931 auto session = GetSceneSession(persistentId);
7932 if (session == nullptr) {
7933 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr");
7934 continue;
7935 }
7936 if (sceneSession->GetPersistentId() != persistentId) {
7937 session->UpdateHighlightStatus(false, false);
7938 }
7939 }
7940 sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
7941 highlightIds_.clear();
7942 highlightIds_.insert(sceneSession->GetPersistentId());
7943 }
7944 TLOGI(WmsLogTag::WMS_FOCUS, "%{public}s", GetHighlightIdsStr().c_str());
7945 }
7946
7947 /** @note @window.focus */
AddHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)7948 void SceneSessionManager::AddHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
7949 {
7950 if (sceneSession == nullptr) {
7951 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7952 return;
7953 }
7954 sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
7955 {
7956 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
7957 highlightIds_.insert(sceneSession->GetPersistentId());
7958 }
7959 TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
7960 }
7961
7962 /** @note @window.focus */
RemoveHighlightSessionIds(const sptr<SceneSession> & sceneSession)7963 void SceneSessionManager::RemoveHighlightSessionIds(const sptr<SceneSession>& sceneSession)
7964 {
7965 if (sceneSession == nullptr) {
7966 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7967 return;
7968 }
7969 {
7970 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
7971 if (highlightIds_.find(sceneSession->GetPersistentId()) != highlightIds_.end()) {
7972 sceneSession->UpdateHighlightStatus(false, false);
7973 highlightIds_.erase(sceneSession->GetPersistentId());
7974 } else {
7975 TLOGE(WmsLogTag::WMS_FOCUS, "not found scene session with id: %{public}d", sceneSession->GetPersistentId());
7976 }
7977
7978 }
7979 TLOGI(WmsLogTag::WMS_FOCUS, "%{public}s", GetHighlightIdsStr().c_str());
7980 }
7981
7982 /** @note @window.focus */
GetHighlightIdsStr()7983 std::string SceneSessionManager::GetHighlightIdsStr()
7984 {
7985 std::ostringstream oss;
7986 {
7987 std::lock_guard<std::mutex> lock(highlightIdsMutex_);
7988 for (auto it = highlightIds_.begin(); it != highlightIds_.end(); it++) {
7989 oss << *it;
7990 if(std::next(it) != highlightIds_.end()) {
7991 oss << ", ";
7992 }
7993 }
7994
7995 }
7996 return oss.str();
7997 }
7998
NotifyFocusStatus(const sptr<SceneSession> & sceneSession,bool isFocused,const sptr<FocusGroup> & focusGroup)7999 void SceneSessionManager::NotifyFocusStatus(const sptr<SceneSession>& sceneSession, bool isFocused,
8000 const sptr<FocusGroup>& focusGroup)
8001 {
8002 if (focusGroup == nullptr) {
8003 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr");
8004 return;
8005 }
8006 int32_t persistentId = sceneSession->GetPersistentId();
8007
8008 TLOGI(WmsLogTag::WMS_FOCUS,
8009 "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
8010 sceneSession->GetSessionInfo().bundleName_.c_str(),
8011 sceneSession->GetSessionInfo().abilityName_.c_str(),
8012 sceneSession->GetWindowNameAllType().c_str(),
8013 persistentId, isFocused);
8014 if (isFocused) {
8015 if (IsSessionVisibleForeground(sceneSession)) {
8016 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
8017 }
8018 UpdateBrightness(focusGroup->GetFocusedSessionId());
8019 FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
8020 }
8021 DisplayId focusGroupId = focusGroup->GetDisplayGroupId() == DEFAULT_DISPLAY_ID ? DEFAULT_DISPLAY_ID : sceneSession->GetDisplayId();
8022 // notify window manager
8023 sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
8024 sceneSession->GetWindowId(),
8025 focusGroupId,
8026 sceneSession->GetCallingPid(),
8027 sceneSession->GetCallingUid(),
8028 sceneSession->GetWindowType(),
8029 sceneSession->GetAbilityToken()
8030 );
8031 SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
8032 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
8033 sceneSession->NotifyFocusStatus(isFocused);
8034 // notify listenerController focused
8035 auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
8036 if (isFocused && MissionChanged(prevSession, sceneSession)) {
8037 NotifyFocusedByMission(sceneSession);
8038 }
8039 }
8040
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)8041 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
8042 const std::string& reason)
8043 {
8044 uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
8045 nlohmann::json payload;
8046 payload.emplace("uid", uid);
8047 payload.emplace("bundleName", bundleName);
8048 payload.emplace("reason", reason);
8049 nlohmann::json reply;
8050 return ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
8051 }
8052
NotifyFocusStatusByMission(const sptr<SceneSession> & prevSession,const sptr<SceneSession> & currSession)8053 void SceneSessionManager::NotifyFocusStatusByMission(const sptr<SceneSession>& prevSession,
8054 const sptr<SceneSession>& currSession)
8055 {
8056 if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
8057 TLOGD(WmsLogTag::WMS_FOCUS, "Unfocused, id: %{public}d", prevSession->GetMissionId());
8058 listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
8059 }
8060 if (currSession && !currSession->GetSessionInfo().isSystem_) {
8061 TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", currSession->GetMissionId());
8062 listenerController_->NotifySessionFocused(currSession->GetMissionId());
8063 }
8064 }
8065
NotifyUnFocusedByMission(const sptr<SceneSession> & sceneSession)8066 void SceneSessionManager::NotifyUnFocusedByMission(const sptr<SceneSession>& sceneSession)
8067 {
8068 if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
8069 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", sceneSession->GetMissionId());
8070 listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
8071 }
8072 }
8073
NotifyFocusedByMission(const sptr<SceneSession> & sceneSession)8074 void SceneSessionManager::NotifyFocusedByMission(const sptr<SceneSession>& sceneSession)
8075 {
8076 if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
8077 TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", sceneSession->GetMissionId());
8078 listenerController_->NotifySessionFocused(sceneSession->GetMissionId());
8079 }
8080 }
8081
MissionChanged(const sptr<SceneSession> & prevSession,const sptr<SceneSession> & currSession)8082 bool SceneSessionManager::MissionChanged(const sptr<SceneSession>& prevSession, const sptr<SceneSession>& currSession)
8083 {
8084 if (prevSession == nullptr && currSession == nullptr) {
8085 return false;
8086 }
8087 if (prevSession == nullptr || currSession == nullptr) {
8088 return true;
8089 }
8090 return prevSession->GetMissionId() != currSession->GetMissionId();
8091 }
8092
GetAllSessionFocusInfo()8093 std::string SceneSessionManager::GetAllSessionFocusInfo()
8094 {
8095 std::ostringstream os;
8096 auto func = [&os](sptr<SceneSession> session) {
8097 if (session == nullptr) {
8098 TLOGNE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
8099 return false;
8100 }
8101 os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
8102 ", focusable: " << session->GetFocusable() << ";";
8103 return false;
8104 };
8105 TraverseSessionTree(func, true);
8106 return os.str();
8107 }
8108
UpdateFocus(int32_t persistentId,bool isFocused)8109 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
8110 {
8111 auto task = [this, persistentId, isFocused]() {
8112 // notify session and client
8113 auto sceneSession = GetSceneSession(persistentId);
8114 if (sceneSession == nullptr) {
8115 TLOGNE(WmsLogTag::WMS_FOCUS, "UpdateFocus could not find window, persistentId:%{public}d", persistentId);
8116 return WSError::WS_ERROR_INVALID_WINDOW;
8117 }
8118 TLOGNI(WmsLogTag::WMS_FOCUS, "UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
8119 sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
8120 // focusId change
8121 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8122 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8123 if (isFocused) {
8124 SetFocusedSessionId(displayId, persistentId);
8125 UpdateBrightness(focusedSessionId);
8126 FocusIDChange(persistentId, sceneSession);
8127 } else if (persistentId == GetFocusedSessionId()) {
8128 SetFocusedSessionId(displayId, INVALID_SESSION_ID);
8129 }
8130 // notify window manager
8131 sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
8132 sceneSession->GetWindowId(),
8133 static_cast<DisplayId>(0),
8134 sceneSession->GetCallingPid(),
8135 sceneSession->GetCallingUid(),
8136 sceneSession->GetWindowType(),
8137 sceneSession->GetAbilityToken()
8138 );
8139 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
8140 WSError res = WSError::WS_OK;
8141 res = sceneSession->UpdateFocus(isFocused);
8142 if (res != WSError::WS_OK) {
8143 return res;
8144 }
8145 TLOGNI(WmsLogTag::WMS_FOCUS, "UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
8146 sceneSession->GetSessionInfo().isSystem_);
8147 if (!sceneSession->GetSessionInfo().isSystem_) {
8148 if (isFocused) {
8149 TLOGND(WmsLogTag::WMS_FOCUS, "NotifyFocused, id: %{public}d", sceneSession->GetPersistentId());
8150 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
8151 } else {
8152 TLOGND(WmsLogTag::WMS_FOCUS, "NotifyUnFocused, id: %{public}d", sceneSession->GetPersistentId());
8153 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
8154 }
8155 }
8156 return WSError::WS_OK;
8157 };
8158
8159 taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
8160 return WSError::WS_OK;
8161 }
8162
UpdateWindowMode(int32_t persistentId,int32_t windowMode)8163 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
8164 {
8165 TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, mode: %{public}d", persistentId, windowMode);
8166 auto sceneSession = GetSceneSession(persistentId);
8167 if (sceneSession == nullptr) {
8168 TLOGE(WmsLogTag::DEFAULT, "could not find window, Id:%{public}d", persistentId);
8169 return WSError::WS_ERROR_INVALID_WINDOW;
8170 }
8171 WindowMode mode = static_cast<WindowMode>(windowMode);
8172 return sceneSession->UpdateWindowMode(mode);
8173 }
8174
GetNormalSingleHandTransform() const8175 SingleHandTransform SceneSessionManager::GetNormalSingleHandTransform() const
8176 {
8177 return singleHandTransform_;
8178 }
8179
GetSingleHandScreenInfo() const8180 SingleHandScreenInfo SceneSessionManager::GetSingleHandScreenInfo() const
8181 {
8182 return singleHandScreenInfo_;
8183 }
8184
GetOriginRect() const8185 WSRect SceneSessionManager::GetOriginRect() const
8186 {
8187 return originRect_;
8188 }
8189
GetSingleHandRect() const8190 WSRect SceneSessionManager::GetSingleHandRect() const
8191 {
8192 return singleHandRect_;
8193 }
8194
NotifySingleHandInfoChange(SingleHandScreenInfo singleHandScreenInfo,WSRect originRect,WSRect singleHandRect)8195 void SceneSessionManager::NotifySingleHandInfoChange(SingleHandScreenInfo singleHandScreenInfo, WSRect originRect, WSRect singleHandRect)
8196 {
8197 const char* const funcName = __func__;
8198 taskScheduler_->PostAsyncTask([this, singleHandScreenInfo, originRect, singleHandRect, funcName] {
8199 if (!systemConfig_.IsPhoneWindow()) {
8200 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: only support phone", funcName);
8201 return;
8202 }
8203 int32_t displayWidth = 0;
8204 int32_t displayHeight = 0;
8205 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
8206 if (!GetDisplaySizeById(defaultScreenId, displayWidth, displayHeight)) {
8207 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: get display size failed", funcName);
8208 return;
8209 }
8210 singleHandScreenInfo_ = singleHandScreenInfo;
8211 originRect_ = originRect;
8212 singleHandRect_ = singleHandRect;
8213 singleHandTransform_.posX = singleHandRect.posX_;
8214 singleHandTransform_.posY = singleHandRect.posY_;
8215 singleHandTransform_.scaleX = static_cast<float>(singleHandScreenInfo_.scaleRatio) / 100;
8216 singleHandTransform_.scaleY = singleHandTransform_.scaleX;
8217 {
8218 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8219 for (const auto& [_, sceneSession] : sceneSessionMap_) {
8220 if (sceneSession == nullptr || !IsInDefaultScreen(sceneSession) ||
8221 sceneSession->GetWindowName().find("OneHandModeBackground", 0) != std::string::npos) {
8222 continue;
8223 }
8224 sceneSession->SetSingleHandModeFlag(true);
8225 sceneSession->SetSingleHandTransform(singleHandTransform_);
8226 sceneSession->NotifySingleHandTransformChange(singleHandTransform_);
8227 }
8228 }
8229 FlushWindowInfoToMMI();
8230 }, funcName);
8231 }
8232
RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc && func)8233 void SceneSessionManager::RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc&& func)
8234 {
8235 getRSNodeByStringIDFunc_ = std::move(func);
8236 }
8237
RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc && func)8238 void SceneSessionManager::RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc&& func)
8239 {
8240 setTopWindowBoundaryByIDFunc_ = std::move(func);
8241 }
8242
RegisterSingleHandContainerNode(const std::string & stringId)8243 void SceneSessionManager::RegisterSingleHandContainerNode(const std::string& stringId)
8244 {
8245 if (getRSNodeByStringIDFunc_ == nullptr) {
8246 TLOGE(WmsLogTag::WMS_LAYOUT, "func is nullptr");
8247 return;
8248 }
8249 auto rsNode = getRSNodeByStringIDFunc_(stringId);
8250 if (rsNode == nullptr) {
8251 TLOGE(WmsLogTag::WMS_LAYOUT, "node is nullptr");
8252 return;
8253 }
8254 TLOGI(WmsLogTag::WMS_LAYOUT, "get OneHandModeBox node, id: %{public}" PRIu64, rsNode->GetId());
8255 setTopWindowBoundaryByIDFunc_(stringId);
8256 rsInterface_.SetWindowContainer(rsNode->GetId(), true);
8257 }
8258
GetSingleHandCompatibleModeConfig() const8259 const SingleHandCompatibleModeConfig& SceneSessionManager::GetSingleHandCompatibleModeConfig() const
8260 {
8261 return singleHandCompatibleModeConfig_;
8262 }
8263
8264 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)8265 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
8266 MMI::PointerEvent::PointerItem& pointerItem)
8267 {
8268 struct PointerEventData {
8269 double x;
8270 double y;
8271 uint64_t time;
8272 } pointerEventData = {
8273 .x = pointerItem.GetDisplayX(),
8274 .y = pointerItem.GetDisplayY(),
8275 .time = pointerEvent->GetActionTime()
8276 };
8277
8278 const uint32_t MAX_HMAC_SIZE = 64;
8279 uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
8280 uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
8281 uint32_t enhanceDataLen = MAX_HMAC_SIZE;
8282 if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
8283 sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
8284 pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
8285 }
8286 }
8287 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
8288
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)8289 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
8290 {
8291 if (!pointerEvent) {
8292 TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null");
8293 return WSError::WS_ERROR_NULLPTR;
8294 }
8295 MMI::PointerEvent::PointerItem pointerItem;
8296 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
8297 TLOGE(WmsLogTag::WMS_EVENT, "Failed to get pointerItem");
8298 return WSError::WS_ERROR_INVALID_PARAM;
8299 }
8300 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
8301 FillSecCompEnhanceData(pointerEvent, pointerItem);
8302 #endif
8303 TLOGI(WmsLogTag::WMS_EVENT, "eid=%{public}d,ac=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
8304 pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
8305 pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
8306 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
8307 return WSError::WS_OK;
8308 }
8309
SetScreenLocked(const bool isScreenLocked)8310 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
8311 {
8312 taskScheduler_->PostTask([this, isScreenLocked] {
8313 isScreenLocked_ = isScreenLocked;
8314 DeleteStateDetectTask();
8315 NotifyPiPWindowVisibleChange(isScreenLocked);
8316 }, __func__);
8317 }
8318
SetUserAuthPassed(bool isUserAuthPassed)8319 void SceneSessionManager::SetUserAuthPassed(bool isUserAuthPassed)
8320 {
8321 taskScheduler_->PostTask([this, isUserAuthPassed] {
8322 isUserAuthPassed_ = isUserAuthPassed;
8323 }, __func__);
8324 }
8325
DeleteStateDetectTask()8326 void SceneSessionManager::DeleteStateDetectTask()
8327 {
8328 if (!IsScreenLocked()) {
8329 return;
8330 }
8331 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8332 for (auto iter : sceneSessionMap_) {
8333 auto& session = iter.second;
8334 if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
8335 taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
8336 DetectTaskInfo detectTaskInfo;
8337 session->SetDetectTaskInfo(detectTaskInfo);
8338 }
8339 }
8340 }
8341
IsScreenLocked() const8342 bool SceneSessionManager::IsScreenLocked() const
8343 {
8344 return isScreenLocked_;
8345 }
8346
IsUserAuthPassed() const8347 bool SceneSessionManager::IsUserAuthPassed() const
8348 {
8349 return isUserAuthPassed_;
8350 }
8351
RegisterWindowChanged(const WindowChangedFunc & func)8352 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
8353 {
8354 WindowChangedFunc_ = func;
8355 }
8356
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)8357 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
8358 const std::unordered_set<std::string>& privacyBundles)
8359 {
8360 bool needNotify = false;
8361 static int reSendTimes = MAX_RESEND_TIMES;
8362 std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
8363 do {
8364 if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
8365 TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
8366 needNotify = !privacyBundles.empty();
8367 break;
8368 }
8369 const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
8370 if (lastPrivacyBundles.size() != privacyBundles.size()) {
8371 TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
8372 lastPrivacyBundles.size(), privacyBundles.size());
8373 needNotify = true;
8374 break;
8375 }
8376 for (const auto& bundle : lastPrivacyBundles) {
8377 if (privacyBundles.find(bundle) == privacyBundles.end()) {
8378 needNotify = true;
8379 break;
8380 }
8381 }
8382 } while (false);
8383
8384 TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
8385 displayId, needNotify);
8386 if (needNotify) {
8387 reSendTimes = MAX_RESEND_TIMES;
8388 privacyBundleMap_[displayId] = privacyBundles;
8389 } else if (reSendTimes > 0) {
8390 needNotify = true;
8391 reSendTimes--;
8392 privacyBundleMap_[displayId] = privacyBundles;
8393 }
8394 return needNotify;
8395 }
8396
UpdatePrivateStateAndNotify(uint32_t persistentId)8397 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
8398 {
8399 auto sceneSession = GetSceneSession(persistentId);
8400 if (sceneSession == nullptr) {
8401 TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid=%{public}u.", persistentId);
8402 return;
8403 }
8404
8405 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8406 std::unordered_set<std::string> privacyBundleList;
8407 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
8408 if (isUserBackground_ || !JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
8409 return;
8410 }
8411
8412 std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
8413 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
8414 !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
8415 ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
8416 if (!bundleListForNotify.empty()) {
8417 TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
8418 }
8419 for (const auto& bundle : bundleListForNotify) {
8420 TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display=%{public}" PRIu64 ", bundle=%{public}s.",
8421 displayId, bundle.c_str());
8422 }
8423 }
8424
UpdatePrivateStateAndNotifyForAllScreens()8425 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
8426 {
8427 auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
8428 for (auto& iter : screenProperties) {
8429 auto displayId = iter.first;
8430 std::unordered_set<std::string> privacyBundleList;
8431 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
8432
8433 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
8434 !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
8435 }
8436 }
8437
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)8438 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
8439 std::unordered_set<std::string>& privacyBundles)
8440 {
8441 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8442 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
8443 if (sceneSession == nullptr) {
8444 TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid=%{public}d.", persistentId);
8445 continue;
8446 }
8447 auto sessionProperty = sceneSession->GetSessionProperty();
8448 auto currentDisplayId = sessionProperty->GetDisplayId();
8449 if (displayId != currentDisplayId) {
8450 continue;
8451 }
8452 bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
8453 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
8454 if (isForeground && sceneSession->GetParentSession() != nullptr) {
8455 isForeground = isForeground &&
8456 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
8457 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
8458 }
8459 bool isPrivate = sessionProperty->GetPrivacyMode() ||
8460 sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
8461 bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
8462 if ((isForeground || IsSystemWindowVisible) && isPrivate) {
8463 if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
8464 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
8465 } else {
8466 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "bundle name is empty, wid=%{public}d.", persistentId);
8467 privacyBundles.insert(sceneSession->GetWindowName());
8468 }
8469 }
8470 }
8471 }
8472
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)8473 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
8474 {
8475 if (sceneSession == nullptr) {
8476 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
8477 return;
8478 }
8479 sceneSession->SetSessionStateChangeNotifyManagerListener(
8480 [this](int32_t persistentId, const SessionState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
8481 OnSessionStateChange(persistentId, state);
8482 });
8483 TLOGD(WmsLogTag::DEFAULT, "success");
8484 }
8485
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)8486 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
8487 {
8488 if (sceneSession == nullptr) {
8489 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
8490 return;
8491 }
8492 sceneSession->SetSessionInfoChangeNotifyManagerListener([this](int32_t persistentId) {
8493 NotifyWindowInfoChangeFromSession(persistentId);
8494 });
8495 }
8496
RegisterDisplayIdChangedNotifyManagerFunc(const sptr<SceneSession> & sceneSession)8497 void SceneSessionManager::RegisterDisplayIdChangedNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
8498 {
8499 if (sceneSession == nullptr) {
8500 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
8501 return;
8502 }
8503 sceneSession->SetDisplayIdChangedNotifyManagerListener([this](int32_t persistentId, uint64_t displayId) {
8504 NotifyDisplayIdChanged(persistentId, displayId);
8505 });
8506 }
8507
RegisterRequestFocusStatusNotifyManagerFunc(const sptr<SceneSession> & sceneSession)8508 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
8509 {
8510 if (sceneSession == nullptr) {
8511 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
8512 return;
8513 }
8514 sceneSession->SetRequestFocusStatusNotifyManagerListener(
8515 [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
8516 RequestFocusStatus(persistentId, isFocused, byForeground, reason);
8517 });
8518 TLOGD(WmsLogTag::DEFAULT, "success");
8519 }
8520
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)8521 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
8522 {
8523 GetStateFromManagerFunc func = [this](const ManagerState key) {
8524 switch (key) {
8525 case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
8526 return this->IsScreenLocked();
8527 break;
8528 default:
8529 return false;
8530 break;
8531 }
8532 };
8533 if (sceneSession == nullptr) {
8534 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
8535 return;
8536 }
8537 sceneSession->SetGetStateFromManagerListener(func);
8538 TLOGD(WmsLogTag::DEFAULT, "success");
8539 }
8540
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)8541 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
8542 {
8543 SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
8544 const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
8545 if (sceneSession == nullptr || property == nullptr) {
8546 TLOGNE(WmsLogTag::DEFAULT, "params is nullptr");
8547 return;
8548 }
8549 switch (action) {
8550 case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
8551 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
8552 sceneSession->keepScreenLock_);
8553 break;
8554 case WSPropertyChangeAction::ACTION_UPDATE_VIEW_KEEP_SCREEN_ON:
8555 HandleKeepScreenOn(sceneSession, property->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
8556 sceneSession->viewKeepScreenLock_);
8557 break;
8558 case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
8559 case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
8560 case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
8561 case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
8562 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
8563 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
8564 case WSPropertyChangeAction::ACTION_UPDATE_FOLLOW_SCREEN_CHANGE:
8565 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
8566 break;
8567 case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
8568 SetBrightness(sceneSession, property->GetBrightness());
8569 break;
8570 case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
8571 case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
8572 UpdatePrivateStateAndNotify(property->GetPersistentId());
8573 break;
8574 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
8575 CheckAndNotifyWaterMarkChangedResult();
8576 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
8577 break;
8578 case WSPropertyChangeAction::ACTION_UPDATE_MODE:
8579 ProcessWindowModeType();
8580 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
8581 break;
8582 case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
8583 HandleHideNonSystemFloatingWindows(property, sceneSession);
8584 break;
8585 case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
8586 FlushWindowInfoToMMI();
8587 break;
8588 default:
8589 break;
8590 }
8591 };
8592 if (sceneSession != nullptr) {
8593 sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
8594 }
8595 }
8596
OnSessionStateChange(int32_t persistentId,const SessionState & state)8597 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
8598 int32_t persistentId, const SessionState& state)
8599 {
8600 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
8601 TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, state:%{public}u", persistentId, state);
8602 SceneSessionChangeInfo changeInfo {
8603 .persistentId_ = persistentId,
8604 .changeInfo_ = "Session state change to " + std::to_string(static_cast<uint32_t>(state)),
8605 .logTag_ = WmsLogTag::WMS_LIFE,
8606 };
8607 SessionChangeRecorder::GetInstance().RecordSceneSessionChange(RecordType::SESSION_STATE_RECORD, changeInfo);
8608 auto sceneSession = GetSceneSession(persistentId);
8609 if (sceneSession == nullptr) {
8610 TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
8611 return;
8612 }
8613 switch (state) {
8614 case SessionState::STATE_FOREGROUND:
8615 ProcessFocusWhenForeground(sceneSession);
8616 if (!IsSessionVisibleForeground(sceneSession)) {
8617 sceneSession->SetPostProcessProperty(true);
8618 break;
8619 }
8620 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
8621 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
8622 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
8623 sceneSession->keepScreenLock_);
8624 HandleKeepScreenOn(sceneSession, sceneSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
8625 sceneSession->viewKeepScreenLock_);
8626 UpdatePrivateStateAndNotify(persistentId);
8627 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8628 ProcessSubSessionForeground(sceneSession);
8629 }
8630 break;
8631 case SessionState::STATE_BACKGROUND:
8632 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
8633 RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
8634 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
8635 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
8636 HandleKeepScreenOn(sceneSession, false, WINDOW_SCREEN_LOCK_PREFIX, sceneSession->keepScreenLock_);
8637 HandleKeepScreenOn(sceneSession, false, VIEW_SCREEN_LOCK_PREFIX, sceneSession->viewKeepScreenLock_);
8638 UpdatePrivateStateAndNotify(persistentId);
8639 if (persistentId == brightnessSessionId_) {
8640 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8641 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8642 UpdateBrightness(focusedSessionId);
8643 }
8644 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8645 ProcessSubSessionBackground(sceneSession);
8646 }
8647 break;
8648 case SessionState::STATE_CONNECT:
8649 SetSessionSnapshotSkipForAppProcess(sceneSession);
8650 SetSessionSnapshotSkipForAppBundleName(sceneSession);
8651 SetSessionWatermarkForAppProcess(sceneSession);
8652 break;
8653 case SessionState::STATE_DISCONNECT:
8654 if (SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
8655 RemoveProcessSnapshotSkip(sceneSession->GetCallingPid());
8656 RemoveProcessWatermarkPid(sceneSession->GetCallingPid());
8657 }
8658 break;
8659 default:
8660 break;
8661 }
8662 }
8663
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)8664 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
8665 {
8666 auto persistentId = sceneSession->GetPersistentId();
8667 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8668 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
8669 if (focusGroup == nullptr) {
8670 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
8671 return;
8672 }
8673 bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
8674 bool needBlockNotifyUnfocusStatus = focusGroup->GetNeedBlockNotifyUnfocusStatus();
8675 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
8676 persistentId == focusGroup->GetFocusedSessionId()) {
8677 if (focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground()) {
8678 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
8679 focusGroup->SetNeedBlockNotifyUnfocusStatus(false);
8680 NotifyFocusStatus(sceneSession, true, focusGroup);
8681 sceneSession->NotifyHighlightChange(true);
8682 }
8683 } else if (!sceneSession->IsFocusedOnShow()) {
8684 if (IsSessionVisibleForeground(sceneSession)) {
8685 sceneSession->SetFocusedOnShow(true);
8686 }
8687 } else {
8688 if (Session::IsScbCoreEnabled()) {
8689 ProcessFocusWhenForegroundScbCore(sceneSession);
8690 } else {
8691 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
8692 }
8693 }
8694 }
8695
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)8696 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
8697 {
8698 if (sceneSession == nullptr) {
8699 TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
8700 return;
8701 }
8702 if (sceneSession->IsFocusableOnShow()) {
8703 if (IsSessionVisibleForeground(sceneSession)) {
8704 RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
8705 } else {
8706 PostProcessFocusState state = {true, true, true, FocusChangeReason::APP_FOREGROUND};
8707 sceneSession->SetPostProcessFocusState(state);
8708 }
8709 } else {
8710 TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
8711 sceneSession->GetPersistentId());
8712 }
8713 }
8714
ProcessWindowModeType()8715 void SceneSessionManager::ProcessWindowModeType()
8716 {
8717 if (isScreenLocked_) {
8718 return;
8719 }
8720 NotifyRSSWindowModeTypeUpdate();
8721 }
8722
IsSmallFoldProduct()8723 static bool IsSmallFoldProduct()
8724 {
8725 static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
8726 if (foldScreenType.empty()) {
8727 return false;
8728 }
8729 return foldScreenType[0] == SMALL_FOLD_PRODUCT_TYPE;
8730 }
8731
IsInDefaultScreen(const sptr<SceneSession> & sceneSession)8732 bool SceneSessionManager::IsInDefaultScreen(const sptr<SceneSession>& sceneSession)
8733 {
8734 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
8735 return sceneSession->GetSessionProperty()->GetDisplayId() == defaultScreenId;
8736 }
8737
IsNeedSkipWindowModeTypeCheck(const sptr<SceneSession> & sceneSession,bool isSmallFold)8738 bool SceneSessionManager::IsNeedSkipWindowModeTypeCheck(const sptr<SceneSession>& sceneSession, bool isSmallFold)
8739 {
8740 if (sceneSession == nullptr ||
8741 !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
8742 !sceneSession->GetRSVisible() ||
8743 !sceneSession->IsSessionForeground()) {
8744 return true;
8745 }
8746 if (isSmallFold && !IsInDefaultScreen(sceneSession)) {
8747 return true;
8748 }
8749 return false;
8750 }
8751
CheckWindowModeType()8752 WindowModeType SceneSessionManager::CheckWindowModeType()
8753 {
8754 bool inSplit = false;
8755 bool inFloating = false;
8756 bool fullScreen = false;
8757 bool isSmallFold = IsSmallFoldProduct();
8758 {
8759 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8760 for (const auto& session : sceneSessionMap_) {
8761 if (IsNeedSkipWindowModeTypeCheck(session.second, isSmallFold)) {
8762 continue;
8763 }
8764 auto mode = session.second->GetWindowMode();
8765 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
8766 inSplit = true;
8767 }
8768 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
8769 inFloating = true;
8770 }
8771 if (WindowHelper::IsFullScreenWindow(mode)) {
8772 fullScreen = true;
8773 }
8774 }
8775 }
8776
8777 WindowModeType type;
8778 if (inSplit) {
8779 if (inFloating) {
8780 type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
8781 } else {
8782 type = WindowModeType::WINDOW_MODE_SPLIT;
8783 }
8784 } else {
8785 if (inFloating) {
8786 if (fullScreen) {
8787 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
8788 } else {
8789 type = WindowModeType::WINDOW_MODE_FLOATING;
8790 }
8791 } else if (fullScreen) {
8792 type = WindowModeType::WINDOW_MODE_FULLSCREEN;
8793 } else {
8794 type = WindowModeType::WINDOW_MODE_OTHER;
8795 }
8796 }
8797 return type;
8798 }
8799
NotifyRSSWindowModeTypeUpdate()8800 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
8801 {
8802 WindowModeType type = CheckWindowModeType();
8803 if (lastWindowModeType_ == type) {
8804 return;
8805 }
8806 lastWindowModeType_ = type;
8807 TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
8808 static_cast<uint8_t>(type));
8809 SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
8810 }
8811
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)8812 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
8813 {
8814 if (sceneSession == nullptr) {
8815 TLOGD(WmsLogTag::WMS_SUB, "session is nullptr");
8816 return;
8817 }
8818 std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
8819 for (auto& subSession : sceneSession->GetSubSession()) {
8820 if (subSession == nullptr) {
8821 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
8822 continue;
8823 }
8824 if (!subSession->GetSubSession().empty()) {
8825 ProcessSubSessionForeground(subSession);
8826 }
8827 if (subSession->IsTopmost()) {
8828 modalVec.push_back(subSession);
8829 TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
8830 continue;
8831 }
8832 const auto& state = subSession->GetSessionState();
8833 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
8834 TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
8835 continue;
8836 }
8837 RequestSessionFocus(subSession->GetPersistentId(), true);
8838 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
8839 HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
8840 subSession->keepScreenLock_);
8841 HandleKeepScreenOn(subSession, subSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
8842 subSession->viewKeepScreenLock_);
8843 }
8844
8845 for (const auto& modal : modalVec) {
8846 if (modal == nullptr) {
8847 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
8848 continue;
8849 }
8850 const auto& state = modal->GetSessionState();
8851 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
8852 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
8853 continue;
8854 }
8855 auto modalSession = GetSceneSession(modal->GetPersistentId());
8856 if (modalSession == nullptr) {
8857 TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
8858 continue;
8859 }
8860 NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
8861 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8862 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
8863 if (focusGroup == nullptr) {
8864 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
8865 return;
8866 }
8867 auto focusedSessionId = focusGroup->GetFocusedSessionId();
8868 bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
8869 if (modal->GetPersistentId() == focusedSessionId && needBlockNotifyFocusStatusUntilForeground) {
8870 focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
8871 focusGroup->SetNeedBlockNotifyUnfocusStatus(false);
8872 NotifyFocusStatus(modalSession, true, focusGroup);
8873 }
8874 HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
8875 modalSession->keepScreenLock_);
8876 HandleKeepScreenOn(modalSession, modalSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
8877 modalSession->viewKeepScreenLock_);
8878 }
8879 }
8880
ProcessModalTopmostRequestFocusImmediately(const sptr<SceneSession> & sceneSession)8881 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmediately(const sptr<SceneSession>& sceneSession)
8882 {
8883 // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
8884 sptr<SceneSession> mainSession = nullptr;
8885 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8886 mainSession = sceneSession;
8887 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
8888 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
8889 }
8890 if (mainSession == nullptr) {
8891 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
8892 return WSError::WS_DO_NOTHING;
8893 }
8894
8895 std::vector<sptr<SceneSession>> topmostVec;
8896 for (auto subSession : mainSession->GetSubSession()) {
8897 if (subSession && subSession->IsTopmost()) {
8898 topmostVec.push_back(subSession);
8899 }
8900 }
8901 auto displayId = mainSession->GetSessionProperty()->GetDisplayId();
8902 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8903 auto conditionFunc = [this, focusedSessionId](const sptr<SceneSession>& iter) {
8904 return iter && iter->GetPersistentId() == focusedSessionId;
8905 };
8906 if (std::find_if(topmostVec.begin(), topmostVec.end(), std::move(conditionFunc)) != topmostVec.end()) {
8907 TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId);
8908 return WSError::WS_OK;
8909 }
8910 WSError ret = WSError::WS_DO_NOTHING;
8911 for (auto topmostSession : topmostVec) {
8912 if (topmostSession == nullptr) {
8913 continue;
8914 }
8915 // no need to consider order, since rule of zOrder
8916 if (RequestSessionFocusImmediately(topmostSession->GetPersistentId(), false) == WSError::WS_OK) {
8917 ret = WSError::WS_OK;
8918 }
8919 }
8920 return ret;
8921 }
8922
ProcessSubWindowRequestFocusImmediately(const sptr<SceneSession> & sceneSession)8923 WSError SceneSessionManager::ProcessSubWindowRequestFocusImmediately(const sptr<SceneSession>& sceneSession)
8924 {
8925 if (sceneSession == nullptr) {
8926 TLOGD(WmsLogTag::WMS_FOCUS, "session is null");
8927 return WSError::WS_DO_NOTHING;
8928 }
8929 std::vector<sptr<SceneSession>> subSessionVec = sceneSession->GetSubSession();
8930 if (subSessionVec.empty()) {
8931 TLOGD(WmsLogTag::WMS_FOCUS, "has no sub window");
8932 return WSError::WS_DO_NOTHING;
8933 }
8934 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8935 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8936 auto conditionFunc = [this, focusedSessionId](const sptr<SceneSession>& iter) {
8937 return iter && iter->GetPersistentId() == focusedSessionId;
8938 };
8939 if (std::find_if(subSessionVec.begin(), subSessionVec.end(), std::move(conditionFunc)) != subSessionVec.end()) {
8940 TLOGD(WmsLogTag::WMS_SUB, "sub window id: %{public}d has been focused!", focusedSessionId);
8941 return WSError::WS_OK;
8942 }
8943 WSError ret = WSError::WS_DO_NOTHING;
8944 for (auto session : subSessionVec) {
8945 if (session == nullptr) {
8946 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
8947 continue;
8948 }
8949 if (!IsSessionVisibleForeground(session)) {
8950 continue;
8951 }
8952 if (RequestSessionFocus(session->GetPersistentId(), true, FocusChangeReason::REQUEST_WITH_CHECK_SUB_WINDOW) ==
8953 WSError::WS_OK) {
8954 ret = WSError::WS_OK;
8955 }
8956 }
8957 return ret;
8958 }
8959
ProcessDialogRequestFocusImmediately(const sptr<SceneSession> & sceneSession)8960 WSError SceneSessionManager::ProcessDialogRequestFocusImmediately(const sptr<SceneSession>& sceneSession)
8961 {
8962 // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
8963 sptr<SceneSession> mainSession = nullptr;
8964 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8965 mainSession = sceneSession;
8966 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
8967 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
8968 }
8969 if (mainSession == nullptr) {
8970 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
8971 return WSError::WS_DO_NOTHING;
8972 }
8973 std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
8974 auto displayId = mainSession->GetSessionProperty()->GetDisplayId();
8975 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8976 auto conditionFunc = [this, focusedSessionId](const sptr<Session>& iter) {
8977 return iter && iter->GetPersistentId() == focusedSessionId;
8978 };
8979 if (std::find_if(dialogVec.begin(), dialogVec.end(), std::move(conditionFunc)) != dialogVec.end()) {
8980 TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId);
8981 return WSError::WS_OK;
8982 }
8983 WSError ret = WSError::WS_DO_NOTHING;
8984 for (auto dialog : dialogVec) {
8985 if (dialog == nullptr) {
8986 continue;
8987 }
8988 // no need to consider order, since rule of zOrder
8989 if (RequestSessionFocusImmediately(dialog->GetPersistentId(), false) == WSError::WS_OK) {
8990 ret = WSError::WS_OK;
8991 }
8992 }
8993 return ret;
8994 }
8995
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)8996 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
8997 {
8998 if (sceneSession == nullptr) {
8999 TLOGD(WmsLogTag::WMS_SUB, "session is nullptr");
9000 return;
9001 }
9002 for (auto& subSession : sceneSession->GetSubSession()) {
9003 if (subSession == nullptr) {
9004 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
9005 continue;
9006 }
9007 if (!subSession->GetSubSession().empty()) {
9008 ProcessSubSessionBackground(subSession);
9009 }
9010 const auto& state = subSession->GetSessionState();
9011 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9012 TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
9013 continue;
9014 }
9015 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
9016 HandleKeepScreenOn(subSession, false, WINDOW_SCREEN_LOCK_PREFIX, subSession->keepScreenLock_);
9017 HandleKeepScreenOn(subSession, false, VIEW_SCREEN_LOCK_PREFIX, subSession->viewKeepScreenLock_);
9018 UpdatePrivateStateAndNotify(subSession->GetPersistentId());
9019 }
9020 std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
9021 for (const auto& dialog : dialogVec) {
9022 if (dialog == nullptr) {
9023 TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
9024 continue;
9025 }
9026 auto dialogSession = GetSceneSession(dialog->GetPersistentId());
9027 if (dialogSession == nullptr) {
9028 TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
9029 continue;
9030 }
9031 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
9032 HandleKeepScreenOn(dialogSession, false, WINDOW_SCREEN_LOCK_PREFIX, dialogSession->keepScreenLock_);
9033 HandleKeepScreenOn(dialogSession, false, VIEW_SCREEN_LOCK_PREFIX, dialogSession->viewKeepScreenLock_);
9034 UpdatePrivateStateAndNotify(dialog->GetPersistentId());
9035 }
9036 for (const auto& toastSession : sceneSession->GetToastSession()) {
9037 if (toastSession == nullptr) {
9038 TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
9039 continue;
9040 }
9041 const auto& state = toastSession->GetSessionState();
9042 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9043 TLOGD(WmsLogTag::WMS_TOAST, "toast session is not active");
9044 continue;
9045 }
9046 NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
9047 HandleKeepScreenOn(toastSession, false, WINDOW_SCREEN_LOCK_PREFIX, toastSession->keepScreenLock_);
9048 HandleKeepScreenOn(toastSession, false, VIEW_SCREEN_LOCK_PREFIX, toastSession->viewKeepScreenLock_);
9049 UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
9050 toastSession->SetActive(false);
9051 toastSession->BackgroundTask();
9052 }
9053 }
9054
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)9055 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
9056 const sptr<WindowSessionProperty>& property)
9057 {
9058 if (sceneSession == nullptr) {
9059 TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
9060 return WSError::WS_ERROR_NULLPTR;
9061 }
9062 auto sessionProperty = sceneSession->GetSessionProperty();
9063 uint32_t flags = property->GetWindowFlags();
9064 uint32_t oldFlags = sessionProperty->GetWindowFlags();
9065 if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
9066 (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
9067 !property->GetSystemCalling()) {
9068 TLOGE(WmsLogTag::DEFAULT, "permission denied");
9069 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9070 }
9071 sessionProperty->SetWindowFlags(flags);
9072 CheckAndNotifyWaterMarkChangedResult();
9073 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
9074 sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
9075 }
9076 TLOGI(WmsLogTag::DEFAULT, "set flags: %{public}u", flags);
9077 return WSError::WS_OK;
9078 }
9079
CheckAndNotifyWaterMarkChangedResult()9080 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
9081 {
9082 bool currentWaterMarkShowState = false;
9083 {
9084 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9085 for (const auto& [_, session] : sceneSessionMap_) {
9086 if (!session) {
9087 continue;
9088 }
9089 bool hasWaterMark = session->GetSessionProperty()->GetWindowFlags() &
9090 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
9091 bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
9092 if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
9093 currentWaterMarkShowState = true;
9094 break;
9095 }
9096 }
9097 if (combinedExtWindowFlags_.waterMarkFlag) {
9098 TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
9099 currentWaterMarkShowState = true;
9100 }
9101 }
9102 if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
9103 lastWaterMarkShowState_ = currentWaterMarkShowState;
9104 NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
9105 }
9106 }
9107
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)9108 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
9109 {
9110 TLOGD(WmsLogTag::DEFAULT, "hasWaterMark: %{public}u", static_cast<uint32_t>(hasWaterMark));
9111 SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
9112 return WSError::WS_OK;
9113 }
9114
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const9115 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
9116 {
9117 if (!bundleMgr_) {
9118 TLOGE(WmsLogTag::DEFAULT, "bundle manager is nullptr.");
9119 return;
9120 }
9121
9122 AAFwk::Want want;
9123 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
9124 auto uid = abilityInfo.uid;
9125 want.SetParam("uid", uid);
9126 bundleMgr_->ProcessPreload(want);
9127 }
9128
NotifyCompleteFirstFrameDrawing(int32_t persistentId)9129 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
9130 {
9131 auto sceneSession = GetSceneSession(persistentId);
9132 if (sceneSession == nullptr) {
9133 TLOGE(WmsLogTag::WMS_MAIN, " sceneSession is nullptr.");
9134 return;
9135 }
9136
9137 const auto& sessionInfo = sceneSession->GetSessionInfo();
9138 if (IsAtomicServiceFreeInstall(sessionInfo)) {
9139 TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
9140 sceneSession->GetPersistentId(), sceneSession->GetWindowType());
9141 FillSessionInfo(sceneSession);
9142 }
9143 TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
9144 sceneSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
9145 sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
9146 auto abilityInfo = sessionInfo.abilityInfo;
9147 if (abilityInfo == nullptr) {
9148 TLOGE(WmsLogTag::WMS_MAIN, " abilityInfo is null, Id: %{public}d", persistentId);
9149 return;
9150 }
9151
9152 [this, persistentId] {
9153 auto task = [persistentId] {
9154 AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
9155 };
9156 TLOGNI(WmsLogTag::DEFAULT, "Post CompleteFirstFrameDrawing task. Id: %{public}d", persistentId);
9157 eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
9158 }();
9159
9160 auto task = [this, abilityInfo, sceneSession, persistentId] {
9161 if (!sceneSession->GetSessionInfo().isSystem_ && !(abilityInfo->excludeFromMissions)) {
9162 TLOGND(WmsLogTag::WMS_PATTERN, "NotifyCreated, id: %{public}d", persistentId);
9163 listenerController_->NotifySessionLifecycleEvent(
9164 ISessionLifecycleListener::SessionLifecycleEvent::CREATED, sceneSession->GetSessionInfo());
9165 }
9166 ProcessPreload(*abilityInfo);
9167 };
9168
9169 if (sceneSession->GetLeashWinSurfaceNode()) {
9170 SetSkipSelfWhenShowOnVirtualScreen(sceneSession->GetLeashWinSurfaceNode()->GetId(),
9171 sceneSession->GetSkipSelfWhenShowOnVirtualScreen());
9172 }
9173 return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
9174 }
9175
NotifySessionMovedToFront(int32_t persistentId)9176 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
9177 {
9178 auto sceneSession = GetSceneSession(persistentId);
9179 if (sceneSession == nullptr) {
9180 TLOGE(WmsLogTag::DEFAULT, "session is invalid with %{public}d", persistentId);
9181 return;
9182 }
9183 TLOGI(WmsLogTag::DEFAULT, "id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
9184 sceneSession->GetSessionInfo().isSystem_);
9185 if (!sceneSession->GetSessionInfo().isSystem_ &&
9186 sceneSession->GetSessionInfo().abilityInfo &&
9187 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
9188 listenerController_->NotifySessionMovedToFront(persistentId);
9189 }
9190 }
9191
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)9192 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
9193 {
9194 TLOGI(WmsLogTag::WMS_MAIN, "in");
9195 const char* const where = __func__;
9196 auto task = [this, &token, &label, where]() {
9197 auto sceneSession = FindSessionByToken(token);
9198 if (sceneSession == nullptr) {
9199 TLOGNE(WmsLogTag::WMS_MAIN, "fail to find session by token");
9200 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
9201 }
9202 sceneSession->SetSessionLabel(label);
9203 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d, system: %{public}d",
9204 where, sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().isSystem_);
9205 if (!sceneSession->GetSessionInfo().isSystem_) {
9206 TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, sceneSession->GetPersistentId());
9207 listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
9208 }
9209 return WSError::WS_OK;
9210 };
9211 return taskScheduler_->PostSyncTask(task, where);
9212 }
9213
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)9214 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
9215 const std::shared_ptr<Media::PixelMap>& icon)
9216 {
9217 TLOGI(WmsLogTag::WMS_MAIN, "in");
9218 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9219 TLOGE(WmsLogTag::WMS_MAIN, "The caller is not system-app, can not use system-api");
9220 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9221 }
9222 const char* const where = __func__;
9223 auto task = [this, &token, &icon, where]() {
9224 auto sceneSession = FindSessionByToken(token);
9225 if (sceneSession == nullptr) {
9226 TLOGNE(WmsLogTag::WMS_MAIN, "fail to find session by token");
9227 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
9228 }
9229 sceneSession->SetSessionIcon(icon);
9230 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d, system: %{public}d",
9231 where, sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().isSystem_);
9232 if (!sceneSession->GetSessionInfo().isSystem_ &&
9233 sceneSession->GetSessionInfo().abilityInfo &&
9234 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
9235 TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, sceneSession->GetPersistentId());
9236 listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
9237 }
9238 return WSError::WS_OK;
9239 };
9240 return taskScheduler_->PostSyncTask(task, where);
9241 }
9242
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)9243 WSError SceneSessionManager::IsValidSessionIds(
9244 const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
9245 {
9246 TLOGI(WmsLogTag::DEFAULT, "in");
9247 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9248 for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
9249 auto search = sceneSessionMap_.find(sessionIds.at(i));
9250 if (search == sceneSessionMap_.end() || search->second == nullptr) {
9251 results.push_back(false);
9252 continue;
9253 }
9254 results.push_back(true);
9255 }
9256 return WSError::WS_OK;
9257 }
9258
RegisterSessionListener(const sptr<ISessionListener> & listener)9259 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
9260 {
9261 TLOGI(WmsLogTag::DEFAULT, "in");
9262 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9263 TLOGE(WmsLogTag::DEFAULT, "not system-app, can not use system-api");
9264 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9265 }
9266 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9267 TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
9268 return WSError::WS_ERROR_INVALID_PERMISSION;
9269 }
9270 auto task = [this, &listener] {
9271 WSError ret = listenerController_->AddSessionListener(listener);
9272 // app continue report for distributed scheduled service
9273 SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
9274 static_cast<int32_t>(ret));
9275 return ret;
9276 };
9277 return taskScheduler_->PostSyncTask(task, "AddSessionListener");
9278 }
9279
UnRegisterSessionListener(const sptr<ISessionListener> & listener)9280 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
9281 {
9282 TLOGI(WmsLogTag::DEFAULT, "in");
9283 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9284 TLOGE(WmsLogTag::DEFAULT, "not system-app, can not use system-api");
9285 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9286 }
9287 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9288 TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
9289 return WSError::WS_ERROR_INVALID_PERMISSION;
9290 }
9291 auto task = [this, &listener] {
9292 listenerController_->DelSessionListener(listener);
9293 return WSError::WS_OK;
9294 };
9295 return taskScheduler_->PostSyncTask(task, "DelSessionListener");
9296 }
9297
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)9298 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
9299 std::vector<SessionInfoBean>& sessionInfos)
9300 {
9301 TLOGI(WmsLogTag::DEFAULT, "num max %{public}d", numMax);
9302 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9303 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
9304 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9305 }
9306 if (!SessionPermission::VerifySessionPermission()) {
9307 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
9308 return WSError::WS_ERROR_INVALID_PERMISSION;
9309 }
9310 auto task = [this, &deviceId, numMax, &sessionInfos]() {
9311 if (CheckIsRemote(deviceId)) {
9312 int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
9313 if (ret != ERR_OK) {
9314 return WSError::WS_ERROR_INVALID_PARAM;
9315 } else {
9316 return WSError::WS_OK;
9317 }
9318 }
9319 std::map<int32_t, sptr<SceneSession>>::iterator iter;
9320 std::vector<sptr<SceneSession>> sceneSessionInfos;
9321 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9322 for (const auto& [_, sceneSession] : sceneSessionMap_) {
9323 if (sceneSession == nullptr) {
9324 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
9325 continue;
9326 }
9327 const auto& sessionInfo = sceneSession->GetSessionInfo();
9328 if (sessionInfo.isSystem_) {
9329 TLOGND(WmsLogTag::WMS_LIFE, "sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
9330 continue;
9331 }
9332 auto want = sessionInfo.want;
9333 if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
9334 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d, want is null or bundleName is empty "
9335 "or want bundleName is empty", sceneSession->GetPersistentId());
9336 continue;
9337 }
9338 if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
9339 break;
9340 }
9341 TLOGND(WmsLogTag::WMS_LIFE, "GetSessionInfos session: %{public}d, bundleName:%{public}s",
9342 sceneSession->GetPersistentId(), sessionInfo.bundleName_.c_str());
9343 sceneSessionInfos.emplace_back(sceneSession);
9344 }
9345 return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
9346 };
9347 return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
9348 }
9349
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)9350 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
9351 {
9352 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
9353 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
9354 TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
9355 return WSError::WS_ERROR_INVALID_PERMISSION;
9356 }
9357 if (pid < 0) {
9358 return WSError::WS_ERROR_INVALID_PARAM;
9359 }
9360 auto task = [this, pid, &windowStates] {
9361 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9362 for (const auto& [_, sceneSession] : sceneSessionMap_) {
9363 if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
9364 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9365 MainWindowState windowState;
9366 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
9367 windowState.isVisible_ = sceneSession->GetRSVisible();
9368 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
9369 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
9370 windowStates.emplace_back(windowState);
9371 }
9372 }
9373 return WSError::WS_OK;
9374 };
9375 return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
9376 }
9377
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)9378 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
9379 std::vector<SessionInfoBean>& sessionInfos)
9380 {
9381 TLOGI(WmsLogTag::DEFAULT, "begin");
9382 int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
9383 if (result != ERR_OK) {
9384 TLOGE(WmsLogTag::DEFAULT, "failed, result=%{public}d", result);
9385 return result;
9386 }
9387 return ERR_OK;
9388 }
9389
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)9390 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
9391 int32_t persistentId, SessionInfoBean& sessionInfo)
9392 {
9393 TLOGI(WmsLogTag::DEFAULT, "id %{public}d", persistentId);
9394 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9395 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
9396 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9397 }
9398 if (!SessionPermission::VerifySessionPermission()) {
9399 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
9400 return WSError::WS_ERROR_INVALID_PERMISSION;
9401 }
9402 return taskScheduler_->PostSyncTask([this, &deviceId, persistentId, &sessionInfo]() {
9403 if (CheckIsRemote(deviceId)) {
9404 if (GetRemoteSessionInfo(deviceId, persistentId, sessionInfo) != ERR_OK) {
9405 return WSError::WS_ERROR_INVALID_PARAM;
9406 } else {
9407 return WSError::WS_OK;
9408 }
9409 }
9410
9411 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9412 if (auto iter = sceneSessionMap_.find(persistentId); iter != sceneSessionMap_.end()) {
9413 auto sceneSession = iter->second;
9414 if (sceneSession == nullptr) {
9415 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d is nullptr", persistentId);
9416 return WSError::WS_ERROR_INVALID_PARAM;
9417 }
9418 const auto& sceneSessionInfo = sceneSession->GetSessionInfo();
9419 if (sceneSessionInfo.isSystem_) {
9420 TLOGND(WmsLogTag::WMS_LIFE, "sessionId: %{public}d isSystemScene", persistentId);
9421 return WSError::WS_ERROR_INVALID_PARAM;
9422 }
9423 auto want = sceneSessionInfo.want;
9424 if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
9425 want->GetElement().GetBundleName().empty()) {
9426 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d, want is null or bundleName is empty "
9427 "or want bundleName is empty", persistentId);
9428 return WSError::WS_ERROR_INTERNAL_ERROR;
9429 }
9430 TLOGND(WmsLogTag::WMS_LIFE, "GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
9431 sceneSessionInfo.bundleName_.c_str());
9432 return SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
9433 } else {
9434 TLOGNW(WmsLogTag::WMS_LIFE, "sessionId: %{public}d not found", persistentId);
9435 return WSError::WS_ERROR_INVALID_PARAM;
9436 }
9437 }, __func__);
9438 }
9439
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)9440 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
9441 SessionInfoBean& sessionInfo)
9442 {
9443 TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
9444 continueSessionId.c_str());
9445 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9446 TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
9447 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9448 }
9449 if (!SessionPermission::VerifySessionPermission()) {
9450 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
9451 return WSError::WS_ERROR_INVALID_PERMISSION;
9452 }
9453 return taskScheduler_->PostSyncTask([this, continueSessionId, &sessionInfo]() {
9454 WSError ret = WSError::WS_ERROR_INVALID_SESSION;
9455 {
9456 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9457 for (const auto& [_, sceneSession] : sceneSessionMap_) {
9458 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
9459 ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
9460 break;
9461 }
9462 }
9463 }
9464
9465 TLOGNI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
9466 // app continue report for distributed scheduled service
9467 SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
9468 static_cast<int32_t>(ret));
9469 return ret;
9470 }, __func__);
9471 }
9472
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)9473 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
9474 int32_t persistentId, SessionInfoBean& sessionInfo)
9475 {
9476 TLOGI(WmsLogTag::DEFAULT, "in");
9477 std::vector<SessionInfoBean> sessionVector;
9478 int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
9479 if (result != ERR_OK) {
9480 return result;
9481 }
9482 for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
9483 if (iter->id == persistentId) {
9484 sessionInfo = *iter;
9485 return ERR_OK;
9486 }
9487 }
9488 TLOGW(WmsLogTag::DEFAULT, "missionId not found");
9489 return ERR_INVALID_VALUE;
9490 }
9491
CheckIsRemote(const std::string & deviceId)9492 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
9493 {
9494 if (deviceId.empty()) {
9495 TLOGI(WmsLogTag::DEFAULT, "empty");
9496 return false;
9497 }
9498 std::string localDeviceId;
9499 if (!GetLocalDeviceId(localDeviceId)) {
9500 TLOGE(WmsLogTag::DEFAULT, "GetLocalDeviceId failed");
9501 return false;
9502 }
9503 if (localDeviceId == deviceId) {
9504 TLOGI(WmsLogTag::DEFAULT, "deviceId is local.");
9505 return false;
9506 }
9507 TLOGD(WmsLogTag::DEFAULT, "Checked deviceId=%{public}s", AnonymizeDeviceId(deviceId).c_str());
9508 return true;
9509 }
9510
GetLocalDeviceId(std::string & localDeviceId)9511 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
9512 {
9513 auto localNode = std::make_unique<NodeBasicInfo>();
9514 int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
9515 if (errCode != ERR_OK) {
9516 TLOGE(WmsLogTag::DEFAULT, "GetLocalNodeDeviceInfo errCode=%{public}d", errCode);
9517 return false;
9518 }
9519 if (localNode != nullptr) {
9520 localDeviceId = localNode->networkId;
9521 TLOGD(WmsLogTag::DEFAULT, "get local deviceId, deviceId=%{public}s", AnonymizeDeviceId(localDeviceId).c_str());
9522 return true;
9523 }
9524 TLOGE(WmsLogTag::DEFAULT, "localDeviceId null");
9525 return false;
9526 }
9527
AnonymizeDeviceId(const std::string & deviceId)9528 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
9529 {
9530 if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
9531 return EMPTY_DEVICE_ID;
9532 }
9533 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
9534 anonDeviceId.append("******");
9535 return anonDeviceId;
9536 }
9537
DumpSessionAll(std::vector<std::string> & infos)9538 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
9539 {
9540 TLOGI(WmsLogTag::DEFAULT, "in.");
9541 if (!SessionPermission::IsSystemCalling()) {
9542 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
9543 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9544 }
9545
9546 return taskScheduler_->PostSyncTask([this, &infos]() {
9547 infos.push_back("User ID #" + std::to_string(currentUserId_));
9548 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9549 for (const auto& [_, session] : sceneSessionMap_) {
9550 if (session) {
9551 session->DumpSessionInfo(infos);
9552 }
9553 }
9554 return WSError::WS_OK;
9555 }, __func__);
9556 }
9557
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)9558 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
9559 {
9560 TLOGI(WmsLogTag::DEFAULT, "id %{public}d", persistentId);
9561 if (!SessionPermission::IsSystemCalling()) {
9562 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
9563 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9564 }
9565
9566 return taskScheduler_->PostSyncTask([this, persistentId, &infos]() {
9567 infos.push_back("User ID #" + std::to_string(currentUserId_));
9568 auto session = GetSceneSession(persistentId);
9569 if (session) {
9570 session->DumpSessionInfo(infos);
9571 } else {
9572 infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
9573 }
9574 return WSError::WS_OK;
9575 }, __func__);
9576 }
9577
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)9578 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
9579 const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
9580 {
9581 if (bundleMgr_ == nullptr) {
9582 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
9583 return WSError::WS_ERROR_NULLPTR;
9584 }
9585 const auto& elementName = want.GetElement();
9586 int32_t ret{0};
9587 auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
9588 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
9589 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
9590 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
9591 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
9592 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
9593 std::vector<AppExecFwk::BundleInfo> bundleInfos;
9594 if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
9595 TLOGD(WmsLogTag::DEFAULT, "want is empty queryAllAbilityInfos");
9596 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
9597 if (ret) {
9598 TLOGE(WmsLogTag::DEFAULT, "Query all ability infos from BMS failed!");
9599 return WSError::WS_ERROR_INVALID_PARAM;
9600 }
9601 } else if (!elementName.GetBundleName().empty()) {
9602 AppExecFwk::BundleInfo bundleInfo;
9603 TLOGD(WmsLogTag::DEFAULT, "bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
9604 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
9605 if (ret) {
9606 TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed!");
9607 return WSError::WS_ERROR_INVALID_PARAM;
9608 }
9609 bundleInfos.push_back(bundleInfo);
9610 } else {
9611 TLOGE(WmsLogTag::DEFAULT, "invalid want:%{public}s", want.ToString().c_str());
9612 return WSError::WS_ERROR_INVALID_PARAM;
9613 }
9614 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos, userId);
9615 }
9616
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)9617 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
9618 const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
9619 {
9620 if (bundleMgr_ == nullptr) {
9621 TLOGE(WmsLogTag::WMS_RECOVER, "bundleMgr is nullptr");
9622 return WSError::WS_ERROR_NULLPTR;
9623 }
9624 if (bundleNames.empty()) {
9625 TLOGE(WmsLogTag::WMS_RECOVER, "bundleNames is empty");
9626 return WSError::WS_ERROR_INVALID_PARAM;
9627 }
9628 auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
9629 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
9630 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
9631 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
9632 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
9633 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
9634 std::vector<AppExecFwk::BundleInfo> bundleInfos;
9635 auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
9636 if (ret) {
9637 TLOGE(WmsLogTag::WMS_RECOVER, "Query batch ability infos from BMS failed!");
9638 return WSError::WS_ERROR_INVALID_PARAM;
9639 }
9640 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos, userId);
9641 }
9642
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)9643 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
9644 const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
9645 {
9646 if (bundleMgr_ == nullptr) {
9647 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
9648 return WSError::WS_ERROR_NULLPTR;
9649 }
9650 auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
9651 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
9652 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
9653 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
9654 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
9655 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
9656 AppExecFwk::BundleInfo bundleInfo;
9657 if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
9658 TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
9659 return WSError::WS_ERROR_INVALID_PARAM;
9660 }
9661 auto& hapModulesList = bundleInfo.hapModuleInfos;
9662 if (hapModulesList.empty()) {
9663 TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
9664 return WSError::WS_ERROR_INVALID_PARAM;
9665 }
9666 auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
9667 for (auto& hapModule : hapModulesList) {
9668 bool isModuleAbilityHook = false;
9669 if (!hapModule.abilitySrcEntryDelegator.empty() && !hapModule.abilityStageSrcEntryDelegator.empty()) {
9670 isModuleAbilityHook = true;
9671 }
9672 auto& abilityInfoList = hapModule.abilityInfos;
9673 for (auto& abilityInfo : abilityInfoList) {
9674 abilityInfo.windowModes = ExtractSupportWindowModeFromMetaData(
9675 std::make_shared<OHOS::AppExecFwk::AbilityInfo>(abilityInfo));
9676 if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
9677 scbAbilityInfo.abilityInfo_ = abilityInfo;
9678 scbAbilityInfo.sdkVersion_ = sdkVersion;
9679 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
9680 scbAbilityInfo.isAbilityHook_ = isModuleAbilityHook;
9681 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
9682 scbAbilityInfo.isForceRotate_ = bundleInfo.applicationInfo.isForceRotate;
9683 return WSError::WS_OK;
9684 }
9685 }
9686 }
9687 TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
9688 return WSError::WS_ERROR_INVALID_PARAM;
9689 }
9690
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos,int32_t userId)9691 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
9692 std::vector<SCBAbilityInfo>& scbAbilityInfos, int32_t userId)
9693 {
9694 if (bundleInfos.empty()) {
9695 TLOGE(WmsLogTag::DEFAULT, "bundleInfos is empty");
9696 return WSError::WS_ERROR_INVALID_PARAM;
9697 }
9698 std::vector<AppExecFwk::BundleInfo> collaboratorBundleInfos;
9699 for (auto& bundleInfo : bundleInfos) {
9700 auto& hapModulesList = bundleInfo.hapModuleInfos;
9701 auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
9702 if (hapModulesList.empty()) {
9703 TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty");
9704 continue;
9705 }
9706 if (WindowHelper::IsNumber(bundleInfo.applicationInfo.codePath) &&
9707 CheckCollaboratorType(std::stoi(bundleInfo.applicationInfo.codePath))) {
9708 collaboratorBundleInfos.emplace_back(bundleInfo);
9709 continue;
9710 }
9711 for (auto& hapModule : hapModulesList) {
9712 auto& abilityInfoList = hapModule.abilityInfos;
9713 bool isModuleAbilityHook = false;
9714 if (!hapModule.abilitySrcEntryDelegator.empty() && !hapModule.abilityStageSrcEntryDelegator.empty()) {
9715 isModuleAbilityHook = true;
9716 }
9717 for (auto& abilityInfo : abilityInfoList) {
9718 SCBAbilityInfo scbAbilityInfo;
9719 scbAbilityInfo.abilityInfo_ = abilityInfo;
9720 scbAbilityInfo.abilityInfo_.windowModes = ExtractSupportWindowModeFromMetaData(
9721 std::make_shared<OHOS::AppExecFwk::AbilityInfo>(abilityInfo));
9722 scbAbilityInfo.sdkVersion_ = sdkVersion;
9723 scbAbilityInfo.isAbilityHook_ = isModuleAbilityHook;
9724 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
9725 scbAbilityInfos.push_back(scbAbilityInfo);
9726 }
9727 }
9728 }
9729 GetCollaboratorAbilityInfos(collaboratorBundleInfos, scbAbilityInfos, userId);
9730 return WSError::WS_OK;
9731 }
9732
GetCollaboratorAbilityInfos(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos,int32_t userId)9733 void SceneSessionManager::GetCollaboratorAbilityInfos(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
9734 std::vector<SCBAbilityInfo>& scbAbilityInfos, int32_t userId)
9735 {
9736 if (bundleInfos.empty()) {
9737 TLOGD(WmsLogTag::DEFAULT, "bundleInfos is empty");
9738 return;
9739 }
9740 std::vector<AppExecFwk::AbilityInfo> launcherAbilityInfos;
9741 AAFwk::Want want;
9742 want.SetAction(AAFwk::Want::ACTION_HOME);
9743 want.AddEntity(AAFwk::Want::ENTITY_HOME);
9744 if (!bundleMgr_ || bundleMgr_->QueryLauncherAbilityInfos(want, userId, launcherAbilityInfos) != ERR_OK) {
9745 TLOGE(WmsLogTag::DEFAULT, "Query launcher ability infos from BMS failed!");
9746 return;
9747 }
9748 std::unordered_map<std::string, AppExecFwk::AbilityInfo> abilityInfoMap;
9749 for (auto& abilityInfo : launcherAbilityInfos) {
9750 abilityInfoMap.emplace(abilityInfo.bundleName, abilityInfo);
9751 }
9752 for (auto& bundleInfo : bundleInfos) {
9753 AppExecFwk::AbilityInfo abilityInfo;
9754 auto& hapModulesList = bundleInfo.hapModuleInfos;
9755 auto iter = abilityInfoMap.find(bundleInfo.name);
9756 if (iter == abilityInfoMap.end()) {
9757 TLOGW(WmsLogTag::DEFAULT, "launcher ability not found, bundle:%{public}s", bundleInfo.name.c_str());
9758 auto hapModuleListIter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
9759 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
9760 if (hapModuleListIter != hapModulesList.end()) {
9761 abilityInfo = hapModuleListIter->abilityInfos[0];
9762 } else {
9763 continue;
9764 }
9765 } else {
9766 if (!AbilityInfoManager::FindAbilityInfo(
9767 bundleInfo, iter->second.moduleName, iter->second.name, abilityInfo)) {
9768 continue;
9769 }
9770 }
9771 SCBAbilityInfo scbAbilityInfo;
9772 scbAbilityInfo.abilityInfo_ = abilityInfo;
9773 scbAbilityInfo.sdkVersion_ = bundleInfo.targetVersion % 100; // %100 to get the real version
9774 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
9775 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
9776 scbAbilityInfo.isForceRotate_ = bundleInfo.applicationInfo.isForceRotate;
9777 scbAbilityInfos.push_back(scbAbilityInfo);
9778 }
9779 }
9780
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo & abilityInfo)9781 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
9782 {
9783 if (abilityInfo.orientationId == 0) {
9784 return;
9785 }
9786 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
9787 if (resConfig == nullptr) {
9788 TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
9789 return;
9790 }
9791 std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
9792 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
9793 if (resourceMgr == nullptr) {
9794 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
9795 return;
9796 }
9797 std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
9798 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
9799 TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
9800 }
9801 std::string orientation;
9802 auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
9803 if (ret != Global::Resource::RState::SUCCESS) {
9804 TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
9805 static_cast<int32_t>(ret), abilityInfo.orientationId);
9806 return;
9807 }
9808 if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
9809 TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
9810 return;
9811 }
9812 abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
9813 }
9814
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)9815 WSError SceneSessionManager::TerminateSessionNew(
9816 const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
9817 {
9818 if (info == nullptr) {
9819 TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
9820 return WSError::WS_ERROR_INVALID_PARAM;
9821 }
9822 TLOGI(WmsLogTag::WMS_LIFE,
9823 "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
9824 info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
9825 int32_t callingPid = IPCSkeleton::GetCallingPid();
9826 uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
9827 auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
9828 sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
9829 if (sceneSession == nullptr) {
9830 TLOGNE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
9831 return WSError::WS_ERROR_INVALID_PARAM;
9832 }
9833 const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
9834 if (!pidCheck &&
9835 !SessionPermission::VerifyPermissionByCallerToken(callerToken,
9836 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9837 TLOGNE(WmsLogTag::WMS_LIFE,
9838 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
9839 sceneSession->GetCallingPid(), callingPid);
9840 return WSError::WS_ERROR_INVALID_PERMISSION;
9841 }
9842 WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
9843 return errCode;
9844 };
9845 return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
9846 }
9847
SetVmaCacheStatus(bool flag)9848 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
9849 {
9850 TLOGI(WmsLogTag::DEFAULT, "flag: %{public}d", flag);
9851 RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
9852 return WSError::WS_OK;
9853 }
9854
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)9855 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
9856 SessionSnapshot& snapshot, bool isLowResolution)
9857 {
9858 TLOGI(WmsLogTag::DEFAULT, "id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
9859 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9860 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
9861 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9862 }
9863 if (!SessionPermission::VerifySessionPermission()) {
9864 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
9865 return WSError::WS_ERROR_INVALID_PERMISSION;
9866 }
9867 return taskScheduler_->PostSyncTask([this, &deviceId, persistentId, &snapshot, isLowResolution]() {
9868 if (CheckIsRemote(deviceId)) {
9869 if (GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot) != ERR_OK) {
9870 return WSError::WS_ERROR_INVALID_PARAM;
9871 } else {
9872 return WSError::WS_OK;
9873 }
9874 }
9875 auto sceneSession = GetSceneSession(persistentId);
9876 if (!sceneSession) {
9877 TLOGNE(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
9878 return WSError::WS_ERROR_INVALID_PARAM;
9879 }
9880 const auto& sessionInfo = sceneSession->GetSessionInfo();
9881 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
9882 TLOGNW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
9883 sceneSession->GetPersistentId());
9884 }
9885 snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
9886 snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
9887 snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
9888 if (auto oriSnapshot = sceneSession->Snapshot()) {
9889 if (isLowResolution) {
9890 OHOS::Media::InitializationOptions options;
9891 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
9892 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
9893 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
9894 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
9895 } else {
9896 snapshot.snapshot = oriSnapshot;
9897 }
9898 }
9899 return WSError::WS_OK;
9900 }, __func__);
9901 }
9902
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)9903 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
9904 {
9905 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
9906 TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
9907 return WMError::WM_ERROR_NOT_SYSTEM_APP;
9908 }
9909 return taskScheduler_->PostSyncTask([this, persistentId, &snapshot]() {
9910 auto sceneSession = GetSceneSession(persistentId);
9911 if (!sceneSession) {
9912 TLOGNW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
9913 return WMError::WM_ERROR_INVALID_PARAM;
9914 }
9915 const auto& sessionInfo = sceneSession->GetSessionInfo();
9916 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
9917 TLOGNW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
9918 sceneSession->GetPersistentId());
9919 }
9920 snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
9921 snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
9922 snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
9923 float snapShotScale = sceneSession->GetFloatingScale() > 1.0f ? 1.0f : sceneSession->GetFloatingScale();
9924 if (auto oriSnapshot = sceneSession->Snapshot(false, snapShotScale, false)) {
9925 if (sceneSession->GetFloatingScale() > 1.0f) {
9926 oriSnapshot->scale(sceneSession->GetFloatingScale(), sceneSession->GetFloatingScale());
9927 }
9928 snapshot.snapshot = oriSnapshot;
9929 TLOGNI(WmsLogTag::WMS_SYSTEM, "snapshot WxH=%{public}dx%{public}d",
9930 oriSnapshot->GetWidth(), oriSnapshot->GetHeight());
9931 return WMError::WM_OK;
9932 }
9933 return WMError::WM_ERROR_NULLPTR;
9934 }, __func__);
9935 }
9936
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)9937 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
9938 {
9939 if (!SessionPermission::IsSACalling()) {
9940 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Permission denied!");
9941 return WSError::WS_ERROR_INVALID_PERMISSION;
9942 }
9943 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "PersistentId=%{public}d", persistentId);
9944 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
9945 if (sceneSession == nullptr) {
9946 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sceneSession is nullptr");
9947 return WSError::WS_ERROR_NULLPTR;
9948 }
9949 return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
9950 }
9951
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)9952 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
9953 AAFwk::MissionSnapshot& sessionSnapshot)
9954 {
9955 TLOGI(WmsLogTag::DEFAULT, "begin");
9956 int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
9957 sessionId, sessionSnapshot);
9958 if (result != ERR_OK) {
9959 TLOGE(WmsLogTag::DEFAULT, "failed, result=%{public}d", result);
9960 return result;
9961 }
9962 return ERR_OK;
9963 }
9964
GetCollaboratorByType(int32_t collaboratorType)9965 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
9966 {
9967 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
9968 std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
9969 auto iter = collaboratorMap_.find(collaboratorType);
9970 if (iter == collaboratorMap_.end()) {
9971 TLOGE(WmsLogTag::WMS_MAIN, "Fail to found collaborator with type: %{public}d", collaboratorType);
9972 return collaborator;
9973 }
9974 collaborator = iter->second;
9975 if (collaborator == nullptr) {
9976 TLOGE(WmsLogTag::WMS_MAIN, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
9977 }
9978 return collaborator;
9979 }
9980
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession,int32_t requestId)9981 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession, int32_t requestId)
9982 {
9983 const char* const where = __func__;
9984 auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
9985 requestId, where]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
9986 auto sceneSession = weakSceneSession.promote();
9987 if (sceneSession == nullptr) {
9988 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session is nullptr", where);
9989 return WSError::WS_ERROR_NULLPTR;
9990 }
9991 auto persistentId = sceneSession->GetPersistentId();
9992 if (!GetSceneSession(persistentId)) {
9993 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session is invalid, id:%{public}d", where, persistentId);
9994 return WSError::WS_ERROR_INVALID_SESSION;
9995 }
9996 const auto& sessionInfo = sceneSession->GetSessionInfo();
9997 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: state:%{public}d, id:%{public}d",
9998 where, sessionInfo.callState_, persistentId);
9999 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession, requestId);
10000 bool isColdStart = false;
10001 AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
10002 CloseAllFd(sessionInfo.want);
10003 if (isColdStart) {
10004 TLOGNI(WmsLogTag::WMS_MAIN, "Cold start, identityToken:%{public}s, bundleName:%{public}s",
10005 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
10006 sceneSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
10007 sceneSession->ResetSessionConnectState();
10008 sceneSession->UpdatePrivacyModeControlInfo();
10009 }
10010 return WSError::WS_OK;
10011 };
10012 std::string taskName = "RequestSceneSessionByCall:PID:" +
10013 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
10014 taskScheduler_->PostAsyncTask(task, taskName);
10015 return WSError::WS_OK;
10016 }
10017
StartAbilityBySpecified(const SessionInfo & sessionInfo)10018 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
10019 {
10020 const char* const where = __func__;
10021 ffrtQueueHelper_->SubmitTask([this, sessionInfo, where] {
10022 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: bundleName: %{public}s, "
10023 "moduleName: %{public}s, abilityName: %{public}s", where,
10024 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
10025 AAFwk::Want want;
10026 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
10027 if (sessionInfo.want != nullptr) {
10028 want.SetParams(sessionInfo.want->GetParams());
10029 want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast<int>(sessionInfo.screenId_));
10030 }
10031 auto result = AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
10032 CloseAllFd(sessionInfo.want);
10033 TLOGNI(WmsLogTag::WMS_LIFE, "start specified ability by SCB result: %{public}d", result);
10034 if (result == ERR_OK) {
10035 return;
10036 }
10037 auto task = [bundleName = sessionInfo.bundleName_, appInstanceKey = sessionInfo.appInstanceKey_] {
10038 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCountByBundleNameAndInstanceKey(
10039 bundleName, appInstanceKey);
10040 };
10041 taskScheduler_->PostAsyncTask(task, where);
10042 });
10043 }
10044
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)10045 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
10046 {
10047 TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
10048 if (pid == -1) {
10049 TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
10050 return;
10051 }
10052 int32_t ret = HiSysEventWrite(
10053 HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
10054 "WINDOW_STATE_ERROR",
10055 HiviewDFX::HiSysEvent::EventType::FAULT,
10056 "PID", pid,
10057 "PERSISTENT_ID", persistentId);
10058 if (ret != 0) {
10059 TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
10060 }
10061 auto task = [this, pid] {
10062 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10063 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10064 if (!sceneSession || pid != sceneSession->GetCallingPid() ||
10065 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10066 continue;
10067 }
10068 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
10069 TLOGNI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
10070 abilitySessionInfo->persistentId);
10071 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
10072 }
10073 };
10074 // delay 2000ms, wait for hidumper
10075 taskScheduler_->PostAsyncTask(task, __func__, 2000);
10076 }
10077
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)10078 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
10079 {
10080 if (!targetToken) {
10081 TLOGE(WmsLogTag::DEFAULT, "Token is null, cannot find main window");
10082 return nullptr;
10083 }
10084
10085 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10086 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
10087 [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
10088 if (pair.second->IsTerminated()) {
10089 return false;
10090 }
10091 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10092 return pair.second->GetAbilityToken() == targetToken;
10093 }
10094 return false;
10095 });
10096 if (iter == sceneSessionMap_.end()) {
10097 TLOGE(WmsLogTag::DEFAULT, "Cannot find session");
10098 return nullptr;
10099 }
10100 return iter->second;
10101 }
10102
ConfigSupportCreateFloatWindow()10103 void SceneSessionManager::ConfigSupportCreateFloatWindow()
10104 {
10105 auto task = [this] {
10106 systemConfig_.supportCreateFloatWindow_ = true;
10107 };
10108 taskScheduler_->PostAsyncTask(task, "ConfigSupportCreateFloatWindow");
10109 }
10110
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)10111 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
10112 {
10113 if (!SessionPermission::IsSystemCalling()) {
10114 TLOGE(WmsLogTag::WMS_DIALOG, "permission denied!");
10115 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10116 }
10117 if (targetToken == nullptr) {
10118 TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
10119 return WSError::WS_ERROR_NULLPTR;
10120 }
10121
10122 auto task = [this, persistentId, targetToken]() {
10123 auto sceneSession = GetSceneSession(static_cast<int32_t>(persistentId));
10124 if (sceneSession == nullptr) {
10125 TLOGNE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
10126 return WSError::WS_ERROR_NULLPTR;
10127 }
10128 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
10129 TLOGNE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", sceneSession->GetWindowType());
10130 return WSError::WS_OK;
10131 }
10132 sceneSession->dialogTargetToken_ = targetToken;
10133 sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
10134 if (parentSession == nullptr) {
10135 sceneSession->NotifyDestroy();
10136 return WSError::WS_ERROR_INVALID_PARAM;
10137 }
10138 sptr<WindowSessionProperty> parentProperty = parentSession->GetSessionProperty();
10139 sptr<WindowSessionProperty> property = sceneSession->GetSessionProperty();
10140 auto displayId = parentProperty->GetDisplayId();
10141 property->SetDisplayId(displayId);
10142 sceneSession->SetScreenId(displayId);
10143 sceneSession->SetParentSession(parentSession);
10144 sceneSession->SetParentPersistentId(parentSession->GetPersistentId());
10145 sceneSession->SetClientDisplayId(parentSession->GetClientDisplayId());
10146 UpdateParentSessionForDialog(sceneSession, sceneSession->GetSessionProperty());
10147 TLOGNI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
10148 persistentId, parentSession->GetPersistentId());
10149 return WSError::WS_OK;
10150 };
10151 return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
10152 }
10153
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)10154 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
10155 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
10156 {
10157 SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
10158 }
10159
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)10160 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
10161 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
10162 {
10163 auto isSaCall = SessionPermission::IsSACalling();
10164 if (!isSaCall) {
10165 TLOGE(WmsLogTag::DEFAULT, "The interface only support for sa call");
10166 return WMError::WM_ERROR_INVALID_PERMISSION;
10167 }
10168 auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
10169 std::map<int32_t, sptr<SceneSession>>::iterator iter;
10170 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10171 for (auto missionId : missionIds) {
10172 iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
10173 if (iter == sceneSessionMap_.end()) {
10174 continue;
10175 }
10176 auto sceneSession = iter->second;
10177 if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
10178 continue;
10179 }
10180 surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
10181 GetSurfaceNodeIdsFromSubSession(sceneSession, surfaceNodeIds);
10182 if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
10183 surfaceNodeIds.push_back(missionId);
10184 continue;
10185 }
10186 if (sceneSession->GetLeashWinSurfaceNode()) {
10187 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
10188 }
10189 }
10190 return WMError::WM_OK;
10191 };
10192 return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
10193 }
10194
GetSurfaceNodeIdsFromSubSession(const sptr<SceneSession> & sceneSession,std::vector<uint64_t> & surfaceNodeIds)10195 WMError SceneSessionManager::GetSurfaceNodeIdsFromSubSession(
10196 const sptr<SceneSession>& sceneSession, std::vector<uint64_t>& surfaceNodeIds)
10197 {
10198 if (sceneSession == nullptr) {
10199 return WMError::WM_DO_NOTHING;
10200 }
10201 for (const auto& subSession : sceneSession->GetSubSession()) {
10202 if (subSession == nullptr) {
10203 continue;
10204 }
10205 GetSurfaceNodeIdsFromSubSession(subSession, surfaceNodeIds);
10206 }
10207 if (sceneSession->GetSurfaceNode() == nullptr) {
10208 return WMError::WM_DO_NOTHING;
10209 }
10210 surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
10211 if (sceneSession->GetLeashWinSurfaceNode()) {
10212 surfaceNodeIds.push_back(static_cast<uint64_t>(sceneSession->GetPersistentId()));
10213 }
10214 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, surfaceId: %{public}" PRIu64,
10215 sceneSession->GetPersistentId(), sceneSession->GetSurfaceNode()->GetId());
10216 return WMError::WM_OK;
10217 }
10218
OnSetSurfaceNodeIds(DisplayId displayId,const std::vector<uint64_t> & surfaceNodeIds)10219 void DisplayChangeListener::OnSetSurfaceNodeIds(DisplayId displayId, const std::vector<uint64_t>& surfaceNodeIds)
10220 {
10221 SceneSessionManager::GetInstance().SetSurfaceNodeIds(displayId, surfaceNodeIds);
10222 }
10223
SetSurfaceNodeIds(DisplayId displayId,const std::vector<uint64_t> & surfaceNodeIds)10224 WMError SceneSessionManager::SetSurfaceNodeIds(DisplayId displayId, const std::vector<uint64_t>& surfaceNodeIds)
10225 {
10226 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "displayId: %{public}" PRIu64, displayId);
10227 auto task = [this, displayId, &surfaceNodeIds, where = __func__]() {
10228 for (auto it = sessionBlackListInfoMap_[displayId].begin(); it != sessionBlackListInfoMap_[displayId].end(); ) {
10229 if (it->privacyWindowTag == WMS_DEFAULT) {
10230 it = sessionBlackListInfoMap_[displayId].erase(it);
10231 } else {
10232 ++it;
10233 }
10234 }
10235 for (auto surfaceNodeId : surfaceNodeIds) {
10236 sptr<SceneSession> sceneSession = SelectSesssionFromMap(surfaceNodeId);
10237 if (sceneSession == nullptr) {
10238 continue;
10239 }
10240 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: %{public}d, %{public}" PRIu64,
10241 where, sceneSession->GetPersistentId(), surfaceNodeId);
10242 sessionBlackListInfoMap_[displayId].insert({ .windowId = sceneSession->GetPersistentId() });
10243 }
10244 UpdateVirtualScreenBlackList(displayId);
10245 return WMError::WM_OK;
10246 };
10247 return taskScheduler_->PostSyncTask(task, __func__);
10248 }
10249
OnVirtualScreenDisconnected(DisplayId displayId)10250 void DisplayChangeListener::OnVirtualScreenDisconnected(DisplayId displayId)
10251 {
10252 SceneSessionManager::GetInstance().OnVirtualScreenDisconnected(displayId);
10253 }
10254
OnVirtualScreenDisconnected(DisplayId displayId)10255 WMError SceneSessionManager::OnVirtualScreenDisconnected(DisplayId displayId)
10256 {
10257 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "displayId: %{public}" PRIu64, displayId);
10258 auto task = [this, displayId, where = __func__]() {
10259 bool isSessionBlackListErased = sessionBlackListInfoMap_.erase(displayId) > 0;
10260 bool isScreenConfigErased = screenRSBlackListConfigMap_.erase(displayId) > 0;
10261 if (isSessionBlackListErased || isScreenConfigErased) {
10262 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: displayId %{public}" PRIu64, where, displayId);
10263 return WMError::WM_OK;
10264 }
10265 return WMError::WM_DO_NOTHING;
10266 };
10267 return taskScheduler_->PostSyncTask(task, __func__);
10268 }
10269
AddSessionBlackList(const std::unordered_set<std::string> & bundleNames,const std::unordered_set<std::string> & privacyWindowTags)10270 WMError SceneSessionManager::AddSessionBlackList(
10271 const std::unordered_set<std::string>& bundleNames, const std::unordered_set<std::string>& privacyWindowTags)
10272 {
10273 if (!SessionPermission::IsSACalling()) {
10274 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
10275 return WMError::WM_ERROR_INVALID_PERMISSION;
10276 }
10277 for (const auto& bundleName : bundleNames) {
10278 bundleRSBlackListConfigMap_.insert({ bundleName, {} });
10279 bundleRSBlackListConfigMap_[bundleName].insert(privacyWindowTags.begin(), privacyWindowTags.end());
10280 }
10281 std::vector<sptr<SceneSession>> sceneSessionList;
10282 {
10283 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10284 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10285 if (sceneSession && bundleNames.find(sceneSession->GetSessionInfo().bundleName_) != bundleNames.end()) {
10286 sceneSessionList.emplace_back(sceneSession);
10287 }
10288 }
10289 }
10290 return AddSessionBlackList(sceneSessionList, privacyWindowTags);
10291 }
10292
AddSessionBlackList(const std::vector<sptr<SceneSession>> & sceneSessionList,const std::unordered_set<std::string> & privacyWindowTags)10293 WMError SceneSessionManager::AddSessionBlackList(const std::vector<sptr<SceneSession>>& sceneSessionList,
10294 const std::unordered_set<std::string>& privacyWindowTags)
10295 {
10296 for (const auto& sceneSession : sceneSessionList) {
10297 for (const auto& privacyWindowTag : privacyWindowTags) {
10298 sessionRSBlackListConfigSet_.insert(
10299 { .windowId = sceneSession->GetPersistentId(), .privacyWindowTag = privacyWindowTag });
10300 }
10301 }
10302 return FlushSessionBlackListInfoMapWhenAdd();
10303 }
10304
RemoveSessionBlackList(const std::unordered_set<std::string> & bundleNames,const std::unordered_set<std::string> & privacyWindowTags)10305 WMError SceneSessionManager::RemoveSessionBlackList(
10306 const std::unordered_set<std::string>& bundleNames, const std::unordered_set<std::string>& privacyWindowTags)
10307 {
10308 if (!SessionPermission::IsSACalling()) {
10309 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
10310 return WMError::WM_ERROR_INVALID_PERMISSION;
10311 }
10312 for (const auto& bundleName : bundleNames) {
10313 bundleRSBlackListConfigMap_.insert({ bundleName, {} });
10314 for(const auto& privacyWindowTag : privacyWindowTags) {
10315 bundleRSBlackListConfigMap_[bundleName].erase(privacyWindowTag);
10316 }
10317 if (bundleRSBlackListConfigMap_[bundleName].empty()) {
10318 bundleRSBlackListConfigMap_.erase(bundleName);
10319 }
10320 }
10321 std::vector<sptr<SceneSession>> sceneSessionList;
10322 {
10323 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10324 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10325 if (sceneSession && bundleNames.find(sceneSession->GetSessionInfo().bundleName_) != bundleNames.end()) {
10326 sceneSessionList.emplace_back(sceneSession);
10327 }
10328 }
10329 }
10330 return RemoveSessionBlackList(sceneSessionList, privacyWindowTags);
10331 }
10332
RemoveSessionBlackList(const std::vector<sptr<SceneSession>> & sceneSessionList,const std::unordered_set<std::string> & privacyWindowTags)10333 WMError SceneSessionManager::RemoveSessionBlackList(const std::vector<sptr<SceneSession>>& sceneSessionList,
10334 const std::unordered_set<std::string>& privacyWindowTags)
10335 {
10336 for (const auto& sceneSession : sceneSessionList) {
10337 for (const auto& privacyWindowTag : privacyWindowTags) {
10338 sessionRSBlackListConfigSet_.erase(
10339 { .windowId = sceneSession->GetPersistentId(), .privacyWindowTag = privacyWindowTag });
10340 }
10341 }
10342 return FlushSessionBlackListInfoMapWhenRemove();
10343 }
10344
FlushSessionBlackListInfoMapWhenAdd()10345 WMError SceneSessionManager::FlushSessionBlackListInfoMapWhenAdd()
10346 {
10347 for (const auto& [screenId, screenBlackListInfo] : screenRSBlackListConfigMap_) {
10348 for (const auto& info : sessionRSBlackListConfigSet_) {
10349 if (screenBlackListInfo.find({ .privacyWindowTag = info.privacyWindowTag }) != screenBlackListInfo.end()) {
10350 sessionBlackListInfoMap_[screenId].insert(info);
10351 }
10352 }
10353 UpdateVirtualScreenBlackList(screenId);
10354 }
10355 return WMError::WM_OK;
10356 }
10357
FlushSessionBlackListInfoMapWhenAdd(ScreenId screenId)10358 WMError SceneSessionManager::FlushSessionBlackListInfoMapWhenAdd(ScreenId screenId)
10359 {
10360 auto screenBlackListInfo = screenRSBlackListConfigMap_[screenId];
10361 for (const auto& info : sessionRSBlackListConfigSet_) {
10362 if (screenBlackListInfo.find({ .privacyWindowTag = info.privacyWindowTag }) != screenBlackListInfo.end()) {
10363 sessionBlackListInfoMap_[screenId].insert(info);
10364 }
10365 }
10366 UpdateVirtualScreenBlackList(screenId);
10367 return WMError::WM_OK;
10368 }
10369
FlushSessionBlackListInfoMapWhenRemove()10370 WMError SceneSessionManager::FlushSessionBlackListInfoMapWhenRemove()
10371 {
10372 for (auto& [screenId, infoSet] : sessionBlackListInfoMap_) {
10373 for (auto it = infoSet.begin(); it != infoSet.end(); ) {
10374 const auto& info = *it;
10375 if (info.privacyWindowTag == WMS_DEFAULT) {
10376 ++it;
10377 continue;
10378 }
10379 bool notInScreenConfigMap = screenRSBlackListConfigMap_[screenId].find(
10380 { .privacyWindowTag = info.privacyWindowTag }) == screenRSBlackListConfigMap_[screenId].end();
10381 bool notInSessionConfigSet = sessionRSBlackListConfigSet_.find(info) == sessionRSBlackListConfigSet_.end();
10382 if (notInScreenConfigMap || notInSessionConfigSet) {
10383 it = infoSet.erase(it);
10384 } else {
10385 ++it;
10386 }
10387 }
10388 UpdateVirtualScreenBlackList(screenId);
10389 }
10390 return WMError::WM_OK;
10391 }
10392
FlushSessionBlackListInfoMapWhenRemove(ScreenId screenId)10393 WMError SceneSessionManager::FlushSessionBlackListInfoMapWhenRemove(ScreenId screenId)
10394 {
10395 if (sessionBlackListInfoMap_.find(screenId) == sessionBlackListInfoMap_.end()) {
10396 std::vector<uint64_t> emptyList;
10397 rsInterface_.SetVirtualScreenBlackList(screenId, emptyList);
10398 return WMError::WM_OK;
10399 }
10400 auto& infoSet = sessionBlackListInfoMap_[screenId];
10401 for (auto it = infoSet.begin(); it != infoSet.end(); ) {
10402 const auto& info = *it;
10403 if (info.privacyWindowTag == WMS_DEFAULT) {
10404 ++it;
10405 continue;
10406 }
10407 bool notInScreenConfigMap = screenRSBlackListConfigMap_[screenId].find(
10408 { .privacyWindowTag = info.privacyWindowTag }) == screenRSBlackListConfigMap_[screenId].end();
10409 bool notInSessionConfigSet = sessionRSBlackListConfigSet_.find(info) == sessionRSBlackListConfigSet_.end();
10410 if (notInScreenConfigMap || notInSessionConfigSet) {
10411 it = infoSet.erase(it);
10412 } else {
10413 ++it;
10414 }
10415 }
10416 UpdateVirtualScreenBlackList(screenId);
10417 return WMError::WM_OK;
10418 }
10419
UpdateVirtualScreenBlackList(ScreenId screenId)10420 void SceneSessionManager::UpdateVirtualScreenBlackList(ScreenId screenId)
10421 {
10422 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Configsize: [%{public}zu, %{public}zu], %{public}zu",
10423 sessionRSBlackListConfigSet_.size(), screenRSBlackListConfigMap_.size(), sessionBlackListInfoMap_.size());
10424 std::unordered_set<uint64_t> skipSurfaceNodeIdSet;
10425 for (const auto& info : sessionBlackListInfoMap_[screenId]) {
10426 AddskipSurfaceNodeIdSet(info.windowId, skipSurfaceNodeIdSet);
10427 }
10428 std::vector<uint64_t> skipSurfaceNodeIds(skipSurfaceNodeIdSet.begin(), skipSurfaceNodeIdSet.end());
10429 std::ostringstream oss;
10430 oss << "surfaceNodeIds[" << screenId << "]: ";
10431 for (auto id : skipSurfaceNodeIds) {
10432 oss << id << " ";
10433 }
10434 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "%{public}s", oss.str().c_str());
10435 rsInterface_.SetVirtualScreenBlackList(screenId, skipSurfaceNodeIds);
10436 }
10437
NotifyOnAttachToFrameNode(const sptr<Session> & session)10438 void SceneSessionManager::NotifyOnAttachToFrameNode(const sptr<Session>& session)
10439 {
10440 auto where = __func__;
10441 wptr<Session> weakSession(session);
10442 auto task = [this, weakSession, where] {
10443 auto session = weakSession.promote();
10444 if (session == nullptr) {
10445 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s, session is nullptr", where);
10446 return;
10447 }
10448 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s, wid: %{public}d", where, session->GetPersistentId());
10449 if (WindowHelper::IsMainWindow(session->GetWindowType())) {
10450 AddSkipSurfaceNodeWhenAttach(session->GetPersistentId(),
10451 session->GetSessionInfo().bundleName_, static_cast<uint64_t>(session->GetPersistentId()));
10452 } else {
10453 auto surfaceNode = session->GetSurfaceNode();
10454 if (surfaceNode == nullptr) {
10455 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s, surfaceNode is nullptr", where);
10456 return;
10457 }
10458 AddSkipSurfaceNodeWhenAttach(session->GetPersistentId(),
10459 session->GetSessionInfo().bundleName_, surfaceNode->GetId());
10460 }
10461 };
10462 taskScheduler_->PostAsyncTask(task, where);
10463 }
10464
AddSkipSurfaceNodeWhenAttach(int32_t windowId,const std::string & bundleName,uint64_t surfaceNodeId)10465 void SceneSessionManager::AddSkipSurfaceNodeWhenAttach(
10466 int32_t windowId, const std::string& bundleName, uint64_t surfaceNodeId)
10467 {
10468 if (bundleRSBlackListConfigMap_.find(bundleName) != bundleRSBlackListConfigMap_.end()) {
10469 for (const auto& tag : bundleRSBlackListConfigMap_[bundleName]) {
10470 sessionRSBlackListConfigSet_.insert({ .windowId = windowId, .privacyWindowTag = tag });
10471 for (const auto& [screenId, infoSet] : screenRSBlackListConfigMap_) {
10472 if (infoSet.find({ .privacyWindowTag = tag }) != infoSet.end()) {
10473 sessionBlackListInfoMap_[screenId].insert({ .windowId = windowId, .privacyWindowTag = tag });
10474 std::vector<uint64_t> skipSurfaceNodeIds = { surfaceNodeId };
10475 rsInterface_.AddVirtualScreenBlackList(screenId, skipSurfaceNodeIds);
10476 }
10477 }
10478 }
10479 }
10480 }
10481
AddskipSurfaceNodeIdSet(int32_t windowId,std::unordered_set<uint64_t> & skipSurfaceNodeIdSet)10482 void SceneSessionManager::AddskipSurfaceNodeIdSet(int32_t windowId, std::unordered_set<uint64_t>& skipSurfaceNodeIdSet)
10483 {
10484 auto sceneSession = GetSceneSession(windowId);
10485 if (sceneSession == nullptr) {
10486 return;
10487 }
10488 if (SessionHelper::IsMainWindow(static_cast<WindowType>(sceneSession->GetWindowType()))) {
10489 auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
10490 if (leashWinSurfaceNode != nullptr) {
10491 skipSurfaceNodeIdSet.insert(static_cast<uint64_t>(sceneSession->GetPersistentId()));
10492 }
10493 }
10494 auto surfaceNode = sceneSession->GetSurfaceNode();
10495 if (surfaceNode != nullptr) {
10496 skipSurfaceNodeIdSet.insert(surfaceNode->GetId());
10497 }
10498 }
10499
UpdateSubSessionBlackList(const sptr<SceneSession> & sceneSession)10500 WMError SceneSessionManager::UpdateSubSessionBlackList(const sptr<SceneSession>& sceneSession)
10501 {
10502 WMError ret = WMError::WM_DO_NOTHING;
10503 auto parentSession = sceneSession->GetParentSession();
10504 if (parentSession == nullptr) {
10505 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "win: %{public}d parent session is null", sceneSession->GetPersistentId());
10506 return ret;
10507 }
10508 SessionBlackListInfo parentSessionBlackListInfo = { .windowId = parentSession->GetPersistentId() };
10509 ScreenId rsScreenId = SCREEN_ID_INVALID;
10510 for (auto& [displayId, sessionBlackListInfoSet] : sessionBlackListInfoMap_) {
10511 if (sessionBlackListInfoSet.count(parentSessionBlackListInfo) > 0) {
10512 sessionBlackListInfoSet.insert({ .windowId = sceneSession->GetPersistentId() });
10513 rsScreenId = displayId;
10514 ret = WMError::WM_OK;
10515 }
10516 }
10517 if (ret != WMError::WM_OK) {
10518 return ret;
10519 }
10520 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "rsScreenId: %{public}" PRIu64 " win: %{public}d parentId: %{public}d",
10521 rsScreenId, sceneSession->GetPersistentId(), parentSession->GetPersistentId());
10522 SessionBlackListInfoSet funcSet = sessionBlackListInfoMap_[rsScreenId];
10523 std::vector<uint64_t> surfaceNodeIds;
10524 for (const auto& sessionBlackListInfo : funcSet) {
10525 sptr<SceneSession> session = GetSceneSession(sessionBlackListInfo.windowId);
10526 if (session == nullptr) {
10527 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "session %{public}d is null", sessionBlackListInfo.windowId);
10528 continue;
10529 }
10530 if (session->GetSurfaceNode() == nullptr) {
10531 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode %{public}d is null", sessionBlackListInfo.windowId);
10532 continue;
10533 }
10534 surfaceNodeIds.push_back(session->GetSurfaceNode()->GetId());
10535 if (session->GetLeashWinSurfaceNode()) {
10536 surfaceNodeIds.push_back(static_cast<uint64_t>(session->GetPersistentId()));
10537 }
10538 }
10539 std::ostringstream oss;
10540 oss << "surfaceNodeIds[" << rsScreenId << "]: ";
10541 for (auto id : surfaceNodeIds) {
10542 oss << id << " ";
10543 }
10544 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s", oss.str().c_str());
10545 rsInterface_.SetVirtualScreenBlackList(rsScreenId, surfaceNodeIds);
10546 return ret;
10547 }
10548
RemoveSessionFromBlackList(const sptr<SceneSession> & sceneSession)10549 WMError SceneSessionManager::RemoveSessionFromBlackList(const sptr<SceneSession>& sceneSession)
10550 {
10551 WMError ret = WMError::WM_DO_NOTHING;
10552 if (sceneSession == nullptr) {
10553 return ret;
10554 }
10555 RemoveSessionFromBlackListInfoSet(sceneSession, sessionRSBlackListConfigSet_);
10556 for (auto it = sessionBlackListInfoMap_.begin(); it != sessionBlackListInfoMap_.end();) {
10557 auto& sessionBlackListInfoSet = it->second;
10558 RemoveSessionFromBlackListInfoSet(sceneSession, sessionBlackListInfoSet);
10559 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, displayId: %{public}" PRIu64,
10560 sceneSession->GetPersistentId(), it->first);
10561 ret = WMError::WM_OK;
10562 if (sessionBlackListInfoSet.empty()) {
10563 it = sessionBlackListInfoMap_.erase(it);
10564 } else {
10565 ++it;
10566 }
10567 }
10568 return ret;
10569 }
10570
RemoveSessionFromBlackListInfoSet(const sptr<SceneSession> & sceneSession,SessionBlackListInfoSet & sessionBlackListInfoSet)10571 void SceneSessionManager::RemoveSessionFromBlackListInfoSet(
10572 const sptr<SceneSession>& sceneSession, SessionBlackListInfoSet& sessionBlackListInfoSet)
10573 {
10574 for (auto it = sessionBlackListInfoSet.begin(); it != sessionBlackListInfoSet.end();) {
10575 if (it->windowId == sceneSession->GetPersistentId()) {
10576 it = sessionBlackListInfoSet.erase(it);
10577 } else {
10578 ++it;
10579 }
10580 }
10581 }
10582
RecoverWindowPropertyChangeFlag(uint32_t observedFlags,uint32_t interestedFlags)10583 WMError SceneSessionManager::RecoverWindowPropertyChangeFlag(uint32_t observedFlags, uint32_t interestedFlags)
10584 {
10585 observedFlags_ |= observedFlags;
10586 interestedFlags_ |= interestedFlags;
10587 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "observedFlags: %{public}u, interestedFlags: %{public}u",
10588 observedFlags_, interestedFlags_);
10589 return WMError::WM_OK;
10590 }
10591
RegisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey,uint32_t interestInfo,const sptr<IWindowManagerAgent> & windowManagerAgent)10592 WMError SceneSessionManager::RegisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey,
10593 uint32_t interestInfo, const sptr<IWindowManagerAgent>& windowManagerAgent)
10594 {
10595 observedFlags_ |= static_cast<uint32_t>(windowInfoKey);
10596 interestedFlags_ |= interestInfo;
10597 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "observedFlags: %{public}u, interestedFlags: %{public}u",
10598 observedFlags_, interestedFlags_);
10599 return RegisterWindowManagerAgent(
10600 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_PROPERTY, windowManagerAgent);
10601 }
10602
UnregisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey,uint32_t interestInfo,const sptr<IWindowManagerAgent> & windowManagerAgent)10603 WMError SceneSessionManager::UnregisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey,
10604 uint32_t interestInfo, const sptr<IWindowManagerAgent>& windowManagerAgent)
10605 {
10606 observedFlags_ &= ~(static_cast<uint32_t>(windowInfoKey));
10607 interestedFlags_ &= ~interestInfo;
10608 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "observedFlags: %{public}u, interestedFlags: %{public}u",
10609 observedFlags_, interestedFlags_);
10610 return UnregisterWindowManagerAgent(
10611 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_PROPERTY, windowManagerAgent);
10612 }
10613
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)10614 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
10615 const sptr<IWindowManagerAgent>& windowManagerAgent)
10616 {
10617 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
10618 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
10619 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
10620 if (!SessionPermission::IsSystemCalling()) {
10621 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
10622 return WMError::WM_ERROR_NOT_SYSTEM_APP;
10623 }
10624 } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
10625 if (!SessionPermission::IsSystemServiceCalling()) {
10626 return WMError::WM_ERROR_INVALID_PERMISSION;
10627 }
10628 }
10629 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
10630 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
10631 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
10632 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
10633 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE ||
10634 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY ||
10635 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_PROPERTY) {
10636 if (!SessionPermission::IsSACalling()) {
10637 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
10638 return WMError::WM_ERROR_INVALID_PERMISSION;
10639 }
10640 }
10641 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
10642 TLOGE(WmsLogTag::DEFAULT, "windowManagerAgent is null");
10643 return WMError::WM_ERROR_NULLPTR;
10644 }
10645 const auto callingPid = IPCSkeleton::GetCallingRealPid();
10646 auto task = [this, windowManagerAgent, type, callingPid]() {
10647 return SessionManagerAgentController::GetInstance()
10648 .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
10649 };
10650 return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
10651 }
10652
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)10653 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
10654 const sptr<IWindowManagerAgent>& windowManagerAgent)
10655 {
10656 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
10657 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
10658 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
10659 if (!SessionPermission::IsSystemCalling()) {
10660 TLOGE(WmsLogTag::DEFAULT, "IsSystemCalling permission denied!");
10661 return WMError::WM_ERROR_NOT_SYSTEM_APP;
10662 }
10663 }
10664 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
10665 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
10666 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
10667 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
10668 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE ||
10669 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_PROPERTY) {
10670 if (!SessionPermission::IsSACalling()) {
10671 TLOGE(WmsLogTag::WMS_LIFE, "IsSACalling permission denied!");
10672 return WMError::WM_ERROR_INVALID_PERMISSION;
10673 }
10674 }
10675 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
10676 TLOGE(WmsLogTag::DEFAULT, "windowManagerAgent is null");
10677 return WMError::WM_ERROR_NULLPTR;
10678 }
10679 const auto callingPid = IPCSkeleton::GetCallingRealPid();
10680 auto task = [this, windowManagerAgent, type, callingPid]() {
10681 return SessionManagerAgentController::GetInstance()
10682 .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
10683 };
10684 return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
10685 }
10686
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)10687 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
10688 {
10689 SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
10690 }
10691
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)10692 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
10693 {
10694 SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
10695 }
10696
StartWindowInfoReportLoop()10697 void SceneSessionManager::StartWindowInfoReportLoop()
10698 {
10699 TLOGD(WmsLogTag::WMS_STARTUP_PAGE, "in");
10700 if (isReportTaskStart_) {
10701 TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "Report is ReportTask Start");
10702 return;
10703 }
10704 auto task = [this] {
10705 WindowInfoReporter::GetInstance().ReportRecordedInfos();
10706 ReportWindowProfileInfos();
10707 isReportTaskStart_ = false;
10708 StartWindowInfoReportLoop();
10709 };
10710 int64_t delayTime = 1000 * 60 * 60; // an hour.
10711 bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
10712 if (!ret) {
10713 TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "failed. task is WindowInfoReport");
10714 return;
10715 }
10716 isReportTaskStart_ = true;
10717 }
10718
InitPersistentStorage()10719 void SceneSessionManager::InitPersistentStorage()
10720 {
10721 if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
10722 int32_t storageMode = -1;
10723 ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
10724 if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
10725 storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
10726 TLOGI(WmsLogTag::DEFAULT, "init MaximizeMode as %{public}d from persistent storage", storageMode);
10727 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
10728 }
10729 }
10730 }
10731
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)10732 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
10733 {
10734 TLOGD(WmsLogTag::DEFAULT, "in.");
10735 if (!SessionPermission::IsSystemServiceCalling()) {
10736 TLOGE(WmsLogTag::DEFAULT, "Only support for system service.");
10737 return WMError::WM_ERROR_NOT_SYSTEM_APP;
10738 }
10739 auto task = [this, &infos]() {
10740 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetAccessibilityWindowInfo");
10741 std::map<int32_t, sptr<SceneSession>>::iterator iter;
10742 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10743 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
10744 sptr<SceneSession> sceneSession = iter->second;
10745 if (sceneSession == nullptr) {
10746 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "null scene session");
10747 continue;
10748 }
10749 bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
10750 sceneSession->IsVisibleForAccessibility() :
10751 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
10752 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, "
10753 "winType=%{public}d, state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
10754 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
10755 sceneSession->GetSessionState(), isVisibleForAccessibility);
10756 if (isVisibleForAccessibility) {
10757 FillWindowInfo(infos, iter->second);
10758 }
10759 }
10760 return WMError::WM_OK;
10761 };
10762 return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
10763 }
10764
CheckUnreliableWindowType(WindowType windowType)10765 static bool CheckUnreliableWindowType(WindowType windowType)
10766 {
10767 if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
10768 windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
10769 windowType == WindowType::WINDOW_TYPE_TOAST) {
10770 return true;
10771 }
10772 TLOGD(WmsLogTag::DEFAULT, "false, WindowType=%{public}d", windowType);
10773 return false;
10774 }
10775
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)10776 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
10777 std::vector<sptr<UnreliableWindowInfo>>& infos)
10778 {
10779 if (sceneSession == nullptr) {
10780 TLOGW(WmsLogTag::DEFAULT, "null scene session.");
10781 return;
10782 }
10783 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10784 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10785 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10786 TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
10787 return;
10788 }
10789 sptr<UnreliableWindowInfo> info = sptr<UnreliableWindowInfo>::MakeSptr();
10790 info->windowId_ = sceneSession->GetPersistentId();
10791 WSRect windowRect = sceneSession->GetSessionRect();
10792 info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
10793 info->zOrder_ = sceneSession->GetZOrder();
10794 info->floatingScale_ = sceneSession->GetFloatingScale();
10795 info->scaleX_ = sceneSession->GetScaleX();
10796 info->scaleY_ = sceneSession->GetScaleY();
10797 infos.emplace_back(info);
10798 TLOGD(WmsLogTag::WMS_MAIN, "wid=%{public}d", info->windowId_);
10799 }
10800
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)10801 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
10802 std::vector<sptr<UnreliableWindowInfo>>& infos)
10803 {
10804 TLOGD(WmsLogTag::DEFAULT, "in.");
10805 if (!SessionPermission::IsSystemServiceCalling()) {
10806 TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
10807 return WMError::WM_ERROR_NOT_SYSTEM_APP;
10808 }
10809 auto task = [this, windowId, &infos]() {
10810 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10811 for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
10812 if (sceneSession == nullptr) {
10813 TLOGNW(WmsLogTag::DEFAULT, "null scene session");
10814 continue;
10815 }
10816 if (sessionId == windowId) {
10817 TLOGNI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
10818 FillUnreliableWindowInfo(sceneSession, infos);
10819 continue;
10820 }
10821 if (sceneSession->GetSystemTouchable() && sceneSession->GetForegroundInteractiveStatus()) {
10822 TLOGND(WmsLogTag::DEFAULT, "persistentId: %{public}d is system touchable", sessionId);
10823 continue;
10824 }
10825 if (!sceneSession->GetRSVisible()) {
10826 TLOGND(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
10827 continue;
10828 }
10829 TLOGND(WmsLogTag::DEFAULT, "name=%{public}s, isSystem=%{public}d, "
10830 "persistentId=%{public}d, winType=%{public}d, state=%{public}d, visible=%{public}d",
10831 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
10832 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
10833 if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
10834 TLOGI(WmsLogTag::DEFAULT, "persistentId=%{public}d, "
10835 "WindowType=%{public}d", sessionId, sceneSession->GetWindowType());
10836 FillUnreliableWindowInfo(sceneSession, infos);
10837 }
10838 }
10839 return WMError::WM_OK;
10840 };
10841 return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
10842 }
10843
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)10844 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
10845 {
10846 TLOGD(WmsLogTag::DEFAULT, "persistentId=%{public}d, updateType=%{public}d", persistentId, type);
10847 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
10848 if (sceneSession == nullptr) {
10849 TLOGD(WmsLogTag::DEFAULT, "sceneSession nullptr!");
10850 return;
10851 }
10852 wptr<SceneSession> weakSceneSession(sceneSession);
10853 if (processingFlushUIParams_.load()) {
10854 TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
10855 auto task = [this, weakSceneSession, type]() {
10856 auto sceneSession = weakSceneSession.promote();
10857 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
10858 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10859 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
10860 }
10861 };
10862 taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
10863 return;
10864 }
10865 auto task = [this, weakSceneSession, type]() {
10866 auto sceneSession = weakSceneSession.promote();
10867 NotifyAllAccessibilityInfo();
10868 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
10869 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10870 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
10871 }
10872 };
10873 taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:PID:" + std::to_string(persistentId));
10874 auto notifySceneInputTask = [weakSceneSession, type]() {
10875 auto sceneSession = weakSceneSession.promote();
10876 if (sceneSession == nullptr) {
10877 return;
10878 }
10879 SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
10880 };
10881 taskScheduler_->PostAsyncTask(notifySceneInputTask, "notifySceneInputTask");
10882 }
10883
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)10884 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
10885 const sptr<SceneSession>& sceneSession)
10886 {
10887 if (sceneSession == nullptr) {
10888 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "null scene session.");
10889 return false;
10890 }
10891 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10892 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10893 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10894 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "filter gesture window.");
10895 return false;
10896 }
10897 if (sceneSession->GetSessionInfo().bundleName_.find("SCBDragScale") != std::string::npos) {
10898 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "filter DragScale window.");
10899 return false;
10900 }
10901 if (sceneSession->GetHidingStartingWindow()) {
10902 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "filter hiding starting win: %{public}d", sceneSession->GetPersistentId());
10903 return false;
10904 }
10905 sptr<AccessibilityWindowInfo> info = sptr<AccessibilityWindowInfo>::MakeSptr();
10906 if (sceneSession->GetSessionInfo().isSystem_) {
10907 info->wid_ = 1;
10908 info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
10909 } else {
10910 info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
10911 }
10912 info->uiNodeId_ = sceneSession->GetUINodeId();
10913 info->type_ = sceneSession->GetWindowType();
10914 info->mode_ = sceneSession->GetWindowMode();
10915 info->layer_ = sceneSession->GetZOrder();
10916 info->scaleVal_ = sceneSession->GetFloatingScale();
10917 info->scaleX_ = sceneSession->GetScaleX();
10918 info->scaleY_ = sceneSession->GetScaleY();
10919 info->isCompatScaleMode_ = sceneSession->IsInCompatScaleMode();
10920 info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
10921 info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
10922 info->isDecorEnable_ = sceneSession->GetSessionProperty()->IsDecorEnable();
10923 WSRect wsRect = sceneSession->GetSessionGlobalRectWithSingleHandScale(); // only accessability and mmi need global
10924 DisplayId displayId = sceneSession->GetSessionProperty()->GetDisplayId();
10925 if (!sceneSession->GetSessionInfo().isSystem_ &&
10926 PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(displayId) &&
10927 !sceneSession->GetSessionProperty()->IsSystemKeyboard()) {
10928 displayId = sceneSession->TransformGlobalRectToRelativeRect(wsRect);
10929 }
10930 info->displayId_ = displayId;
10931 info->focused_ = sceneSession->GetPersistentId() == GetFocusedSessionId(displayId);
10932 info->windowRect_ = { wsRect.posX_, wsRect.posY_, wsRect.width_, wsRect.height_ };
10933 infos.emplace_back(info);
10934 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, innerWid: %{public}d, nodeId: %{public}d"
10935 ", bundleName: %{public}s, displayId: %{public}" PRIu64 ", rect: %{public}s",
10936 info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str(),
10937 info->displayId_, info->windowRect_.ToString().c_str());
10938 return true;
10939 }
10940
SelectSesssionFromMap(const uint64_t & surfaceId)10941 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
10942 {
10943 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10944 for (const auto& [_, sceneSession] : sceneSessionMap_) {
10945 if (sceneSession == nullptr) {
10946 continue;
10947 }
10948 if (sceneSession->GetSurfaceNode() == nullptr) {
10949 continue;
10950 }
10951 if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
10952 return sceneSession;
10953 }
10954 }
10955 return nullptr;
10956 }
10957
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)10958 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
10959 {
10960 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "in");
10961 auto task = [this, weak = std::weak_ptr<RSOcclusionData>(occlusiontionData)]() {
10962 auto weakOcclusionData = weak.lock();
10963 if (weakOcclusionData == nullptr) {
10964 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "weak occlusionData is nullptr");
10965 return;
10966 }
10967 std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
10968 std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
10969 GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
10970 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
10971 if (currVisibleData.size() != 0) {
10972 visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
10973 }
10974 if (visibilityChangeInfos.size() != 0) {
10975 DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
10976 CacVisibleWindowNum();
10977 }
10978
10979 std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
10980 if (currDrawingContentData.size() != 0) {
10981 drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
10982 }
10983 if (drawingContentChangeInfos.size() != 0) {
10984 DealwithDrawingContentChange(drawingContentChangeInfos);
10985 }
10986 };
10987 taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
10988 }
10989
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)10990 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
10991 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
10992 std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
10993 {
10994 VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
10995 for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
10996 WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
10997 auto visibilityState = static_cast<WindowVisibilityState>(iter->second);
10998 sptr<SceneSession> session = SelectSesssionFromMap(iter->first);
10999 switch (windowLayerState) {
11000 case WINDOW_ALL_VISIBLE:
11001 case WINDOW_SEMI_VISIBLE:
11002 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
11003 break;
11004 case WINDOW_IN_VISIBLE:
11005 if (session != nullptr && session->GetHidingStartingWindow()) {
11006 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "change to visible: %{public}d", session->GetPersistentId());
11007 visibilityState = WINDOW_VISIBILITY_STATE_NO_OCCLUSION;
11008 }
11009 currVisibleData.emplace_back(iter->first, visibilityState);
11010 break;
11011 case WINDOW_LAYER_DRAWING:
11012 currDrawingContentData.emplace_back(iter->first, true);
11013 break;
11014 case WINDOW_LAYER_NO_DRAWING:
11015 currDrawingContentData.emplace_back(iter->first, false);
11016 break;
11017 default:
11018 break;
11019 }
11020 }
11021 }
11022
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)11023 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
11024 WindowVisibilityState visibleState,
11025 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
11026 std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
11027 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
11028 {
11029 if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
11030 visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11031 auto subSessions = GetSubSceneSession(session->GetWindowId());
11032 if (subSessions.empty()) {
11033 return;
11034 }
11035
11036 RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
11037
11038 for (const auto& subSession : subSessions) {
11039 if (subSession == nullptr) {
11040 continue;
11041 }
11042 if (GetSessionRSVisible(subSession, currVisibleData)) {
11043 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Update subwindow visibility for winId: %{public}d",
11044 subSession->GetWindowId());
11045 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
11046 }
11047 }
11048 }
11049 }
11050
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)11051 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
11052 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
11053 {
11054 bool sessionRSVisible = false;
11055 for (const auto& [surfaceId, visibleState] : currVisibleData) {
11056 sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
11057 if (visibilitySession == nullptr) {
11058 continue;
11059 }
11060 if (session->GetWindowId() == visibilitySession->GetWindowId()) {
11061 if (visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11062 sessionRSVisible = true;
11063 }
11064 break;
11065 }
11066 }
11067 return sessionRSVisible;
11068 }
11069
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)11070 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
11071 WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
11072 std::string& visibilityInfo)
11073 {
11074 if (session == nullptr) {
11075 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Session is invalid!");
11076 return;
11077 }
11078 session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
11079 session->SetVisibilityState(visibleState);
11080 int32_t windowId = session->GetWindowId();
11081 if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
11082 session->NotifyWindowVisibility();
11083 }
11084 auto windowVisibilityInfo = sptr<WindowVisibilityInfo>::MakeSptr(
11085 windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType());
11086 windowVisibilityInfo->SetAppIndex(session->GetSessionInfo().appIndex_);
11087 windowVisibilityInfo->SetBundleName(session->GetSessionInfo().bundleName_);
11088 windowVisibilityInfo->SetAbilityName(session->GetSessionInfo().abilityName_);
11089 windowVisibilityInfo->SetIsSystem(session->GetSessionInfo().isSystem_);
11090 windowVisibilityInfo->SetZOrder(session->GetZOrder());
11091
11092 int32_t callingWindowId = session->GetSessionInfo().callerPersistentId_;
11093 sptr<SceneSession> callerSession = GetSceneSession(callingWindowId);
11094 if (callerSession) {
11095 windowVisibilityInfo->SetCallingPid(callerSession->GetCallingPid());
11096 }
11097 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "callingWindowId %{public}d, callingPid %{public}d",
11098 callingWindowId, windowVisibilityInfo->GetCallingPid());
11099
11100 windowVisibilityInfos.emplace_back(windowVisibilityInfo);
11101
11102 visibilityInfo +=
11103 "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
11104 }
11105
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)11106 void SceneSessionManager::RemoveDuplicateSubSession(
11107 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
11108 std::vector<sptr<SceneSession>>& subSessions)
11109 {
11110 for (const auto& elem : visibilityChangeInfo) {
11111 uint64_t surfaceId = elem.first;
11112 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11113 if (session == nullptr) {
11114 continue;
11115 }
11116 for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
11117 auto subSession = *iterator;
11118 if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
11119 iterator = subSessions.erase(iterator);
11120 } else {
11121 ++iterator;
11122 }
11123 }
11124 }
11125 }
11126
GetSubSceneSession(int32_t parentWindowId)11127 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
11128 {
11129 std::vector<sptr<SceneSession>> subSessions;
11130 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11131 for (const auto& iter : sceneSessionMap_) {
11132 auto sceneSession = iter.second;
11133 if (sceneSession == nullptr) {
11134 continue;
11135 }
11136 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11137 continue;
11138 }
11139 const auto& mainOrFloatSession = sceneSession->GetMainOrFloatSession();
11140 if (mainOrFloatSession != nullptr && mainOrFloatSession->GetWindowId() == parentWindowId) {
11141 subSessions.push_back(sceneSession);
11142 }
11143 }
11144 return subSessions;
11145 }
11146
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)11147 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
11148 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
11149 {
11150 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
11151 std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
11152 uint32_t i, j;
11153 i = j = 0;
11154 for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
11155 if (lastVisibleData_[i].first < currVisibleData[j].first) {
11156 if (IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
11157 i++;
11158 continue;
11159 }
11160 if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11161 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
11162 }
11163 i++;
11164 } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
11165 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11166 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
11167 }
11168 j++;
11169 } else {
11170 if (lastVisibleData_[i].second != currVisibleData[j].second &&
11171 !IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
11172 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
11173 }
11174 i++;
11175 j++;
11176 }
11177 }
11178 for (; i < lastVisibleData_.size(); ++i) {
11179 if (IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
11180 continue;
11181 }
11182 if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11183 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
11184 }
11185 }
11186 for (; j < currVisibleData.size(); ++j) {
11187 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11188 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
11189 }
11190 }
11191 lastVisibleData_ = currVisibleData;
11192 return visibilityChangeInfo;
11193 }
11194
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)11195 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
11196 visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
11197 {
11198 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
11199 #ifdef MEMMGR_WINDOW_ENABLE
11200 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
11201 #endif
11202
11203 std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
11204 for (const auto& elem : visibilityChangeInfo) {
11205 uint64_t surfaceId = elem.first;
11206 WindowVisibilityState visibleState = elem.second;
11207 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
11208 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11209 if (session == nullptr) {
11210 continue;
11211 }
11212 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
11213 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
11214 if (session->GetParentSession() != nullptr &&
11215 !session->GetParentSession()->IsSessionForeground() &&
11216 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
11217 continue;
11218 }
11219 }
11220 SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
11221 UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
11222 #ifdef MEMMGR_WINDOW_ENABLE
11223 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
11224 session->GetCallingUid(), isVisible));
11225 #endif
11226 CheckAndNotifyWaterMarkChangedResult();
11227 }
11228 if (windowVisibilityInfos.size() != 0) {
11229 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
11230 visibilityInfo.c_str());
11231 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
11232 }
11233 ProcessWindowModeType();
11234 #ifdef MEMMGR_WINDOW_ENABLE
11235 if (memMgrWindowInfos.size() != 0) {
11236 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "Notify memMgrWindowInfos changed start");
11237 taskScheduler_ ->AddExportTask("notifyMemMgr", [memMgrWindowInfos = std::move(memMgrWindowInfos)]() {
11238 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
11239 });
11240 }
11241 #endif
11242 }
11243
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)11244 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
11245 drawingContentChangeInfo)
11246 {
11247 std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
11248 for (const auto& [surfaceId, drawingState] : drawingContentChangeInfo) {
11249 int32_t windowId = 0;
11250 int32_t pid = 0;
11251 int32_t uid = 0;
11252 WindowType type = WindowType::APP_WINDOW_BASE;
11253 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11254 if (session == nullptr) {
11255 if (!GetSpecifiedDrawingData(surfaceId, pid, uid)) {
11256 continue;
11257 }
11258 RemoveSpecifiedDrawingData(surfaceId);
11259 } else {
11260 windowId = session->GetWindowId();
11261 pid = session->GetCallingPid();
11262 uid = session->GetCallingUid();
11263 type = session->GetWindowType();
11264 }
11265 windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(windowId, pid, uid, drawingState, type));
11266 if (openDebugTrace_) {
11267 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
11268 "drawingState:(%d )", pid, surfaceId, drawingState);
11269 }
11270 TLOGD(WmsLogTag::DEFAULT, "drawing status changed pid:%{public}d, "
11271 "surfaceId:%{public}" PRIu64 ", drawingState:%{public}d", pid, surfaceId, drawingState);
11272 }
11273 if (windowDrawingContenInfos.size() != 0) {
11274 TLOGD(WmsLogTag::DEFAULT, "Notify WindowDrawingContenInfo changed start");
11275 SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
11276 }
11277 }
11278
NotifyAppUseControlList(ControlAppType type,int32_t userId,const std::vector<AppUseControlInfo> & controlList)11279 WSError SceneSessionManager::NotifyAppUseControlList(
11280 ControlAppType type, int32_t userId, const std::vector<AppUseControlInfo>& controlList)
11281 {
11282 TLOGI(WmsLogTag::WMS_LIFE,
11283 "controlApptype: %{public}d userId: %{public}d controlList size: %{public}zu",
11284 static_cast<int>(type), userId, controlList.size());
11285 if (!SessionPermission::IsSACalling()) {
11286 TLOGW(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
11287 return WSError::WS_ERROR_INVALID_PERMISSION;
11288 }
11289 if (type == ControlAppType::APP_LOCK &&
11290 !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WRITE_APP_LOCK)) {
11291 TLOGW(WmsLogTag::WMS_LIFE, "write app lock permission denied");
11292 return WSError::WS_ERROR_INVALID_PERMISSION;
11293 }
11294 if (currentUserId_ != userId) {
11295 if (currentUserId_ != DEFAULT_USERID) {
11296 TLOGW(WmsLogTag::WMS_LIFE, "invalid userId, currentUserId_:%{public}d userId:%{public}d",
11297 currentUserId_.load(), userId);
11298 return WSError::WS_ERROR_INVALID_OPERATION;
11299 }
11300 int32_t userIdByUid = GetUserIdByUid(getuid());
11301 if (userId != userIdByUid) {
11302 TLOGW(WmsLogTag::WMS_LIFE,
11303 "invalid userId, currentUserId_:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
11304 currentUserId_.load(), userId, userIdByUid);
11305 return WSError::WS_ERROR_INVALID_OPERATION;
11306 }
11307 }
11308 taskScheduler_->PostAsyncTask([this, type, userId, controlList] {
11309 if (notifyAppUseControlListFunc_ != nullptr) {
11310 notifyAppUseControlListFunc_(type, userId, controlList);
11311 }
11312
11313 std::vector<sptr<SceneSession>> mainSessions;
11314 for (const auto& appUseControlInfo : controlList) {
11315 RefreshAllAppUseControlMap(appUseControlInfo, type);
11316 GetMainSessionByBundleNameAndAppIndex(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_, mainSessions);
11317 if (mainSessions.empty()) {
11318 continue;
11319 }
11320 ControlInfo controlInfo = {
11321 .isNeedControl = appUseControlInfo.isNeedControl_,
11322 .isControlRecentOnly = appUseControlInfo.isControlRecentOnly_
11323 };
11324 for (const auto& session : mainSessions) {
11325 session->NotifyUpdateAppUseControl(type, controlInfo);
11326 }
11327 mainSessions.clear();
11328 }
11329 }, __func__);
11330 return WSError::WS_OK;
11331 }
11332
RefreshAllAppUseControlMap(const AppUseControlInfo & appUseControlInfo,ControlAppType type)11333 void SceneSessionManager::RefreshAllAppUseControlMap(const AppUseControlInfo& appUseControlInfo, ControlAppType type)
11334 {
11335 ControlInfo controlInfo = {
11336 .isNeedControl = appUseControlInfo.isNeedControl_,
11337 .isControlRecentOnly = appUseControlInfo.isControlRecentOnly_
11338 };
11339 std::string key = SessionUtils::GetAppLockKey(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_);
11340 if (!controlInfo.isNeedControl && !controlInfo.isControlRecentOnly) {
11341 if (allAppUseControlMap_.find(key) != allAppUseControlMap_.end()) {
11342 allAppUseControlMap_[key].erase(type);
11343 if (allAppUseControlMap_[key].empty()){
11344 allAppUseControlMap_.erase(key);
11345 }
11346 }
11347 } else {
11348 allAppUseControlMap_[key][type] = controlInfo;
11349 }
11350 }
11351
RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc && func)11352 void SceneSessionManager::RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc&& func)
11353 {
11354 taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
11355 notifyAppUseControlListFunc_ = std::move(callback);
11356 }, __func__);
11357 }
11358
GetSpecifiedDrawingData(uint64_t surfaceId,int32_t & pid,int32_t & uid)11359 bool SceneSessionManager::GetSpecifiedDrawingData(uint64_t surfaceId, int32_t& pid, int32_t& uid)
11360 {
11361 auto it = lastDrawingSessionInfoMap_.find(surfaceId);
11362 if (it != lastDrawingSessionInfoMap_.end()) {
11363 pid = it->second.pid_;
11364 uid = it->second.uid_;
11365 return true;
11366 }
11367 return false;
11368 }
11369
RemoveSpecifiedDrawingData(uint64_t surfaceId)11370 void SceneSessionManager::RemoveSpecifiedDrawingData(uint64_t surfaceId)
11371 {
11372 auto it = lastDrawingSessionInfoMap_.find(surfaceId);
11373 if (it != lastDrawingSessionInfoMap_.end()) {
11374 lastDrawingSessionInfoMap_.erase(it);
11375 }
11376 }
11377
GetWindowDrawingContentChangeInfo(const std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)11378 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
11379 const std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
11380 {
11381 std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
11382 for (const auto& [surfaceId, isWindowDrawing] : currDrawingContentData) {
11383 int32_t pid = 0;
11384 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11385 bool isDrawingStateChanged =
11386 session == nullptr || (GetPreWindowDrawingState(surfaceId, isWindowDrawing, pid) != isWindowDrawing &&
11387 GetProcessDrawingState(surfaceId, pid));
11388 if (isDrawingStateChanged) {
11389 processDrawingContentChangeInfo.emplace_back(surfaceId, isWindowDrawing);
11390 }
11391 }
11392 return processDrawingContentChangeInfo;
11393 }
11394
GetPreWindowDrawingState(uint64_t surfaceId,bool currentWindowDrawing,int32_t & pid)11395 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t surfaceId, bool currentWindowDrawing, int32_t& pid)
11396 {
11397 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11398 if (session == nullptr) {
11399 return false;
11400 }
11401 pid = session->GetCallingPid();
11402 bool preWindowDrawing = session->GetDrawingContentState();
11403 session->SetDrawingContentState(currentWindowDrawing);
11404 UpdateWindowDrawingData(surfaceId, pid, session->GetCallingUid());
11405 return preWindowDrawing;
11406 }
11407
UpdateWindowDrawingData(uint64_t surfaceId,int32_t pid,int32_t uid)11408 void SceneSessionManager::UpdateWindowDrawingData(uint64_t surfaceId, int32_t pid, int32_t uid)
11409 {
11410 lastDrawingSessionInfoMap_[surfaceId] = { pid, uid };
11411 }
11412
GetProcessDrawingState(uint64_t surfaceId,int32_t pid)11413 bool SceneSessionManager::GetProcessDrawingState(uint64_t surfaceId, int32_t pid)
11414 {
11415 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11416 for (const auto& [_, sceneSession] : sceneSessionMap_) {
11417 if (sceneSession == nullptr) {
11418 continue;
11419 }
11420 if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
11421 surfaceId != sceneSession->GetSurfaceNode()->GetId()) {
11422 if (sceneSession->GetDrawingContentState()) {
11423 return false;
11424 }
11425 }
11426 }
11427 return true;
11428 }
11429
InitWithRenderServiceAdded()11430 void SceneSessionManager::InitWithRenderServiceAdded()
11431 {
11432 auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
11433 this->WindowLayerInfoChangeCallback(occlusiontionData);
11434 };
11435 TLOGI(WmsLogTag::DEFAULT, "RegisterWindowVisibilityChangeCallback");
11436 if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
11437 TLOGE(WmsLogTag::DEFAULT, "RegisterWindowVisibilityChangeCallback failed");
11438 }
11439 }
11440
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType,bool isRegularAnimation)11441 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType, bool isRegularAnimation)
11442 {
11443 if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
11444 TLOGE(WmsLogTag::DEFAULT, "The input scene type is valid, scene type is %{public}d", sceneType);
11445 return WMError::WM_ERROR_INVALID_PARAM;
11446 }
11447
11448 auto task = [this, sceneType, isRegularAnimation]() {
11449 TLOGND(WmsLogTag::WMS_PC, "Set system animated scene %{public}d.", sceneType);
11450 bool ret = rsInterface_.SetSystemAnimatedScenes(
11451 static_cast<SystemAnimatedScenes>(sceneType), isRegularAnimation);
11452 if (!ret) {
11453 TLOGNE(WmsLogTag::WMS_PC, "Set system animated scene failed.");
11454 }
11455 };
11456 taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
11457 return WMError::WM_OK;
11458 }
11459
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)11460 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
11461 {
11462 if (!SessionPermission::IsSystemCalling()) {
11463 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
11464 return WSError::WS_ERROR_NOT_SYSTEM_APP;
11465 }
11466 if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
11467 TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
11468 return WSError::WS_ERROR_INVALID_PERMISSION;
11469 }
11470 TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
11471 visible ? "VISIBLE" : "INVISIBLE", pid, uid);
11472 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
11473 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
11474 visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
11475 WindowType::WINDOW_TYPE_APP_COMPONENT));
11476 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
11477 return WSError::WS_OK;
11478 }
11479
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)11480 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
11481 {
11482 if (sceneSession == nullptr) {
11483 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr!");
11484 return;
11485 }
11486 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "in, wid: %{public}d, RSVisible: %{public}d, WindowMode: %{public}u",
11487 sceneSession->GetWindowId(), sceneSession->GetRSVisible(), sceneSession->GetWindowMode());
11488 if (sceneSession->GetRSVisible() || sceneSession->GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
11489 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
11490 #ifdef MEMMGR_WINDOW_ENABLE
11491 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
11492 #endif
11493 sceneSession->SetRSVisible(false);
11494 sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
11495 sceneSession->ClearExtWindowFlags();
11496 auto windowVisibilityInfo = new WindowVisibilityInfo(sceneSession->GetWindowId(),
11497 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
11498 WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType());
11499 windowVisibilityInfo->SetAppIndex(sceneSession->GetSessionInfo().appIndex_);
11500 windowVisibilityInfo->SetBundleName(sceneSession->GetSessionInfo().bundleName_);
11501 windowVisibilityInfo->SetAbilityName(sceneSession->GetSessionInfo().abilityName_);
11502 windowVisibilityInfo->SetIsSystem(sceneSession->GetSessionInfo().isSystem_);
11503 windowVisibilityInfo->SetZOrder(sceneSession->GetZOrder());
11504 windowVisibilityInfos.emplace_back(windowVisibilityInfo);
11505 #ifdef MEMMGR_WINDOW_ENABLE
11506 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
11507 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
11508 #endif
11509 TLOGD(WmsLogTag::DEFAULT, "covered status changed window:%{public}u, isVisible:%{public}d",
11510 sceneSession->GetWindowId(), sceneSession->GetRSVisible());
11511 CheckAndNotifyWaterMarkChangedResult();
11512 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
11513 #ifdef MEMMGR_WINDOW_ENABLE
11514 TLOGD(WmsLogTag::DEFAULT, "Notify memMgrWindowInfos changed start");
11515 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
11516 #endif
11517 }
11518 }
11519
FindSessionByToken(const sptr<IRemoteObject> & token,WindowType type)11520 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token, WindowType type)
11521 {
11522 if (token == nullptr) {
11523 TLOGW(WmsLogTag::WMS_MAIN, "token is nullptr");
11524 return nullptr;
11525 }
11526 sptr<SceneSession> session = nullptr;
11527 auto cmpFunc = [token, type](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
11528 if (pair.second == nullptr) {
11529 return false;
11530 }
11531 if (pair.second->GetWindowType() == type) {
11532 return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
11533 }
11534 return false;
11535 };
11536 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11537 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
11538 if (iter != sceneSessionMap_.end()) {
11539 session = iter->second;
11540 }
11541 return session;
11542 }
11543
FindSessionByAffinity(const std::string & affinity)11544 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(const std::string& affinity)
11545 {
11546 if (affinity.size() == 0) {
11547 TLOGI(WmsLogTag::DEFAULT, "AbilityInfo affinity is empty");
11548 return nullptr;
11549 }
11550 sptr<SceneSession> session = nullptr;
11551 auto cmpFunc = [this, &affinity](const auto& pair) {
11552 auto sceneSession = pair.second;
11553 if (sceneSession == nullptr || !CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
11554 return false;
11555 }
11556 return sceneSession->GetSessionInfo().sessionAffinity == affinity;
11557 };
11558 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11559 if (auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
11560 iter != sceneSessionMap_.end()) {
11561 session = iter->second;
11562 }
11563 return session;
11564 }
11565
PreloadInLakeApp(const std::string & bundleName)11566 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
11567 {
11568 TLOGD(WmsLogTag::DEFAULT, "name %{public}s", bundleName.c_str());
11569 if (auto collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE)) {
11570 TLOGI(WmsLogTag::DEFAULT, "NotifyPreloadAbility: %{public}s", bundleName.c_str());
11571 collaborator->NotifyPreloadAbility(bundleName);
11572 }
11573 }
11574
PendingSessionToForeground(const sptr<IRemoteObject> & token)11575 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
11576 {
11577 TLOGI(WmsLogTag::WMS_LIFE, "in");
11578 auto pid = IPCSkeleton::GetCallingRealPid();
11579 if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
11580 TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
11581 return WSError::WS_ERROR_INVALID_PERMISSION;
11582 }
11583
11584 return taskScheduler_->PostSyncTask([this, &token]() {
11585 if (auto session = FindSessionByToken(token)) {
11586 return session->PendingSessionToForeground();
11587 }
11588 TLOGNE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
11589 return WSError::WS_ERROR_INVALID_PARAM;
11590 }, __func__);
11591 }
11592
PendingSessionToBackground(const sptr<IRemoteObject> & token,const BackgroundParams & params)11593 WSError SceneSessionManager::PendingSessionToBackground(const sptr<IRemoteObject>& token,
11594 const BackgroundParams& params)
11595 {
11596 TLOGI(WmsLogTag::WMS_LIFE, "in");
11597 if (!SessionPermission::IsSACalling()) {
11598 TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to background!");
11599 return WSError::WS_ERROR_INVALID_PERMISSION;
11600 }
11601 return taskScheduler_->PostSyncTask([this, &token, params] {
11602 sptr<SceneSession> session = nullptr;
11603 if (params.persistentId > INVALID_SESSION_ID) {
11604 TLOGNI(WmsLogTag::WMS_LIFE, "Find scene sesion by persistentId: %{public}d", params.persistentId);
11605 session = GetSceneSession(params.persistentId);
11606 } else if (token != nullptr) {
11607 TLOGNI(WmsLogTag::WMS_LIFE, "Find scene sesion by token");
11608 session = FindSessionByToken(token);
11609 }
11610 if (session == nullptr) {
11611 TLOGNE(WmsLogTag::WMS_LIFE, "fail to find session");
11612 return WSError::WS_ERROR_INVALID_PARAM;
11613 }
11614 return session->PendingSessionToBackground(params);
11615 }, __func__);
11616 }
11617
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)11618 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
11619 bool shouldBackToCaller)
11620 {
11621 return taskScheduler_->PostSyncTask([this, &token, shouldBackToCaller] {
11622 if (auto session = FindSessionByToken(token)) {
11623 return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
11624 }
11625 TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
11626 return WSError::WS_ERROR_INVALID_PARAM;
11627 }, __func__);
11628 }
11629
ClearDisplayStatusBarTemporarilyFlags()11630 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
11631 {
11632 for (auto persistentId : avoidAreaListenerSessionSet_) {
11633 auto sceneSession = GetSceneSession(persistentId);
11634 if (sceneSession == nullptr) {
11635 continue;
11636 }
11637 sceneSession->SetIsDisplayStatusBarTemporarily(false);
11638 }
11639 }
11640
GetFocusSessionToken(sptr<IRemoteObject> & token,DisplayId displayId)11641 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject>& token, DisplayId displayId)
11642 {
11643 if (!SessionPermission::IsSACalling()) {
11644 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
11645 return WSError::WS_ERROR_INVALID_PERMISSION;
11646 }
11647 return taskScheduler_->PostSyncTask([this, &token, where = __func__, displayId]() {
11648 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
11649 if (focusGroup == nullptr) {
11650 TLOGNE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
11651 return WSError::WS_ERROR_INVALID_SESSION;
11652 }
11653 TLOGND(WmsLogTag::WMS_FOCUS, "%{public}s with focusedSessionId: %{public}d",
11654 where, focusGroup->GetFocusedSessionId());
11655 if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
11656 token = sceneSession->GetAbilityToken();
11657 if (token == nullptr) {
11658 TLOGNE(WmsLogTag::WMS_FOCUS, "token is nullptr");
11659 return WSError::WS_ERROR_INVALID_PARAM;
11660 }
11661 return WSError::WS_OK;
11662 }
11663 return WSError::WS_ERROR_INVALID_SESSION;
11664 }, __func__);
11665 }
11666
GetFocusSessionElement(AppExecFwk::ElementName & element,DisplayId displayId)11667 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element, DisplayId displayId)
11668 {
11669 auto pid = IPCSkeleton::GetCallingRealPid();
11670 AppExecFwk::RunningProcessInfo info;
11671 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
11672 if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
11673 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
11674 return WSError::WS_ERROR_INVALID_PERMISSION;
11675 }
11676 return taskScheduler_->PostSyncTask([this, &element, where = __func__, displayId]() {
11677 auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
11678 if (focusGroup == nullptr) {
11679 TLOGNE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
11680 return WSError::WS_ERROR_INVALID_SESSION;
11681 }
11682 TLOGND(WmsLogTag::WMS_FOCUS, "%{public}s with focusedSessionId: %{public}d",
11683 where, focusGroup->GetFocusedSessionId());
11684 if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
11685 const auto& sessionInfo = sceneSession->GetSessionInfo();
11686 element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
11687 sessionInfo.abilityName_, sessionInfo.moduleName_);
11688 return WSError::WS_OK;
11689 }
11690 return WSError::WS_ERROR_INVALID_SESSION;
11691 }, __func__);
11692 }
11693
IsFocusWindowParent(const sptr<IRemoteObject> & token,bool & isParent)11694 WSError SceneSessionManager::IsFocusWindowParent(const sptr<IRemoteObject>& token, bool& isParent)
11695 {
11696 if (!SessionPermission::IsSACalling()) {
11697 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
11698 return WSError::WS_ERROR_INVALID_PERMISSION;
11699 }
11700 return taskScheduler_->PostSyncTask([this, &token, &isParent, where = __func__]() {
11701 std::vector<std::pair<DisplayId, int32_t>> allFocusedSessionList =
11702 windowFocusController_->GetAllFocusedSessionList();
11703 if (allFocusedSessionList.size() == 0) {
11704 TLOGNE(WmsLogTag::WMS_FOCUS, "%{public}s has no focus group", where);
11705 return WSError::WS_ERROR_INVALID_SESSION;
11706 }
11707 for (const auto& focusState : allFocusedSessionList) {
11708 auto focusedSession = GetSceneSession(focusState.second);
11709 if (focusedSession == nullptr) {
11710 TLOGNE(WmsLogTag::WMS_FOCUS, "%{public}s session is nullptr: %{public}d", where, focusState.second);
11711 return WSError::WS_ERROR_INVALID_SESSION;
11712 }
11713 if (focusedSession->GetAbilityToken() == token || focusedSession->HasParentSessionWithToken(token)) {
11714 isParent = true;
11715 return WSError::WS_OK;
11716 }
11717 }
11718 isParent = false;
11719 return WSError::WS_OK;
11720 }, __func__);
11721 }
11722
UpdateSessionAvoidAreaListener(int32_t persistentId,bool haveListener)11723 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t persistentId, bool haveListener)
11724 {
11725 const auto callingPid = IPCSkeleton::GetCallingRealPid();
11726 auto task = [this, persistentId, haveListener, callingPid, where = __func__]() {
11727 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d haveListener %{public}d",
11728 where, persistentId, haveListener);
11729 auto sceneSession = GetSceneSession(persistentId);
11730 if (sceneSession == nullptr) {
11731 TLOGND(WmsLogTag::WMS_IMMS, "%{public}s sceneSession is nullptr", where);
11732 return WSError::WS_DO_NOTHING;
11733 }
11734 if (callingPid != sceneSession->GetCallingPid()) {
11735 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s Permission denied, not called by the same process", where);
11736 return WSError::WS_ERROR_INVALID_PERMISSION;
11737 }
11738 if (haveListener) {
11739 avoidAreaListenerSessionSet_.insert(persistentId);
11740 UpdateAvoidArea(persistentId);
11741 } else {
11742 avoidAreaListenerSessionSet_.erase(persistentId);
11743 }
11744 return WSError::WS_OK;
11745 };
11746 return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
11747 }
11748
UpdateSessionScreenshotAppEventListener(int32_t persistentId,bool haveListener)11749 WMError SceneSessionManager::UpdateSessionScreenshotAppEventListener(int32_t persistentId, bool haveListener)
11750 {
11751 return taskScheduler_->PostSyncTask([this, persistentId, haveListener, where = __func__]() {
11752 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win: %{public}d haveListener: %{public}u",
11753 where, persistentId, haveListener);
11754 auto sceneSession = GetSceneSession(persistentId);
11755 if (sceneSession == nullptr) {
11756 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win: %{public}d sceneSession is nullptr", where, persistentId);
11757 return WMError::WM_ERROR_NULLPTR;
11758 }
11759 if (haveListener) {
11760 screenshotAppEventListenerSessionSet_.insert(persistentId);
11761 } else {
11762 screenshotAppEventListenerSessionSet_.erase(persistentId);
11763 }
11764 return WMError::WM_OK;
11765 }, __func__);
11766 }
11767
UpdateAvoidSessionAvoidArea(WindowType type)11768 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type)
11769 {
11770 AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
11771 AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
11772 AvoidArea avoidArea = rootSceneSession_->GetAvoidAreaByType(avoidType);
11773 rootSceneSession_->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
11774
11775 for (auto persistentId : avoidAreaListenerSessionSet_) {
11776 auto sceneSession = GetSceneSession(persistentId);
11777 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
11778 continue;
11779 }
11780 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(avoidType);
11781 sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
11782 }
11783 }
11784
UpdateNormalSessionAvoidArea(int32_t persistentId,const sptr<SceneSession> & sceneSession,bool & needUpdate)11785 void SceneSessionManager::UpdateNormalSessionAvoidArea(
11786 int32_t persistentId, const sptr<SceneSession>& sceneSession, bool& needUpdate)
11787 {
11788 if (rootSceneSession_->GetPersistentId() == persistentId) {
11789 UpdateRootSceneSessionAvoidArea(persistentId, needUpdate);
11790 return;
11791 }
11792 if (sceneSession == nullptr) {
11793 TLOGE(WmsLogTag::WMS_IMMS, "session is nullptr, win %{public}d", persistentId);
11794 needUpdate = false;
11795 return;
11796 }
11797 if (!IsSessionVisibleForeground(sceneSession)) {
11798 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u isVisible %{public}u sessionState %{public}u",
11799 persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
11800 needUpdate = false;
11801 return;
11802 }
11803 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
11804 TLOGD(WmsLogTag::WMS_IMMS,
11805 "win %{public}d not in avoidAreaListenerNodes, cannot update avoid area", persistentId);
11806 needUpdate = false;
11807 return;
11808 }
11809 sceneSession->UpdateSizeChangeReason(SizeChangeReason::AVOID_AREA_CHANGE);
11810 sceneSession->NotifyClientToUpdateRect("AvoidAreaChange", nullptr);
11811 }
11812
UpdateRootSceneSessionAvoidArea(int32_t persistentId,bool & needUpdate)11813 void SceneSessionManager::UpdateRootSceneSessionAvoidArea(int32_t persistentId, bool& needUpdate)
11814 {
11815 using T = std::underlying_type_t<AvoidAreaType>;
11816 for (T avoidAreaType = static_cast<T>(AvoidAreaType::TYPE_START);
11817 avoidAreaType < static_cast<T>(AvoidAreaType::TYPE_END); avoidAreaType++) {
11818 AvoidArea avoidArea = rootSceneSession_->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidAreaType));
11819 if (avoidAreaType == static_cast<T>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
11820 !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
11821 rootSceneSession_->GetSessionRect().height_)) {
11822 continue;
11823 }
11824 rootSceneSession_->UpdateAvoidArea(new AvoidArea(avoidArea), static_cast<AvoidAreaType>(avoidAreaType));
11825 }
11826 needUpdate = true;
11827 }
11828
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)11829 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
11830 {
11831 int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
11832 auto sceneSession = GetSceneSession(windowId);
11833 if (sceneSession == nullptr) {
11834 TLOGW(WmsLogTag::WMS_EVENT, "window not exist: %{public}d", windowId);
11835 return;
11836 }
11837
11838 TLOGI(WmsLogTag::WMS_EVENT, "Notify window:%{public}d, pid:%{public}d", windowId, pid);
11839 taskScheduler_->PostAsyncTask([weakSceneSession = wptr<SceneSession>(sceneSession), startMoving] {
11840 auto sceneSession = weakSceneSession.promote();
11841 if (sceneSession == nullptr) {
11842 TLOGNW(WmsLogTag::WMS_EVENT, "session is null");
11843 return;
11844 }
11845 SceneInputManager::GetInstance().NotifyMMIWindowPidChange(sceneSession, startMoving);
11846 }, __func__);
11847 }
11848
UpdateAvoidArea(int32_t persistentId)11849 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
11850 {
11851 taskScheduler_->PostAsyncTask([this, persistentId] {
11852 bool needUpdate = false;
11853 auto sceneSession = GetSceneSession(persistentId);
11854 if (sceneSession != nullptr && sceneSession->IsImmersiveType()) {
11855 UpdateAvoidSessionAvoidArea(sceneSession->GetWindowType());
11856 } else {
11857 UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
11858 }
11859 if (needUpdate) {
11860 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
11861 }
11862 }, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
11863 }
11864
GetKeyboardOccupiedAreaWithRotation(int32_t persistentId,Rotation rotation,std::vector<std::pair<bool,WSRect>> & avoidAreas)11865 void SceneSessionManager::GetKeyboardOccupiedAreaWithRotation(
11866 int32_t persistentId, Rotation rotation, std::vector<std::pair<bool, WSRect>>& avoidAreas)
11867 {
11868 if (systemConfig_.IsPcWindow()) {
11869 TLOGE(WmsLogTag::WMS_KEYBOARD, "The PC device is not compatible, id: %{public}d", persistentId);
11870 return;
11871 }
11872
11873 auto sceneSession = GetSceneSession(persistentId);
11874 if (sceneSession == nullptr) {
11875 TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is nullptr, id: %{public}d", persistentId);
11876 return;
11877 }
11878 auto keyboardSession = GetKeyboardSession(sceneSession->GetSessionProperty()->GetDisplayId(), false);
11879 if (keyboardSession == nullptr) {
11880 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr, id: %{public}d", persistentId);
11881 return;
11882 }
11883
11884 std::pair<bool, WSRect> keyboardOccupiedArea = {true, {0, 0, 0, 0}};
11885 const KeyboardLayoutParams& keyboardLayoutParams = keyboardSession->GetSessionProperty()->GetKeyboardLayoutParams();
11886 Rect nextRect;
11887 if (rotation == Rotation::ROTATION_0 || rotation == Rotation::ROTATION_180) {
11888 nextRect = keyboardLayoutParams.PortraitPanelRect_;
11889 } else if (rotation == Rotation::ROTATION_90 || rotation == Rotation::ROTATION_270) {
11890 nextRect = keyboardLayoutParams.LandscapePanelRect_;
11891 } else {
11892 TLOGE(WmsLogTag::WMS_KEYBOARD,
11893 "Rotation is invalid, id: %{public}d, rotation: %{public}u", persistentId, rotation);
11894 return;
11895 }
11896 keyboardOccupiedArea.second = {
11897 nextRect.posX_, nextRect.posY_, static_cast<int32_t>(nextRect.width_), static_cast<int32_t>(nextRect.height_)
11898 };
11899
11900 if (!keyboardSession->IsSessionForeground() ||
11901 keyboardLayoutParams.gravity_ == WindowGravity::WINDOW_GRAVITY_FLOAT) {
11902 keyboardOccupiedArea.first = false;
11903 }
11904 TLOGI(WmsLogTag::WMS_KEYBOARD, "next keyboardOccupiedArea: [%{public}d, %{public}s]", keyboardOccupiedArea.first,
11905 keyboardOccupiedArea.second.ToString().c_str());
11906 avoidAreas.emplace_back(keyboardOccupiedArea);
11907 }
11908
UpdateGestureBackEnabled(int32_t persistentId)11909 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
11910 {
11911 auto task = [this, persistentId, where = __func__] {
11912 auto sceneSession = GetSceneSession(persistentId);
11913 if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
11914 TLOGND(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable");
11915 return;
11916 }
11917 auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
11918 if (needEnableGestureBack) {
11919 gestureBackEnableWindowIdSet_.erase(persistentId);
11920 } else {
11921 gestureBackEnableWindowIdSet_.insert(persistentId);
11922 }
11923 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
11924 sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
11925 (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
11926 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
11927 enterRecent_.load() || !sceneSession->IsFocused()) {
11928 needEnableGestureBack = true;
11929 }
11930 if (gestureNavigationEnabledChangeFunc_ != nullptr) {
11931 gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
11932 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
11933 } else {
11934 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s callback func is null", where);
11935 }
11936 };
11937 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
11938 }
11939
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)11940 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
11941 {
11942 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u isVisible %{public}u",
11943 persistentId, isVisible);
11944 taskScheduler_->PostTask([this, persistentId, isVisible] {
11945 auto sceneSession = GetSceneSession(persistentId);
11946 if (sceneSession == nullptr) {
11947 TLOGNE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
11948 return;
11949 }
11950 sceneSession->SetIsStatusBarVisible(isVisible);
11951 }, __func__);
11952 return WSError::WS_OK;
11953 }
11954
NotifyStatusBarConstantlyShow(DisplayId displayId,bool isVisible)11955 void SceneSessionManager::NotifyStatusBarConstantlyShow(DisplayId displayId, bool isVisible)
11956 {
11957 TLOGD(WmsLogTag::WMS_IMMS, "displayId %{public}" PRIu64 " isVisible %{public}u", displayId, isVisible);
11958 const char* const where = __func__;
11959 auto task = [this, displayId, isVisible] {
11960 statusBarConstantlyShowMap_[displayId] = isVisible;
11961 UpdateRootSceneAvoidArea();
11962 return WMError::WM_OK;
11963 };
11964 taskScheduler_->PostAsyncTask(task, where);
11965 }
11966
GetStatusBarConstantlyShow(DisplayId displayId,bool & isVisible) const11967 void SceneSessionManager::GetStatusBarConstantlyShow(DisplayId displayId, bool& isVisible) const
11968 {
11969 auto it = statusBarConstantlyShowMap_.find(displayId);
11970 if (it != statusBarConstantlyShowMap_.end()) {
11971 isVisible = it->second;
11972 } else {
11973 isVisible = false;
11974 }
11975 }
11976
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)11977 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
11978 {
11979 TLOGI(WmsLogTag::WMS_IMMS, "isVisible %{public}u "
11980 "area %{public}s, displayId %{public}" PRIu64, isVisible, barArea.ToString().c_str(), displayId);
11981 taskScheduler_->PostAsyncTask([this, isVisible, barArea, displayId, where = __func__] {
11982 bool isNeedUpdate = true;
11983 {
11984 std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
11985 isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
11986 currAINavigationBarAreaMap_.count(displayId) == 0 ||
11987 currAINavigationBarAreaMap_[displayId] != barArea;
11988 if (isNeedUpdate) {
11989 isAINavigationBarVisible_ = isVisible;
11990 currAINavigationBarAreaMap_.clear();
11991 currAINavigationBarAreaMap_[displayId] = barArea;
11992 }
11993 if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
11994 TLOGND(WmsLogTag::WMS_IMMS, "%{public}s barArea should be empty if invisible", where);
11995 currAINavigationBarAreaMap_[displayId] = WSRect();
11996 }
11997 }
11998 if (isNeedUpdate) {
11999 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s isVisible %{public}u bar area %{public}s",
12000 where, isVisible, barArea.ToString().c_str());
12001 for (auto persistentId : avoidAreaListenerSessionSet_) {
12002 NotifySessionAINavigationBarChange(persistentId);
12003 }
12004 rootSceneSession_->UpdateAvoidArea(
12005 new AvoidArea(rootSceneSession_->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR)),
12006 AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
12007 }
12008 }, __func__);
12009 return WSError::WS_OK;
12010 }
12011
NotifyNextAvoidRectInfo(AvoidAreaType type,const WSRect & portraitRect,const WSRect & landspaceRect,DisplayId displayId)12012 WSError SceneSessionManager::NotifyNextAvoidRectInfo(AvoidAreaType type,
12013 const WSRect& portraitRect, const WSRect& landspaceRect, DisplayId displayId)
12014 {
12015 TLOGD(WmsLogTag::WMS_IMMS, "type %{public}d "
12016 "portraitRect %{public}s, portraitRect %{public}s, displayId %{public}" PRIu64,
12017 type, portraitRect.ToString().c_str(), landspaceRect.ToString().c_str(), displayId);
12018 std::lock_guard<std::mutex> lock(nextAvoidRectInfoMapMutex_);
12019 nextAvoidRectInfoMap_[type][displayId] = { portraitRect, landspaceRect };
12020 return WSError::WS_OK;
12021 }
12022
GetNextAvoidRectInfo(DisplayId displayId,AvoidAreaType type,std::pair<WSRect,WSRect> & nextSystemBarAvoidAreaRectInfo)12023 WSError SceneSessionManager::GetNextAvoidRectInfo(DisplayId displayId, AvoidAreaType type,
12024 std::pair<WSRect, WSRect>& nextSystemBarAvoidAreaRectInfo)
12025 {
12026 {
12027 std::lock_guard<std::mutex> lock(nextAvoidRectInfoMapMutex_);
12028 if (nextAvoidRectInfoMap_.count(type) == 0 || nextAvoidRectInfoMap_[type].count(displayId) == 0) {
12029 TLOGI(WmsLogTag::WMS_IMMS, "get failed, type %{public}d displayId %{public}" PRIu64, type, displayId);
12030 return WSError::WS_DO_NOTHING;
12031 }
12032 nextSystemBarAvoidAreaRectInfo = nextAvoidRectInfoMap_[type][displayId];
12033 }
12034 return WSError::WS_OK;
12035 }
12036
NotifySessionAINavigationBarChange(int32_t persistentId)12037 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
12038 {
12039 auto sceneSession = GetSceneSession(persistentId);
12040 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
12041 TLOGD(WmsLogTag::WMS_IMMS, "scene session is nullptr or not visible");
12042 return;
12043 }
12044 sceneSession->HandleLayoutAvoidAreaUpdate(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
12045 }
12046
GetAINavigationBarArea(uint64_t displayId)12047 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
12048 {
12049 std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
12050 if (currAINavigationBarAreaMap_.count(displayId) == 0) {
12051 return {};
12052 }
12053 return currAINavigationBarAreaMap_[displayId];
12054 }
12055
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)12056 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
12057 {
12058 const auto callingPid = IPCSkeleton::GetCallingRealPid();
12059 auto task = [this, persistentId, haveListener, callingPid]() {
12060 TLOGNI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
12061 persistentId, haveListener);
12062 auto sceneSession = GetSceneSession(persistentId);
12063 if (sceneSession == nullptr) {
12064 TLOGNE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
12065 return WSError::WS_DO_NOTHING;
12066 }
12067 if (callingPid != sceneSession->GetCallingPid()) {
12068 TLOGNE(WmsLogTag::WMS_EVENT, "Permission denied");
12069 return WSError::WS_ERROR_INVALID_PERMISSION;
12070 }
12071 if (haveListener) {
12072 touchOutsideListenerSessionSet_.insert(persistentId);
12073 } else {
12074 touchOutsideListenerSessionSet_.erase(persistentId);
12075 }
12076 return WSError::WS_OK;
12077 };
12078 return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
12079 }
12080
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)12081 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
12082 {
12083 const auto callingPid = IPCSkeleton::GetCallingRealPid();
12084 return taskScheduler_->PostSyncTask([this, persistentId, haveListener, callingPid]() -> WSError {
12085 TLOGNI(WmsLogTag::WMS_LIFE, "persistentId: %{public}d haveListener:%{public}d",
12086 persistentId, haveListener);
12087 auto sceneSession = GetSceneSession(persistentId);
12088 if (sceneSession == nullptr) {
12089 TLOGND(WmsLogTag::WMS_LIFE, "sceneSession is nullptr.");
12090 return haveListener ? WSError::WS_DO_NOTHING : WSError::WS_OK;
12091 }
12092 if (callingPid != sceneSession->GetCallingPid()) {
12093 TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
12094 return WSError::WS_ERROR_INVALID_PERMISSION;
12095 }
12096 if (haveListener) {
12097 windowVisibilityListenerSessionSet_.insert(persistentId);
12098 sceneSession->NotifyWindowVisibility();
12099 } else {
12100 windowVisibilityListenerSessionSet_.erase(persistentId);
12101 }
12102 return WSError::WS_OK;
12103 }, __func__);
12104 }
12105
UpdateDarkColorModeToRS()12106 void SceneSessionManager::UpdateDarkColorModeToRS()
12107 {
12108 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
12109 if (appContext == nullptr) {
12110 TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
12111 return;
12112 }
12113 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
12114 if (config == nullptr) {
12115 TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
12116 return;
12117 }
12118 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
12119 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
12120 bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
12121 TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d", colorMode.c_str(), ret);
12122 }
12123
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)12124 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
12125 {
12126 processVirtualPixelRatioChangeFunc_ = func;
12127 TLOGI(WmsLogTag::DEFAULT, "end");
12128 }
12129
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)12130 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
12131 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
12132 {
12133 if (displayInfo == nullptr) {
12134 TLOGE(WmsLogTag::DEFAULT, "displayInfo is nullptr.");
12135 return;
12136 }
12137 taskScheduler_->PostSyncTask([this, displayInfo, type, where = __func__]() {
12138 if (processVirtualPixelRatioChangeFunc_ != nullptr &&
12139 type == DisplayStateChangeType::RESOLUTION_CHANGE &&
12140 displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
12141 Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
12142 displayInfo->GetWidth(), displayInfo->GetHeight() };
12143 processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
12144 }
12145 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12146 for (const auto& [_, sceneSession] : sceneSessionMap_) {
12147 if (sceneSession == nullptr) {
12148 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s null scene session", where);
12149 continue;
12150 }
12151 if (sceneSession->GetSessionProperty()->GetDisplayId() != displayInfo->GetDisplayId()) {
12152 continue;
12153 }
12154 if (sceneSession->GetSessionInfo().isSystem_) {
12155 continue;
12156 }
12157 if (sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
12158 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE) {
12159 sceneSession->UpdateDensity();
12160 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "UpdateDensity name=%{public}s, persistentId=%{public}d, "
12161 "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
12162 sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
12163 sceneSession->GetSessionState(), sceneSession->IsVisible());
12164 } else if (sceneSession->GetSessionState() == SessionState::STATE_BACKGROUND && systemConfig_.IsPcWindow()) {
12165 sceneSession->SaveLastDensity();
12166 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "SaveLastDensity name=%{public}s, persistentId=%{public}d, "
12167 "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
12168 sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
12169 sceneSession->GetSessionState(), sceneSession->IsVisible());
12170 }
12171 }
12172 UpdateDisplayRegion(displayInfo);
12173 return WSError::WS_OK;
12174 }, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
12175 }
12176
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)12177 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
12178 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
12179 {
12180 if (displayInfo == nullptr) {
12181 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr.");
12182 return;
12183 }
12184 taskScheduler_->PostSyncTask([this, displayInfo, where = __func__]() {
12185 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12186 for (const auto& [_, sceneSession] : sceneSessionMap_) {
12187 if (sceneSession == nullptr) {
12188 TLOGNE(WmsLogTag::DMS, "%{public}s null scene session", where);
12189 continue;
12190 }
12191 if (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
12192 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) {
12193 continue;
12194 }
12195 if (NearEqual(sceneSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
12196 NearEqual(sceneSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
12197 sceneSession->GetRotation() != displayInfo->GetRotation()) {
12198 sceneSession->UpdateRotationAvoidArea();
12199 TLOGND(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
12200 "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
12201 sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState(),
12202 sceneSession->IsVisible());
12203 }
12204 sceneSession->SetRotation(displayInfo->GetRotation());
12205 sceneSession->UpdateOrientation();
12206 }
12207 UpdateDisplayRegion(displayInfo);
12208 return WSError::WS_OK;
12209 }, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
12210 }
12211
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)12212 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
12213 {
12214 if (displayInfo == nullptr) {
12215 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
12216 return;
12217 }
12218
12219 taskScheduler_->PostAsyncTask([this, displayInfo] {
12220 ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
12221 displayInfo->GetScaleX(),
12222 displayInfo->GetScaleY(),
12223 displayInfo->GetPivotX(),
12224 displayInfo->GetPivotY(),
12225 displayInfo->GetTranslateX(),
12226 displayInfo->GetTranslateY());
12227 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
12228 FlushWindowInfoToMMI(true);
12229 }, __func__);
12230 }
12231
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)12232 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
12233 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
12234 {
12235 TLOGD(WmsLogTag::DEFAULT, "type: %{public}u", type);
12236 switch (type) {
12237 case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
12238 SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
12239 displayInfo, displayInfoMap, type);
12240 SceneSessionManager::GetInstance().FlushWindowInfoToMMI();
12241 break;
12242 }
12243 case DisplayStateChangeType::UPDATE_ROTATION: {
12244 SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
12245 displayInfo, displayInfoMap, type);
12246 break;
12247 }
12248 case DisplayStateChangeType::UPDATE_SCALE: {
12249 SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
12250 break;
12251 }
12252 default:
12253 return;
12254 }
12255 }
12256
CheckIfNeedMultipleFocus(const std::string & name,const ScreenType & screenType)12257 bool CheckIfNeedMultipleFocus(const std::string& name, const ScreenType& screenType)
12258 {
12259 if (screenType == ScreenType::VIRTUAL && (name == "CeliaView" || name == "DevEcoViewer")) {
12260 return true;
12261 }
12262 return false;
12263 }
12264
OnScreenConnected(const sptr<ScreenSession> & screenSession)12265 void ScreenConnectionChangeListener::OnScreenConnected(const sptr<ScreenSession>& screenSession)
12266 {
12267 if (screenSession == nullptr) {
12268 TLOGE(WmsLogTag::WMS_FOCUS, "screenSession is nullptr");
12269 return;
12270 }
12271 TLOGI(WmsLogTag::WMS_FOCUS,
12272 "name: %{public}s, screenId: %{public}" PRIu64 ", displayGroupId: %{public}" PRIu64
12273 " ,screenType: %{public}u",
12274 screenSession->GetName().c_str(),
12275 screenSession->GetScreenId(),
12276 screenSession->GetDisplayGroupId(),
12277 screenSession->GetScreenProperty().GetScreenType());
12278 if (CheckIfNeedMultipleFocus(screenSession->GetName(), screenSession->GetScreenProperty().GetScreenType())) {
12279 SceneSessionManager::GetInstance().AddFocusGroup(screenSession->GetDisplayGroupId(),
12280 screenSession->GetScreenId());
12281 }
12282
12283 // Window Layout Global Coordinate System: monitors screen position changes in the global coordinate system
12284 screenSession->RegisterScreenChangeListener(&SceneScreenChangeListener::GetInstance());
12285 }
12286
OnScreenDisconnected(const sptr<ScreenSession> & screenSession)12287 void ScreenConnectionChangeListener::OnScreenDisconnected(const sptr<ScreenSession>& screenSession)
12288 {
12289 if (screenSession == nullptr) {
12290 TLOGE(WmsLogTag::WMS_FOCUS, "screenSession is nullptr");
12291 return;
12292 }
12293 TLOGI(WmsLogTag::WMS_FOCUS,
12294 "name: %{public}s, screenId: %{public}" PRIu64 ", displayGroupId: %{public}" PRIu64
12295 " ,screenType: %{public}u",
12296 screenSession->GetName().c_str(),
12297 screenSession->GetScreenId(),
12298 screenSession->GetDisplayGroupId(),
12299 screenSession->GetScreenProperty().GetScreenType());
12300 if (CheckIfNeedMultipleFocus(screenSession->GetName(), screenSession->GetScreenProperty().GetScreenType())) {
12301 SceneSessionManager::GetInstance().RemoveFocusGroup(screenSession->GetDisplayGroupId(),
12302 screenSession->GetScreenId());
12303 }
12304
12305 // Window Layout Global Coordinate System
12306 screenSession->UnregisterScreenChangeListener(&SceneScreenChangeListener::GetInstance());
12307 }
12308
OnScreenshot(DisplayId displayId)12309 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
12310 {
12311 SceneSessionManager::GetInstance().OnScreenshot(displayId);
12312 }
12313
OnScreenshot(DisplayId displayId)12314 void SceneSessionManager::OnScreenshot(DisplayId displayId)
12315 {
12316 taskScheduler_->PostAsyncTask([this, displayId]() {
12317 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12318 for (const auto& [_, sceneSession] : sceneSessionMap_) {
12319 if (sceneSession == nullptr) {
12320 continue;
12321 }
12322 auto state = sceneSession->GetSessionState();
12323 if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
12324 sceneSession->NotifyScreenshot();
12325 }
12326 }
12327 }, "OnScreenshot:PID:" + std::to_string(displayId));
12328 }
12329
NotifyScreenshotEvent(ScreenshotEventType type)12330 WMError SceneSessionManager::NotifyScreenshotEvent(ScreenshotEventType type)
12331 {
12332 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "event: %{public}d", type);
12333 if (!SessionPermission::IsSystemCalling()) {
12334 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
12335 return WMError::WM_ERROR_NOT_SYSTEM_APP;
12336 }
12337 taskScheduler_->PostAsyncTask([this, type, where = __func__] {
12338 for (auto persistentId : screenshotAppEventListenerSessionSet_) {
12339 auto sceneSession = GetSceneSession(persistentId);
12340 if (sceneSession == nullptr) {
12341 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win: %{public}d session is null", where, persistentId);
12342 continue;
12343 }
12344 auto state = sceneSession->GetSessionState();
12345 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win: %{public}d, state: %{public}u, event: %{public}d",
12346 where, sceneSession->GetPersistentId(), state, type);
12347 if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
12348 sceneSession->NotifyScreenshotAppEvent(type);
12349 }
12350 }
12351 }, __func__);
12352 return WMError::WM_OK;
12353 }
12354
ClearSession(int32_t persistentId)12355 WSError SceneSessionManager::ClearSession(int32_t persistentId)
12356 {
12357 TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", persistentId);
12358 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12359 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
12360 return WSError::WS_ERROR_NOT_SYSTEM_APP;
12361 }
12362 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12363 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12364 return WSError::WS_ERROR_INVALID_PERMISSION;
12365 }
12366 taskScheduler_->PostAsyncTask([this, persistentId]() {
12367 auto sceneSession = GetSceneSession(persistentId);
12368 return ClearSession(sceneSession);
12369 }, "ClearSession:PID:" + std::to_string(persistentId));
12370 return WSError::WS_OK;
12371 }
12372
ClearSession(sptr<SceneSession> sceneSession)12373 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
12374 {
12375 TLOGD(WmsLogTag::WMS_LIFE, "in");
12376 if (sceneSession == nullptr) {
12377 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
12378 return WSError::WS_ERROR_INVALID_SESSION;
12379 }
12380 if (!IsSessionClearable(sceneSession)) {
12381 TLOGE(WmsLogTag::WMS_LIFE, "session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
12382 return WSError::WS_ERROR_INVALID_SESSION;
12383 }
12384 const WSError errCode = sceneSession->Clear(false, true);
12385 return errCode;
12386 }
12387
ClearAllSessions()12388 WSError SceneSessionManager::ClearAllSessions()
12389 {
12390 TLOGD(WmsLogTag::WMS_LIFE, "in");
12391 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12392 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
12393 return WSError::WS_ERROR_NOT_SYSTEM_APP;
12394 }
12395 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12396 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12397 return WSError::WS_ERROR_INVALID_PERMISSION;
12398 }
12399 auto task = [this]() {
12400 std::vector<sptr<SceneSession>> sessionVector;
12401 GetAllClearableSessions(sessionVector);
12402 for (uint32_t i = 0; i < sessionVector.size(); i++) {
12403 ClearSession(sessionVector[i]);
12404 }
12405 return WSError::WS_OK;
12406 };
12407 taskScheduler_->PostAsyncTask(task, __func__);
12408 return WSError::WS_OK;
12409 }
12410
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)12411 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
12412 {
12413 TLOGD(WmsLogTag::WMS_LIFE, "in");
12414 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12415 for (const auto& [_, sceneSession] : sceneSessionMap_) {
12416 if (IsSessionClearable(sceneSession)) {
12417 sessionVector.push_back(sceneSession);
12418 }
12419 }
12420 }
12421
LockSession(int32_t sessionId)12422 WSError SceneSessionManager::LockSession(int32_t sessionId)
12423 {
12424 TLOGI(WmsLogTag::DEFAULT, "id: %{public}d", sessionId);
12425 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12426 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
12427 return WSError::WS_ERROR_NOT_SYSTEM_APP;
12428 }
12429 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12430 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12431 return WSError::WS_ERROR_INVALID_PERMISSION;
12432 }
12433 const char* const where = __func__;
12434 auto task = [this, sessionId, where]() {
12435 auto sceneSession = GetSceneSession(sessionId);
12436 if (sceneSession == nullptr) {
12437 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s cannot find session, id: %{public}d", where, sessionId);
12438 return WSError::WS_ERROR_INVALID_PARAM;
12439 }
12440 sceneSession->SetSessionInfoLockedState(true);
12441 return WSError::WS_OK;
12442 };
12443 return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
12444 }
12445
UnlockSession(int32_t sessionId)12446 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
12447 {
12448 TLOGI(WmsLogTag::DEFAULT, "id: %{public}d", sessionId);
12449 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12450 TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
12451 return WSError::WS_ERROR_NOT_SYSTEM_APP;
12452 }
12453 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12454 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12455 return WSError::WS_ERROR_INVALID_PERMISSION;
12456 }
12457 const char* const where = __func__;
12458 auto task = [this, sessionId, where]() {
12459 auto sceneSession = GetSceneSession(sessionId);
12460 if (sceneSession == nullptr) {
12461 TLOGNE(WmsLogTag::DEFAULT, "%{public}s cannot find session, id: %{public}d", where, sessionId);
12462 return WSError::WS_ERROR_INVALID_PARAM;
12463 }
12464 sceneSession->SetSessionInfoLockedState(false);
12465 return WSError::WS_OK;
12466 };
12467 return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
12468 }
12469
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)12470 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
12471 {
12472 TLOGI(WmsLogTag::WMS_LIFE, "in");
12473 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12474 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
12475 return WSError::WS_ERROR_NOT_SYSTEM_APP;
12476 }
12477 if (!SessionPermission::VerifySessionPermission()) {
12478 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12479 return WSError::WS_ERROR_INVALID_PERMISSION;
12480 }
12481
12482 return WSError::WS_OK;
12483 }
12484
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)12485 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
12486 std::vector<int32_t>& result)
12487 {
12488 TLOGI(WmsLogTag::WMS_LIFE, "in");
12489 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12490 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
12491 return WSError::WS_ERROR_NOT_SYSTEM_APP;
12492 }
12493 if (!SessionPermission::VerifySessionPermission()) {
12494 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12495 return WSError::WS_ERROR_INVALID_PERMISSION;
12496 }
12497
12498 result.insert(result.end(), sessionIds.begin(), sessionIds.end());
12499 return WSError::WS_OK;
12500 }
12501
IsSessionClearable(sptr<SceneSession> sceneSession)12502 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> sceneSession)
12503 {
12504 if (sceneSession == nullptr) {
12505 TLOGI(WmsLogTag::WMS_MAIN, "sceneSession is nullptr");
12506 return false;
12507 }
12508 const auto& sessionInfo = sceneSession->GetSessionInfo();
12509 if (sessionInfo.abilityInfo == nullptr) {
12510 TLOGI(WmsLogTag::WMS_MAIN, "sceneSession abilityInfo is nullptr");
12511 return false;
12512 }
12513 if (sessionInfo.abilityInfo->excludeFromMissions && !sceneSession->IsAnco()) {
12514 TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is excludeFromMissions", sceneSession->GetPersistentId());
12515 return false;
12516 }
12517 if (sessionInfo.abilityInfo->unclearableMission) {
12518 TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is unclearable", sceneSession->GetPersistentId());
12519 return false;
12520 }
12521 if (sessionInfo.isSystem_) {
12522 TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is system app", sceneSession->GetPersistentId());
12523 return false;
12524 }
12525 if (sessionInfo.lockedState) {
12526 TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is in lockedState", sceneSession->GetPersistentId());
12527 return false;
12528 }
12529
12530 return true;
12531 }
12532
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)12533 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
12534 const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
12535 {
12536 TLOGI(WmsLogTag::DEFAULT, "type: %{public}d", type);
12537 auto isSaCall = SessionPermission::IsSACalling();
12538 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12539 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
12540 return WSError::WS_ERROR_INVALID_PERMISSION;
12541 }
12542 if (!CheckCollaboratorType(type)) {
12543 TLOGW(WmsLogTag::DEFAULT, "collaborator register failed, invalid type.");
12544 return WSError::WS_ERROR_INVALID_TYPE;
12545 }
12546 if (impl == nullptr) {
12547 TLOGE(WmsLogTag::DEFAULT, "Collaborator is nullptr");
12548 return WSError::WS_ERROR_NULLPTR;
12549 }
12550 if (impl->AsObject() == nullptr || !impl->AsObject()->AddDeathRecipient(collaboratorDeathRecipient_)) {
12551 TLOGE(WmsLogTag::DEFAULT, "Failed to add collaborator death recipient");
12552 return WSError::WS_ERROR_IPC_FAILED;
12553 }
12554 {
12555 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
12556 collaboratorMap_[type] = impl;
12557 }
12558 auto task = [this] {
12559 if (abilityManagerCollaboratorRegisteredFunc_) {
12560 abilityManagerCollaboratorRegisteredFunc_();
12561 }
12562 };
12563 taskScheduler_->PostTask(task, __func__);
12564 return WSError::WS_OK;
12565 }
12566
UnregisterIAbilityManagerCollaborator(int32_t type)12567 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
12568 {
12569 TLOGI(WmsLogTag::DEFAULT, "type: %{public}d", type);
12570 auto isSaCall = SessionPermission::IsSACalling();
12571 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12572 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
12573 return WSError::WS_ERROR_INVALID_PERMISSION;
12574 }
12575 if (!CheckCollaboratorType(type)) {
12576 TLOGE(WmsLogTag::DEFAULT, "collaborator unregister failed, invalid type.");
12577 return WSError::WS_ERROR_INVALID_TYPE;
12578 }
12579 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(type);
12580 if (collaborator != nullptr && collaborator->AsObject() != nullptr) {
12581 TLOGI(WmsLogTag::DEFAULT, "Remove collaborator death recipient");
12582 collaborator->AsObject()->RemoveDeathRecipient(collaboratorDeathRecipient_);
12583 }
12584 {
12585 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
12586 collaboratorMap_.erase(type);
12587 }
12588 return WSError::WS_OK;
12589 }
12590
ClearAllCollaboratorSessions()12591 void SceneSessionManager::ClearAllCollaboratorSessions()
12592 {
12593 TLOGI(WmsLogTag::WMS_MAIN, "in");
12594 std::vector<sptr<SceneSession>> collaboratorSessions;
12595 {
12596 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12597 for (const auto& [_, sceneSession] : sceneSessionMap_) {
12598 if (sceneSession != nullptr && CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
12599 collaboratorSessions.push_back(sceneSession);
12600 }
12601 }
12602 }
12603 for (const auto& sceneSession : collaboratorSessions) {
12604 sceneSession->Clear();
12605 }
12606 }
12607
CheckCollaboratorType(int32_t type)12608 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
12609 {
12610 if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
12611 TLOGD(WmsLogTag::WMS_MAIN, "type is invalid");
12612 return false;
12613 }
12614 return true;
12615 }
12616
CheckIfReuseSession(SessionInfo & sessionInfo)12617 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
12618 {
12619 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
12620 sessionInfo.moduleName_);
12621 if (abilityInfo == nullptr) {
12622 TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
12623 return BrokerStates::BROKER_UNKOWN;
12624 }
12625 sessionInfo.abilityInfo = abilityInfo;
12626 int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
12627 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
12628 collaboratorType = CollaboratorType::RESERVE_TYPE;
12629 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
12630 collaboratorType = CollaboratorType::OTHERS_TYPE;
12631 }
12632 if (!CheckCollaboratorType(collaboratorType)) {
12633 TLOGW(WmsLogTag::DEFAULT, "checked not collaborator!");
12634 return BrokerStates::BROKER_UNKOWN;
12635 }
12636 BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
12637 sessionInfo.collaboratorType_ = collaboratorType;
12638 sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
12639 if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
12640 TLOGI(WmsLogTag::DEFAULT, "FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
12641 sessionInfo.reuse = true;
12642 } else {
12643 sessionInfo.reuse = false;
12644 }
12645 TLOGI(WmsLogTag::DEFAULT, "end: affinity %{public}s type %{public}d reuse %{public}d",
12646 sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
12647 return resultValue;
12648 }
12649
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)12650 BrokerStates SceneSessionManager::NotifyStartAbility(
12651 int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
12652 {
12653 TLOGI(WmsLogTag::WMS_LIFE, "type %{public}d id %{public}d windowMode %{public}d",
12654 collaboratorType, persistentId, sessionInfo.windowMode);
12655 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
12656 if (collaborator == nullptr) {
12657 return BrokerStates::BROKER_UNKOWN;
12658 }
12659 if (sessionInfo.want == nullptr) {
12660 TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo.want is nullptr, init");
12661 sessionInfo.want = std::make_shared<AAFwk::Want>();
12662 sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
12663 sessionInfo.moduleName_);
12664 }
12665 auto accessTokenIDEx = sessionInfo.callingTokenId_;
12666 if (collaborator != nullptr) {
12667 containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
12668 std::chrono::system_clock::now().time_since_epoch()).count();
12669
12670 std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
12671 if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
12672 TLOGI(WmsLogTag::WMS_LIFE, "want affinity exit %{public}s.", affinity.c_str());
12673 return BrokerStates::BROKER_UNKOWN;
12674 }
12675 sessionInfo.want->SetParam("oh_persistentId", persistentId);
12676 std::shared_ptr<int32_t> ret = std::make_shared<int32_t>(0);
12677 std::shared_ptr<AAFwk::Want> notifyWant = std::make_shared<AAFwk::Want>(sessionInfo.GetWantSafely());
12678 bool isTimeout = ffrtQueueHelper_->SubmitTaskAndWait([this, collaborator, accessTokenIDEx,
12679 notifyWant, abilityInfo = sessionInfo.abilityInfo, windowMode = sessionInfo.windowMode, ret] {
12680 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("WMS:SSM:NotifyStartAbility",
12681 NOTIFY_START_ABILITY_TIMEOUT/1000, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
12682 auto result = collaborator->NotifyStartAbility(*abilityInfo, currentUserId_, *notifyWant,
12683 static_cast<uint64_t>(accessTokenIDEx), windowMode);
12684 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
12685 *ret = static_cast<int32_t>(result);
12686 }, NOTIFY_START_ABILITY_TIMEOUT);
12687
12688 if (isTimeout) {
12689 TLOGE(WmsLogTag::WMS_LIFE, "notify start ability timeout, id: %{public}d", persistentId);
12690 return BrokerStates::BROKER_NOT_START;
12691 }
12692 sessionInfo.SetWantSafely(*notifyWant);
12693 TLOGI(WmsLogTag::WMS_LIFE, "collaborator ret: %{public}d", *ret);
12694 if (*ret == 0) {
12695 return BrokerStates::BROKER_STARTED;
12696 } else {
12697 return BrokerStates::BROKER_NOT_START;
12698 }
12699 }
12700 return BrokerStates::BROKER_UNKOWN;
12701 }
12702
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)12703 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
12704 {
12705 if (sceneSession == nullptr) {
12706 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
12707 return;
12708 }
12709 if (sessionInfo.want == nullptr) {
12710 TLOGI(WmsLogTag::DEFAULT, "sessionInfo.want is nullptr");
12711 return;
12712 }
12713 if (auto collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType())) {
12714 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
12715 abilitySessionInfo->want = sessionInfo.GetWantSafely();
12716 int32_t missionId = abilitySessionInfo->persistentId;
12717 std::string bundleName = sessionInfo.bundleName_;
12718 int64_t timestamp = containerStartAbilityTime_;
12719 WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
12720 TLOGI(WmsLogTag::DEFAULT, "call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
12721 missionId, bundleName.c_str());
12722 collaborator->NotifyMissionCreated(abilitySessionInfo);
12723 }
12724 }
12725
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)12726 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
12727 sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
12728 {
12729 TLOGD(WmsLogTag::DEFAULT, "type: %{public}d", collaboratorType);
12730 if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
12731 TLOGI(WmsLogTag::DEFAULT, "called");
12732 collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
12733 }
12734 }
12735
12736
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)12737 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
12738 {
12739 TLOGD(WmsLogTag::DEFAULT, "in");
12740 if (sceneSession == nullptr) {
12741 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
12742 return;
12743 }
12744 if (auto collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType())) {
12745 TLOGI(WmsLogTag::DEFAULT, "called UpdateMissionInfo");
12746 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
12747 collaborator->UpdateMissionInfo(abilitySessionInfo);
12748 }
12749 }
12750
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)12751 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
12752 {
12753 TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, type: %{public}d", persistentId, collaboratorType);
12754 if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
12755 TLOGI(WmsLogTag::DEFAULT, "called %{public}d", persistentId);
12756 collaborator->NotifyMoveMissionToForeground(persistentId);
12757 }
12758 }
12759
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)12760 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
12761 {
12762 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, type: %{public}d", persistentId, collaboratorType);
12763 if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
12764 const char* const where = __func__;
12765 ffrtQueueHelper_->SubmitTask([collaborator, persistentId, where] {
12766 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("WMS:SSM:NotifyClearMission",
12767 NOTIFY_START_ABILITY_TIMEOUT/1000, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
12768 int32_t ret = collaborator->NotifyClearMission(persistentId);
12769 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
12770 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s called clear mission ret: %{public}d, persistent id: %{public}d",
12771 where, ret, persistentId);
12772 });
12773 }
12774 }
12775
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)12776 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
12777 {
12778 if (sceneSession == nullptr) {
12779 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
12780 return false;
12781 }
12782 std::string sessionAffinity;
12783 TLOGI(WmsLogTag::WMS_LIFE, "call");
12784 if (sceneSession->GetSessionInfo().want != nullptr) {
12785 sessionAffinity = sceneSession->GetSessionInfo().want
12786 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
12787 }
12788 if (sessionAffinity.empty()) {
12789 TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
12790 BrokerStates notifyReturn = NotifyStartAbility(
12791 sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
12792 if (notifyReturn == BrokerStates::BROKER_NOT_START) {
12793 TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
12794 return false;
12795 }
12796 }
12797 if (sceneSession->GetSessionInfo().want != nullptr) {
12798 sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
12799 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
12800 TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
12801 sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
12802 sceneSession->GetSessionInfo().sessionAffinity.c_str());
12803 } else {
12804 TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
12805 }
12806 return true;
12807 }
12808
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)12809 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
12810 {
12811 if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
12812 return false;
12813 }
12814 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
12815 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
12816 return true;
12817 }
12818
AddWindowDragHotArea(DisplayId displayId,uint32_t type,WSRect & area)12819 void SceneSessionManager::AddWindowDragHotArea(DisplayId displayId, uint32_t type, WSRect& area)
12820 {
12821 TLOGI(WmsLogTag::WMS_LAYOUT, "displayId: %{public}" PRIu64 ", "
12822 "type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
12823 "height: %{public}d", displayId, type, area.posX_, area.posY_, area.width_, area.height_);
12824 SceneSession::AddOrUpdateWindowDragHotArea(displayId, type, area);
12825 }
12826
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)12827 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
12828 {
12829 auto task = [this, persistentId, isMaximize]() {
12830 TLOGND(WmsLogTag::WMS_PC, "update maximize mode, id: %{public}d, isMaximize: %{public}d",
12831 persistentId, isMaximize);
12832 auto sceneSession = GetSceneSession(persistentId);
12833 if (sceneSession == nullptr) {
12834 TLOGNE(WmsLogTag::WMS_PC, "could not find window, persistentId:%{public}d", persistentId);
12835 return WSError::WS_ERROR_INVALID_WINDOW;
12836 }
12837 sceneSession->UpdateMaximizeMode(isMaximize);
12838 return WSError::WS_OK;
12839 };
12840 taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
12841 return WSError::WS_OK;
12842 }
12843
GetIsLayoutFullScreen(bool & isLayoutFullScreen)12844 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
12845 {
12846 auto task = [this, &isLayoutFullScreen]() {
12847 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12848 for (const auto& [_, sceneSession] : sceneSessionMap_) {
12849 if (sceneSession == nullptr) {
12850 TLOGNE(WmsLogTag::WMS_IMMS, "Session is nullptr");
12851 continue;
12852 }
12853 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
12854 continue;
12855 }
12856 auto state = sceneSession->GetSessionState();
12857 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
12858 continue;
12859 }
12860 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
12861 continue;
12862 }
12863 isLayoutFullScreen = sceneSession->GetSessionProperty()->IsLayoutFullScreen();
12864 if (isLayoutFullScreen) {
12865 TLOGND(WmsLogTag::WMS_IMMS, "Current window is immersive, persistentId:%{public}d",
12866 sceneSession->GetPersistentId());
12867 return WSError::WS_OK;
12868 } else {
12869 TLOGND(WmsLogTag::WMS_IMMS, "Current window is not immersive, persistentId:%{public}d",
12870 sceneSession->GetPersistentId());
12871 }
12872 }
12873 TLOGND(WmsLogTag::WMS_IMMS, "No immersive window");
12874 return WSError::WS_OK;
12875 };
12876
12877 taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
12878 return WSError::WS_OK;
12879 }
12880
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)12881 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
12882 {
12883 auto sceneSession = GetSceneSession(persistentId);
12884 if (!sceneSession) {
12885 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
12886 return WSError::WS_ERROR_INVALID_WINDOW;
12887 }
12888 auto fromScreenId = sceneSession->GetSessionInfo().screenId_;
12889 sceneSession->SetScreenId(screenId);
12890 sceneSession->GetSessionProperty()->SetDisplayId(screenId);
12891 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, move display %{public}" PRIu64 " from %{public}" PRIu64,
12892 sceneSession->GetPersistentId(), screenId, fromScreenId);
12893 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
12894 sceneSession->NotifyDisplayMove(fromScreenId, screenId);
12895 sceneSession->UpdateDensity();
12896 if (fromScreenId != screenId) {
12897 sceneSession->AddPropertyDirtyFlags(static_cast<uint32_t>(SessionPropertyFlag::DISPLAY_ID));
12898 }
12899 uint64_t displayId = screenId;
12900 if (sceneSession->IsPcFoldDevice() && PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
12901 displayId = sceneSession->GetClientDisplayId();
12902 }
12903 NotifyDisplayIdChanged(persistentId, displayId);
12904 return WSError::WS_OK;
12905 }
12906
NotifyStackEmpty(int32_t persistentId)12907 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
12908 {
12909 TLOGI(WmsLogTag::WMS_LIFE, "persistentId %{public}d", persistentId);
12910 auto task = [this, persistentId]() {
12911 auto sceneSession = GetSceneSession(persistentId);
12912 if (!sceneSession) {
12913 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
12914 return WSError::WS_ERROR_INVALID_WINDOW;
12915 }
12916 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::STACK_EMPTY);
12917 return WSError::WS_OK;
12918 };
12919 taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
12920 return WSError::WS_OK;
12921 }
12922
OnImmersiveStateChange(ScreenId screenId,bool & immersive)12923 void DisplayChangeListener::OnImmersiveStateChange(ScreenId screenId, bool& immersive)
12924 {
12925 immersive = SceneSessionManager::GetInstance().GetImmersiveState(screenId);
12926 }
12927
GetImmersiveState(ScreenId screenId)12928 bool SceneSessionManager::GetImmersiveState(ScreenId screenId)
12929 {
12930 return taskScheduler_->PostSyncTask([this, screenId, where = __func__] {
12931 bool isPcOrPadFreeMultiWindowMode = false;
12932 IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
12933 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12934 for (const auto& [_, sceneSession] : sceneSessionMap_) {
12935 if (sceneSession == nullptr) {
12936 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is nullptr", where);
12937 continue;
12938 }
12939 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
12940 continue;
12941 }
12942 auto state = sceneSession->GetSessionState();
12943 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
12944 continue;
12945 }
12946 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
12947 continue;
12948 }
12949 if (sceneSession->GetSessionProperty()->GetDisplayId() != screenId) {
12950 continue;
12951 }
12952 if (isPcOrPadFreeMultiWindowMode) {
12953 if (sceneSession->IsLayoutFullScreen()) {
12954 return true;
12955 }
12956 continue;
12957 }
12958 auto sysBarProperty = sceneSession->GetSessionProperty()->GetSystemBarProperty();
12959 if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
12960 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s window is immersive. id: %{public}d", where,
12961 sceneSession->GetPersistentId());
12962 return true;
12963 } else {
12964 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s statusBar is enabled. id: %{public}d", where,
12965 sceneSession->GetPersistentId());
12966 break;
12967 }
12968 }
12969 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s not immersive", where);
12970 return false;
12971 }, __func__);
12972 }
12973
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)12974 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
12975 bool withAnimation)
12976 {
12977 session->NotifySessionForeground(reason, withAnimation);
12978 }
12979
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)12980 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
12981 bool withAnimation, bool isFromInnerkits)
12982 {
12983 session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
12984 }
12985
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)12986 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
12987 {
12988 auto sceneSession = GetSceneSession(persistentId);
12989 if (sceneSession == nullptr) {
12990 TLOGE(WmsLogTag::DEFAULT, "could not find window, persistentId:%{public}d", persistentId);
12991 return WSError::WS_ERROR_INVALID_WINDOW;
12992 }
12993 return sceneSession->UpdateTitleInTargetPos(isShow, height);
12994 }
12995
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)12996 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
12997 {
12998 TLOGI(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStarted");
12999 if (debugInfos.empty()) {
13000 TLOGE(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStarted debugInfos is empty");
13001 return;
13002 }
13003 }
13004
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)13005 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
13006 {
13007 TLOGI(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStoped");
13008 if (debugInfos.empty()) {
13009 TLOGE(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStoped debugInfos is empty");
13010 return;
13011 }
13012 }
13013
SetHasRootSceneRequestedVsyncFunc(HasRootSceneRequestedVsyncFunc && func)13014 void SceneSessionManager::SetHasRootSceneRequestedVsyncFunc(HasRootSceneRequestedVsyncFunc&& func)
13015 {
13016 if (!func) {
13017 TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
13018 return;
13019 }
13020 hasRootSceneRequestedVsyncFunc_ = std::move(func);
13021 }
13022
HasRootSceneRequestedVsync(bool & hasRootSceneRequestedVsync)13023 WSError SceneSessionManager::HasRootSceneRequestedVsync(bool& hasRootSceneRequestedVsync)
13024 {
13025 if (!hasRootSceneRequestedVsyncFunc_) {
13026 TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
13027 return WSError::WS_ERROR_NULLPTR;
13028 }
13029 hasRootSceneRequestedVsync = hasRootSceneRequestedVsyncFunc_();
13030 return WSError::WS_OK;
13031 }
13032
SetRequestVsyncByRootSceneWhenModeChangeFunc(RequestVsyncByRootSceneWhenModeChangeFunc && func)13033 void SceneSessionManager::SetRequestVsyncByRootSceneWhenModeChangeFunc(
13034 RequestVsyncByRootSceneWhenModeChangeFunc&& func)
13035 {
13036 if (!func) {
13037 TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
13038 return;
13039 }
13040 requestVsyncByRootSceneWhenModeChangeFunc_ = std::move(func);
13041 }
13042
UpdateWindowModeByIdForUITest(int32_t windowId,int32_t updateMode)13043 WMError SceneSessionManager::UpdateWindowModeByIdForUITest(int32_t windowId, int32_t updateMode)
13044 {
13045 if (!SessionPermission::IsSACalling()) {
13046 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
13047 return WMError::WM_ERROR_INVALID_PERMISSION;
13048 }
13049 auto task = [this, windowId, updateMode, where = __func__] {
13050 auto sceneSession = GetSceneSession(windowId);
13051 if (sceneSession == nullptr) {
13052 TLOGNE(WmsLogTag::WMS_LAYOUT, "sceneSession is nullptr, windowId: %{public}d, updateMode: %{public}d",
13053 windowId, updateMode);
13054 return WMError::WM_ERROR_INVALID_WINDOW;
13055 }
13056 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s, windowId: %{public}d, updateMode: %{public}d", where , windowId, updateMode);
13057 return sceneSession->UpdateWindowModeForUITest(updateMode);
13058 };
13059 return taskScheduler_->PostSyncTask(task,
13060 "UpdateWindowModeByIdForUITest windowId: " + std::to_string(windowId) + " updateMode: " + std::to_string(updateMode));
13061 }
13062
RequestVsyncByRootSceneWhenModeChange(const std::shared_ptr<VsyncCallback> & vsyncCallback)13063 WSError SceneSessionManager::RequestVsyncByRootSceneWhenModeChange(const std::shared_ptr<VsyncCallback>& vsyncCallback)
13064 {
13065 if (!requestVsyncByRootSceneWhenModeChangeFunc_) {
13066 TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
13067 return WSError::WS_ERROR_NULLPTR;
13068 }
13069 requestVsyncByRootSceneWhenModeChangeFunc_(vsyncCallback);
13070 return WSError::WS_OK;
13071 }
13072
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)13073 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
13074 {
13075 if (!Session::IsScbCoreEnabled()) {
13076 return;
13077 }
13078 if (onFlushUIParamsFunc_ != nullptr) {
13079 onFlushUIParamsFunc_();
13080 }
13081 const char* const where = __func__;
13082 taskScheduler_->PostAsyncTask([this, screenId, where,
13083 uiParams = std::move(uiParams)]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
13084 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
13085 TLOGND(WmsLogTag::WMS_PIPELINE, "%{public}s", where);
13086 {
13087 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
13088 nextFlushCompletedCV_.notify_all();
13089 }
13090 std::vector<std::pair<uint32_t, uint32_t>> appZOrderList;
13091 processingFlushUIParams_.store(true);
13092 auto keyboardSession = GetKeyboardSession(screenId, false);
13093 {
13094 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13095 for (const auto& [_, sceneSession] : sceneSessionMap_) {
13096 if (sceneSession == nullptr) {
13097 continue;
13098 }
13099 if (isNotCurrentScreen(sceneSession, screenId)) {
13100 TLOGND(WmsLogTag::WMS_PIPELINE, "%{public}s The screenId of this Scenesession is invalid", where);
13101 continue;
13102 }
13103 if (auto iter = uiParams.find(sceneSession->GetPersistentId()); iter != uiParams.end()) {
13104 if ((systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) &&
13105 sceneSession->IsAppSession()) {
13106 if (!sceneSession->IsVisible()) {
13107 appZOrderList.push_back(std::make_pair(0, iter->second.zOrder_));
13108 }
13109 appZOrderList.push_back(std::make_pair(sceneSession->GetZOrder(), iter->second.zOrder_));
13110 }
13111 sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
13112 } else {
13113 sessionMapDirty_ |= sceneSession->UpdateUIParam();
13114 }
13115 }
13116 if (keyboardSession != nullptr) {
13117 keyboardSession->CalculateOccupiedAreaAfterUIRefresh();
13118 }
13119 }
13120 processingFlushUIParams_.store(false);
13121
13122 // post process if dirty
13123 if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
13124 static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
13125 TLOGND(WmsLogTag::WMS_PIPELINE, "%{public}s found dirty: %{public}d", where, sessionMapDirty_);
13126 for (const auto& item : uiParams) {
13127 TLOGND(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f,"
13128 " transY:%{public}f, needSync:%{public}d, interactive:%{public}d", item.first, item.second.zOrder_,
13129 item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
13130 item.second.needSync_, item.second.interactive_);
13131 }
13132 ProcessUpdateLastFocusedAppId(appZOrderList);
13133 ProcessFocusZOrderChange(sessionMapDirty_);
13134 PostProcessFocus();
13135 PostProcessProperty(sessionMapDirty_);
13136 NotifyAllAccessibilityInfo();
13137 AnomalyDetection::SceneZOrderCheckProcess();
13138 } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
13139 PostProcessProperty(sessionMapDirty_);
13140 }
13141 FlushWindowInfoToMMI();
13142 NotifyWindowPropertyChange(screenId);
13143 sessionMapDirty_ = 0;
13144 {
13145 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13146 for (const auto& [_, sceneSession] : sceneSessionMap_) {
13147 if (sceneSession == nullptr) {
13148 continue;
13149 }
13150 if (isNotCurrentScreen(sceneSession, screenId)) {
13151 TLOGND(WmsLogTag::WMS_PIPELINE, "%{public}s The screenId of this Scenesession is invalid", where);
13152 continue;
13153 }
13154 sceneSession->ResetSizeChangeReasonIfDirty();
13155 sceneSession->ResetDirtyFlags();
13156 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
13157 sceneSession->SetUIStateDirty(false);
13158 }
13159 }
13160 }
13161 if (needCloseSync_) {
13162 if (closeSyncFunc_) {
13163 closeSyncFunc_();
13164 }
13165 needCloseSync_ = false;
13166 }
13167 }, __func__);
13168 }
13169
ProcessUpdateLastFocusedAppId(const std::vector<std::pair<uint32_t,uint32_t>> & zOrderList)13170 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<std::pair<uint32_t, uint32_t>>& zOrderList)
13171 {
13172 auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
13173 if (focusGroup == nullptr) {
13174 TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
13175 return;
13176 }
13177 auto lastFocusedAppSessionId = focusGroup->GetLastFocusedAppSessionId();
13178 TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu",
13179 lastFocusedAppSessionId, zOrderList.size());
13180 if (lastFocusedAppSessionId == INVALID_SESSION_ID || zOrderList.empty()) {
13181 return;
13182 }
13183 auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId);
13184 if (lastFocusedAppSession == nullptr) {
13185 return;
13186 }
13187 uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
13188 auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder]
13189 (const std::pair<uint32_t, uint32_t>& pair) {
13190 return pair.first < lastFocusedAppZOrder && pair.second > lastFocusedAppZOrder;
13191 });
13192 if (it != zOrderList.end()) {
13193 TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
13194 focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
13195 }
13196 }
13197
ProcessFocusZOrderChange(uint32_t dirty)13198 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
13199 {
13200 if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
13201 return;
13202 }
13203 if (!systemConfig_.IsPhoneWindow() && !systemConfig_.IsPadWindow()) {
13204 return;
13205 }
13206 TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
13207 auto focusedSessionId = GetFocusedSessionId(DEFAULT_DISPLAY_ID);
13208 auto focusedSession = GetSceneSession(focusedSessionId);
13209 // only when it's from a high zOrder to a low zOrder
13210 if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
13211 focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
13212 return;
13213 }
13214 auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
13215 if (voiceInteractionSession == nullptr) {
13216 return;
13217 }
13218 TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
13219 "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
13220 voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
13221 if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
13222 focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
13223 return;
13224 }
13225 RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
13226 }
13227
PostProcessFocus()13228 void SceneSessionManager::PostProcessFocus()
13229 {
13230 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
13231 // priority process focus requests from top to bottom
13232 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
13233 {
13234 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13235 for (auto& iter : sceneSessionMap_) {
13236 auto session = iter.second;
13237 if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
13238 continue;
13239 }
13240 processingSessions.push_back(iter);
13241 }
13242 }
13243 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
13244 bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
13245 !rhs.second->GetPostProcessFocusState().isFocused_;
13246 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
13247 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
13248 return focusCmp || lhsZOrder > rhsZOrder;
13249 };
13250 std::sort(processingSessions.begin(), processingSessions.end(), cmp);
13251
13252 // only change focus one time
13253 std::unordered_set<DisplayId> focusChangedSet;
13254 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
13255 auto session = iter->second;
13256 if (session == nullptr) {
13257 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
13258 continue;
13259 }
13260 auto displayId = session->GetSessionProperty()->GetDisplayId();
13261 auto displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
13262 TLOGD(WmsLogTag::WMS_PIPELINE,
13263 "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
13264 session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
13265 session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
13266 if (focusChangedSet.find(displayGroupId) != focusChangedSet.end()) {
13267 session->ResetPostProcessFocusState();
13268 continue;
13269 }
13270 if (!session->IsFocusedOnShow()) {
13271 if (IsSessionVisibleForeground(session)) {
13272 session->SetFocusedOnShow(true);
13273 }
13274 session->ResetPostProcessFocusState();
13275 continue;
13276 }
13277
13278 WSError ret = WSError::WS_DO_NOTHING;
13279 if (session->GetPostProcessFocusState().isFocused_) {
13280 if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP &&
13281 session->IsDelayFocusChange()) {
13282 TLOGI(WmsLogTag::WMS_FOCUS, "delay focus change until the window is visible");
13283 continue;
13284 } else if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
13285 ret = RequestSessionFocusImmediately(session->GetPersistentId());
13286 } else if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::RECENT) {
13287 ret = RequestSessionFocus(session->GetPersistentId(),
13288 session->GetPostProcessFocusState().byForeground_,
13289 session->GetPostProcessFocusState().reason_);
13290 } else {
13291 ret = RequestSessionFocus(session->GetPersistentId(), true,
13292 session->GetPostProcessFocusState().reason_);
13293 }
13294 } else {
13295 ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
13296 }
13297 session->ResetPostProcessFocusState();
13298 // if succeed then end process
13299 if (ret == WSError::WS_OK) {
13300 focusChangedSet.insert(displayGroupId);
13301 }
13302 }
13303 }
13304
PostProcessProperty(uint32_t dirty)13305 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
13306 {
13307 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
13308 if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
13309 // only trigger update avoid area
13310 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13311 for (auto& iter : sceneSessionMap_) {
13312 auto session = iter.second;
13313 if (session == nullptr) {
13314 continue;
13315 }
13316 session->PostProcessNotifyAvoidArea();
13317 }
13318 return;
13319 }
13320
13321 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
13322 {
13323 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13324 for (auto& iter : sceneSessionMap_) {
13325 auto session = iter.second;
13326 if (session == nullptr || !session->GetPostProcessProperty()) {
13327 continue;
13328 }
13329 processingSessions.push_back(iter);
13330 }
13331 }
13332
13333 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
13334 auto session = iter->second;
13335 if (session == nullptr) {
13336 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
13337 continue;
13338 }
13339 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
13340 UpdateForceHideState(session, session->GetSessionProperty(), true);
13341 HandleKeepScreenOn(session, session->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX, session->keepScreenLock_);
13342 HandleKeepScreenOn(session, session->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
13343 session->viewKeepScreenLock_);
13344 UpdatePrivateStateAndNotify(session->GetPersistentId());
13345 if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
13346 ProcessSubSessionForeground(session);
13347 }
13348 session->SetPostProcessProperty(false);
13349 }
13350
13351 // update avoid area
13352 {
13353 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13354 for (auto& iter : sceneSessionMap_) {
13355 auto session = iter.second;
13356 if (session == nullptr) {
13357 continue;
13358 }
13359 session->PostProcessNotifyAvoidArea();
13360 }
13361 }
13362 }
13363
13364 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)13365 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
13366 {
13367 TLOGI(WmsLogTag::WMS_HIERARCHY, "id %{public}d", persistentId);
13368 auto isSaCall = SessionPermission::IsSACalling();
13369 if (!isSaCall) {
13370 TLOGE(WmsLogTag::WMS_HIERARCHY, "The interface only support for sa call");
13371 return WSError::WS_ERROR_INVALID_PERMISSION;
13372 }
13373 auto task = [this, persistentId]() {
13374 auto sceneSession = GetSceneSession(persistentId);
13375 if (sceneSession == nullptr) {
13376 TLOGNE(WmsLogTag::WMS_HIERARCHY, "session is nullptr");
13377 return WSError::WS_ERROR_INVALID_SESSION;
13378 }
13379 if (!IsSessionVisibleForeground(sceneSession)) {
13380 TLOGND(WmsLogTag::WMS_HIERARCHY, "session is not visible!");
13381 return WSError::WS_DO_NOTHING;
13382 }
13383 FocusChangeReason reason = FocusChangeReason::MOVE_UP;
13384 RequestSessionFocus(persistentId, true, reason);
13385 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
13386 sceneSession->RaiseToAppTop();
13387 }
13388 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
13389 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
13390 TLOGND(WmsLogTag::WMS_HIERARCHY, "parent session id: %{public}d", sceneSession->GetParentPersistentId());
13391 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
13392 }
13393 if (sceneSession == nullptr) {
13394 TLOGNE(WmsLogTag::WMS_HIERARCHY, "parent session is nullptr");
13395 return WSError::WS_ERROR_INVALID_SESSION;
13396 }
13397 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
13398 sceneSession->NotifyClick(true, false);
13399 return WSError::WS_OK;
13400 } else {
13401 TLOGNE(WmsLogTag::WMS_HIERARCHY, "session is not app main window!");
13402 return WSError::WS_ERROR_INVALID_SESSION;
13403 }
13404 };
13405 taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
13406 return WSError::WS_OK;
13407 }
13408
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)13409 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
13410 {
13411 TLOGI(WmsLogTag::WMS_FOCUS, "from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
13412 sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
13413 if (sourceSession == nullptr) {
13414 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr, id: %{public}d", sourcePersistentId);
13415 return WSError::WS_ERROR_INVALID_SESSION;
13416 }
13417 auto displayId = sourceSession->GetSessionProperty()->GetDisplayId();
13418 auto focusedSessionId = GetFocusedSessionId(displayId);
13419 if (sourcePersistentId != focusedSessionId) {
13420 TLOGE(WmsLogTag::WMS_FOCUS, "source session need be focused, focusedSessionId: %{public}d", focusedSessionId);
13421 return WSError::WS_ERROR_INVALID_OPERATION;
13422 }
13423 if (targetPersistentId == focusedSessionId) {
13424 TLOGE(WmsLogTag::WMS_FOCUS, "target session has been focused, focusedSessionId: %{public}d", focusedSessionId);
13425 return WSError::WS_DO_NOTHING;
13426 }
13427 WSError ret = GetAppMainSceneSession(sourcePersistentId, sourceSession);
13428 if (ret != WSError::WS_OK) {
13429 return ret;
13430 }
13431 sptr<SceneSession> targetSession = nullptr;
13432 ret = GetAppMainSceneSession(targetPersistentId, targetSession);
13433 if (ret != WSError::WS_OK) {
13434 return ret;
13435 }
13436 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
13437 TLOGE(WmsLogTag::WMS_FOCUS, "verify bundle failed, source name is %{public}s but target name is %{public}s)",
13438 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
13439 return WSError::WS_ERROR_INVALID_CALLING;
13440 }
13441 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
13442 return WSError::WS_ERROR_INVALID_CALLING;
13443 }
13444 int32_t callingPid = IPCSkeleton::GetCallingPid();
13445 if (callingPid != targetSession->GetCallingPid()) {
13446 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
13447 return WSError::WS_ERROR_INVALID_CALLING;
13448 }
13449 targetSession->NotifyClick(true, false);
13450 FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
13451 return RequestSessionFocus(targetPersistentId, false, reason);
13452 }
13453
GetAppMainSceneSession(int32_t persistentId,sptr<SceneSession> & sceneSession)13454 WSError SceneSessionManager::GetAppMainSceneSession(int32_t persistentId, sptr<SceneSession>& sceneSession)
13455 {
13456 sceneSession = GetSceneSession(persistentId);
13457 if (sceneSession == nullptr) {
13458 TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) is nullptr", persistentId);
13459 return WSError::WS_ERROR_INVALID_SESSION;
13460 }
13461 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
13462 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
13463 TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) is not main window or sub window", persistentId);
13464 return WSError::WS_ERROR_INVALID_CALLING;
13465 }
13466 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
13467 if (sceneSession == nullptr) {
13468 TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) parent is nullptr", persistentId);
13469 return WSError::WS_ERROR_INVALID_SESSION;
13470 }
13471 }
13472 return WSError::WS_OK;
13473 }
13474
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam,SnapshotNodeType snapshotNode,bool needSnapshot)13475 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
13476 const float scaleParam, SnapshotNodeType snapshotNode, bool needSnapshot)
13477 {
13478 auto sceneSession = GetSceneSession(persistentId);
13479 if (!sceneSession) {
13480 TLOGE(WmsLogTag::WMS_MAIN, "get scene session is nullptr");
13481 return nullptr;
13482 }
13483
13484 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
13485 auto isPersistentImageFit = ScenePersistentStorage::HasKey("SetImageForRecent_" + std::to_string(persistentId),
13486 ScenePersistentStorageType::MAXIMIZE_STATE);
13487
13488 bool isPc = systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode();
13489 bool useCurWindow = (snapshotNode == SnapshotNodeType::DEFAULT_NODE) ?
13490 isPc : (snapshotNode == SnapshotNodeType::LEASH_NODE) ? false : true;
13491 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
13492 if (needSnapshot && !isPersistentImageFit) {
13493 pixelMap = sceneSession->Snapshot(true, scaleParam, useCurWindow);
13494 }
13495 if (!pixelMap) {
13496 TLOGI(WmsLogTag::WMS_MAIN, "get local snapshot pixelmap start");
13497 pixelMap = sceneSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
13498 }
13499 return pixelMap;
13500 }
13501
GetSceneSessionMap()13502 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
13503 {
13504 std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
13505 {
13506 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13507 retSceneSessionMap = sceneSessionMap_;
13508 }
13509 EraseIf(retSceneSessionMap, [this](const auto& pair) {
13510 if (pair.second == nullptr) {
13511 return true;
13512 }
13513
13514 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
13515 if (pair.second->IsVisible()) {
13516 return false;
13517 }
13518 return true;
13519 }
13520
13521 if (pair.second->IsSystemInput()) {
13522 return false;
13523 } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
13524 return false;
13525 }
13526
13527 if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
13528 return true;
13529 }
13530 return false;
13531 });
13532 return retSceneSessionMap;
13533 }
13534
NotifyUpdateRectAfterLayout()13535 void SceneSessionManager::NotifyUpdateRectAfterLayout()
13536 {
13537 std::shared_ptr<RSTransaction> rsTransaction = nullptr;
13538 std::shared_ptr<RSUIContext> rsUIContext;
13539 if (auto rootSceneSession = GetRootSceneSession()) {
13540 rsUIContext = rootSceneSession->GetRSUIContext();
13541 }
13542 rsTransaction = RSSyncTransactionAdapter::GetRSTransaction(rsUIContext);
13543 auto task = [this, rsTransaction] {
13544 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13545 for (const auto& [_, sceneSession] : sceneSessionMap_) {
13546 if (sceneSession && sceneSession->IsDirtyWindow()) {
13547 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
13548 }
13549 }
13550 };
13551 // need sync task since animation transcation need
13552 taskScheduler_->PostAsyncTask(task, __func__);
13553 }
13554
ListWindowInfo(const WindowInfoOption & windowInfoOption,std::vector<sptr<WindowInfo>> & infos)13555 WMError SceneSessionManager::ListWindowInfo(const WindowInfoOption& windowInfoOption,
13556 std::vector<sptr<WindowInfo>>& infos)
13557 {
13558 if (!(SessionPermission::IsSACalling())) {
13559 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied");
13560 return WMError::WM_ERROR_INVALID_PERMISSION;
13561 }
13562 const char* const where = __func__;
13563 return taskScheduler_->PostSyncTask([this, windowInfoOption, &infos, where] {
13564 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::ListWindowInfo (%u) "
13565 "(%u) (%" PRIu64 ") (%d)",
13566 static_cast<WindowInfoFilterOptionDataType>(windowInfoOption.windowInfoFilterOption),
13567 static_cast<WindowInfoTypeOptionDataType>(windowInfoOption.windowInfoTypeOption),
13568 windowInfoOption.displayId, windowInfoOption.windowId);
13569 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13570 for (const auto& [_, sceneSession] : sceneSessionMap_) {
13571 if (sceneSession == nullptr) {
13572 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: session is null", where);
13573 continue;
13574 }
13575 if (!FilterForListWindowInfo(windowInfoOption, sceneSession)) {
13576 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: filter win: %{public}d",
13577 where, sceneSession->GetWindowId());
13578 continue;
13579 }
13580 auto windowInfo = sptr<WindowInfo>::MakeSptr();
13581 if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_UI_INFO)) {
13582 windowInfo->windowUIInfo = sceneSession->GetWindowUIInfoForWindowInfo();
13583 }
13584 if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_DISPLAY_INFO)) {
13585 windowInfo->windowDisplayInfo = sceneSession->GetWindowDisplayInfoForWindowInfo();
13586 }
13587 if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_LAYOUT_INFO)) {
13588 windowInfo->windowLayoutInfo = sceneSession->GetWindowLayoutInfoForWindowInfo();
13589 }
13590 if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_META_INFO)) {
13591 windowInfo->windowMetaInfo = sceneSession->GetWindowMetaInfoForWindowInfo();
13592 }
13593 infos.emplace_back(windowInfo);
13594 }
13595 return WMError::WM_OK;
13596 }, __func__);
13597 }
13598
FilterForListWindowInfo(const WindowInfoOption & windowInfoOption,const sptr<SceneSession> & sceneSession) const13599 bool SceneSessionManager::FilterForListWindowInfo(const WindowInfoOption& windowInfoOption,
13600 const sptr<SceneSession>& sceneSession) const
13601 {
13602 DisplayId displayId = windowInfoOption.displayId;
13603 if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(sceneSession->GetSessionProperty()->GetDisplayId())) {
13604 if (displayId == DEFAULT_DISPLAY_ID && sceneSession->GetSessionGlobalRect().posY_ >= GetFoldLowerScreenPosY()) {
13605 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "fold lower screen win: %{public}d", sceneSession->GetWindowId());
13606 return false;
13607 }
13608 if (displayId == VIRTUAL_DISPLAY_ID) {
13609 if (sceneSession->GetSessionGlobalRect().posY_ +
13610 sceneSession->GetSessionGlobalRect().height_ < GetFoldLowerScreenPosY()) {
13611 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "fold virtual screen win: %{public}d", sceneSession->GetWindowId());
13612 return false;
13613 }
13614 displayId = DEFAULT_DISPLAY_ID;
13615 }
13616 }
13617 if (displayId != DISPLAY_ID_INVALID && sceneSession->GetSessionProperty()->GetDisplayId() != displayId) {
13618 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "win: %{public}d, target displayId: %{public}" PRIu64,
13619 sceneSession->GetWindowId(), displayId);
13620 return false;
13621 }
13622 if (windowInfoOption.windowId != 0 && sceneSession->GetWindowId() != windowInfoOption.windowId) {
13623 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "win: %{public}d, target winId: %{public}d",
13624 sceneSession->GetWindowId(), windowInfoOption.windowId);
13625 return false;
13626 }
13627 if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::EXCLUDE_SYSTEM) &&
13628 sceneSession->GetSessionInfo().isSystem_) {
13629 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "exclude system win: %{public}d", sceneSession->GetWindowId());
13630 return false;
13631 }
13632 if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::VISIBLE) &&
13633 (sceneSession->GetVisibilityState() == WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION ||
13634 sceneSession->GetVisibilityState() == WINDOW_LAYER_STATE_MAX)) {
13635 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "exclude unvisible win: %{public}d", sceneSession->GetWindowId());
13636 return false;
13637 }
13638 if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::FOREGROUND) &&
13639 !IsSessionVisibleForeground(sceneSession)) {
13640 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "exclude background win: %{public}d", sceneSession->GetWindowId());
13641 return false;
13642 }
13643 return true;
13644 }
13645
GetAllWindowLayoutInfo(DisplayId displayId,std::vector<sptr<WindowLayoutInfo>> & infos)13646 WMError SceneSessionManager::GetAllWindowLayoutInfo(DisplayId displayId,
13647 std::vector<sptr<WindowLayoutInfo>>& infos)
13648 {
13649 auto task = [this, displayId, &infos, funcName = __func__]() mutable {
13650 bool isVirtualDisplay = false;
13651 if (displayId == VIRTUAL_DISPLAY_ID) {
13652 displayId = DEFAULT_DISPLAY_ID;
13653 isVirtualDisplay = true;
13654 }
13655 std::vector<sptr<SceneSession>> filteredSessions;
13656 FilterForGetAllWindowLayoutInfo(displayId, isVirtualDisplay, filteredSessions);
13657 for (const auto& session : filteredSessions) {
13658 Rect globalScaledRect;
13659 session->GetGlobalScaledRect(globalScaledRect);
13660 if (isVirtualDisplay) {
13661 globalScaledRect.posY_ -= GetFoldLowerScreenPosY();
13662 }
13663 HookWindowInfo hookWindowInfo = GetAppHookWindowInfo(session->GetSessionInfo().bundleName_);
13664 if (hookWindowInfo.enableHookWindow &&
13665 WindowHelper::IsMainWindow(session->GetWindowType()) &&
13666 !MathHelper::NearEqual(hookWindowInfo.widthHookRatio, HookWindowInfo::DEFAULT_WINDOW_SIZE_HOOK_RATIO)) {
13667 globalScaledRect.width_ =
13668 static_cast<uint32_t>(globalScaledRect.width_ * hookWindowInfo.widthHookRatio);
13669 TLOGD(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}u, hook window width, hooked width:%{public}u, "
13670 "widthHookRatio:%{public}f.", funcName, session->GetPersistentId(), globalScaledRect.width_,
13671 hookWindowInfo.widthHookRatio);
13672 }
13673 auto windowLayoutInfo = sptr<WindowLayoutInfo>::MakeSptr();
13674 windowLayoutInfo->rect = globalScaledRect;
13675 infos.emplace_back(windowLayoutInfo);
13676 }
13677 return WMError::WM_OK;
13678 };
13679 return taskScheduler_->PostSyncTask(task, __func__);
13680 }
13681
FilterForGetAllWindowLayoutInfo(DisplayId displayId,bool isVirtualDisplay,std::vector<sptr<SceneSession>> & filteredSessions)13682 void SceneSessionManager::FilterForGetAllWindowLayoutInfo(DisplayId displayId, bool isVirtualDisplay,
13683 std::vector<sptr<SceneSession>>& filteredSessions)
13684 {
13685 {
13686 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13687 for (const auto& [_, session] : sceneSessionMap_) {
13688 if (session == nullptr) {
13689 continue;
13690 }
13691 if (session->GetSessionGlobalRect().IsInvalid()) {
13692 continue;
13693 }
13694 if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(session->GetSessionProperty()->GetDisplayId()) &&
13695 displayId == DEFAULT_DISPLAY_ID) {
13696 if (isVirtualDisplay &&
13697 session->GetSessionRect().posY_ + session->GetSessionRect().height_ < GetFoldLowerScreenPosY()) {
13698 continue;
13699 }
13700 if (!isVirtualDisplay && session->GetSessionRect().posY_ >= GetFoldLowerScreenPosY()) {
13701 continue;
13702 }
13703 }
13704 if (IsGetWindowLayoutInfoNeeded(session) && session->GetSessionProperty()->GetDisplayId() == displayId &&
13705 session->GetVisibilityState() != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
13706 filteredSessions.emplace_back(session);
13707 }
13708 }
13709 }
13710 std::sort(filteredSessions.begin(), filteredSessions.end(),
13711 [](const sptr<SceneSession>& lhs, const sptr<SceneSession>& rhs) {
13712 return lhs->GetZOrder() > rhs->GetZOrder();
13713 });
13714 }
13715
GetFoldLowerScreenPosY() const13716 int32_t SceneSessionManager::GetFoldLowerScreenPosY() const
13717 {
13718 const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
13719 PcFoldScreenManager::GetInstance().GetDisplayRects();
13720 constexpr int32_t SUPER_FOLD_DIVIDE_FACTOR = 2;
13721 return foldCreaseRect.height_ != 0 ?
13722 defaultDisplayRect.height_ - foldCreaseRect.height_ / SUPER_FOLD_DIVIDE_FACTOR + foldCreaseRect.height_ :
13723 defaultDisplayRect.height_;
13724 }
13725
IsGetWindowLayoutInfoNeeded(const sptr<SceneSession> & session) const13726 bool SceneSessionManager::IsGetWindowLayoutInfoNeeded(const sptr<SceneSession>& session) const
13727 {
13728 std::string name = session->GetWindowName();
13729 size_t pos = name.size();
13730 while (pos > 0 && std::isdigit(static_cast<unsigned char>(name[pos - 1]))) {
13731 --pos;
13732 }
13733 name.resize(pos);
13734 return !session->GetSessionInfo().isSystem_ || LAYOUT_INFO_WHITELIST.find(name) != LAYOUT_INFO_WHITELIST.end();
13735 }
13736
GetGlobalWindowMode(DisplayId displayId,GlobalWindowMode & globalWinMode)13737 WMError SceneSessionManager::GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode)
13738 {
13739 return taskScheduler_->PostSyncTask([this, displayId, &globalWinMode, where = __func__] {
13740 globalWinMode = GlobalWindowMode::UNKNOWN;
13741 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: displayId=%{public}" PRIu64, where, displayId);
13742 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13743 for (const auto& [_, session] : sceneSessionMap_) {
13744 if (session == nullptr) {
13745 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: session is null", where);
13746 continue;
13747 }
13748 if (displayId != DISPLAY_ID_INVALID && !IsSessionInSpecificDisplay(session, displayId)) {
13749 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: not in display, win: [%{public}d, %{public}s]",
13750 where, session->GetWindowId(), session->GetWindowName().c_str());
13751 continue;
13752 }
13753 if (!session->IsSessionForeground()) {
13754 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: skip win=[%{public}d, %{public}s], stat: %{public}u",
13755 where, session->GetWindowId(), session->GetWindowName().c_str(),
13756 static_cast<uint32_t>(session->GetSessionState()));
13757 continue;
13758 }
13759 WindowMode winMode = session->GetWindowMode();
13760 if (WindowHelper::IsPipWindowMode(winMode)) {
13761 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: found pip win=[%{public}d, %{public}s]",
13762 where, session->GetWindowId(), session->GetWindowName().c_str());
13763 globalWinMode = globalWinMode | GlobalWindowMode::PIP;
13764 } else if (WindowHelper::IsFullScreenWindow(winMode)) {
13765 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: found fullscreen win=[%{public}d, %{public}s]",
13766 where, session->GetWindowId(), session->GetWindowName().c_str());
13767 globalWinMode = globalWinMode | GlobalWindowMode::FULLSCREEN;
13768 } else if (WindowHelper::IsSplitWindowMode(winMode)) {
13769 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: found split win=[%{public}d, %{public}s]",
13770 where, session->GetWindowId(), session->GetWindowName().c_str());
13771 globalWinMode = globalWinMode | GlobalWindowMode::SPLIT;
13772 } else if (WindowHelper::IsFloatingWindow(winMode)) {
13773 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: found floating win=[%{public}d, %{public}s]",
13774 where, session->GetWindowId(), session->GetWindowName().c_str());
13775 globalWinMode = globalWinMode | GlobalWindowMode::FLOAT;
13776 }
13777 if (globalWinMode == GlobalWindowMode::ALL) {
13778 break;
13779 }
13780 }
13781 return WMError::WM_OK;
13782 }, __func__);
13783 }
13784
GetTopNavDestinationName(int32_t windowId,std::string & topNavDestName)13785 WMError SceneSessionManager::GetTopNavDestinationName(int32_t windowId, std::string& topNavDestName)
13786 {
13787 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
13788 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13789 return WMError::WM_ERROR_NOT_SYSTEM_APP;
13790 }
13791 auto session = GetSceneSession(windowId);
13792 if (session == nullptr) {
13793 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "no session with id: %{public}d", windowId);
13794 return WMError::WM_ERROR_INVALID_WINDOW;
13795 }
13796 if (!session->IsSessionForeground()) {
13797 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid operation: win=%{public}d, stat: %{public}u",
13798 session->GetWindowId(), static_cast<uint32_t>(session->GetSessionState()));
13799 return WMError::WM_ERROR_INVALID_OPERATION;
13800 }
13801 auto wsErrCode = session->GetTopNavDestinationName(topNavDestName);
13802 if (wsErrCode != WSError::WS_OK) {
13803 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "get failed: win=%{public}d, errCode=%{public}d",
13804 session->GetWindowId(), static_cast<int32_t>(wsErrCode));
13805 return WMError::WM_ERROR_SYSTEM_ABNORMALLY;
13806 }
13807 return WMError::WM_OK;
13808 }
13809
IsSessionInSpecificDisplay(const sptr<SceneSession> & session,DisplayId displayId) const13810 bool SceneSessionManager::IsSessionInSpecificDisplay(const sptr<SceneSession>& session, DisplayId displayId) const
13811 {
13812 if (session == nullptr) {
13813 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "session is null");
13814 return false;
13815 }
13816 if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(session->GetSessionProperty()->GetDisplayId()) &&
13817 (displayId == VIRTUAL_DISPLAY_ID || displayId == DEFAULT_DISPLAY_ID)) {
13818 bool isVirtualDisplay = displayId == VIRTUAL_DISPLAY_ID;
13819 if (isVirtualDisplay &&
13820 session->GetSessionRect().posY_ + session->GetSessionRect().height_ < GetFoldLowerScreenPosY()) {
13821 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "not in virtual display, win: [%{public}d, %{public}s]",
13822 session->GetWindowId(), session->GetWindowName().c_str());
13823 return false;
13824 }
13825 if (!isVirtualDisplay && session->GetSessionRect().posY_ >= GetFoldLowerScreenPosY()) {
13826 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "in virtual display, win: [%{public}d, %{public}s]",
13827 session->GetWindowId(), session->GetWindowName().c_str());
13828 return false;
13829 }
13830 return true;
13831 }
13832 return displayId == session->GetSessionProperty()->GetDisplayId();
13833 }
13834
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)13835 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
13836 {
13837 auto task = [this, &infos, where = __func__]() {
13838 for (auto [surfaceId, _] : lastVisibleData_) {
13839 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
13840 if (session == nullptr) {
13841 continue;
13842 }
13843 WSRect hostRect = session->GetSessionRect();
13844 Rect rect = {hostRect.posX_, hostRect.posY_,
13845 static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
13846 auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
13847 session->GetSessionProperty());
13848 auto windowVisibilityInfo = sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
13849 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
13850 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_,
13851 session->IsFocused());
13852 windowVisibilityInfo->SetAppIndex(session->GetSessionInfo().appIndex_);
13853 windowVisibilityInfo->SetIsSystem(session->GetSessionInfo().isSystem_);
13854 windowVisibilityInfo->SetZOrder(session->GetZOrder());
13855 Rect globalDisplayRect = session->GetSessionProperty()->GetGlobalDisplayRect();
13856 windowVisibilityInfo->SetGlobalDisplayRect(globalDisplayRect);
13857 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: wid=%{public}d, globalDisplayRect=%{public}s",
13858 where, static_cast<int32_t>(session->GetPersistentId()), globalDisplayRect.ToString().c_str());
13859 HookWindowInfo hookWindowInfo = GetAppHookWindowInfo(session->GetSessionInfo().bundleName_);
13860 if (hookWindowInfo.enableHookWindow &&
13861 WindowHelper::IsMainWindow(session->GetWindowType()) &&
13862 !MathHelper::NearEqual(hookWindowInfo.widthHookRatio, HookWindowInfo::DEFAULT_WINDOW_SIZE_HOOK_RATIO)) {
13863 rect.width_ = static_cast<uint32_t>(rect.width_ * hookWindowInfo.widthHookRatio);
13864 globalDisplayRect.width_ =
13865 static_cast<uint32_t>(globalDisplayRect.width_ * hookWindowInfo.widthHookRatio);
13866 windowVisibilityInfo->rect_ = rect;
13867 windowVisibilityInfo->SetGlobalDisplayRect(globalDisplayRect);
13868 TLOGD(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}u, hook window width, hooked width:%{public}u, "
13869 "hooked globalDisplay width:%{public}u, widthHookRatio:%{public}f.", where,
13870 session->GetPersistentId(), rect.width_, globalDisplayRect.width_, hookWindowInfo.widthHookRatio);
13871 }
13872 infos.emplace_back(windowVisibilityInfo);
13873 }
13874 return WMError::WM_OK;
13875 };
13876 return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
13877 }
13878
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)13879 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
13880 {
13881 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13882 for (const auto& [id, session] : sceneSessionMap_) {
13883 if (session == nullptr) {
13884 continue;
13885 }
13886 uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
13887 windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
13888 }
13889 }
13890
FlushWindowInfoToMMI(const bool forceFlush)13891 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
13892 {
13893 auto task = [this, forceFlush] {
13894 if (isUserBackground_) {
13895 TLOGND(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
13896 return;
13897 }
13898 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
13899 SceneInputManager::GetInstance().ResetSessionDirty();
13900 auto [windowInfoList, pixelMapList] = SceneInputManager::GetInstance().GetFullWindowInfoList();
13901 TLOGND(WmsLogTag::WMS_EVENT, "windowInfoList size: %{public}d", static_cast<int32_t>(windowInfoList.size()));
13902 SceneInputManager::GetInstance().
13903 FlushDisplayInfoToMMI(std::move(windowInfoList), std::move(pixelMapList), forceFlush);
13904 };
13905 TLOGD(WmsLogTag::WMS_EVENT, "in");
13906 taskScheduler_->PostAsyncTask(task, __func__);
13907 }
13908
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string & taskName,const int delayTime)13909 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask&& task,
13910 const std::string& taskName, const int delayTime)
13911 {
13912 taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
13913 }
13914
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)13915 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
13916 int32_t& parentId)
13917 {
13918 // This function should be called in task
13919 auto iter = extSessionInfoMap_.find(token);
13920 if (iter == extSessionInfoMap_.end()) {
13921 return false;
13922 }
13923 persistentId = iter->second.persistentId;
13924 parentId = iter->second.parentId;
13925 return true;
13926 }
13927
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession,bool isConstrainedModal)13928 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession, bool isConstrainedModal)
13929 {
13930 const char* const where = __func__;
13931 auto task = [this, remoteExtSession, isConstrainedModal, where]() {
13932 auto iter = remoteExtSessionMap_.find(remoteExtSession);
13933 if (iter == remoteExtSessionMap_.end()) {
13934 TLOGNI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession");
13935 return;
13936 }
13937 int32_t persistentId = INVALID_SESSION_ID;
13938 int32_t parentId = INVALID_SESSION_ID;
13939 auto abilityToken = iter->second;
13940 if (!GetExtensionWindowIds(abilityToken, persistentId, parentId)) {
13941 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
13942 return;
13943 }
13944
13945 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: persistentId=%{public}d, parentId=%{public}d",
13946 where, persistentId, parentId);
13947 auto sceneSession = GetSceneSession(parentId);
13948 if (sceneSession != nullptr) {
13949 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
13950 sceneSession->RemoveExtWindowFlags(persistentId);
13951 if (oldFlags.hideNonSecureWindowsFlag) {
13952 HandleSecureSessionShouldHide(sceneSession);
13953 }
13954 if (oldFlags.waterMarkFlag) {
13955 CheckAndNotifyWaterMarkChangedResult();
13956 }
13957 if (oldFlags.privacyModeFlag) {
13958 UpdatePrivateStateAndNotify(parentId);
13959 }
13960 if (!isConstrainedModal) {
13961 sceneSession->RemoveNormalModalUIExtension(persistentId);
13962 }
13963 sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
13964 sceneSession->RemoveExtensionTokenInfo(abilityToken);
13965 } else {
13966 ExtensionWindowFlags actions;
13967 actions.SetAllActive();
13968 HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
13969 }
13970 extSessionInfoMap_.erase(iter->second);
13971 remoteExtSessionMap_.erase(iter);
13972 };
13973 taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
13974 }
13975
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)13976 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
13977 {
13978 auto pid = IPCSkeleton::GetCallingRealPid();
13979 const char* const where = __func__;
13980 auto task = [this, token, pid, rect, where]() {
13981 int32_t persistentId = INVALID_SESSION_ID;
13982 int32_t parentId = INVALID_SESSION_ID;
13983 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
13984 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
13985 return;
13986 }
13987 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid=%{public}d, persistentId=%{public}d, "
13988 "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
13989 where, pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
13990 auto parentSession = GetSceneSession(parentId);
13991 if (parentSession) {
13992 auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetClientRect().posX_;
13993 auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetClientRect().posY_;
13994 Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
13995 WSRect transRect = { globalRect.posX_, globalRect.posY_, globalRect.width_, globalRect.height_ };
13996 parentSession->TransformRelativeRectToGlobalRect(transRect);
13997 globalRect.posY_ = transRect.posY_;
13998 ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect, rect, true };
13999 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid: %{public}d, persistentId: %{public}d, "
14000 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
14001 where, pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
14002 parentSession->GetSessionGlobalRect().ToString().c_str());
14003 parentSession->UpdateNormalModalUIExtension(extensionInfo);
14004 }
14005 };
14006 taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
14007 }
14008
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)14009 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
14010 {
14011 auto pid = IPCSkeleton::GetCallingRealPid();
14012 const char* const where = __func__;
14013 auto task = [this, token, pid, posX, posY, where]() {
14014 int32_t persistentId = INVALID_SESSION_ID;
14015 int32_t parentId = INVALID_SESSION_ID;
14016 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
14017 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
14018 return;
14019 }
14020 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid=%{public}d, persistentId=%{public}d, "
14021 "parentId=%{public}d", where, pid, persistentId, parentId);
14022 auto parentSession = GetSceneSession(parentId);
14023 if (parentSession) {
14024 auto modalUIExtensionEventInfo = parentSession->GetLastModalUIExtensionEventInfo();
14025 if (modalUIExtensionEventInfo && modalUIExtensionEventInfo.value().pid == pid &&
14026 modalUIExtensionEventInfo.value().persistentId == persistentId) {
14027 parentSession->ProcessPointDownSession(posX, posY);
14028 }
14029 }
14030 };
14031 taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
14032 }
14033
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId,bool isConstrainedModal)14034 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
14035 const sptr<IRemoteObject>& token, uint64_t surfaceNodeId, bool isConstrainedModal)
14036 {
14037 auto pid = IPCSkeleton::GetCallingRealPid();
14038 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
14039 const char* const where = __func__;
14040 auto task = [this, sessionStage, token, surfaceNodeId, isConstrainedModal, pid, callingTokenId, where]() {
14041 if (sessionStage == nullptr || token == nullptr) {
14042 TLOGNE(WmsLogTag::WMS_UIEXT, "input is nullptr");
14043 return;
14044 }
14045 auto remoteExtSession = sessionStage->AsObject();
14046 if (remoteExtSession == nullptr) {
14047 TLOGNE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
14048 return;
14049 }
14050 if (extensionDeath_ == nullptr) {
14051 TLOGNE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
14052 return;
14053 }
14054 if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
14055 TLOGNE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
14056 return;
14057 }
14058
14059 AAFwk::UIExtensionSessionInfo info;
14060 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
14061 if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
14062 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
14063 return;
14064 }
14065
14066 int32_t persistentId = info.persistentId;
14067 int32_t parentId = static_cast<int32_t>(info.hostWindowId);
14068 UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
14069 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: persistentId=%{public}d, parentId=%{public}d, "
14070 "usage=%{public}u, surfaceNodeId=%{public}" PRIu64 ", pid=%{public}d",
14071 where, persistentId, parentId, usage, surfaceNodeId, pid);
14072
14073 remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
14074 extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
14075
14076 auto parentSession = GetSceneSession(parentId);
14077 if (!parentSession) {
14078 TLOGNI(WmsLogTag::WMS_UIEXT, "no parent session for %{public}d", persistentId);
14079 return;
14080 }
14081
14082 UIExtensionTokenInfo tokenInfo;
14083 tokenInfo.abilityToken = token;
14084 tokenInfo.callingTokenId = callingTokenId;
14085 tokenInfo.canShowOnLockScreen = IsUIExtCanShowOnLockScreen(info.elementName, callingTokenId,
14086 info.extensionAbilityType);
14087 parentSession->AddExtensionTokenInfo(tokenInfo);
14088 parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
14089 if (usage == UIExtensionUsage::MODAL && parentSession->GetCallingPid() != GetPid()) {
14090 ExtensionWindowEventInfo extensionInfo {
14091 .persistentId = persistentId,
14092 .pid = pid,
14093 };
14094 if (!isConstrainedModal) {
14095 parentSession->AddNormalModalUIExtension(extensionInfo);
14096 }
14097 }
14098 };
14099 taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
14100 }
14101
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,bool isConstrainedModal)14102 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
14103 const sptr<IRemoteObject>& token, bool isConstrainedModal)
14104 {
14105 TLOGD(WmsLogTag::WMS_UIEXT, "in");
14106 auto task = [this, sessionStage, token, isConstrainedModal]() {
14107 if (sessionStage == nullptr || token == nullptr) {
14108 TLOGNE(WmsLogTag::WMS_UIEXT, "input is nullptr");
14109 return;
14110 }
14111 auto remoteExtSession = sessionStage->AsObject();
14112 if (remoteExtSession == nullptr) {
14113 TLOGNE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
14114 return;
14115 }
14116 auto iter = remoteExtSessionMap_.find(remoteExtSession);
14117 if (iter == remoteExtSessionMap_.end() || iter->second != token) {
14118 TLOGNE(WmsLogTag::WMS_UIEXT, "token not match");
14119 return;
14120 }
14121
14122 DestroyExtensionSession(remoteExtSession, isConstrainedModal);
14123 };
14124 taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
14125 }
14126
CalculateCombinedExtWindowFlags()14127 void SceneSessionManager::CalculateCombinedExtWindowFlags()
14128 {
14129 // Only correct when each flag is true when active, and once a uiextension is active, the host is active
14130 combinedExtWindowFlags_.bitData = 0;
14131 for (const auto& iter: extWindowFlagsMap_) {
14132 combinedExtWindowFlags_.bitData |= iter.second.bitData;
14133 }
14134 specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
14135 }
14136
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)14137 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
14138 ExtensionWindowFlags actions)
14139 {
14140 auto iter = extWindowFlagsMap_.find(persistentId);
14141 // Each flag is false when inactive, 0 means all flags are inactive
14142 auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
14143 ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
14144 if (newFlags.bitData == 0) {
14145 extWindowFlagsMap_.erase(persistentId);
14146 } else {
14147 extWindowFlagsMap_[persistentId] = newFlags;
14148 }
14149 CalculateCombinedExtWindowFlags();
14150 }
14151
HideNonSecureFloatingWindows()14152 void SceneSessionManager::HideNonSecureFloatingWindows()
14153 {
14154 if (systemConfig_.IsPcWindow()) {
14155 TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't hide");
14156 return;
14157 }
14158 bool shouldHide = false;
14159 {
14160 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14161 for (const auto& iter: sceneSessionMap_) {
14162 auto& session = iter.second;
14163 if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
14164 shouldHide = true;
14165 break;
14166 }
14167 }
14168 }
14169 if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
14170 TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
14171 shouldHide = true;
14172 }
14173 if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
14174 return;
14175 }
14176
14177 shouldHideNonSecureFloatingWindows_.store(shouldHide);
14178 for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
14179 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
14180 session->NotifyForceHideChange(shouldHide);
14181 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
14182 session->GetWindowName().c_str(), persistentId, shouldHide);
14183 }
14184 }
14185 }
14186
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)14187 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
14188 {
14189 // don't let sub-window show when switching secure host window to background
14190 if (!sceneSession->IsSessionForeground()) {
14191 return;
14192 }
14193
14194 auto parentId = sceneSession->GetPersistentId();
14195 bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
14196 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14197 for (const auto& [_, session] : sceneSessionMap_) {
14198 if (!session) {
14199 continue;
14200 }
14201 auto sessionProperty = session->GetSessionProperty();
14202 if (sessionProperty->GetParentPersistentId() != parentId) {
14203 continue;
14204 }
14205 if (SessionHelper::IsNonSecureToUIExtension(sessionProperty->GetWindowType()) &&
14206 !session->IsSystemSpecificSession()) {
14207 session->NotifyForceHideChange(shouldHide);
14208 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
14209 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
14210 }
14211 }
14212 }
14213
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)14214 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
14215 {
14216 if (sceneSession == nullptr) {
14217 TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
14218 return WSError::WS_ERROR_INVALID_SESSION;
14219 }
14220
14221 HideNonSecureFloatingWindows();
14222 HideNonSecureSubWindows(sceneSession);
14223 return WSError::WS_OK;
14224 }
14225
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)14226 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
14227 ExtensionWindowFlags actions)
14228 {
14229 UpdateSpecialExtWindowFlags(persistentId, flags, actions);
14230 if (actions.waterMarkFlag) {
14231 CheckAndNotifyWaterMarkChangedResult();
14232 }
14233 if (actions.hideNonSecureWindowsFlag) {
14234 HideNonSecureFloatingWindows();
14235 }
14236 if (actions.privacyModeFlag) {
14237 UpdatePrivateStateAndNotifyForAllScreens();
14238 }
14239 }
14240
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)14241 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
14242 {
14243 TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
14244 if (!SessionPermission::IsSystemCalling()) {
14245 TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
14246 return WSError::WS_ERROR_NOT_SYSTEM_APP;
14247 }
14248 const auto callingPid = IPCSkeleton::GetCallingRealPid();
14249 const char* const where = __func__;
14250 auto task = [this, persistentId, shouldHide, callingPid, where]() {
14251 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14252 auto iter = sceneSessionMap_.find(persistentId);
14253 if (iter == sceneSessionMap_.end()) {
14254 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: Session with persistentId %{public}d not found",
14255 where, persistentId);
14256 return WSError::WS_ERROR_INVALID_SESSION;
14257 }
14258 auto sceneSession = iter->second;
14259 if (sceneSession == nullptr) {
14260 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: sceneSession is nullptr.", where);
14261 return WSError::WS_ERROR_NULLPTR;
14262 }
14263 if (callingPid != sceneSession->GetCallingPid()) {
14264 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: Permission denied", where);
14265 return WSError::WS_ERROR_INVALID_PERMISSION;
14266 }
14267 sceneSession->SetShouldHideNonSecureWindows(shouldHide);
14268 return HandleSecureSessionShouldHide(sceneSession);
14269 };
14270
14271 taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
14272 return WSError::WS_OK;
14273 }
14274
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const14275 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
14276 {
14277 auto ret = WSError::WS_OK;
14278 bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
14279 if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
14280 actions.hideNonSecureWindowsFlag = false;
14281 actions.waterMarkFlag = false;
14282 TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
14283 ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
14284 }
14285 auto needPrivacyWindow = actions.privacyModeFlag;
14286 if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
14287 actions.privacyModeFlag = false;
14288 TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
14289 ret = WSError::WS_ERROR_INVALID_PERMISSION;
14290 }
14291 return ret;
14292 }
14293
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)14294 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
14295 uint32_t extWindowActions)
14296 {
14297 ExtensionWindowFlags actions(extWindowActions);
14298 auto ret = CheckExtWindowFlagsPermission(actions);
14299 if (ret != WSError::WS_OK) {
14300 return ret;
14301 }
14302
14303 ExtensionWindowFlags flags(extWindowFlags);
14304 const char* const where = __func__;
14305 auto task = [this, token, flags, actions, where]() {
14306 int32_t persistentId = INVALID_SESSION_ID;
14307 int32_t parentId = INVALID_SESSION_ID;
14308 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
14309 TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
14310 return WSError::WS_ERROR_INVALID_OPERATION;
14311 }
14312
14313 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: parentId=%{public}d, persistentId=%{public}d, "
14314 "extWindowFlags=%{public}d, actions=%{public}d", where, parentId, persistentId,
14315 flags.bitData, actions.bitData);
14316 auto sceneSession = GetSceneSession(parentId);
14317 if (sceneSession == nullptr) {
14318 TLOGND(WmsLogTag::WMS_UIEXT, "%{public}s: Parent session with persistentId %{public}d not found",
14319 where, parentId);
14320 HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
14321 return WSError::WS_OK;
14322 }
14323
14324 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
14325 sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
14326 auto newFlags = sceneSession->GetCombinedExtWindowFlags();
14327 if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
14328 HandleSecureSessionShouldHide(sceneSession);
14329 }
14330 if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
14331 CheckAndNotifyWaterMarkChangedResult();
14332 }
14333 if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
14334 UpdatePrivateStateAndNotify(parentId);
14335 }
14336 return WSError::WS_OK;
14337 };
14338
14339 taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
14340 return ret;
14341 }
14342
GetHostWindowRect(int32_t hostWindowId,Rect & rect)14343 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
14344 {
14345 TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
14346 if (!SessionPermission::IsSystemCalling()) {
14347 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
14348 return WSError::WS_ERROR_NOT_SYSTEM_APP;
14349 }
14350 auto task = [this, hostWindowId, &rect]() {
14351 auto sceneSession = GetSceneSession(hostWindowId);
14352 if (sceneSession == nullptr) {
14353 TLOGNE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
14354 return WSError::WS_ERROR_INVALID_SESSION;
14355 }
14356 WSRect hostRect = sceneSession->GetSessionScreenRelativeRect();
14357 auto currScreenFoldStatus = PcFoldScreenManager::GetInstance().GetScreenFoldStatus();
14358 auto needTransRect = currScreenFoldStatus != SuperFoldStatus::UNKNOWN &&
14359 currScreenFoldStatus != SuperFoldStatus::FOLDED && currScreenFoldStatus != SuperFoldStatus::EXPANDED;
14360 auto isSystemKeyboard = sceneSession->GetSessionProperty() != nullptr &&
14361 sceneSession->GetSessionProperty()->IsSystemKeyboard();
14362 if (!isSystemKeyboard && needTransRect) {
14363 WSRect globalRect = hostRect;
14364 sceneSession->TransformGlobalRectToRelativeRect(hostRect);
14365 TLOGI(WmsLogTag::WMS_UIEXT, "Transform globalRect: %{public}s to relativeRect: %{public}s",
14366 globalRect.ToString().c_str(), hostRect.ToString().c_str());
14367 }
14368 rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
14369 return WSError::WS_OK;
14370 };
14371 taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
14372 return WSError::WS_OK;
14373 }
14374
GetHostGlobalScaledRect(int32_t hostWindowId,Rect & globalScaledRect)14375 WSError SceneSessionManager::GetHostGlobalScaledRect(int32_t hostWindowId, Rect& globalScaledRect)
14376 {
14377 TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
14378 auto sceneSession = GetSceneSession(hostWindowId);
14379 if (sceneSession == nullptr) {
14380 TLOGNE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
14381 return WSError::WS_ERROR_INVALID_SESSION;
14382 }
14383 sceneSession->GetGlobalScaledRect(globalScaledRect);
14384 return WSError::WS_OK;
14385 }
14386
ReclaimPurgeableCleanMem()14387 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
14388 {
14389 #ifdef MEMMGR_WINDOW_ENABLE
14390 return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
14391 #else
14392 return -1;
14393 #endif
14394 }
14395
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)14396 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
14397 const std::vector<VisibleWindowNumInfo>& currentInfo)
14398 {
14399 if (lastInfo.size() != currentInfo.size()) {
14400 TLOGE(WmsLogTag::DEFAULT, "last and current info is not Same");
14401 return false;
14402 }
14403 int sizeOfLastInfo = static_cast<int>(lastInfo.size());
14404 for (int i = 0; i < sizeOfLastInfo; i++) {
14405 if (lastInfo[i].displayId != currentInfo[i].displayId ||
14406 lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
14407 TLOGE(WmsLogTag::DEFAULT, "last and current visible window num is not Same");
14408 return false;
14409 }
14410 }
14411 return true;
14412 }
14413
CacVisibleWindowNum()14414 void SceneSessionManager::CacVisibleWindowNum()
14415 {
14416 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
14417 {
14418 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14419 sceneSessionMapCopy = sceneSessionMap_;
14420 }
14421 std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
14422 bool isFullScreen = true;
14423 for (const auto& elem : sceneSessionMapCopy) {
14424 auto curSession = elem.second;
14425 if (curSession == nullptr) {
14426 continue;
14427 }
14428 bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
14429 curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
14430 if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
14431 continue;
14432 }
14433
14434 bool isWindowVisible = curSession->GetRSVisible();
14435 if (isWindowVisible) {
14436 auto windowMode = curSession->GetWindowMode();
14437 if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
14438 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
14439 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
14440 isFullScreen = false;
14441 }
14442 int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
14443 auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
14444 [displayId](const VisibleWindowNumInfo& info) {
14445 return (static_cast<int32_t>(info.displayId)) == displayId;
14446 });
14447 if (it == visibleWindowNumInfo.end()) {
14448 visibleWindowNumInfo.push_back({displayId, 1});
14449 } else {
14450 it->visibleWindowNum++;
14451 }
14452 }
14453 }
14454 if (isFullScreen) {
14455 std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
14456 [](auto& info) { info.visibleWindowNum = 1; });
14457 }
14458 std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
14459 if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
14460 SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
14461 lastInfo_ = visibleWindowNumInfo;
14462 }
14463 }
14464
ReportWindowProfileInfos()14465 void SceneSessionManager::ReportWindowProfileInfos()
14466 {
14467 enum class WindowVisibleState : int32_t {
14468 FOCUSBLE = 0,
14469 FULLY_VISIBLE,
14470 MINIMIZED,
14471 TOTALLY_OCCLUSION,
14472 PARTLY_OCCLUSION
14473 };
14474 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
14475 {
14476 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14477 sceneSessionMapCopy = sceneSessionMap_;
14478 }
14479 auto focusWindowId = GetFocusedSessionId();
14480 for (const auto& [_, currSession] : sceneSessionMapCopy) {
14481 if (currSession == nullptr || currSession->GetSessionInfo().isSystem_ ||
14482 currSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
14483 continue;
14484 }
14485 WindowProfileInfo windowProfileInfo;
14486 WSRect rect = currSession->GetSessionRect();
14487 std::stringstream rectStr;
14488 rectStr << "[" << rect.posX_ << " " << rect.posY_ << " " << rect.width_ << " " << rect.height_ << "]";
14489 windowProfileInfo.rect = rectStr.str();
14490 windowProfileInfo.zorder = static_cast<int32_t>(currSession->GetZOrder());
14491 windowProfileInfo.bundleName = currSession->GetSessionInfo().bundleName_;
14492 windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
14493 currSession->GetSessionProperty()->GetDisplayId());
14494 windowProfileInfo.windowSceneMode = static_cast<int32_t>(currSession->GetWindowMode());
14495 if (focusWindowId == static_cast<int32_t>(currSession->GetWindowId())) {
14496 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
14497 } else if (currSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
14498 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
14499 } else if (currSession->GetVisibilityState() == WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
14500 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::TOTALLY_OCCLUSION);
14501 } else if (currSession->GetVisibilityState() == WINDOW_VISIBILITY_STATE_NO_OCCLUSION) {
14502 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FULLY_VISIBLE);
14503 } else {
14504 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::PARTLY_OCCLUSION);
14505 }
14506 WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
14507 TLOGD(WmsLogTag::DEFAULT,
14508 "bundleName:%{public}s, windowVisibleState:%{public}d, windowLocatedScreen:%{public}d, "
14509 "windowSceneMode:%{public}d, windowZorder:%{public}d, windowRect:%{public}s",
14510 windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
14511 windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode,
14512 windowProfileInfo.zorder, windowProfileInfo.rect.c_str());
14513 }
14514 }
14515
GetCustomDecorHeight(int32_t persistentId)14516 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
14517 {
14518 int32_t height = 0;
14519 auto sceneSession = GetSceneSession(persistentId);
14520 if (sceneSession == nullptr) {
14521 TLOGE(WmsLogTag::WMS_DECOR, "session is invalid, id: %{public}d", persistentId);
14522 return 0;
14523 }
14524 height = sceneSession->GetCustomDecorHeight();
14525 TLOGD(WmsLogTag::WMS_DECOR, "decor height: %{public}d", height);
14526 return height;
14527 }
14528
RemoveFailRecoveredSession()14529 void SceneSessionManager::RemoveFailRecoveredSession()
14530 {
14531 for (const auto persistentId : failRecoveredPersistentIdSet_) {
14532 auto sceneSession = GetSceneSession(persistentId);
14533 if (sceneSession == nullptr) {
14534 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
14535 continue;
14536 }
14537 if (!sceneSession->IsRecovered()) {
14538 TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId=%{public}d", persistentId);
14539 continue;
14540 }
14541 TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId=%{public}d", persistentId);
14542 ExceptionInfo exceptionInfo;
14543 exceptionInfo.needRemoveSession = true;
14544 sceneSession->NotifySessionExceptionInner(SetAbilitySessionInfo(sceneSession), exceptionInfo);
14545 }
14546 failRecoveredPersistentIdSet_.clear();
14547 }
14548
GetDisplayRegion(DisplayId displayId)14549 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
14550 {
14551 if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
14552 return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
14553 }
14554 TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
14555 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
14556 if (display == nullptr) {
14557 TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
14558 return nullptr;
14559 }
14560 auto displayInfo = display->GetDisplayInfo();
14561 if (displayInfo == nullptr) {
14562 TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
14563 return nullptr;
14564 }
14565 int32_t displayWidth = displayInfo->GetWidth();
14566 int32_t displayHeight = displayInfo->GetHeight();
14567 if (displayWidth == 0 || displayHeight == 0) {
14568 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
14569 return nullptr;
14570 }
14571 if (PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
14572 const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
14573 PcFoldScreenManager::GetInstance().GetDisplayRects();
14574 displayHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
14575 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "update display height in pc fold");
14576 }
14577 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
14578 auto region = std::make_shared<SkRegion>(rect);
14579 displayRegionMap_[displayId] = region;
14580 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w=%{public}d, h=%{public}d", displayWidth, displayHeight);
14581 return std::make_shared<SkRegion>(rect);
14582 }
14583
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)14584 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
14585 {
14586 if (displayInfo == nullptr) {
14587 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "update display region failed, displayInfo is nullptr.");
14588 return;
14589 }
14590 auto displayId = displayInfo->GetDisplayId();
14591 int32_t displayWidth = displayInfo->GetWidth();
14592 int32_t displayHeight = displayInfo->GetHeight();
14593 if (displayWidth == 0 || displayHeight == 0) {
14594 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid display size of display: %{public}" PRIu64, displayId);
14595 return;
14596 }
14597 if (PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
14598 const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
14599 PcFoldScreenManager::GetInstance().GetDisplayRects();
14600 displayHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
14601 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "update display height in pc fold");
14602 }
14603 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
14604 auto region = std::make_shared<SkRegion>(rect);
14605 displayRegionMap_[displayId] = region;
14606 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "update display region to w: %{public}d, h: %{public}d",
14607 displayWidth, displayHeight);
14608 }
14609
GetDisplaySizeById(DisplayId displayId,int32_t & displayWidth,int32_t & displayHeight)14610 bool SceneSessionManager::GetDisplaySizeById(DisplayId displayId, int32_t& displayWidth, int32_t& displayHeight)
14611 {
14612 auto region = GetDisplayRegion(displayId);
14613 if (region == nullptr) {
14614 TLOGW(WmsLogTag::WMS_LAYOUT, "failed, displayId:%{public}" PRIu64, displayId);
14615 return false;
14616 }
14617 const SkIRect& rect = region->getBounds();
14618 displayWidth = rect.fRight;
14619 displayHeight = rect.fBottom;
14620 return true;
14621 }
14622
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)14623 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
14624 {
14625 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14626 for (const auto& [_, sceneSession] : sceneSessionMap_) {
14627 if (sceneSession == nullptr) {
14628 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "session is null");
14629 continue;
14630 }
14631 if (Session::IsScbCoreEnabled()) {
14632 if (!sceneSession->IsVisibleForAccessibility()) {
14633 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "unvisible: isSys=%{public}d, inWid=%{public}d, bundle=%{public}s, "
14634 "zOrder=%{public}u, displayId=%{public}" PRIu64 ", nodeId=%{public}d, "
14635 "sysTouchable=%{public}d, interactive=%{public}d, visibleForeground=%{public}d",
14636 sceneSession->GetSessionInfo().isSystem_, static_cast<int32_t>(sceneSession->GetPersistentId()),
14637 sceneSession->GetSessionInfo().bundleName_.c_str(), sceneSession->GetZOrder(),
14638 sceneSession->GetSessionProperty()->GetDisplayId(), sceneSession->GetUINodeId(),
14639 sceneSession->GetSystemTouchable(), sceneSession->GetForegroundInteractiveStatus(),
14640 sceneSession->IsVisibleForeground());
14641 continue;
14642 }
14643 } else {
14644 if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
14645 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "unvisible2: isSys=%{public}d, inWid=%{public}d, bundle=%{public}s, "
14646 "zOrder=%{public}u, displayId=%{public}" PRIu64 ", nodeId=%{public}d, "
14647 "sysTouchable=%{public}d, interactive=%{public}d, visibleForeground=%{public}d",
14648 sceneSession->GetSessionInfo().isSystem_, static_cast<int32_t>(sceneSession->GetPersistentId()),
14649 sceneSession->GetSessionInfo().bundleName_.c_str(), sceneSession->GetZOrder(),
14650 sceneSession->GetSessionProperty()->GetDisplayId(), sceneSession->GetUINodeId(),
14651 sceneSession->GetSystemTouchable(), sceneSession->GetForegroundInteractiveStatus(),
14652 sceneSession->IsVisibleForeground());
14653 continue;
14654 }
14655 }
14656 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
14657 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
14658 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
14659 continue;
14660 }
14661 if (sceneSession->GetSessionInfo().bundleName_.find("SCBDragScale") != std::string::npos) {
14662 continue;
14663 }
14664 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "isSys=%{public}d, inWid=%{public}d, bundle=%{public}s, zOrder=%{public}u",
14665 sceneSession->GetSessionInfo().isSystem_, static_cast<int32_t>(sceneSession->GetPersistentId()),
14666 sceneSession->GetSessionInfo().bundleName_.c_str(), sceneSession->GetZOrder());
14667 sceneSessionList.push_back(sceneSession);
14668 }
14669 }
14670
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)14671 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
14672 std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
14673 {
14674 for (const auto& sceneSession : sceneSessionList) {
14675 if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
14676 TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
14677 }
14678 }
14679 }
14680
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)14681 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
14682 {
14683 std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
14684 return a->GetZOrder() > b->GetZOrder();
14685 });
14686 std::vector<sptr<SceneSession>> result;
14687 std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
14688 for (const auto& sceneSession : sceneSessionList) {
14689 if (sceneSession == nullptr) {
14690 TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
14691 continue;
14692 }
14693 std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
14694 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
14695 if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
14696 unaccountedSpace = unaccountedSpaceMap[displayId];
14697 } else {
14698 unaccountedSpace = GetDisplayRegion(displayId);
14699 if (unaccountedSpace == nullptr) {
14700 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
14701 continue;
14702 }
14703 unaccountedSpaceMap[displayId] = unaccountedSpace;
14704 }
14705 if (SubtractIntersectArea(unaccountedSpace, sceneSession)) {
14706 result.push_back(sceneSession);
14707 }
14708 if (unaccountedSpace->isEmpty()) {
14709 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "break after: inWid=%{public}d, zOrder=%{public}u",
14710 static_cast<int32_t>(sceneSession->GetPersistentId()), sceneSession->GetZOrder());
14711 break;
14712 }
14713 }
14714 sceneSessionList = result;
14715 }
14716
SubtractIntersectArea(std::shared_ptr<SkRegion> & unaccountedSpace,const sptr<SceneSession> & sceneSession)14717 bool SceneSessionManager::SubtractIntersectArea(std::shared_ptr<SkRegion>& unaccountedSpace,
14718 const sptr<SceneSession>& sceneSession)
14719 {
14720 if (unaccountedSpace == nullptr || sceneSession == nullptr) {
14721 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "space or session is null");
14722 return false;
14723 }
14724 auto hotAreas = sceneSession->GetTouchHotAreas();
14725 WSRect wsRect = sceneSession->GetSessionRect();
14726 for (auto& rect : hotAreas) {
14727 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "id=%{public}d, rect=%{public}s, hotArea=%{public}s",
14728 static_cast<int32_t>(sceneSession->GetPersistentId()), wsRect.ToString().c_str(), rect.ToString().c_str());
14729 if (rect != Rect::EMPTY_RECT) {
14730 rect.posX_ += wsRect.posX_;
14731 rect.posY_ += wsRect.posY_;
14732 }
14733 }
14734 if (hotAreas.empty()) {
14735 hotAreas.push_back({.posX_ = wsRect.posX_, .posY_ = wsRect.posY_,
14736 .width_ = wsRect.width_, .height_ = wsRect.height_});
14737 }
14738 bool hasIntersectArea = false;
14739 for (const auto& rect : hotAreas) {
14740 SkIRect windowBounds {.fLeft = rect.posX_, .fTop = rect.posY_,
14741 .fRight = rect.posX_ + rect.width_, .fBottom = rect.posY_ + rect.height_};
14742 SkRegion windowRegion(windowBounds);
14743 if (unaccountedSpace->quickReject(windowRegion)) {
14744 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "quick reject: inWid=%{public}d, "
14745 "bounds=[l=%{public}d, t=%{public}d, r=%{public}d, b=%{public}d]",
14746 static_cast<int32_t>(sceneSession->GetPersistentId()),
14747 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
14748 continue;
14749 }
14750 if (!unaccountedSpace->intersects(windowRegion)) {
14751 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "no intersects: inWid=%{public}d, "
14752 "bounds=[l=%{public}d, t=%{public}d, r=%{public}d, b=%{public}d]",
14753 static_cast<int32_t>(sceneSession->GetPersistentId()),
14754 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
14755 continue;
14756 }
14757 hasIntersectArea = true;
14758 unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
14759 if (unaccountedSpace->isEmpty()) {
14760 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "break hot area: inWid=%{public}d, "
14761 "bounds=[l=%{public}d, t=%{public}d, r=%{public}d, b=%{public}d]",
14762 static_cast<int32_t>(sceneSession->GetPersistentId()),
14763 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
14764 break;
14765 }
14766 }
14767 return hasIntersectArea;
14768 }
14769
NotifyAllAccessibilityInfo()14770 void SceneSessionManager::NotifyAllAccessibilityInfo()
14771 {
14772 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyAllAccessibilityInfo");
14773 if (isUserBackground_) {
14774 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
14775 return;
14776 }
14777 std::vector<sptr<SceneSession>> sceneSessionList;
14778 GetAllSceneSessionForAccessibility(sceneSessionList);
14779 FilterSceneSessionCovered(sceneSessionList);
14780
14781 std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
14782 FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
14783
14784 for (const auto& item : accessibilityInfo) {
14785 TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid=%{public}d, inWid=%{public}d, "
14786 "bundle=%{public}s,bounds=(x=%{public}d, y=%{public}d, w=%{public}d, h=%{public}d)",
14787 item->wid_, item->innerWid_, item->bundleName_.c_str(),
14788 item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
14789 for (const auto& rect : item->touchHotAreas_) {
14790 TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d,"
14791 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
14792 }
14793 }
14794
14795 SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
14796 WindowUpdateType::WINDOW_UPDATE_ALL);
14797 }
14798
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)14799 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
14800 const sptr<WindowSessionProperty>& property)
14801 {
14802 auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
14803 if (property == nullptr) {
14804 return windowStatus;
14805 }
14806 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
14807 windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
14808 if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
14809 windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
14810 }
14811 } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
14812 windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
14813 } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
14814 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
14815 } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
14816 windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
14817 }
14818 return windowStatus;
14819 }
14820
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)14821 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
14822 {
14823 if (!SessionPermission::IsStartedByInputMethod()) {
14824 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
14825 return WMError::WM_ERROR_INVALID_PERMISSION;
14826 }
14827 auto sceneSession = GetSceneSession(persistentId);
14828 if (sceneSession == nullptr) {
14829 TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is null, persistentId: %{public}d", persistentId);
14830 return WMError::WM_ERROR_NULLPTR;
14831 }
14832 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
14833 auto focusedSessionId = GetFocusedSessionId(displayId);
14834 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
14835 persistentId, sceneSession->GetWindowType());
14836 uint32_t callingWindowId = sceneSession->GetSessionProperty()->GetCallingSessionId();
14837 auto callingSession = GetSceneSession(callingWindowId);
14838 if (callingSession == nullptr) {
14839 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
14840 callingSession = GetSceneSession(focusedSessionId);
14841 if (callingSession == nullptr) {
14842 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
14843 return WMError::WM_ERROR_INVALID_WINDOW;
14844 }
14845 }
14846 if (callingSession->IsSystemSession()) {
14847 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
14848 } else {
14849 windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
14850 callingSession->GetSessionProperty());
14851 }
14852 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
14853 persistentId, windowStatus);
14854 return WMError::WM_OK;
14855 }
14856
GetCallingWindowRect(int32_t persistentId,Rect & rect)14857 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
14858 {
14859 if (!SessionPermission::IsStartedByInputMethod()) {
14860 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
14861 return WMError::WM_ERROR_INVALID_PERMISSION;
14862 }
14863 auto sceneSession = GetSceneSession(persistentId);
14864 if (sceneSession == nullptr) {
14865 TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is null, persistentId: %{public}d", persistentId);
14866 return WMError::WM_ERROR_NULLPTR;
14867 }
14868 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
14869 auto focusedSessionId = GetFocusedSessionId(displayId);
14870 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
14871 persistentId, sceneSession->GetWindowType());
14872 uint32_t callingWindowId = sceneSession->GetSessionProperty()->GetCallingSessionId();
14873 auto callingSession = GetSceneSession(callingWindowId);
14874 if (callingSession == nullptr) {
14875 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
14876 callingSession = GetSceneSession(focusedSessionId);
14877 if (callingSession == nullptr) {
14878 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
14879 return WMError::WM_ERROR_INVALID_WINDOW;
14880 }
14881 }
14882 WSRect sessionRect = callingSession->GetSessionRect();
14883 rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
14884 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
14885 "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
14886 return WMError::WM_OK;
14887 }
14888
GetWindowModeType(WindowModeType & windowModeType)14889 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
14890 {
14891 if (!SessionPermission::IsSACalling()) {
14892 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
14893 return WMError::WM_ERROR_INVALID_PERMISSION;
14894 }
14895 windowModeType = CheckWindowModeType();
14896 return WMError::WM_OK;
14897 }
14898
GetWindowStyleType(WindowStyleType & windowStyleType)14899 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
14900 {
14901 if (!SessionPermission::IsSACalling()) {
14902 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
14903 return WMError::WM_ERROR_INVALID_PERMISSION;
14904 }
14905 if (systemConfig_.IsPcWindow()) {
14906 windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
14907 return WMError::WM_OK;
14908 }
14909 windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
14910 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
14911 return WMError::WM_OK;
14912 }
14913
CheckSceneZOrder()14914 void SceneSessionManager::CheckSceneZOrder()
14915 {
14916 auto task = [this]() {
14917 AnomalyDetection::SceneZOrderCheckProcess();
14918 };
14919 taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
14920 }
14921
NotifyEnterRecentTask(bool enterRecent)14922 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
14923 {
14924 TLOGD(WmsLogTag::WMS_IMMS, "enterRecent %{public}u", enterRecent);
14925 enterRecent_.store(enterRecent);
14926 SetSystemAnimatedScenes(enterRecent ?
14927 SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
14928 auto task = [this] {
14929 for (auto persistentId : gestureBackEnableWindowIdSet_) {
14930 auto sceneSession = GetSceneSession(persistentId);
14931 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
14932 continue;
14933 }
14934 UpdateGestureBackEnabled(persistentId);
14935 }
14936 };
14937 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
14938 return WSError::WS_OK;
14939 }
14940
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)14941 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
14942 {
14943 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
14944 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
14945 return WMError::WM_ERROR_INVALID_PERMISSION;
14946 }
14947
14948 if (!topNInfo.empty() || (topNum <= 0)) {
14949 return WMError::WM_ERROR_INVALID_PARAM;
14950 }
14951
14952 TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
14953 auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
14954 if (session == nullptr) {
14955 return false;
14956 }
14957
14958 if (topNum == 0) {
14959 return true;
14960 }
14961
14962 if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
14963 TLOGND(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
14964 return false;
14965 }
14966
14967 MainWindowInfo info;
14968 info.pid_ = session->GetCallingPid();
14969 info.bundleName_ = session->GetSessionInfo().bundleName_;
14970 topNInfo.push_back(info);
14971 topNum--;
14972 TLOGNE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
14973 topNum, info.pid_, info.bundleName_.c_str());
14974 return false;
14975 };
14976 TraverseSessionTree(func, true);
14977
14978 return WMError::WM_OK;
14979 }
14980
GetCallingWindowInfo(CallingWindowInfo & callingWindowInfo)14981 WMError SceneSessionManager::GetCallingWindowInfo(CallingWindowInfo& callingWindowInfo)
14982 {
14983 int32_t curUserId = GetUserIdByUid(getuid());
14984 if (curUserId != callingWindowInfo.userId_) {
14985 TLOGE(WmsLogTag::WMS_KEYBOARD, "Target user not exists, targetUserId: %{public}d, curUserId: %{public}d, id: %{public}d",
14986 callingWindowInfo.userId_, curUserId, callingWindowInfo.windowId_);
14987 return WMError::WM_ERROR_INVALID_PARAM;
14988 }
14989 auto sceneSession = GetSceneSession(callingWindowInfo.windowId_);
14990 if (sceneSession == nullptr) {
14991 TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is nullptr, id: %{public}d", callingWindowInfo.windowId_);
14992 return WMError::WM_ERROR_NULLPTR;
14993 }
14994 callingWindowInfo.callingPid_ = sceneSession->GetCallingPid();
14995 callingWindowInfo.displayId_ = sceneSession->GetSessionProperty()->GetDisplayId();
14996 if (sceneSession->IsPcFoldDevice() && PcFoldScreenManager::GetInstance().IsHalfFolded(callingWindowInfo.displayId_)) {
14997 callingWindowInfo.displayId_ = sceneSession->GetClientDisplayId();
14998 }
14999 TLOGI(WmsLogTag::WMS_KEYBOARD, "info: [id: %{public}d, pid: %{public}d, "
15000 "displayId: %{public}" PRIu64" , userId: %{public}d]", callingWindowInfo.windowId_,
15001 callingWindowInfo.callingPid_, callingWindowInfo.displayId_, callingWindowInfo.userId_);
15002 return WMError::WM_OK;
15003 }
15004
NotifyDisplayIdChanged(int32_t persistentId,uint64_t displayId)15005 void SceneSessionManager::NotifyDisplayIdChanged(int32_t persistentId, uint64_t displayId)
15006 {
15007 auto sceneSession = GetSceneSession(persistentId);
15008 if (!sceneSession) {
15009 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
15010 return;
15011 }
15012 // Find keyboard session.
15013 const auto& keyboardSessionVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
15014 for (const auto& keyboardSession : keyboardSessionVec) {
15015 if (!keyboardSession) {
15016 continue;
15017 }
15018 TLOGD(WmsLogTag::WMS_KEYBOARD, "isSystemKeyboard: %{public}d, callingSessionId: %{public}d",
15019 keyboardSession->IsSystemKeyboard(), keyboardSession->GetCallingSessionId());
15020 if (!keyboardSession->IsSystemKeyboard() &&
15021 static_cast<int32_t>(keyboardSession->GetCallingSessionId()) == persistentId) {
15022 CallingWindowInfo callingWindowInfo(persistentId, sceneSession->GetCallingPid(), displayId, GetUserIdByUid(getuid()));
15023 SessionManagerAgentController::GetInstance().NotifyCallingWindowDisplayChanged(callingWindowInfo);
15024 break;
15025 }
15026 }
15027 return;
15028 }
15029
GetWindowIdsByCoordinate(DisplayId displayId,int32_t windowNumber,int32_t x,int32_t y,std::vector<int32_t> & windowIds)15030 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
15031 int32_t x, int32_t y, std::vector<int32_t>& windowIds)
15032 {
15033 TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
15034 displayId, windowNumber, x, y);
15035 if (displayId == DISPLAY_ID_INVALID) {
15036 TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
15037 return WMError::WM_ERROR_INVALID_PARAM;
15038 }
15039 bool findAllWindow = windowNumber <= 0;
15040 std::string callerBundleName = SessionPermission::GetCallingBundleName();
15041 ChangeWindowRectYInVirtualDisplay(displayId, y);
15042 bool checkPoint = (x >= 0 && y >= 0);
15043 auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
15044 findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
15045 if (session == nullptr) {
15046 return false;
15047 }
15048 if (!findAllWindow && windowNumber == 0) {
15049 return true;
15050 }
15051 bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
15052 bool isSameDisplayId = session->GetSessionProperty()->GetDisplayId() == displayId;
15053 bool isRsVisible = session->GetRSVisible();
15054 WSRect windowRect = session->GetSessionRect();
15055 bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
15056 TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
15057 " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
15058 session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
15059 session->GetSessionProperty()->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
15060 if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
15061 return false;
15062 }
15063 windowIds.emplace_back(session->GetPersistentId());
15064 windowNumber--;
15065 return false;
15066 };
15067 return taskScheduler_->PostSyncTask([this, func = std::move(func)] {
15068 TraverseSessionTree(func, true);
15069 return WMError::WM_OK;
15070 }, __func__);
15071 }
15072
ChangeWindowRectYInVirtualDisplay(DisplayId & displayId,int32_t & y)15073 void SceneSessionManager::ChangeWindowRectYInVirtualDisplay(DisplayId& displayId, int32_t& y)
15074 {
15075 if (displayId != VIRTUAL_DISPLAY_ID) {
15076 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "This is not VIRTUAL_DISPLAY_ID");
15077 return;
15078 }
15079 auto defaultScreenDisplay = DisplayManager::GetInstance().GetDisplayById(DEFAULT_DISPLAY_ID);
15080 if (defaultScreenDisplay == nullptr) {
15081 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "get display object failed of defaultScreenDisplay");
15082 return;
15083 }
15084 auto defaultScreenDisplayInfo = defaultScreenDisplay->GetDisplayInfo();
15085 if (defaultScreenDisplayInfo == nullptr) {
15086 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "get display info failed of defaultScreenDisplay");
15087 return;
15088 }
15089 int32_t defaultScreenPhysicalHeight = defaultScreenDisplayInfo->GetPhysicalHeight();
15090 auto screenDisplay = DisplayManager::GetInstance().GetDisplayById(displayId);
15091 int32_t screenHightByDisplayId = defaultScreenPhysicalHeight;
15092 if (screenDisplay != nullptr) {
15093 if (screenDisplay->GetDisplayInfo() != nullptr) {
15094 screenHightByDisplayId = screenDisplay->GetDisplayInfo()->GetHeight();
15095 }
15096 }
15097 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "defaultScreenPhysicalHeight %{public}d screenHightByDisplayId %{public}d",
15098 defaultScreenPhysicalHeight, screenHightByDisplayId);
15099 if (displayId == VIRTUAL_DISPLAY_ID) {
15100 displayId = DEFAULT_DISPLAY_ID;
15101 y = y + defaultScreenPhysicalHeight - screenHightByDisplayId;
15102 }
15103 }
15104
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const15105 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
15106 {
15107 if (!infos.empty()) {
15108 TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
15109 return WMError::WM_ERROR_INVALID_PARAM;
15110 }
15111 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15112 TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
15113 return WMError::WM_ERROR_INVALID_PERMISSION;
15114 }
15115 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15116 for (const auto& iter : sceneSessionMap_) {
15117 auto& session = iter.second;
15118 if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
15119 continue;
15120 }
15121 MainWindowInfo info;
15122 auto abilityInfo = session->GetSessionInfo().abilityInfo;
15123 info.pid_ = session->GetCallingPid();
15124 info.bundleName_ = session->GetSessionInfo().bundleName_;
15125 info.persistentId_ = session->GetPersistentId();
15126 if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
15127 TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
15128 info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
15129 infos.push_back(info);
15130 } else if (abilityInfo != nullptr) {
15131 info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
15132 infos.push_back(info);
15133 TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
15134 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
15135 info.bundleName_.c_str(), info.bundleType_);
15136 }
15137 }
15138 return WMError::WM_OK;
15139 }
15140
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)15141 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
15142 std::vector<int32_t>& clearFailedIds)
15143 {
15144 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15145 TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
15146 return WMError::WM_ERROR_INVALID_PERMISSION;
15147 }
15148 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
15149 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
15150 return WMError::WM_ERROR_INVALID_PERMISSION;
15151 }
15152 clearFailedIds.clear();
15153 for (const auto persistentId : persistentIds) {
15154 auto sceneSession = GetSceneSession(persistentId);
15155 if (sceneSession == nullptr) {
15156 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
15157 clearFailedIds.push_back(persistentId);
15158 continue;
15159 }
15160 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
15161 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
15162 clearFailedIds.push_back(persistentId);
15163 continue;
15164 }
15165 sceneSession->Clear();
15166 TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
15167 }
15168 return WMError::WM_OK;
15169 }
15170
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)15171 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
15172 bool enable)
15173 {
15174 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
15175 width, height, density, enable);
15176
15177 DMHookInfo dmHookInfo;
15178 dmHookInfo.width_ = width;
15179 dmHookInfo.height_ = height;
15180 dmHookInfo.density_ = density;
15181 dmHookInfo.rotation_ = 0;
15182 dmHookInfo.enableHookRotation_ = false;
15183 dmHookInfo.displayOrientation_ = 0;
15184 dmHookInfo.enableHookDisplayOrientation_ = false;
15185 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
15186 return WMError::WM_OK;
15187 }
15188
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)15189 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
15190 {
15191 TLOGI(WmsLogTag::WMS_COMPAT, "hookInfo: [%{public}s], enable: %{public}d", hookInfo.ToString().c_str(), enable);
15192 if (enable && (uid <= 0 || hookInfo.width_ <= 0 || hookInfo.height_ <= 0 || hookInfo.density_ <= 0)) {
15193 TLOGE(WmsLogTag::WMS_COMPAT, "App hookInfo param error.");
15194 return WMError::WM_ERROR_INVALID_PARAM;
15195 }
15196 DMHookInfo dmHookInfo;
15197 dmHookInfo.width_ = hookInfo.width_;
15198 dmHookInfo.height_ = hookInfo.height_;
15199 dmHookInfo.density_ = hookInfo.density_;
15200 dmHookInfo.rotation_ = hookInfo.rotation_;
15201 dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
15202 dmHookInfo.displayOrientation_ = hookInfo.displayOrientation_;
15203 dmHookInfo.enableHookDisplayOrientation_ = hookInfo.enableHookDisplayOrientation_;
15204 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
15205 return WMError::WM_OK;
15206 }
15207
UpdateAppHookWindowInfo(const std::string & bundleName,const HookWindowInfo & hookWindowInfo)15208 WMError SceneSessionManager::UpdateAppHookWindowInfo(const std::string& bundleName,
15209 const HookWindowInfo& hookWindowInfo)
15210 {
15211 if (bundleName.empty()) {
15212 TLOGE(WmsLogTag::WMS_LAYOUT, "Bundle name is empty");
15213 return WMError::WM_ERROR_NULLPTR;
15214 }
15215 if (hookWindowInfo.widthHookRatio < 0.0f) {
15216 TLOGE(WmsLogTag::WMS_LAYOUT, "Invalid hook window parameters: widthHookRatio:%{public}f, "
15217 "bundleName:%{public}s", hookWindowInfo.widthHookRatio, bundleName.c_str());
15218 return WMError::WM_ERROR_INVALID_PARAM;
15219 }
15220 TLOGI(WmsLogTag::WMS_LAYOUT, "bundleName:%{public}s, hookWindowInfo:[%{public}s]", bundleName.c_str(),
15221 hookWindowInfo.ToString().c_str());
15222
15223 HookWindowInfo preInfo;
15224 {
15225 std::unique_lock lock(appHookWindowInfoMapMutex_);
15226 if (appHookWindowInfoMap_.count(bundleName)) {
15227 preInfo = appHookWindowInfoMap_[bundleName];
15228 } else {
15229 preInfo = {};
15230 }
15231 appHookWindowInfoMap_[bundleName] = hookWindowInfo;
15232 }
15233
15234 if (preInfo.enableHookWindow != hookWindowInfo.enableHookWindow ||
15235 !MathHelper::NearZero(preInfo.widthHookRatio - hookWindowInfo.widthHookRatio)) {
15236 //Notify the client of the info change
15237 std::shared_lock lock(sceneSessionMapMutex_);
15238 for (const auto& [_, session] : sceneSessionMap_) {
15239 if (session && session->GetSessionInfo().bundleName_ == bundleName) {
15240 session->NotifyAppHookWindowInfoUpdated();
15241 }
15242 }
15243 }
15244 return WMError::WM_OK;
15245 }
15246
GetAppHookWindowInfo(const std::string & bundleName)15247 HookWindowInfo SceneSessionManager::GetAppHookWindowInfo(const std::string& bundleName)
15248 {
15249 if (bundleName.empty()) {
15250 TLOGW(WmsLogTag::WMS_LAYOUT, "Empty bundle name requested");
15251 return {};
15252 }
15253 std::shared_lock lock(appHookWindowInfoMapMutex_);
15254 const auto& it = appHookWindowInfoMap_.find(bundleName);
15255 if (it == appHookWindowInfoMap_.end()) {
15256 TLOGD(WmsLogTag::WMS_LAYOUT, "app: %{public}s, hookWindowInfo not find", bundleName.c_str());
15257 return {};
15258 }
15259 return it->second;
15260 }
15261
UpdateAppHookWindowInfoWhenSwitchFreeMultiWindow(bool isOpenFreeMultiWindow)15262 void SceneSessionManager::UpdateAppHookWindowInfoWhenSwitchFreeMultiWindow(bool isOpenFreeMultiWindow)
15263 {
15264 std::unordered_set<std::string> bundleNames;
15265 {
15266 std::unique_lock lock(appHookWindowInfoMapMutex_);
15267 for (auto& [bundleName, hookWindowInfo] : appHookWindowInfoMap_) {
15268 hookWindowInfo.enableHookWindow = !isOpenFreeMultiWindow;
15269 bundleNames.insert(bundleName);
15270 }
15271 }
15272 {
15273 std::shared_lock lock(sceneSessionMapMutex_);
15274 for (const auto& [_, session] : sceneSessionMap_) {
15275 if (session && bundleNames.count(session->GetSessionInfo().bundleName_)) {
15276 session->NotifyAppHookWindowInfoUpdated();
15277 }
15278 }
15279 }
15280 }
15281
NotifyHookOrientationChange(int32_t persistentId)15282 WMError SceneSessionManager::NotifyHookOrientationChange(int32_t persistentId)
15283 {
15284 auto sceneSession = GetSceneSession(persistentId);
15285 if (sceneSession == nullptr) {
15286 TLOGE(WmsLogTag::WMS_COMPAT, "session id:%{public}d is not found", persistentId);
15287 return WMError::WM_ERROR_INVALID_PARAM;
15288 }
15289 sceneSession->UpdateOrientation();
15290 return WMError::WM_OK;
15291 }
15292
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)15293 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
15294 {
15295 SceneSessionManager::GetInstance().SetDelayRemoveSnapshot(true);
15296 SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
15297 }
15298
SetDelayRemoveSnapshot(bool delayRemoveSnapshot)15299 void SceneSessionManager::SetDelayRemoveSnapshot(bool delayRemoveSnapshot)
15300 {
15301 TLOGD(WmsLogTag::WMS_PATTERN, "delayRemoveSnapshot %{public}d", delayRemoveSnapshot);
15302 delayRemoveSnapshot_ = delayRemoveSnapshot;
15303 }
15304
GetDelayRemoveSnapshot() const15305 bool SceneSessionManager::GetDelayRemoveSnapshot() const
15306 {
15307 return delayRemoveSnapshot_;
15308 }
15309
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)15310 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
15311 {
15312 ScreenFoldData screenFoldData;
15313 WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
15314 if (ret != WMError::WM_OK) {
15315 return ret;
15316 }
15317 return CheckAndReportScreenFoldStatus(screenFoldData);
15318 }
15319
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)15320 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
15321 ScreenFoldData& screenFoldData)
15322 {
15323 if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
15324 TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
15325 return WMError::WM_DO_NOTHING;
15326 }
15327
15328 screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
15329 screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
15330 screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
15331 screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
15332 screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
15333 if (!screenFoldData.GetTypeCThermalWithUtil()) {
15334 TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
15335 return WMError::WM_DO_NOTHING;
15336 }
15337 AppExecFwk::ElementName element = {};
15338 WSError ret = GetFocusSessionElement(element);
15339 auto sceneSession = GetSceneSession(windowFocusController_->GetFocusedSessionId(DEFAULT_DISPLAY_ID));
15340 if (sceneSession == nullptr || ret != WSError::WS_OK) {
15341 TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
15342 return WMError::WM_DO_NOTHING;
15343 }
15344 screenFoldData.SetFocusedPkgName(element.GetURI());
15345 return WMError::WM_OK;
15346 }
15347
CheckAndReportScreenFoldStatus(ScreenFoldData & data)15348 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
15349 {
15350 static ScreenFoldData lastScreenHalfFoldData;
15351 if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
15352 lastScreenHalfFoldData = data;
15353 return WMError::WM_DO_NOTHING;
15354 }
15355 WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
15356 if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
15357 if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
15358 lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
15359 } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
15360 // if stay at half-fold less than 15s, combine this change with last
15361 data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
15362 data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
15363 data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
15364 }
15365 lastScreenHalfFoldData.SetInvalid();
15366 }
15367 WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
15368 return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
15369 currentScreenFoldStatusReportRet;
15370 }
15371
15372 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)15373 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
15374 {
15375 if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
15376 return WMError::WM_DO_NOTHING;
15377 }
15378
15379 int32_t ret = HiSysEventWrite(
15380 OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
15381 "FOLDSCREEN_STATE_CHANGE",
15382 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
15383 "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
15384 "LASTFOLDSTATE", data.currentScreenFoldStatus_,
15385 "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
15386 "STATE", -1,
15387 "TIME", data.currentScreenFoldStatusDuration_,
15388 "ROTATION", data.screenRotation_,
15389 "PACKAGE", data.focusedPackageName_,
15390 "ANGLE", data.postureAngle_,
15391 "TYPECTHERMAL", data.typeCThermal_,
15392 "SCREENTHERMAL", -1,
15393 "SCANGLE", -1,
15394 "ISTENT", -1);
15395 if (ret != 0) {
15396 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
15397 return WMError::WM_DO_NOTHING;
15398 }
15399 return WMError::WM_OK;
15400 }
15401
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userId)15402 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userId)
15403 {
15404 if (currentUserId_ != static_cast<int32_t>(userId)) {
15405 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
15406 currentUserId_.load(), userId);
15407 return;
15408 }
15409 if (secExtensionData == nullptr) {
15410 TLOGE(WmsLogTag::WMS_EVENT, "invalid secExtensionData");
15411 return;
15412 }
15413 auto secSurfaceInfoMap = secExtensionData->GetSecData();
15414 auto task = [secSurfaceInfoMap]()-> WSError {
15415 SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
15416 return WSError::WS_OK;
15417 };
15418 taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
15419 }
15420
RegisterSecSurfaceInfoListener()15421 void SceneSessionManager::RegisterSecSurfaceInfoListener()
15422 {
15423 auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
15424 this->UpdateSecSurfaceInfo(secExtensionData, userid);
15425 };
15426 TLOGI(WmsLogTag::WMS_EVENT, "in");
15427 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
15428 TLOGE(WmsLogTag::WMS_EVENT, "failed");
15429 }
15430 }
15431
UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,uint64_t userId)15432 void SceneSessionManager::UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,
15433 uint64_t userId)
15434 {
15435 if (currentUserId_ != static_cast<int32_t>(userId)) {
15436 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
15437 currentUserId_.load(), userId);
15438 return;
15439 }
15440 if (constrainedModalUIExtData == nullptr) {
15441 TLOGE(WmsLogTag::WMS_EVENT, "invalid constrainedModalUIExtData");
15442 return;
15443 }
15444 auto constrainedModalUIExtInfoMap = constrainedModalUIExtData->GetSecData();
15445 auto task = [constrainedModalUIExtInfoMap]()-> WSError {
15446 SceneInputManager::GetInstance().UpdateConstrainedModalUIExtInfo(constrainedModalUIExtInfoMap);
15447 return WSError::WS_OK;
15448 };
15449 taskScheduler_->PostAsyncTask(task, "UpdateConstrainedModalUIExtInfo");
15450 }
15451
RegisterConstrainedModalUIExtInfoListener()15452 void SceneSessionManager::RegisterConstrainedModalUIExtInfoListener()
15453 {
15454 auto callBack = [this](std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData, uint64_t userid) {
15455 this->UpdateConstrainedModalUIExtInfo(constrainedModalUIExtData, userid);
15456 };
15457 TLOGI(WmsLogTag::WMS_EVENT, "in");
15458 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack, true) != WM_OK) {
15459 TLOGE(WmsLogTag::WMS_EVENT, "failed");
15460 }
15461 }
15462
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)15463 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
15464 const AppForceLandscapeConfig& config)
15465 {
15466 if (bundleName.empty()) {
15467 TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
15468 return WSError::WS_ERROR_NULLPTR;
15469 }
15470 AppForceLandscapeConfig preConfig;
15471 {
15472 std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
15473 if (appForceLandscapeMap_.count(bundleName)) {
15474 preConfig = appForceLandscapeMap_[bundleName];
15475 } else {
15476 preConfig = {};
15477 }
15478 appForceLandscapeMap_[bundleName] = config;
15479 }
15480 TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s, supportSplit: %{public}d, "
15481 "arkUIOptions: %{public}s", bundleName.c_str(), config.mode_, config.homePage_.c_str(), config.supportSplit_,
15482 config.arkUIOptions_.c_str());
15483
15484 if (preConfig.mode_ == FORCE_SPLIT_MODE || config.mode_ == FORCE_SPLIT_MODE ||
15485 preConfig.mode_ == NAV_FORCE_SPLIT_MODE || config.mode_ == NAV_FORCE_SPLIT_MODE) {
15486 //Notify the client of the mode change
15487 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15488 for (const auto& iter : sceneSessionMap_) {
15489 auto& session = iter.second;
15490 if (session && session->GetSessionInfo().bundleName_ == bundleName) {
15491 session->NotifyAppForceLandscapeConfigUpdated();
15492 }
15493 }
15494 }
15495 return WSError::WS_OK;
15496 }
15497
GetAppForceLandscapeConfig(const std::string & bundleName)15498 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
15499 {
15500 if (bundleName.empty()) {
15501 return {};
15502 }
15503 std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
15504 if (appForceLandscapeMap_.empty() ||
15505 appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
15506 TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
15507 return {};
15508 }
15509 return appForceLandscapeMap_[bundleName];
15510 }
15511
TerminateSessionByPersistentId(int32_t persistentId)15512 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
15513 {
15514 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
15515 TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
15516 return WMError::WM_ERROR_INVALID_PERMISSION;
15517 }
15518 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
15519 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
15520 return WMError::WM_ERROR_NOT_SYSTEM_APP;
15521 }
15522 auto sceneSession = GetSceneSession(persistentId);
15523 if (sceneSession == nullptr) {
15524 TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
15525 return WMError::WM_ERROR_INVALID_PARAM;
15526 }
15527 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
15528 TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
15529 return WMError::WM_ERROR_INVALID_PARAM;
15530 }
15531 sceneSession->Clear(true);
15532 TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
15533 return WMError::WM_OK;
15534 }
15535
PendingSessionToBackgroundByPersistentId(const int32_t persistentId,bool shouldBackToCaller)15536 WSError SceneSessionManager::PendingSessionToBackgroundByPersistentId(const int32_t persistentId,
15537 bool shouldBackToCaller)
15538 {
15539 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
15540 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
15541 return WSError::WS_ERROR_INVALID_PERMISSION;
15542 }
15543 uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
15544 if (!SessionPermission::VerifyPermissionByCallerToken(callerToken,
15545 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
15546 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, no manage misson permission");
15547 return WSError::WS_ERROR_INVALID_PERMISSION;
15548 }
15549 return taskScheduler_->PostSyncTask([this, persistentId, shouldBackToCaller] {
15550 auto sceneSession = GetSceneSession(persistentId);
15551 if (sceneSession == nullptr) {
15552 TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
15553 return WSError::WS_ERROR_INVALID_PARAM;
15554 }
15555 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
15556 TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
15557 return WSError::WS_ERROR_INVALID_OPERATION;
15558 }
15559 return sceneSession->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
15560 }, __func__);
15561 }
15562
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)15563 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
15564 {
15565 rootSceneProcessBackEventFunc_ = processBackEventFunc;
15566 TLOGI(WmsLogTag::WMS_EVENT, "end");
15567 }
15568
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)15569 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
15570 const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
15571 {
15572 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15573 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The caller has no permission granted.");
15574 return WMError::WM_ERROR_INVALID_PERMISSION;
15575 }
15576
15577 surfaceNodeIds.clear();
15578 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
15579 for (auto persistentId : persistentIds) {
15580 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "convert wid:%{public}d", persistentId);
15581 auto sceneSession = GetSceneSession(persistentId);
15582 if (sceneSession == nullptr) {
15583 continue;
15584 }
15585 auto callingPid = sceneSession->GetCallingPid();
15586 auto surfaceNode = sceneSession->GetSurfaceNode();
15587 if (surfaceNode != nullptr && callingPid == pid) {
15588 surfaceNodeIds.push_back(surfaceNode->GetId());
15589 auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
15590 if (leashWinSurfaceNode != nullptr) {
15591 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
15592 surfaceNodeIds.push_back(persistentId);
15593 }
15594 }
15595 }
15596
15597 return WMError::WM_OK;
15598 }
15599
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)15600 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
15601 {
15602 TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
15603 auto task = [this, func] {
15604 closeTargetFloatWindowFunc_ = func;
15605 };
15606 taskScheduler_->PostTask(task, __func__);
15607 }
15608
CloseTargetFloatWindow(const std::string & bundleName)15609 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
15610 {
15611 if (!SessionPermission::IsSystemServiceCalling(false)) {
15612 TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
15613 return WMError::WM_ERROR_INVALID_PERMISSION;
15614 }
15615 auto task = [this, bundleName] {
15616 if (closeTargetFloatWindowFunc_) {
15617 TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
15618 closeTargetFloatWindowFunc_(bundleName);
15619 }
15620 };
15621 taskScheduler_->PostTask(task, __func__);
15622 return WMError::WM_OK;
15623 }
15624
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)15625 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
15626 {
15627 SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
15628 }
15629
CloseTargetPiPWindow(const std::string & bundleName)15630 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
15631 {
15632 if (!SessionPermission::IsSystemServiceCalling(false)) {
15633 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
15634 return WMError::WM_ERROR_INVALID_PERMISSION;
15635 }
15636 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15637 for (const auto& iter : sceneSessionMap_) {
15638 auto& session = iter.second;
15639 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
15640 session->GetSessionInfo().bundleName_ == bundleName) {
15641 session->NotifyCloseExistPipWindow();
15642 break;
15643 }
15644 }
15645 return WMError::WM_OK;
15646 }
15647
GetCurrentPiPWindowInfo(std::string & bundleName)15648 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
15649 {
15650 if (!SessionPermission::IsSystemServiceCalling(false)) {
15651 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
15652 return WMError::WM_ERROR_INVALID_PERMISSION;
15653 }
15654 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15655 for (const auto& iter : sceneSessionMap_) {
15656 auto& session = iter.second;
15657 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
15658 bundleName = session->GetSessionInfo().bundleName_;
15659 return WMError::WM_OK;
15660 }
15661 }
15662 TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
15663 return WMError::WM_OK;
15664 }
15665
RefreshPcZOrderList(uint32_t startZOrder,std::vector<int32_t> && persistentIds)15666 void SceneSessionManager::RefreshPcZOrderList(uint32_t startZOrder, std::vector<int32_t>&& persistentIds)
15667 {
15668 const char* const where = __func__;
15669 auto task = [this, startZOrder, persistentIds = std::move(persistentIds), where] {
15670 std::ostringstream oss;
15671 oss << "[";
15672 for (size_t i = 0; i < persistentIds.size(); i++) {
15673 int32_t persistentId = persistentIds[i];
15674 oss << persistentId;
15675 if (i < persistentIds.size() - 1) {
15676 oss << ",";
15677 }
15678 auto sceneSession = GetSceneSession(persistentId);
15679 if (sceneSession == nullptr) {
15680 TLOGNE(WmsLogTag::WMS_LAYOUT, "sceneSession is nullptr persistentId=%{public}d", persistentId);
15681 continue;
15682 }
15683 if (i > UINT32_MAX - startZOrder) {
15684 TLOGNE(WmsLogTag::WMS_LAYOUT, "Z order overflow, stop refresh");
15685 break;
15686 }
15687 sceneSession->SetPcScenePanel(true);
15688 sceneSession->UpdatePCZOrderAndMarkDirty(i + startZOrder);
15689 }
15690 oss << "]";
15691 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: %{public}s", where, oss.str().c_str());
15692 return WSError::WS_OK;
15693 };
15694 taskScheduler_->PostTask(task, __func__);
15695 }
15696
SkipSnapshotForAppProcess(int32_t pid,bool skip)15697 WMError SceneSessionManager::SkipSnapshotForAppProcess(int32_t pid, bool skip)
15698 {
15699 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15700 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
15701 return WMError::WM_ERROR_INVALID_PERMISSION;
15702 }
15703 if (pid < 0) {
15704 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid pid!");
15705 return WMError::WM_ERROR_INVALID_PARAM;
15706 }
15707 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d, skip:%{public}u", pid, skip);
15708 auto task = [this, pid, skip]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
15709 if (skip) {
15710 snapshotSkipPidSet_.insert(pid);
15711 } else {
15712 snapshotSkipPidSet_.erase(pid);
15713 }
15714 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15715 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
15716 if (sceneSession == nullptr) {
15717 continue;
15718 }
15719 if (pid == sceneSession->GetCallingPid()) {
15720 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "send rs set snapshot skip, persistentId:%{public}d, skip:%{public}u",
15721 persistentId, skip);
15722 sceneSession->SetSnapshotSkip(skip);
15723 }
15724 }
15725 };
15726 taskScheduler_->PostTask(task, "SkipSnapshotForAppProcess");
15727 return WMError::WM_OK;
15728 }
15729
RemoveProcessSnapshotSkip(int32_t pid)15730 void SceneSessionManager::RemoveProcessSnapshotSkip(int32_t pid)
15731 {
15732 if (snapshotSkipPidSet_.erase(pid) != 0) {
15733 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "process died, delete pid from snapshot skip pid set. pid:%{public}d", pid);
15734 }
15735 }
15736
SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession> & sceneSession)15737 void SceneSessionManager::SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession>& sceneSession)
15738 {
15739 auto callingPid = sceneSession->GetCallingPid();
15740 if (snapshotSkipPidSet_.find(callingPid) != snapshotSkipPidSet_.end()) {
15741 sceneSession->SetSnapshotSkip(true);
15742 }
15743 }
15744
SkipSnapshotByUserIdAndBundleNames(int32_t userId,const std::vector<std::string> & bundleNameList)15745 WMError SceneSessionManager::SkipSnapshotByUserIdAndBundleNames(int32_t userId,
15746 const std::vector<std::string>& bundleNameList)
15747 {
15748 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15749 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The caller has no permission granted.");
15750 return WMError::WM_ERROR_INVALID_PERMISSION;
15751 }
15752 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "userId:%{public}d", userId);
15753 auto task = [this, userId, bundleNameList]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
15754 snapshotSkipBundleNameSet_.clear();
15755 for (auto& bundleName : bundleNameList) {
15756 snapshotSkipBundleNameSet_.insert(std::move(bundleName));
15757 }
15758 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15759 for (const auto& [_, sceneSession] : sceneSessionMap_) {
15760 if (sceneSession == nullptr) {
15761 continue;
15762 }
15763 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
15764 if (snapshotSkipBundleNameSet_.find(bundleName) != snapshotSkipBundleNameSet_.end()) {
15765 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "set RS snapshot skip true, name:%{public}s",
15766 bundleName.c_str());
15767 sceneSession->SetSnapshotSkip(true);
15768 continue;
15769 }
15770 sceneSession->SetSnapshotSkip(false);
15771 }
15772 };
15773 taskScheduler_->PostTask(task, __func__);
15774 return WMError::WM_OK;
15775 }
15776
SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession> & sceneSession)15777 void SceneSessionManager::SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession>& sceneSession)
15778 {
15779 const std::string& name = sceneSession->GetSessionInfo().bundleName_;
15780 if (snapshotSkipBundleNameSet_.find(name) != snapshotSkipBundleNameSet_.end()) {
15781 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "set RS snapshot skip true, name:%{public}s",
15782 name.c_str());
15783 sceneSession->SetSnapshotSkip(true);
15784 }
15785 }
15786
SetProcessWatermark(int32_t pid,const std::string & watermarkName,bool isEnabled)15787 WMError SceneSessionManager::SetProcessWatermark(int32_t pid, const std::string& watermarkName, bool isEnabled)
15788 {
15789 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15790 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
15791 return WMError::WM_ERROR_INVALID_PERMISSION;
15792 }
15793 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "pid:%{public}d, watermarkName:%{public}s, isEnabled:%{public}u",
15794 pid, watermarkName.c_str(), isEnabled);
15795 if (isEnabled && watermarkName.empty()) {
15796 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "watermarkName is empty!");
15797 return WMError::WM_ERROR_INVALID_PARAM;
15798 }
15799 auto task = [this, pid, watermarkName, isEnabled] {
15800 if (isEnabled) {
15801 processWatermarkPidMap_.insert_or_assign(pid, watermarkName);
15802 } else {
15803 processWatermarkPidMap_.erase(pid);
15804 }
15805
15806 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15807 for (const auto& [_, sceneSession] : sceneSessionMap_) {
15808 if (sceneSession == nullptr) {
15809 continue;
15810 }
15811 if (pid == sceneSession->GetCallingPid()) {
15812 sceneSession->SetWatermarkEnabled(watermarkName, isEnabled);
15813 }
15814 }
15815 };
15816 taskScheduler_->PostTask(task, __func__);
15817 return WMError::WM_OK;
15818 }
15819
SetSessionWatermarkForAppProcess(const sptr<SceneSession> & sceneSession)15820 bool SceneSessionManager::SetSessionWatermarkForAppProcess(const sptr<SceneSession>& sceneSession)
15821 {
15822 if (auto iter = processWatermarkPidMap_.find(sceneSession->GetCallingPid());
15823 iter != processWatermarkPidMap_.end()) {
15824 sceneSession->SetWatermarkEnabled(iter->second, true);
15825 return true;
15826 }
15827 return false;
15828 }
15829
RemoveProcessWatermarkPid(int32_t pid)15830 void SceneSessionManager::RemoveProcessWatermarkPid(int32_t pid)
15831 {
15832 if (processWatermarkPidMap_.find(pid) != processWatermarkPidMap_.end()) {
15833 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "process died, delete pid from watermark pid map. pid:%{public}d", pid);
15834 processWatermarkPidMap_.erase(pid);
15835 }
15836 }
15837
GetRootMainWindowId(int32_t persistentId,int32_t & hostWindowId)15838 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
15839 {
15840 if (!SessionPermission::IsSystemServiceCalling()) {
15841 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
15842 return WMError::WM_ERROR_INVALID_PERMISSION;
15843 }
15844 const char* const where = __func__;
15845 auto task = [this, persistentId, &hostWindowId, where]() {
15846 hostWindowId = INVALID_WINDOW_ID;
15847 sptr<Session> session = GetSceneSession(persistentId);
15848 while (session && SessionHelper::IsSubWindow(session->GetWindowType())) {
15849 session = session->GetParentSession();
15850 }
15851 if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
15852 hostWindowId = session->GetPersistentId();
15853 }
15854 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
15855 where, persistentId, hostWindowId);
15856 return WMError::WM_OK;
15857 };
15858 return taskScheduler_->PostSyncTask(task, where);
15859 }
15860
GetMaxInstanceCount(const std::string & bundleName)15861 uint32_t SceneSessionManager::GetMaxInstanceCount(const std::string& bundleName)
15862 {
15863 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
15864 return MultiInstanceManager::GetInstance().GetMaxInstanceCount(bundleName);
15865 } else {
15866 return 0u;
15867 }
15868 }
15869
GetInstanceCount(const std::string & bundleName)15870 uint32_t SceneSessionManager::GetInstanceCount(const std::string& bundleName)
15871 {
15872 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
15873 return MultiInstanceManager::GetInstance().GetInstanceCount(bundleName);
15874 } else {
15875 return 0u;
15876 }
15877 }
15878
GetLastInstanceKey(const std::string & bundleName)15879 std::string SceneSessionManager::GetLastInstanceKey(const std::string& bundleName)
15880 {
15881 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
15882 return MultiInstanceManager::GetInstance().GetLastInstanceKey(bundleName);
15883 } else {
15884 return "";
15885 }
15886 }
15887
RefreshAppInfo(const std::string & bundleName)15888 void SceneSessionManager::RefreshAppInfo(const std::string& bundleName)
15889 {
15890 MultiInstanceManager::GetInstance().RefreshAppInfo(bundleName);
15891 AbilityInfoManager::GetInstance().RemoveAppInfo(bundleName);
15892 }
15893
UpdateScreenLockStatusForApp(const std::string & bundleName,bool isRelease)15894 WMError SceneSessionManager::UpdateScreenLockStatusForApp(const std::string& bundleName, bool isRelease)
15895 {
15896 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15897 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
15898 return WMError::WM_ERROR_INVALID_PERMISSION;
15899 }
15900 #ifdef POWER_MANAGER_ENABLE
15901 if (isRelease) {
15902 return ReleaseScreenLockForApp(bundleName);
15903 } else {
15904 return RelockScreenLockForApp(bundleName);
15905 }
15906 #else
15907 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Can not find the sub system of PowerMgr");
15908 return WMError::WM_OK;
15909 #endif
15910 }
15911
ReleaseScreenLockForApp(const std::string & bundleName)15912 WMError SceneSessionManager::ReleaseScreenLockForApp(const std::string& bundleName)
15913 {
15914 std::vector<sptr<SceneSession>> sessionsToReleaseScreenLock;
15915 GetAllSessionsToReleaseScreenLock(sessionsToReleaseScreenLock, bundleName);
15916 auto task = [this, bundleName, sessionsToReleaseScreenLock] {
15917 for (const auto& sceneSession : sessionsToReleaseScreenLock) {
15918 if (sceneSession->keepScreenLock_ == nullptr || !sceneSession->keepScreenLock_->IsUsed()) {
15919 continue;
15920 }
15921 auto res = sceneSession->keepScreenLock_->UnLock();
15922 if (res != ERR_OK) {
15923 TLOGNE(WmsLogTag::WMS_ATTRIBUTE,
15924 "release screenlock failed, window:[%{public}d, %{public}s], err:%{public}d",
15925 sceneSession->GetPersistentId(), sceneSession->GetWindowName().c_str(), res);
15926 continue;
15927 }
15928 auto [iter, emplaced] = releasedScreenLockMap_.try_emplace(bundleName, std::unordered_set<int32_t>{});
15929 iter->second.insert(sceneSession->GetPersistentId());
15930 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "release screenlock success, window:[%{public}d, %{public}s]",
15931 sceneSession->GetPersistentId(), sceneSession->GetWindowName().c_str());
15932 }
15933 return WMError::WM_OK;
15934 };
15935 return taskScheduler_->PostSyncTask(task, __func__);
15936 }
15937
GetAllSessionsToReleaseScreenLock(std::vector<sptr<SceneSession>> & sessionsToReleaseScreenLock,const std::string & bundleName)15938 void SceneSessionManager::GetAllSessionsToReleaseScreenLock(
15939 std::vector<sptr<SceneSession>>& sessionsToReleaseScreenLock, const std::string& bundleName) {
15940 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15941 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
15942 if (sceneSession->GetSessionInfo().bundleName_ == bundleName && sceneSession->keepScreenLock_ != nullptr) {
15943 sessionsToReleaseScreenLock.push_back(sceneSession);
15944 }
15945 }
15946 }
15947
RelockScreenLockForApp(const std::string & bundleName)15948 WMError SceneSessionManager::RelockScreenLockForApp(const std::string& bundleName)
15949 {
15950 auto task = [this, bundleName] {
15951 auto iter = releasedScreenLockMap_.find(bundleName);
15952 if (iter == releasedScreenLockMap_.end()) {
15953 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: not found in map", bundleName.c_str());
15954 return WMError::WM_ERROR_INVALID_OPERATION;
15955 }
15956 const auto& persistentIds = iter->second;
15957 for (const int32_t persistentId : persistentIds) {
15958 sptr<SceneSession> sceneSession = GetSceneSession(static_cast<int32_t>(persistentId));
15959 if (sceneSession == nullptr) {
15960 continue;
15961 }
15962 auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
15963 auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(
15964 sceneSession->GetScreenId());
15965 if (screenSession) {
15966 sourceMode = screenSession->GetSourceMode();
15967 }
15968 if (sceneSession->IsKeepScreenOn() && IsSessionVisibleForeground(sceneSession) &&
15969 sourceMode != ScreenSourceMode::SCREEN_UNIQUE && sceneSession->keepScreenLock_ != nullptr) {
15970 auto res = sceneSession->keepScreenLock_->Lock();
15971 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "relock screenlock, window: [%{public}d, %{public}s], res:%{public}d",
15972 persistentId, sceneSession->GetWindowName().c_str(), res);
15973 }
15974 }
15975 releasedScreenLockMap_.erase(bundleName);
15976 return WMError::WM_OK;
15977 };
15978 return taskScheduler_->PostSyncTask(task, __func__);
15979 }
15980
IsPcWindow(bool & isPcWindow)15981 WMError SceneSessionManager::IsPcWindow(bool& isPcWindow)
15982 {
15983 isPcWindow = systemConfig_.IsPcWindow();
15984 return WMError::WM_OK;
15985 }
15986
IsFreeMultiWindow(bool & isFreeMultiWindow)15987 WMError SceneSessionManager::IsFreeMultiWindow(bool& isFreeMultiWindow)
15988 {
15989 isFreeMultiWindow = systemConfig_.freeMultiWindowEnable_;
15990 return WMError::WM_OK;
15991 }
15992
IsPcOrPadFreeMultiWindowMode(bool & isPcOrPadFreeMultiWindowMode)15993 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
15994 {
15995 isPcOrPadFreeMultiWindowMode = (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode());
15996 return WMError::WM_OK;
15997 }
15998
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)15999 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
16000 std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
16001 {
16002 if (!SessionPermission::IsSystemCalling()) {
16003 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
16004 return WMError::WM_ERROR_INVALID_PERMISSION;
16005 }
16006
16007 auto task = [this, windowIds, &windowDisplayIdMap] {
16008 for (const uint64_t windowId : windowIds) {
16009 sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
16010 if (session == nullptr) {
16011 continue;
16012 }
16013 DisplayId displayId = session->GetSessionProperty()->GetDisplayId();
16014 if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(displayId)) {
16015 displayId = session->GetClientDisplayId();
16016 }
16017 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
16018 windowId, displayId);
16019 windowDisplayIdMap.insert({windowId, displayId});
16020 }
16021 return WMError::WM_OK;
16022 };
16023 return taskScheduler_->PostSyncTask(task, __func__);
16024 }
16025
IsLastFrameLayoutFinished(bool & isLayoutFinished)16026 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
16027 {
16028 if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
16029 TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
16030 return WSError::WS_ERROR_NULLPTR;
16031 }
16032 isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
16033 return WSError::WS_OK;
16034 }
16035
IsWindowRectAutoSave(const std::string & key,bool & enabled,int persistentId)16036 WMError SceneSessionManager::IsWindowRectAutoSave(const std::string& key, bool& enabled, int persistentId)
16037 {
16038 return taskScheduler_->PostSyncTask([key, &enabled, persistentId, this] {
16039 auto sceneSession = GetSceneSession(persistentId);
16040 if (sceneSession == nullptr) {
16041 TLOGNE(WmsLogTag::WMS_MAIN, "sceneSession %{public}d is nullptr", persistentId);
16042 return WMError::WM_ERROR_INVALID_SESSION;
16043 }
16044 std::string specifiedKey = key;
16045 if (auto iter = this->isSaveBySpecifiedFlagMap_.find(key);
16046 iter != this->isSaveBySpecifiedFlagMap_.end()) {
16047 if (iter->second) {
16048 specifiedKey = key + sceneSession->GetSessionInfo().specifiedFlag_;
16049 }
16050 }
16051 TLOGND(WmsLogTag::WMS_MAIN, "windowId: %{public}d, specifiedKey: %{public}s", persistentId, specifiedKey.c_str());
16052 if (auto iter = this->isWindowRectAutoSaveMap_.find(specifiedKey);
16053 iter != this->isWindowRectAutoSaveMap_.end()) {
16054 enabled = iter->second;
16055 } else {
16056 enabled = false;
16057 }
16058 return WMError::WM_OK;
16059 });
16060
16061 }
16062
SetImageForRecent(uint32_t imgResourceId,ImageFit imageFit,int32_t persistentId)16063 WMError SceneSessionManager::SetImageForRecent(uint32_t imgResourceId, ImageFit imageFit, int32_t persistentId)
16064 {
16065 auto sceneSession = GetSceneSession(persistentId);
16066 if (sceneSession == nullptr) {
16067 TLOGE(WmsLogTag::WMS_PATTERN, "sceneSession %{public}d is null", persistentId);
16068 return WMError::WM_ERROR_NULLPTR;
16069 }
16070
16071 if (sceneSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
16072 TLOGE(WmsLogTag::WMS_PATTERN, "sessionState is invalid");
16073 return WMError::WM_ERROR_NULLPTR;
16074 }
16075 auto abilityInfo = sceneSession->GetSessionInfo().abilityInfo;
16076 if (abilityInfo == nullptr) {
16077 TLOGE(WmsLogTag::WMS_PATTERN, "abilityInfo is null");
16078 return WMError::WM_ERROR_NULLPTR;
16079 }
16080 if (!abilityInfo->applicationInfo.isSystemApp) {
16081 TLOGE(WmsLogTag::WMS_PATTERN, "%{public}d is not a systemApp", persistentId);
16082 return WMError::WM_ERROR_NOT_SYSTEM_APP;
16083 }
16084 std::shared_ptr<Media::PixelMap> pixelMap = GetPixelMap(imgResourceId, abilityInfo);
16085 if (!pixelMap) {
16086 TLOGE(WmsLogTag::WMS_PATTERN, "get pixelMap failed");
16087 return WMError::WM_ERROR_NULLPTR;
16088 }
16089 auto scenePersistence = sceneSession->GetScenePersistence();
16090 if (scenePersistence == nullptr) {
16091 TLOGE(WmsLogTag::WMS_PATTERN, "scenePersistence is null");
16092 return WMError::WM_ERROR_NULLPTR;
16093 }
16094 // Decoupling from LRU
16095 sceneSession->SetSaveSnapshotCallback([](){});
16096 sceneSession->SaveSnapshot(true, true, pixelMap);
16097 scenePersistence->SetHasSnapshot(true);
16098 ScenePersistentStorage::Insert("SetImageForRecent_" + std::to_string(persistentId), static_cast<int32_t>(imageFit), ScenePersistentStorageType::MAXIMIZE_STATE);
16099 return WMError::WM_OK;
16100 }
16101
GetPersistentImageFit(int32_t persistentId,int32_t & imageFit)16102 bool SceneSessionManager::GetPersistentImageFit(int32_t persistentId, int32_t& imageFit)
16103 {
16104 auto persistentImageFit = ScenePersistentStorage::HasKey("SetImageForRecent_" + std::to_string(persistentId),
16105 ScenePersistentStorageType::MAXIMIZE_STATE);
16106 if (persistentImageFit) {
16107 ScenePersistentStorage::Get("SetImageForRecent_" + std::to_string(persistentId),
16108 imageFit, ScenePersistentStorageType::MAXIMIZE_STATE);
16109 return true;
16110 }
16111 return false;
16112 }
16113
GetPixelMap(uint32_t resourceId,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)16114 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetPixelMap(uint32_t resourceId,
16115 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
16116 {
16117 auto resourceMgr = GetResourceManager(*abilityInfo.get());
16118 if (resourceMgr == nullptr) {
16119 TLOGW(WmsLogTag::WMS_PATTERN, "resource manager is null");
16120 return nullptr;
16121 }
16122
16123 Media::SourceOptions opts;
16124 uint32_t errorCode = 0;
16125 std::unique_ptr<Media::ImageSource> imageSource;
16126 if (!abilityInfo->hapPath.empty()) {
16127 std::unique_ptr<uint8_t[]> imageOut;
16128 size_t len;
16129 if (resourceMgr->GetMediaDataById(resourceId, len, imageOut) != Global::Resource::RState::SUCCESS) {
16130 return nullptr;
16131 }
16132 imageSource = Media::ImageSource::CreateImageSource(imageOut.get(), len, opts, errorCode);
16133 } else {
16134 std::string imagePath;
16135 if (resourceMgr->GetMediaById(resourceId, imagePath) != Global::Resource::RState::SUCCESS) {
16136 return nullptr;
16137 }
16138 imageSource = Media::ImageSource::CreateImageSource(imagePath, opts, errorCode);
16139 }
16140
16141 if (errorCode != 0 || imageSource == nullptr) {
16142 TLOGE(WmsLogTag::WMS_PATTERN, "failed id %{private}d err %{public}d", resourceId, errorCode);
16143 return nullptr;
16144 }
16145
16146 Media::DecodeOptions decodeOpts;
16147 auto pixelMapPtr = imageSource->CreatePixelMap(decodeOpts, errorCode);
16148 if (errorCode != 0) {
16149 TLOGE(WmsLogTag::WMS_PATTERN, "failed id %{private}d err %{public}d", resourceId, errorCode);
16150 return nullptr;
16151 }
16152 return std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
16153 }
16154
SetIsWindowRectAutoSave(const std::string & key,bool enabled,const std::string & abilityKey,bool isSaveBySpecifiedFlag)16155 void SceneSessionManager::SetIsWindowRectAutoSave(const std::string& key, bool enabled,
16156 const std::string& abilityKey, bool isSaveBySpecifiedFlag)
16157 {
16158 taskScheduler_->PostSyncTask([key, enabled, abilityKey, isSaveBySpecifiedFlag ,this] {
16159 if (auto iter = this->isSaveBySpecifiedFlagMap_.find(abilityKey);
16160 iter != this->isSaveBySpecifiedFlagMap_.end()) {
16161 if (!isSaveBySpecifiedFlag) {
16162 this->isSaveBySpecifiedFlagMap_.erase(abilityKey);
16163 } else {
16164 iter->second = isSaveBySpecifiedFlag;
16165 }
16166 } else {
16167 if (isSaveBySpecifiedFlag) {
16168 this->isSaveBySpecifiedFlagMap_.insert({abilityKey, isSaveBySpecifiedFlag});
16169 }
16170 }
16171 if (auto iter = this->isWindowRectAutoSaveMap_.find(key);
16172 iter != this->isWindowRectAutoSaveMap_.end()) {
16173 if (!enabled) {
16174 this->isWindowRectAutoSaveMap_.erase(key);
16175 } else {
16176 iter->second = enabled;
16177 }
16178 } else {
16179 if (enabled) {
16180 this->isWindowRectAutoSaveMap_.insert({key, enabled});
16181 }
16182 }
16183 return WMError::WM_OK;
16184 });
16185 }
16186
MinimizeMainSession(const std::string & bundleName,int32_t appIndex,int32_t userId)16187 WMError SceneSessionManager::MinimizeMainSession(const std::string& bundleName, int32_t appIndex, int32_t userId)
16188 {
16189 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16190 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16191 return WMError::WM_ERROR_INVALID_PERMISSION;
16192 }
16193 if ((currentUserId_ != userId && currentUserId_ != DEFAULT_USERID) ||
16194 (currentUserId_ == DEFAULT_USERID && userId != GetUserIdByUid(getuid()))) {
16195 TLOGW(WmsLogTag::WMS_LIFE, "currentUserId:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
16196 currentUserId_.load(), userId, GetUserIdByUid(getuid()));
16197 return WMError::WM_ERROR_INVALID_OPERATION;
16198 }
16199 const char* const where = __func__;
16200 taskScheduler_->PostAsyncTask([this, bundleName, appIndex, where] {
16201 std::vector<sptr<SceneSession>> mainSessions;
16202 GetMainSessionByBundleNameAndAppIndex(bundleName, appIndex, mainSessions);
16203 if (mainSessions.empty()) {
16204 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, not found any main session", where);
16205 return;
16206 }
16207 for (const auto& session : mainSessions) {
16208 session->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
16209 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, id:%{public}d.", where, session->GetPersistentId());
16210 }
16211 }, __func__);
16212 return WMError::WM_OK;
16213 }
16214
SetStartWindowBackgroundColor(const std::string & moduleName,const std::string & abilityName,uint32_t color,int32_t uid)16215 WMError SceneSessionManager::SetStartWindowBackgroundColor(
16216 const std::string& moduleName, const std::string& abilityName, uint32_t color, int32_t uid)
16217 {
16218 if (!bundleMgr_) {
16219 TLOGE(WmsLogTag::WMS_PATTERN, "bundleMgr is nullptr");
16220 return WMError::WM_ERROR_NO_MEM;
16221 }
16222 std::string bundleName;
16223 if (!bundleMgr_->GetBundleNameForUid(uid, bundleName)) {
16224 TLOGE(WmsLogTag::WMS_PATTERN, "get bundle name failed");
16225 return WMError::WM_ERROR_NO_MEM;
16226 }
16227 AppExecFwk::AbilityInfo abilityInfo;
16228 if (!bundleMgr_->GetAbilityInfo(bundleName, moduleName, abilityName, abilityInfo)) {
16229 TLOGE(WmsLogTag::WMS_PATTERN, "ability not found %{public}s %{public}s %{public}s",
16230 bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
16231 return WMError::WM_ERROR_NO_MEM;
16232 }
16233 auto key = moduleName + abilityName;
16234 {
16235 std::unique_lock<std::shared_mutex> lock(startingWindowColorFromAppMapMutex_);
16236 auto iter = startingWindowColorFromAppMap_.find(bundleName);
16237 if (iter != startingWindowColorFromAppMap_.end()) {
16238 iter->second[key] = color;
16239 } else {
16240 std::unordered_map<std::string, uint32_t> colorMap({{ key, color}});
16241 startingWindowColorFromAppMap_.emplace(bundleName, colorMap);
16242 }
16243 }
16244 StartingWindowInfo info;
16245 uint32_t updateRes = UpdateCachedColorToAppSet(bundleName, moduleName, abilityName, info);
16246 TLOGI(WmsLogTag::WMS_PATTERN, "success %{public}s %{public}s, %{public}x, %{public}u",
16247 bundleName.c_str(), key.c_str(), color, updateRes);
16248 return WMError::WM_OK;
16249 }
16250
ShiftAppWindowPointerEvent(int32_t sourcePersistentId,int32_t targetPersistentId,int32_t fingerId)16251 WMError SceneSessionManager::ShiftAppWindowPointerEvent(int32_t sourcePersistentId, int32_t targetPersistentId,
16252 int32_t fingerId)
16253 {
16254 TLOGD(WmsLogTag::WMS_PC, "sourcePersistentId %{public}d targetPersistentId %{public}d",
16255 sourcePersistentId, targetPersistentId);
16256 sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
16257 if (sourceSession == nullptr) {
16258 TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is nullptr", sourcePersistentId);
16259 return WMError::WM_ERROR_INVALID_SESSION;
16260 }
16261 if (sourceSession->GetSessionProperty()->GetPcAppInpadCompatibleMode() &&
16262 !systemConfig_.IsFreeMultiWindowMode()) {
16263 TLOGE(WmsLogTag::WMS_PC, "This is PcAppInPad, not supported");
16264 return WMError::WM_OK;
16265 }
16266 if (!(systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode())) {
16267 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
16268 }
16269 if (sourcePersistentId == targetPersistentId) {
16270 return WMError::WM_ERROR_INVALID_CALLING;
16271 }
16272 if (!WindowHelper::IsAppWindow(sourceSession->GetWindowType())) {
16273 TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is not app window", sourcePersistentId);
16274 return WMError::WM_ERROR_INVALID_CALLING;
16275 }
16276 sptr<SceneSession> targetSession = GetSceneSession(targetPersistentId);
16277 if (targetSession == nullptr) {
16278 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is nullptr", targetPersistentId);
16279 return WMError::WM_ERROR_INVALID_SESSION;
16280 }
16281 if (!WindowHelper::IsAppWindow(targetSession->GetWindowType())) {
16282 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not app window", targetPersistentId);
16283 return WMError::WM_ERROR_INVALID_CALLING;
16284 }
16285 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
16286 TLOGE(WmsLogTag::WMS_PC, "verify bundle failed, source name is %{public}s but target name is %{public}s",
16287 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
16288 return WMError::WM_ERROR_INVALID_CALLING;
16289 }
16290 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
16291 TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not same bundle as calling", targetPersistentId);
16292 return WMError::WM_ERROR_INVALID_CALLING;
16293 }
16294 int32_t callingPid = IPCSkeleton::GetCallingPid();
16295 if (callingPid != targetSession->GetCallingPid()) {
16296 TLOGE(WmsLogTag::WMS_PC, "permission denied, not call by the same process");
16297 return WMError::WM_ERROR_INVALID_CALLING;
16298 }
16299 return ShiftAppWindowPointerEventInner(sourcePersistentId, targetPersistentId,
16300 targetSession->GetSessionProperty()->GetDisplayId(), fingerId);
16301 }
16302
ShiftAppWindowPointerEventInner(int32_t sourceWindowId,int32_t targetWindowId,DisplayId targetDisplayId,int32_t fingerId)16303 WMError SceneSessionManager::ShiftAppWindowPointerEventInner(
16304 int32_t sourceWindowId, int32_t targetWindowId, DisplayId targetDisplayId, int32_t fingerId)
16305 {
16306 return taskScheduler_->PostSyncTask([sourceWindowId, targetWindowId, targetDisplayId, fingerId] {
16307 auto display = DisplayManager::GetInstance().GetDisplayById(targetDisplayId);
16308 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
16309 if (display) {
16310 vpr = display->GetVirtualPixelRatio();
16311 }
16312 int32_t outside = static_cast<int32_t>(HOTZONE_TOUCH * vpr * 2); // double touch hotzone
16313 MMI::ShiftWindowParam param;
16314 param.sourceWindowId = sourceWindowId;
16315 param.targetWindowId = targetWindowId;
16316 param.x = -outside;
16317 param.y = -outside;
16318 if (fingerId == INVALID_FINGER_ID) {
16319 param.sourceType = MMI::PointerEvent::SOURCE_TYPE_MOUSE;
16320 } else {
16321 param.sourceType = MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN;
16322 param.fingerId = fingerId;
16323 }
16324 int ret = MMI::InputManager::GetInstance()->ShiftAppPointerEvent(param, true);
16325 TLOGNI(WmsLogTag::WMS_PC, "sourceWindowId %{public}d targetWindowId %{public}d vpr %{public}f ret %{public}d",
16326 param.sourceWindowId, param.targetWindowId, vpr, ret);
16327 return ret == 0 ? WMError::WM_OK : WMError::WM_ERROR_INVALID_CALLING;
16328 }, __func__);
16329 }
16330
LockSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,bool isLock)16331 WMError SceneSessionManager::LockSessionByAbilityInfo(const AbilityInfoBase& abilityInfo, bool isLock)
16332 {
16333 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16334 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16335 return WMError::WM_ERROR_INVALID_PERMISSION;
16336 }
16337 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
16338 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
16339 return WMError::WM_ERROR_INVALID_PERMISSION;
16340 }
16341 TLOGI(WmsLogTag::WMS_LIFE,
16342 "bundleName:%{public}s moduleName:%{public}s abilityName:%{public}s appIndex:%{public}d isLock:%{public}d",
16343 abilityInfo.bundleName.c_str(), abilityInfo.moduleName.c_str(), abilityInfo.abilityName.c_str(),
16344 abilityInfo.appIndex, isLock);
16345 if (!abilityInfo.IsValid()) {
16346 TLOGE(WmsLogTag::WMS_LIFE, "abilityInfo not valid");
16347 return WMError::WM_ERROR_INVALID_PARAM;
16348 }
16349 taskScheduler_->PostAsyncTask([this, abilityInfo, isLock, where = __func__] {
16350 std::vector<sptr<SceneSession>> mainSessions;
16351 GetMainSessionByAbilityInfo(abilityInfo, mainSessions);
16352 if (!mainSessions.empty()) {
16353 for (const auto& mainSession : mainSessions) {
16354 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, set isLockedState true, persistentId:%{public}d",
16355 where, mainSession->GetPersistentId());
16356 mainSession->NotifySessionLockStateChange(isLock);
16357 }
16358 if (isLock) {
16359 return;
16360 }
16361 }
16362 if (isLock) {
16363 if (sessionLockedStateCacheSet_.size() > MAX_LOCK_STATUS_CACHE_SIZE) {
16364 auto iter = sessionLockedStateCacheSet_.begin();
16365 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, reach max erase begin:%{public}s", where, (*iter).c_str());
16366 sessionLockedStateCacheSet_.erase(iter);
16367 }
16368 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, update isLockedState into cache set", where);
16369 sessionLockedStateCacheSet_.insert(abilityInfo.ToKeyString());
16370 } else {
16371 sessionLockedStateCacheSet_.erase(abilityInfo.ToKeyString());
16372 }
16373 }, __func__);
16374 return WMError::WM_OK;
16375 }
16376
ConfigSupportFunctionType(SupportFunctionType funcType)16377 void SceneSessionManager::ConfigSupportFunctionType(SupportFunctionType funcType)
16378 {
16379 systemConfig_.supportFunctionType_ = funcType;
16380 }
16381
HasFloatingWindowForeground(const sptr<IRemoteObject> & abilityToken,bool & hasOrNot)16382 WMError SceneSessionManager::HasFloatingWindowForeground(const sptr<IRemoteObject>& abilityToken, bool& hasOrNot)
16383 {
16384 if (!abilityToken) {
16385 TLOGE(WmsLogTag::WMS_SYSTEM, "AbilityToken is null");
16386 return WMError::WM_ERROR_NULLPTR;
16387 }
16388 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
16389 TLOGE(WmsLogTag::WMS_SYSTEM, "Permission denied, only for SA");
16390 return WMError::WM_ERROR_INVALID_PERMISSION;
16391 }
16392
16393 return taskScheduler_->PostSyncTask([this, &abilityToken, &hasOrNot, where = __func__] {
16394 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
16395 for (const auto& [_, session] : sceneSessionMap_) {
16396 if (session && session->GetAbilityToken() == abilityToken &&
16397 session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT && session->IsSessionForeground()) {
16398 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s found", where);
16399 hasOrNot = true;
16400 return WMError::WM_OK;
16401 }
16402 }
16403 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s not found", where);
16404 hasOrNot = false;
16405 return WMError::WM_OK;
16406 }, __func__);
16407 }
16408
GetFbPanelWindowId(uint32_t & windowId)16409 WMError SceneSessionManager::GetFbPanelWindowId(uint32_t& windowId)
16410 {
16411 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
16412 for (const auto& iter : sceneSessionMap_) {
16413 auto& session = iter.second;
16414 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FB &&
16415 session->GetWindowName().find(FB_PANEL_NAME) != std::string::npos) {
16416 windowId = static_cast<uint32_t>(session->GetWindowId());
16417 return WMError::WM_OK;
16418 }
16419 }
16420 TLOGW(WmsLogTag::WMS_SYSTEM, "No Fb panel");
16421 return WMError::WM_ERROR_FB_INTERNAL_ERROR;
16422 }
16423
SetStatusBarAvoidHeight(DisplayId displayId,int32_t height)16424 void SceneSessionManager::SetStatusBarAvoidHeight(DisplayId displayId, int32_t height)
16425 {
16426 const char* const where = __func__;
16427 auto task = [this, where, displayId, height] {
16428 statusBarAvoidHeight_[displayId] = height >= 0 ? height : INVALID_STATUS_BAR_AVOID_HEIGHT;
16429 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s, displayId %{public}" PRIu64 " height %{public}d",
16430 where, displayId, statusBarAvoidHeight_[displayId]);
16431 return WMError::WM_OK;
16432 };
16433 taskScheduler_->PostSyncTask(task, where);
16434 }
16435
GetStatusBarAvoidHeight(DisplayId displayId,WSRect & barArea)16436 void SceneSessionManager::GetStatusBarAvoidHeight(DisplayId displayId, WSRect& barArea)
16437 {
16438 auto it = statusBarAvoidHeight_.find(displayId);
16439 if (it == statusBarAvoidHeight_.end()) {
16440 return;
16441 }
16442 if (it->second == INVALID_STATUS_BAR_AVOID_HEIGHT) {
16443 return;
16444 }
16445 TLOGD(WmsLogTag::WMS_IMMS, "displayId %{public}" PRIu64 " height %{public}d", displayId, it->second);
16446 barArea.height_ = it->second;
16447 }
16448
CloneWindow(int32_t fromPersistentId,int32_t toPersistentId,bool needOffScreen)16449 WSError SceneSessionManager::CloneWindow(int32_t fromPersistentId, int32_t toPersistentId, bool needOffScreen)
16450 {
16451 return taskScheduler_->PostSyncTask([this, fromPersistentId, toPersistentId, needOffScreen]() {
16452 auto toSceneSession = GetSceneSession(toPersistentId);
16453 if (toSceneSession == nullptr) {
16454 TLOGNE(WmsLogTag::WMS_PC, "Session is nullptr, id: %{public}d", toPersistentId);
16455 return WSError::WS_ERROR_NULLPTR;
16456 }
16457 NodeId nodeId = INVALID_NODEID;
16458 if (fromPersistentId >= 0) { // if fromPersistentId < 0, excute CloneWindow(0) to cancel cloneWindow
16459 if (auto fromSceneSession = GetSceneSession(fromPersistentId)) {
16460 if (auto surfaceNode = fromSceneSession->GetSurfaceNode()) {
16461 nodeId = surfaceNode->GetId();
16462 }
16463 } else {
16464 TLOGNE(WmsLogTag::WMS_PC, "Session is nullptr, id: %{public}d", fromPersistentId);
16465 return WSError::WS_ERROR_NULLPTR;
16466 }
16467 }
16468 toSceneSession->CloneWindow(nodeId, needOffScreen);
16469 TLOGNI(WmsLogTag::WMS_PC, "fromSurfaceId: %{public}" PRIu64, nodeId);
16470 return WSError::WS_OK;
16471 }, __func__);
16472 }
16473
UpdateSpecificSessionClientDisplayId(const sptr<WindowSessionProperty> & property)16474 DisplayId SceneSessionManager::UpdateSpecificSessionClientDisplayId(const sptr<WindowSessionProperty>& property)
16475 {
16476 auto initClientDisplayId = DEFAULT_DISPLAY_ID;
16477 // SubWindow
16478 if (auto parentSession = GetSceneSession(property->GetParentPersistentId())) {
16479 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "displayId:%{public}" PRIu64 ", parentClientDisplayId:%{public}" PRIu64
16480 ", isFollowParentWindowDisplayId: %{public}u", property->GetDisplayId(),
16481 parentSession->GetClientDisplayId(), property->IsFollowParentWindowDisplayId());
16482 initClientDisplayId =
16483 property->IsFollowParentWindowDisplayId() ? parentSession->GetClientDisplayId() : property->GetDisplayId();
16484 if (property->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
16485 property->SetDisplayId(DEFAULT_DISPLAY_ID);
16486 }
16487 }
16488 // SystemWindow
16489 if (property->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
16490 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "displayId:%{public}" PRIu64, property->GetDisplayId());
16491 property->SetDisplayId(DEFAULT_DISPLAY_ID);
16492 initClientDisplayId = VIRTUAL_DISPLAY_ID;
16493 }
16494 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winName:%{public}s, type:%{public}u, displayId:%{public}" PRIu64
16495 ", clientDisplayId:%{public}" PRIu64 ", parentId:%{public}d", property->GetWindowName().c_str(),
16496 property->GetWindowType(), property->GetDisplayId(), initClientDisplayId, property->GetParentPersistentId());
16497 return initClientDisplayId;
16498 }
16499
UpdateSessionDisplayIdBySessionInfo(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)16500 void SceneSessionManager::UpdateSessionDisplayIdBySessionInfo(
16501 sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
16502 {
16503 if (sceneSession->GetScreenId() == VIRTUAL_DISPLAY_ID &&
16504 sceneSession->GetSessionProperty()->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
16505 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s move display %{public}" PRIu64 " from %{public}" PRIu64,
16506 sessionInfo.bundleName_.c_str(), sessionInfo.screenId_, VIRTUAL_DISPLAY_ID);
16507 sceneSession->SetScreenId(sessionInfo.screenId_);
16508 sceneSession->GetSessionProperty()->SetDisplayId(sessionInfo.screenId_);
16509 }
16510 }
16511
RemoveLifeCycleTaskByPersistentId(int32_t persistentId,const LifeCycleTaskType taskType)16512 void SceneSessionManager::RemoveLifeCycleTaskByPersistentId(int32_t persistentId,
16513 const LifeCycleTaskType taskType)
16514 {
16515 auto sceneSession = GetSceneSession(persistentId);
16516 if (sceneSession == nullptr) {
16517 TLOGE(WmsLogTag::WMS_LIFE, "session:%{public}d is nullptr", persistentId);
16518 return;
16519 }
16520 sceneSession->RemoveLifeCycleTask(taskType);
16521 }
16522
RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener,const std::vector<int32_t> & persistentIdList)16523 WMError SceneSessionManager::RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener,
16524 const std::vector<int32_t>& persistentIdList)
16525 {
16526 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16527 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16528 return WMError::WM_ERROR_INVALID_PERMISSION;
16529 }
16530 if (persistentIdList.empty()) {
16531 TLOGE(WmsLogTag::WMS_LIFE, "persistentIdList is empty!");
16532 return WMError::WM_ERROR_INVALID_PARAM;
16533 }
16534 if (listener == nullptr) {
16535 TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
16536 return WMError::WM_ERROR_INVALID_PARAM;
16537 }
16538 if (listenerController_->IsListenerMapByIdSizeReachLimit()) {
16539 TLOGW(WmsLogTag::WMS_LIFE, "The number of listeners has reached the upper limit.");
16540 return WMError::WM_ERROR_NO_MEM;
16541 }
16542 return taskScheduler_->PostSyncTask([this, listener, persistentIdList, where = __func__] {
16543 WMError ret = listenerController_->RegisterSessionLifecycleListener(listener, persistentIdList);
16544 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
16545 return ret;
16546 }, __func__);
16547 }
16548
RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener,const std::vector<std::string> & bundleNameList)16549 WMError SceneSessionManager::RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener,
16550 const std::vector<std::string>& bundleNameList)
16551 {
16552 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16553 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16554 return WMError::WM_ERROR_INVALID_PERMISSION;
16555 }
16556 if (listener == nullptr) {
16557 TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
16558 return WMError::WM_ERROR_INVALID_PARAM;
16559 }
16560 if (listenerController_->IsListenerMapByBundleSizeReachLimit(bundleNameList.empty())) {
16561 TLOGW(WmsLogTag::WMS_LIFE, "The number of listeners has reached the upper limit.");
16562 return WMError::WM_ERROR_NO_MEM;
16563 }
16564 taskScheduler_->PostAsyncTask([this, listener, bundleNameList, where = __func__] {
16565 WMError ret = listenerController_->RegisterSessionLifecycleListener(listener, bundleNameList);
16566 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
16567 }, __func__);
16568 return WMError::WM_OK;
16569 }
16570
UnregisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener)16571 WMError SceneSessionManager::UnregisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener)
16572 {
16573 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16574 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16575 return WMError::WM_ERROR_INVALID_PERMISSION;
16576 }
16577 if (listener == nullptr) {
16578 TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
16579 return WMError::WM_ERROR_INVALID_PARAM;
16580 }
16581 taskScheduler_->PostAsyncTask([this, listener, where = __func__] {
16582 WMError ret = listenerController_->UnregisterSessionLifecycleListener(listener);
16583 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
16584 }, __func__);
16585 return WMError::WM_OK;
16586 }
16587
SetParentWindowInner(const sptr<SceneSession> & subSession,const sptr<SceneSession> & oldParentSession,const sptr<SceneSession> & newParentSession)16588 WMError SceneSessionManager::SetParentWindowInner(const sptr<SceneSession>& subSession,
16589 const sptr<SceneSession>& oldParentSession, const sptr<SceneSession>& newParentSession)
16590 {
16591 uint32_t oldSubWindowLevel = oldParentSession->GetSessionProperty()->GetSubWindowLevel();
16592 uint32_t newSubWindowLevel = newParentSession->GetSessionProperty()->GetSubWindowLevel();
16593 if (oldSubWindowLevel < newSubWindowLevel &&
16594 subSession->GetMaxSubWindowLevel() + newSubWindowLevel > MAX_SUB_WINDOW_LEVEL) {
16595 TLOGE(WmsLogTag::WMS_SUB, "newParentSession sub level limit");
16596 return WMError::WM_ERROR_INVALID_PARENT;
16597 }
16598 int32_t oldParentWindowId = oldParentSession->GetPersistentId();
16599 int32_t newParentWindowId = newParentSession->GetPersistentId();
16600 subSession->NotifySetParentSession(oldParentWindowId, newParentWindowId);
16601 int32_t subWindowId = subSession->GetPersistentId();
16602 oldParentSession->RemoveSubSession(subWindowId);
16603 newParentSession->AddSubSession(subSession);
16604 subSession->SetParentSession(newParentSession);
16605 subSession->SetParentPersistentId(newParentWindowId);
16606 subSession->UpdateSubWindowLevel(newSubWindowLevel + 1);
16607 if (oldSubWindowLevel == 0) {
16608 oldParentSession->UnregisterNotifySurfaceBoundsChangeFunc(subWindowId);
16609 if (newSubWindowLevel == 0 && subSession->GetIsFollowParentLayout()) {
16610 subSession->SetFollowParentWindowLayoutEnabled(true);
16611 }
16612 }
16613 if (!oldParentSession->IsSameMainSession(newParentSession) && subSession->IsFocused() &&
16614 !subSession->GetSessionProperty()->GetExclusivelyHighlighted()) {
16615 SetHighlightSessionIds(subSession, true);
16616 }
16617 return WMError::WM_OK;
16618 }
16619
SetParentWindow(int32_t subWindowId,int32_t newParentWindowId)16620 WMError SceneSessionManager::SetParentWindow(int32_t subWindowId, int32_t newParentWindowId)
16621 {
16622 return taskScheduler_->PostSyncTask([this, subWindowId, newParentWindowId, where = __func__] {
16623 auto subSession = GetSceneSession(subWindowId);
16624 if (!subSession || !WindowHelper::IsSubWindow(subSession->GetWindowType())) {
16625 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s subSession is nullptr or type invalid", where);
16626 return WMError::WM_ERROR_INVALID_WINDOW;
16627 }
16628 int32_t oldParentWindowId = subSession->GetParentPersistentId();
16629 auto oldParentSession = GetSceneSession(oldParentWindowId);
16630 if (oldParentSession == nullptr) {
16631 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s oldParentSession is nullptr", where);
16632 return WMError::WM_ERROR_INVALID_PARENT;
16633 }
16634 auto oldWindowType = oldParentSession->GetWindowType();
16635 if (!WindowHelper::IsMainWindow(oldWindowType) && !WindowHelper::IsFloatOrSubWindow(oldWindowType)) {
16636 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s oldParentSession window type invalid", where);
16637 return WMError::WM_ERROR_INVALID_PARENT;
16638 }
16639 auto newParentSession = GetSceneSession(newParentWindowId);
16640 if (newParentSession == nullptr) {
16641 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession is nullptr", where);
16642 return WMError::WM_ERROR_INVALID_PARENT;
16643 }
16644 TLOGND(WmsLogTag::WMS_SUB, "%{public}s subWindowId: %{public}d oldParentWindowId: %{public}d "
16645 "newParentWindowId: %{public}d", where, subWindowId, oldParentWindowId, newParentWindowId);
16646 auto newWindowType = newParentSession->GetWindowType();
16647 if (!WindowHelper::IsMainWindow(newWindowType) && !WindowHelper::IsFloatOrSubWindow(newWindowType)) {
16648 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession window type invalid", where);
16649 return WMError::WM_ERROR_INVALID_PARENT;
16650 }
16651 if (oldParentSession->GetCallingPid() != newParentSession->GetCallingPid()) {
16652 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s callingPid not same", where);
16653 return WMError::WM_ERROR_INVALID_PARENT;
16654 }
16655 if (newParentSession->IsAncestorsSession(subWindowId)) {
16656 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession is subsession ancestor", where);
16657 return WMError::WM_ERROR_INVALID_PARENT;
16658 }
16659 return SetParentWindowInner(subSession, oldParentSession, newParentSession);
16660 });
16661 }
16662
NotifyWindowSystemBarPropertyChange(WindowType type,const SystemBarProperty & systemBarProperty)16663 void SceneSessionManager::NotifyWindowSystemBarPropertyChange(
16664 WindowType type, const SystemBarProperty& systemBarProperty)
16665 {
16666 {
16667 std::lock_guard<std::mutex> lock(lastSystemBarPropertyMapMutex_);
16668 auto iter = lastSystemBarPropertyMap_.find(type);
16669 if (iter != lastSystemBarPropertyMap_.end() && iter->second == systemBarProperty) {
16670 TLOGI(WmsLogTag::WMS_IMMS, "type %{public}d prop same as last time.", type);
16671 return;
16672 }
16673 lastSystemBarPropertyMap_[type] = systemBarProperty;
16674 }
16675 SessionManagerAgentController::GetInstance().NotifyWindowSystemBarPropertyChange(type, systemBarProperty);
16676 }
16677
MinimizeByWindowId(const std::vector<int32_t> & windowIds)16678 WMError SceneSessionManager::MinimizeByWindowId(const std::vector<int32_t>& windowIds)
16679 {
16680 if (!SessionPermission::IsSystemServiceCalling()) {
16681 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system service.");
16682 return WMError::WM_ERROR_INVALID_PERMISSION;
16683 }
16684 if (windowIds.empty()) {
16685 TLOGE(WmsLogTag::WMS_LIFE, "The vector of windowids is empty.");
16686 return WMError::WM_ERROR_INVALID_PARAM;
16687 }
16688 taskScheduler_->PostAsyncTask([this, windowIds, where = __func__]() {
16689 if (minimizeByWindowIdFunc_) {
16690 TLOGNI(WmsLogTag::WMS_PC, "%{public}s", where);
16691 minimizeByWindowIdFunc_(windowIds);
16692 }
16693 }, __func__);
16694 return WMError::WM_OK;
16695 }
16696
RegisterMinimizeByWindowIdCallback(MinimizeByWindowIdFunc && func)16697 void SceneSessionManager::RegisterMinimizeByWindowIdCallback(MinimizeByWindowIdFunc&& func){
16698 minimizeByWindowIdFunc_ = std::move(func);
16699 }
16700
GetActiveSceneSessionCopy()16701 const std::vector<sptr<SceneSession>> SceneSessionManager::GetActiveSceneSessionCopy()
16702 {
16703 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
16704 {
16705 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
16706 sceneSessionMapCopy = sceneSessionMap_;
16707 }
16708 std::vector<sptr<SceneSession>> activeSession;
16709 for (const auto& elem : sceneSessionMapCopy) {
16710 auto curSession = elem.second;
16711 if (curSession == nullptr) {
16712 TLOGW(WmsLogTag::DEFAULT, "curSession nullptr");
16713 continue;
16714 }
16715 if (curSession->GetSessionInfo().isSystem_ ||
16716 (!curSession->IsSessionForeground())) {
16717 continue;
16718 }
16719 activeSession.push_back(curSession);
16720 }
16721 return activeSession;
16722 }
16723
RegisterHookSceneSessionActivationFunc(const sptr<SceneSession> & sceneSession)16724 void SceneSessionManager::RegisterHookSceneSessionActivationFunc(const sptr<SceneSession>& sceneSession)
16725 {
16726 TLOGI(WmsLogTag::WMS_LIFE, "in");
16727 sceneSession->HookSceneSessionActivation([](const sptr<SceneSession>& session, bool isNewWant) {
16728 SceneSessionManager::GetInstance().RequestSceneSessionActivation(session, isNewWant);
16729 });
16730 }
16731
ReportKeyboardCreateException(sptr<SceneSession> & keyboardSession)16732 void SceneSessionManager::ReportKeyboardCreateException(sptr<SceneSession>& keyboardSession) {
16733 std::string msg = "UITYPE:" + std::to_string(static_cast<int32_t>(systemConfig_.windowUIType_)) + ",PanelId:[";
16734 for (const auto& session : GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL)) {
16735 if (!session) {
16736 TLOGW(WmsLogTag::DEFAULT, "session nullptr");
16737 continue;
16738 }
16739 msg += "PanelId:" + std::to_string(session->GetPersistentId()) + ",";
16740 msg += "screenId:" + std::to_string(session->GetScreenId()) + ",";
16741 }
16742 msg += "],";
16743 for (const auto& session : GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT)) {
16744 if (!session) {
16745 TLOGW(WmsLogTag::DEFAULT, "session nullptr");
16746 continue;
16747 }
16748 msg += "keyboardId:" + std::to_string(session->GetPersistentId()) + ",";
16749 msg += "screenId:" + std::to_string(session->GetScreenId()) + ",";
16750 }
16751 WindowInfoReporter::GetInstance().ReportKeyboardLifeCycleException(
16752 keyboardSession->GetPersistentId(),
16753 KeyboardLifeCycleException::CREATE_EXCEPTION,
16754 msg);
16755 }
16756
RegisterSceneSessionDestructCallback(NotifySceneSessionDestructFunc && func)16757 void SceneSessionManager::RegisterSceneSessionDestructCallback(NotifySceneSessionDestructFunc&& func)
16758 {
16759 onSceneSessionDestruct_ = std::move(func);
16760 }
16761
RegisterSceneSessionDestructNotifyManagerFunc(const sptr<SceneSession> & sceneSession)16762 void SceneSessionManager::RegisterSceneSessionDestructNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
16763 {
16764 if (sceneSession == nullptr) {
16765 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
16766 return;
16767 }
16768 sceneSession->SetSceneSessionDestructNotificationFunc([this](int32_t persistentId) {
16769 if (onSceneSessionDestruct_) {
16770 onSceneSessionDestruct_(persistentId);
16771 }
16772 });
16773 }
16774
RegisterSessionPropertyChangeNotifyManagerFunc(const sptr<SceneSession> & sceneSession)16775 void SceneSessionManager::RegisterSessionPropertyChangeNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
16776 {
16777 if (sceneSession == nullptr) {
16778 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is nullptr");
16779 return;
16780 }
16781 sceneSession->SetSessionPropertyChangeNotifyManagerListener(
16782 [this](int32_t persistentId, WindowInfoKey windowInfoKey) {
16783 NotifySessionPropertyChangeFromSession(persistentId, windowInfoKey);
16784 });
16785 }
16786
NotifySessionPropertyChangeFromSession(int32_t persistentId,WindowInfoKey windowInfoKey)16787 void SceneSessionManager::NotifySessionPropertyChangeFromSession(int32_t persistentId, WindowInfoKey windowInfoKey)
16788 {
16789 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "persistentId: %{public}d, windowInfoKey: %{public}u",
16790 persistentId, static_cast<uint32_t>(windowInfoKey));
16791 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
16792 if (sceneSession == nullptr) {
16793 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sceneSession nullptr");
16794 return;
16795 }
16796 NotifyWindowPropertyChangeByWindowInfoKey(sceneSession, windowInfoKey);
16797 }
16798
ConfigSupportZLevel()16799 void SceneSessionManager::ConfigSupportZLevel()
16800 {
16801 TLOGI(WmsLogTag::WMS_HIERARCHY, "support zLevel");
16802 auto task = [this] {
16803 systemConfig_.supportZLevel_ = true;
16804 };
16805 taskScheduler_->PostAsyncTask(task, "ConfigSupportZLevel");
16806 }
16807
NotifyWindowPropertyChangeByWindowInfoKey(const sptr<SceneSession> & sceneSession,WindowInfoKey windowInfoKey)16808 void SceneSessionManager::NotifyWindowPropertyChangeByWindowInfoKey(
16809 const sptr<SceneSession>& sceneSession, WindowInfoKey windowInfoKey)
16810 {
16811 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "windowInfoKey: %{public}u", static_cast<uint32_t>(windowInfoKey));
16812 std::vector<std::unordered_map<WindowInfoKey, WindowChangeInfoType>> windowInfoList;
16813 std::unordered_map<WindowInfoKey, WindowChangeInfoType> windowPropertyChangeInfo;
16814 PackWindowPropertyChangeInfo(sceneSession, windowPropertyChangeInfo);
16815 windowInfoList.push_back(windowPropertyChangeInfo);
16816 SessionManagerAgentController::GetInstance().NotifyWindowPropertyChange(
16817 static_cast<uint32_t>(windowInfoKey), windowInfoList);
16818 }
16819
NotifyWindowPropertyChange(ScreenId screenId)16820 void SceneSessionManager::NotifyWindowPropertyChange(ScreenId screenId)
16821 {
16822 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "ObservedFlags: %{public}u, interestedFlags: %{public}u",
16823 observedFlags_, interestedFlags_);
16824 std::vector<std::unordered_map<WindowInfoKey, WindowChangeInfoType>> windowInfoList;
16825 uint32_t propertyDirtyFlags = 0;
16826 {
16827 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
16828 for (const auto& [_, sceneSession] : sceneSessionMap_) {
16829 if (sceneSession == nullptr) {
16830 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "sceneSession nullptr");
16831 continue;
16832 }
16833 if (isNotCurrentScreen(sceneSession, screenId)) {
16834 continue;
16835 }
16836 if (!(sceneSession->GetPropertyDirtyFlags() & observedFlags_)) {
16837 continue;
16838 }
16839 propertyDirtyFlags |= sceneSession->GetPropertyDirtyFlags();
16840 std::unordered_map<WindowInfoKey, WindowChangeInfoType> windowPropertyChangeInfo;
16841 PackWindowPropertyChangeInfo(sceneSession, windowPropertyChangeInfo);
16842 windowInfoList.emplace_back(windowPropertyChangeInfo);
16843 sceneSession->SetPropertyDirtyFlags(0);
16844 }
16845 }
16846 SessionManagerAgentController::GetInstance().NotifyWindowPropertyChange(propertyDirtyFlags, windowInfoList);
16847 }
16848
PackWindowPropertyChangeInfo(const sptr<SceneSession> & sceneSession,std::unordered_map<WindowInfoKey,WindowChangeInfoType> & windowPropertyChangeInfo)16849 void SceneSessionManager::PackWindowPropertyChangeInfo(const sptr<SceneSession>& sceneSession,
16850 std::unordered_map<WindowInfoKey, WindowChangeInfoType>& windowPropertyChangeInfo)
16851 {
16852 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::WINDOW_ID)) {
16853 windowPropertyChangeInfo[WindowInfoKey::WINDOW_ID] = sceneSession->GetWindowId();
16854 }
16855 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::BUNDLE_NAME)) {
16856 windowPropertyChangeInfo[WindowInfoKey::BUNDLE_NAME] = sceneSession->GetSessionInfo().bundleName_;
16857 }
16858 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::ABILITY_NAME)) {
16859 windowPropertyChangeInfo[WindowInfoKey::ABILITY_NAME] = sceneSession->GetSessionInfo().abilityName_;
16860 }
16861 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::APP_INDEX)) {
16862 windowPropertyChangeInfo[WindowInfoKey::APP_INDEX] = sceneSession->GetSessionInfo().appIndex_;
16863 }
16864 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::VISIBILITY_STATE)) {
16865 windowPropertyChangeInfo[WindowInfoKey::VISIBILITY_STATE] = sceneSession->GetVisibilityState();
16866 }
16867 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::DISPLAY_ID)) {
16868 if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(
16869 sceneSession->GetSessionProperty()->GetDisplayId())) {
16870 WSRect sessionGlobalRect = sceneSession->GetSessionGlobalRect();
16871 windowPropertyChangeInfo[WindowInfoKey::DISPLAY_ID] =
16872 sceneSession->TransformGlobalRectToRelativeRect(sessionGlobalRect);
16873 } else {
16874 windowPropertyChangeInfo[WindowInfoKey::DISPLAY_ID] = sceneSession->GetSessionProperty()->GetDisplayId();
16875 }
16876 }
16877 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::WINDOW_RECT)) {
16878 WSRect wsrect = sceneSession->GetClientRect();
16879 Rect rect = { wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
16880 windowPropertyChangeInfo[WindowInfoKey::WINDOW_RECT] = rect;
16881 }
16882 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::WINDOW_MODE)) {
16883 windowPropertyChangeInfo[WindowInfoKey::WINDOW_MODE] = sceneSession->GetWindowMode();
16884 }
16885 if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::FLOATING_SCALE)) {
16886 windowPropertyChangeInfo[WindowInfoKey::FLOATING_SCALE] = sceneSession->GetFloatingScale();
16887 }
16888 }
16889
UseImplicitAnimation(int32_t hostWindowId,bool useImplicit)16890 WSError SceneSessionManager::UseImplicitAnimation(int32_t hostWindowId, bool useImplicit)
16891 {
16892 TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d, useImplicit:%{public}d", hostWindowId, useImplicit);
16893 auto task = [this, hostWindowId, useImplicit]() {
16894 auto sceneSession = GetSceneSession(hostWindowId);
16895 if (sceneSession == nullptr) {
16896 TLOGNE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
16897 return WSError::WS_ERROR_INVALID_SESSION;
16898 }
16899 return sceneSession->UseImplicitAnimation(useImplicit);
16900 };
16901
16902 return taskScheduler_->PostSyncTask(task, "UseImplicitAnimation");
16903 }
16904
GetApplicationInfo(const std::string & bundleName,SCBApplicationInfo & scbApplicationInfo)16905 WSError SceneSessionManager::GetApplicationInfo(const std::string& bundleName, SCBApplicationInfo& scbApplicationInfo)
16906 {
16907 AppExecFwk::ApplicationInfo applicationInfo;
16908 applicationInfo = MultiInstanceManager::GetInstance().GetApplicationInfo(bundleName);
16909 scbApplicationInfo.startMode_ = applicationInfo.startMode;
16910 return WSError::WS_OK;
16911 }
16912
GetRecentMainSessionInfoList(std::vector<RecentSessionInfo> & recentSessionInfoList)16913 WSError SceneSessionManager::GetRecentMainSessionInfoList(std::vector<RecentSessionInfo>& recentSessionInfoList)
16914 {
16915 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16916 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16917 return WSError::WS_ERROR_INVALID_PERMISSION;
16918 }
16919 if (!recentSessionInfoList.empty()) {
16920 TLOGE(WmsLogTag::WMS_LIFE, "the recent session info list is already loaded");
16921 return WSError::WS_ERROR_INVALID_PARAM;
16922 }
16923 return taskScheduler_->PostSyncTask([this, &recentSessionInfoList, where = __func__] {
16924 for (auto& recentSessionInfo : this->recentMainSessionInfoList_) {
16925 if (auto session = GetMainSessionByPersistentId(recentSessionInfo.missionId)) {
16926 session->SetRecentSessionState(recentSessionInfo, session->GetSessionState());
16927 TLOGI(WmsLogTag::WMS_LIFE, "get recent main session info of id:%{public}d, bundleName:%{public}s, "
16928 "moduleName:%{public}s, abilityName:%{public}s, sessionState:%{public}d, windowType:%{public}d",
16929 recentSessionInfo.missionId, recentSessionInfo.bundleName.c_str(),
16930 recentSessionInfo.moduleName.c_str(), recentSessionInfo.abilityName.c_str(),
16931 recentSessionInfo.sessionState, recentSessionInfo.windowType);
16932 recentSessionInfoList.emplace_back(recentSessionInfo);
16933 }
16934 }
16935 return WSError::WS_OK;
16936 });
16937 }
16938
UpdateRecentMainSessionInfos(const std::vector<int32_t> & recentMainSessionIdList)16939 void SceneSessionManager::UpdateRecentMainSessionInfos(const std::vector<int32_t>& recentMainSessionIdList)
16940 {
16941 taskScheduler_->PostAsyncTask([this, recentMainSessionIdList, where = __func__]() {
16942 this->recentMainSessionInfoList_.clear();
16943
16944 for (int32_t persistentId : recentMainSessionIdList) {
16945 if (auto session = GetMainSessionByPersistentId(persistentId)) {
16946 const auto& sessionInfo = session->GetSessionInfo();
16947 RecentSessionInfo info(persistentId);
16948 info.bundleName = sessionInfo.bundleName_;
16949 info.moduleName = sessionInfo.moduleName_;
16950 info.abilityName = sessionInfo.abilityName_;
16951 info.appIndex = sessionInfo.appIndex_;
16952 info.windowType = session->GetWindowType();
16953
16954 this->recentMainSessionInfoList_.emplace_back(info);
16955 }
16956 }
16957 }, __func__);
16958 }
16959
RegisterTransferSessionToTargetScreenCallback(NotifyTransferSessionToTargetScreenFunc && func)16960 void SceneSessionManager::RegisterTransferSessionToTargetScreenCallback(NotifyTransferSessionToTargetScreenFunc&& func)
16961 {
16962 taskScheduler_->PostAsyncTask([this, func] {
16963 onTransferSessionToTargetScreen_ = std::move(func);
16964 }, __func__);
16965 }
16966
NotifyTransferSessionToTargetScreen(const TransferSessionInfo & info)16967 WMError SceneSessionManager::NotifyTransferSessionToTargetScreen(const TransferSessionInfo& info)
16968 {
16969 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16970 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16971 return WMError::WM_ERROR_INVALID_PERMISSION;
16972 }
16973 if (info.persistentId < 0 || info.toScreenId < 0) {
16974 TLOGE(WmsLogTag::WMS_LIFE, "Param is invalid!");
16975 return WMError::WM_ERROR_INVALID_PARAM;
16976 }
16977 taskScheduler_->PostAsyncTask([this, info, where = __func__]() {
16978 if (onTransferSessionToTargetScreen_) {
16979 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, persistentId: %{public}d toScreenId: %{public}d",
16980 where, info.persistentId, info.toScreenId);
16981 onTransferSessionToTargetScreen_(info);
16982 }
16983 }, __func__);
16984 return WMError::WM_OK;
16985 }
16986
NotifySessionTransferToTargetScreenEvent(const int32_t persistentId,const uint32_t resultCode,const uint64_t fromScreenId,const uint64_t toScreenId)16987 void SceneSessionManager::NotifySessionTransferToTargetScreenEvent(const int32_t persistentId,
16988 const uint32_t resultCode, const uint64_t fromScreenId, const uint64_t toScreenId)
16989 {
16990 auto sceneSession = GetSceneSession(persistentId);
16991 if (sceneSession == nullptr) {
16992 TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is nullptr");
16993 return;
16994 }
16995 listenerController_->NotifySessionTransferToTargetScreenEvent(
16996 sceneSession->GetSessionInfo(), resultCode, fromScreenId, toScreenId);
16997 }
16998
AnimateTo(int32_t windowId,const WindowAnimationProperty & animationProperty,const WindowAnimationOption & animationOption)16999 WMError SceneSessionManager::AnimateTo(int32_t windowId, const WindowAnimationProperty& animationProperty,
17000 const WindowAnimationOption& animationOption)
17001 {
17002 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
17003 TLOGE(WmsLogTag::WMS_ANIMATION, "Permission denied, only for SA");
17004 return WMError::WM_ERROR_INVALID_PERMISSION;
17005 }
17006 auto session = GetSceneSession(windowId);
17007 if (session == nullptr || SessionHelper::IsSystemWindow(session->GetWindowType())) {
17008 TLOGNE(WmsLogTag::WMS_ANIMATION, "Can not find window or is system window");
17009 return WMError::WM_DO_NOTHING;
17010 }
17011 session->AnimateTo(animationProperty, animationOption);
17012 return WMError::WM_OK;
17013 }
17014
GetRouterStackInfo(int32_t persistentId,const sptr<ISessionRouterStackListener> & listener)17015 WMError SceneSessionManager::GetRouterStackInfo(int32_t persistentId,
17016 const sptr<ISessionRouterStackListener>& listener)
17017 {
17018 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17019 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17020 return WMError::WM_ERROR_INVALID_PERMISSION;
17021 }
17022 if (listener == nullptr) {
17023 TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr.");
17024 return WMError::WM_ERROR_NULLPTR;
17025 }
17026 auto session = GetSceneSession(persistentId);
17027 if (session == nullptr) {
17028 TLOGE(WmsLogTag::WMS_LIFE, "Session with persistentId %{public}d not found", persistentId);
17029 return WMError::WM_ERROR_NULLPTR;
17030 }
17031 auto task = [this, weakSceneSession = wptr(session), listener, where = __func__] {
17032 sptr<SceneSession> session = weakSceneSession.promote();
17033 if (session == nullptr) {
17034 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
17035 return;
17036 }
17037 std::string routerStack;
17038 auto ret = session->GetRouterStackInfo(routerStack);
17039 sptr<RouterStackInfo> routerStackInfo = sptr<RouterStackInfo>::MakeSptr(session->GetPersistentId(), routerStack);
17040 if (ret != WMError::WM_OK) {
17041 TLOGNE(WmsLogTag::WMS_LIFE, "failed, persistentId %{public}d", session->GetPersistentId());
17042 routerStackInfo->errCode_ = ret;
17043 listener->SendRouterStackInfo(routerStackInfo);
17044 return;
17045 }
17046 listener->SendRouterStackInfo(routerStackInfo);
17047 };
17048 ffrtQueueHelper_->SubmitTask(task);
17049 return WMError::WM_OK;
17050 }
17051
CreateNewInstanceKey(const std::string & bundleName,std::string & instanceKey)17052 WMError SceneSessionManager::CreateNewInstanceKey(const std::string& bundleName, std::string& instanceKey)
17053 {
17054 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17055 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17056 return WMError::WM_ERROR_INVALID_PERMISSION;
17057 }
17058 if (bundleName.empty()) {
17059 TLOGE(WmsLogTag::WMS_LIFE, "empty bundleName");
17060 return WMError::WM_ERROR_INVALID_PARAM;
17061 }
17062 uint32_t maxInstanceCount = MultiInstanceManager::GetInstance().GetMaxInstanceCount(bundleName);
17063 uint32_t instanceCount = GetInstanceCount(bundleName);
17064 if (instanceCount < maxInstanceCount) {
17065 instanceKey = MultiInstanceManager::GetInstance().CreateNewInstanceKey(bundleName);
17066 } else {
17067 instanceKey = MultiInstanceManager::GetInstance().GetLastInstanceKey(bundleName);
17068 }
17069 TLOGI(WmsLogTag::WMS_LIFE, "create new instanceKey:%{public}s of bundle:%{public}s",
17070 instanceKey.c_str(), bundleName.c_str());
17071 return WMError::WM_OK;
17072 }
17073
RemoveInstanceKey(const std::string & bundleName,const std::string & instanceKey)17074 WMError SceneSessionManager::RemoveInstanceKey(const std::string& bundleName, const std::string& instanceKey)
17075 {
17076 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17077 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17078 return WMError::WM_ERROR_INVALID_PERMISSION;
17079 }
17080 if (bundleName.empty()) {
17081 TLOGE(WmsLogTag::WMS_LIFE, "empty bundleName");
17082 return WMError::WM_ERROR_INVALID_PARAM;
17083 }
17084 if (instanceKey.empty()) {
17085 TLOGE(WmsLogTag::WMS_LIFE, "empty instanceKey");
17086 return WMError::WM_ERROR_INVALID_PARAM;
17087 }
17088 auto task = [bundleName, instanceKey] {
17089 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCountByBundleNameAndInstanceKey(
17090 bundleName, instanceKey);
17091 };
17092 taskScheduler_->PostAsyncTask(task, __func__);
17093 TLOGI(WmsLogTag::WMS_LIFE, "remove instanceKey:%{public}s of bundle:%{public}s",
17094 instanceKey.c_str(), bundleName.c_str());
17095 return WMError::WM_OK;
17096 }
17097
UpdateKioskAppList(const std::vector<std::string> & kioskAppList)17098 WMError SceneSessionManager::UpdateKioskAppList(const std::vector<std::string>& kioskAppList)
17099 {
17100 TLOGI(WmsLogTag::WMS_LIFE, "kioskAppList size: %{public}zu", kioskAppList.size());
17101 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17102 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17103 return WMError::WM_ERROR_INVALID_PERMISSION;
17104 }
17105 if (kioskAppList.empty()) {
17106 TLOGE(WmsLogTag::WMS_LIFE, "empty kioskAppList");
17107 return WMError::WM_ERROR_INVALID_PARAM;
17108 }
17109 taskScheduler_->PostAsyncTask([this, kioskAppList] {
17110 if (updateKioskAppListFunc_ != nullptr) {
17111 updateKioskAppListFunc_(kioskAppList);
17112 return WMError::WM_OK;
17113 }
17114 kioskAppListCache_ = kioskAppList;
17115 return WMError::WM_OK;
17116 }, __func__);
17117 return WMError::WM_OK;
17118 }
17119
RegisterUpdateKioskAppListCallback(UpdateKioskAppListFunc && func)17120 void SceneSessionManager::RegisterUpdateKioskAppListCallback(UpdateKioskAppListFunc&& func)
17121 {
17122 taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
17123 updateKioskAppListFunc_ = std::move(callback);
17124 if (!kioskAppListCache_.empty()) {
17125 updateKioskAppListFunc_(kioskAppListCache_);
17126 }
17127 }, __func__);
17128 }
17129
EnterKioskMode(const sptr<IRemoteObject> & token)17130 WMError SceneSessionManager::EnterKioskMode(const sptr<IRemoteObject>& token)
17131 {
17132 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17133 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17134 return WMError::WM_ERROR_INVALID_PERMISSION;
17135 }
17136 taskScheduler_->PostAsyncTask([this, token, where = __func__] {
17137 auto session = FindSessionByToken(token, WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
17138 if (session == nullptr) {
17139 TLOGNE(WmsLogTag::WMS_LIFE, "token is invalid");
17140 return WMError::WM_ERROR_INVALID_PARAM;
17141 }
17142 if (kioskModeChangeFunc_ != nullptr) {
17143 kioskModeChangeFunc_(true, session->GetPersistentId());
17144 return WMError::WM_OK;
17145 }
17146 isKioskMode_ = true;
17147 kioskAppPersistentId_ = session->GetPersistentId();
17148 return WMError::WM_OK;
17149 }, __func__);
17150 return WMError::WM_OK;
17151 }
17152
ExitKioskMode()17153 WMError SceneSessionManager::ExitKioskMode()
17154 {
17155 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17156 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17157 return WMError::WM_ERROR_INVALID_PERMISSION;
17158 }
17159 taskScheduler_->PostAsyncTask([this, where = __func__] {
17160 if (kioskModeChangeFunc_ != nullptr) {
17161 kioskModeChangeFunc_(false, INVALID_SESSION_ID);
17162 return WMError::WM_OK;
17163 }
17164 isKioskMode_ = false;
17165 kioskAppPersistentId_ = INVALID_SESSION_ID;
17166 return WMError::WM_OK;
17167 }, __func__);
17168 return WMError::WM_OK;
17169 }
17170
RegisterKioskModeChangeCallback(KioskModeChangeFunc && func)17171 void SceneSessionManager::RegisterKioskModeChangeCallback(KioskModeChangeFunc&& func)
17172 {
17173 taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
17174 kioskModeChangeFunc_ = std::move(callback);
17175 kioskModeChangeFunc_(isKioskMode_, kioskAppPersistentId_);
17176 }, __func__);
17177 }
17178
GetSceneSessions(ScreenId screenId)17179 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessions(ScreenId screenId)
17180 {
17181 std::vector<sptr<SceneSession>> sceneSessions;
17182 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
17183 for (const auto& [_, sceneSession] : sceneSessionMap_) {
17184 if (sceneSession != nullptr && sceneSession->GetScreenId() == screenId) {
17185 sceneSessions.emplace_back(sceneSession);
17186 }
17187 }
17188 TLOGD(WmsLogTag::WMS_LAYOUT, "screenId: %{public}" PRIu64 ", sceneSession count: %{public}zu",
17189 screenId, sceneSessions.size());
17190 return sceneSessions;
17191 }
17192
SetPiPSettingSwitchStatus(bool switchStatus)17193 void SceneSessionManager::SetPiPSettingSwitchStatus(bool switchStatus)
17194 {
17195 std::lock_guard<std::mutex> lock(pipSettingSwitchMutex_);
17196 pipSwitchStatus_ = switchStatus;
17197 }
17198
GetPiPSettingSwitchStatus(bool & switchStatus)17199 WMError SceneSessionManager::GetPiPSettingSwitchStatus(bool& switchStatus)
17200 {
17201 std::lock_guard<std::mutex> lock(pipSettingSwitchMutex_);
17202 switchStatus = pipSwitchStatus_;
17203 return WMError::WM_OK;
17204 }
17205
UpdateScreenLockState(int32_t persistentId)17206 WMError SceneSessionManager::UpdateScreenLockState(int32_t persistentId)
17207 {
17208 if (persistentId < 0) {
17209 TLOGE(WmsLogTag::WMS_LIFE, "Param is invalid!");
17210 return WMError::WM_ERROR_INVALID_PARAM;
17211 }
17212 taskScheduler_->PostAsyncTask([this, persistentId, where = __func__]() {
17213 auto sceneSession = GetSceneSession(persistentId);
17214 if (sceneSession != nullptr) {
17215 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
17216 sceneSession->keepScreenLock_);
17217 }
17218 }, __func__);
17219 return WMError::WM_OK;
17220 }
17221
UpdateSystemDecorEnable(bool enable)17222 WMError SceneSessionManager::UpdateSystemDecorEnable(bool enable)
17223 {
17224 TLOGI(WmsLogTag::WMS_DECOR, "set system decor enable: %{public}d", enable);
17225 systemConfig_.isSystemDecorEnable_ = enable;
17226 return WMError::WM_OK;
17227 }
17228 } // namespace OHOS::Rosen
17229