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/host/include/scene_session.h"
17 #include <parameters.h>
18
19 #include <ability_manager_client.h>
20 #include <algorithm>
21 #include <climits>
22 #include "configuration.h"
23 #include <hitrace_meter.h>
24 #include "hitrace/hitracechain.h"
25 #include <type_traits>
26 #ifdef IMF_ENABLE
27 #include <input_method_controller.h>
28 #endif // IMF_ENABLE
29 #include <ipc_skeleton.h>
30 #include <modifier_ng/appearance/rs_behind_window_filter_modifier.h>
31 #include <pointer_event.h>
32 #include <key_event.h>
33 #include <transaction/rs_sync_transaction_controller.h>
34 #include <transaction/rs_transaction.h>
35 #include <ui/rs_surface_node.h>
36 #include <ui/rs_canvas_node.h>
37
38 #include "proxy/include/window_info.h"
39
40 #include "application_context.h"
41 #include "common/include/session_permission.h"
42 #ifdef DEVICE_STATUS_ENABLE
43 #include "interaction_manager.h"
44 #endif // DEVICE_STATUS_ENABLE
45 #include "interfaces/include/ws_common.h"
46 #include "pixel_map.h"
47 #include "rs_adapter.h"
48 #include "session_coordinate_helper.h"
49 #include "session/screen/include/screen_session.h"
50 #include "screen_session_manager_client/include/screen_session_manager_client.h"
51 #include "session/host/include/scene_persistent_storage.h"
52 #include "session/host/include/session_change_recorder.h"
53 #include "session/host/include/session_utils.h"
54 #include "display_manager.h"
55 #include "session_helper.h"
56 #include "window_helper.h"
57 #include "window_manager_hilog.h"
58 #include "wm_math.h"
59 #include <running_lock.h>
60 #include "screen_manager.h"
61 #include "screen.h"
62 #include "fold_screen_state_internel.h"
63 #include "fold_screen_common.h"
64 #include "session/host/include/ability_info_manager.h"
65 #include "session/host/include/atomicservice_basic_engine_plugin.h"
66 #include "session/host/include/multi_instance_manager.h"
67 #include "session/host/include/pc_fold_screen_controller.h"
68
69 #ifdef POWER_MANAGER_ENABLE
70 #include <power_mgr_client.h>
71 #endif
72
73 namespace OHOS::Rosen {
74 namespace {
75 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSession" };
76 const std::string DLP_INDEX = "ohos.dlp.params.index";
77 const std::string ERROR_REASON_LOW_MEMORY_KILL = "LowMemoryKill";
78 constexpr const char* APP_CLONE_INDEX = "ohos.extra.param.key.appCloneIndex";
79 constexpr float MINI_FLOAT_SCALE = 0.3f;
80 constexpr float MOVE_DRAG_POSITION_Z = 100.5f;
81 constexpr DisplayId VIRTUAL_DISPLAY_ID = 999;
82 constexpr WSRectF VELOCITY_RELOCATION_TO_TOP = {0.0f, -10.0f, 0.0f, 0.0f};
83 constexpr WSRectF VELOCITY_RELOCATION_TO_BOTTOM = {0.0f, 10.0f, 0.0f, 0.0f};
84 constexpr int32_t API_VERSION_18 = 18;
85 constexpr int32_t HOOK_SYSTEM_BAR_HEIGHT = 40;
86 constexpr int32_t HOOK_AI_BAR_HEIGHT = 28;
87 constexpr int32_t POW_DOUBLE = 2;
88 constexpr int32_t MULTI_WINDOW_TITLE_BAR_DEFAULT_HEIGHT_VP = 32;
89 constexpr uint32_t ROTATION_DEGREE = 90;
90 constexpr int32_t HALF_VALUE = 2;
91 const int32_t ROTATE_POLICY_WINDOW = 0;
92 const int32_t ROTATE_POLICY_SCREEN = 1;
93 const int32_t SCREEN_LOCK_Z_ORDER = 2000;
94 const std::string OPTIONAL_SHOW = "OPTIONAL_SHOW"; // startWindowType can be changed by startAbility option.
95
CheckIfRectElementIsTooLarge(const WSRect & rect)96 bool CheckIfRectElementIsTooLarge(const WSRect& rect)
97 {
98 int32_t largeNumber = static_cast<int32_t>(SHRT_MAX);
99 if (rect.posX_ >= largeNumber || rect.posY_ >= largeNumber ||
100 rect.width_ >= largeNumber || rect.height_ >= largeNumber) {
101 return true;
102 }
103 return false;
104 }
105 } // namespace
106
107 MaximizeMode SceneSession::maximizeMode_ = MaximizeMode::MODE_RECOVER;
108 std::shared_mutex SceneSession::windowDragHotAreaMutex_;
109 std::map<uint64_t, std::map<uint32_t, WSRect>> SceneSession::windowDragHotAreaMap_;
110 static bool g_enableForceUIFirst = system::GetParameter("window.forceUIFirst.enabled", "1") == "1";
111 GetConstrainedModalExtWindowInfoFunc SceneSession::onGetConstrainedModalExtWindowInfoFunc_;
112
SceneSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)113 SceneSession::SceneSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
114 : Session(info)
115 {
116 GeneratePersistentId(false, info.persistentId_);
117 specificCallback_ = specificCallback;
118 SetCollaboratorType(info.collaboratorType_);
119 TLOGI(WmsLogTag::WMS_LIFE, "Create session, id: %{public}d", GetPersistentId());
120 WindowHelper::SplitStringByDelimiter(
121 system::GetParameter("const.window.containerColorLists", ""), ",", containerColorList_);
122 }
123
~SceneSession()124 SceneSession::~SceneSession()
125 {
126 TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
127 // exclude when user deletes session in recent.
128 if (SessionHelper::IsMainWindow(GetWindowType()) && notifySceneSessionDestructFunc_ && !isUserRequestedExit_) {
129 notifySceneSessionDestructFunc_(GetPersistentId());
130 }
131 }
132
ConnectInner(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,SystemSessionConfig & systemConfig,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token,int32_t pid,int32_t uid,const std::string & identityToken)133 WSError SceneSession::ConnectInner(const sptr<ISessionStage>& sessionStage,
134 const sptr<IWindowEventChannel>& eventChannel,
135 const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
136 sptr<WindowSessionProperty> property, sptr<IRemoteObject> token, int32_t pid, int32_t uid,
137 const std::string& identityToken)
138 {
139 return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, &systemConfig,
140 property, token, pid, uid, identityToken, where = __func__] {
141 auto session = weakThis.promote();
142 if (!session) {
143 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
144 return WSError::WS_ERROR_DESTROYED_OBJECT;
145 }
146 if (SessionHelper::IsMainWindow(session->GetWindowType())) {
147 if (!session->CheckIdentityTokenIfMatched(identityToken)) {
148 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s check failed", where);
149 return WSError::WS_OK;
150 }
151 }
152 if (property) {
153 property->SetCollaboratorType(session->GetCollaboratorType());
154 property->SetAppInstanceKey(session->GetAppInstanceKey());
155 property->SetUseControlState(session->isAppUseControl_);
156 property->SetAncoRealBundleName(session->IsAnco() ? session->GetSessionInfo().bundleName_ : "");
157 }
158 session->RetrieveStatusBarDefaultVisibility();
159 auto ret = LOCK_GUARD_EXPR(SCENE_GUARD, session->Session::ConnectInner(
160 sessionStage, eventChannel, surfaceNode, systemConfig, property, token, pid, uid));
161 if (ret != WSError::WS_OK) {
162 return ret;
163 }
164 session->NotifySingleHandTransformChange(session->GetSingleHandTransform());
165 session->NotifyPropertyWhenConnect();
166 if (session->pcFoldScreenController_) {
167 session->pcFoldScreenController_->OnConnect();
168 }
169 return ret;
170 }, __func__);
171 }
172
Connect(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,SystemSessionConfig & systemConfig,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token,const std::string & identityToken)173 WSError SceneSession::Connect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
174 const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
175 sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
176 const std::string& identityToken)
177 {
178 // Get pid and uid before posting task.
179 int32_t pid = IPCSkeleton::GetCallingRealPid();
180 int32_t uid = IPCSkeleton::GetCallingUid();
181 return ConnectInner(sessionStage, eventChannel, surfaceNode, systemConfig,
182 property, token, pid, uid, identityToken);
183 }
184
Reconnect(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token,int32_t pid,int32_t uid)185 WSError SceneSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
186 const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
187 int32_t pid, int32_t uid)
188 {
189 return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel,
190 surfaceNode, property, token, pid, uid, where = __func__] {
191 auto session = weakThis.promote();
192 if (!session) {
193 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
194 return WSError::WS_ERROR_DESTROYED_OBJECT;
195 }
196 WSError ret = LOCK_GUARD_EXPR(SCENE_GUARD,
197 session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid));
198 if (ret != WSError::WS_OK) {
199 return ret;
200 }
201 return LOCK_GUARD_EXPR(SCENE_GUARD, session->ReconnectInner(property));
202 });
203 }
204
ReconnectInner(sptr<WindowSessionProperty> property)205 WSError SceneSession::ReconnectInner(sptr<WindowSessionProperty> property)
206 {
207 if (property == nullptr) {
208 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
209 return WSError::WS_ERROR_NULLPTR;
210 }
211 WindowState windowState = property->GetWindowState();
212 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, windowState: %{public}d ", GetPersistentId(), windowState);
213 WSError ret = WSError::WS_OK;
214 switch (windowState) {
215 case WindowState::STATE_INITIAL: {
216 TLOGE(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, invalid window state: STATE_INITIAL",
217 GetPersistentId());
218 ret = WSError::WS_ERROR_INVALID_PARAM;
219 break;
220 }
221 case WindowState::STATE_CREATED:
222 break;
223 case WindowState::STATE_SHOWN: {
224 UpdateSessionState(SessionState::STATE_FOREGROUND);
225 UpdateActiveStatus(true);
226 break;
227 }
228 case WindowState::STATE_HIDDEN: {
229 UpdateSessionState(SessionState::STATE_BACKGROUND);
230 break;
231 }
232 default:
233 TLOGE(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, invalid window state: %{public}u",
234 GetPersistentId(), windowState);
235 ret = WSError::WS_ERROR_INVALID_PARAM;
236 break;
237 }
238 if (ret != WSError::WS_OK) {
239 Session::Disconnect(false);
240 }
241 if (pcFoldScreenController_) {
242 pcFoldScreenController_->OnConnect();
243 }
244 return ret;
245 }
246
IsShowOnLockScreen(uint32_t lockScreenZOrder)247 bool SceneSession::IsShowOnLockScreen(uint32_t lockScreenZOrder)
248 {
249 TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: lockScreenZOrder: %{public}d, zOrder_: %{public}d", lockScreenZOrder,
250 zOrder_);
251
252 // must be default screen
253 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
254 auto sessionProperty = GetSessionProperty();
255 if (sessionProperty != nullptr && defaultScreenId != sessionProperty->GetDisplayId()) {
256 TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not default display");
257 return false;
258 }
259
260 // current window on lock screen jurded by zorder
261 if (zOrder_ >= lockScreenZOrder) {
262 TLOGNI(WmsLogTag::WMS_UIEXT, "zOrder is bigger");
263 return true;
264 }
265
266 if (zOrder_ == 0) {
267 if (auto mainSession = GetMainSession()) {
268 TLOGI(WmsLogTag::WMS_UIEXT, "mainSession zOrder=%{public}d", mainSession->GetZOrder());
269 return mainSession->GetZOrder() >= lockScreenZOrder;
270 }
271 }
272 return false;
273 }
274
AddExtensionTokenInfo(const UIExtensionTokenInfo & tokenInfo)275 void SceneSession::AddExtensionTokenInfo(const UIExtensionTokenInfo& tokenInfo)
276 {
277 extensionTokenInfos_.push_back(tokenInfo);
278 TLOGD(WmsLogTag::WMS_UIEXT, "can show:%{public}u, id: %{public}d",
279 tokenInfo.canShowOnLockScreen, GetPersistentId());
280 }
281
RemoveExtensionTokenInfo(const sptr<IRemoteObject> & abilityToken)282 void SceneSession::RemoveExtensionTokenInfo(const sptr<IRemoteObject>& abilityToken)
283 {
284 auto persistentId = GetPersistentId();
285 auto itr = std::remove_if(
286 extensionTokenInfos_.begin(), extensionTokenInfos_.end(),
287 [&abilityToken, persistentId, where = __func__](const auto& tokenInfo) {
288 TLOGND(WmsLogTag::WMS_UIEXT,
289 "%{public}s UIExtOnLock: need remove, token: %{public}u, persistentId: %{public}d",
290 where, tokenInfo.callingTokenId, persistentId);
291 return tokenInfo.abilityToken == abilityToken;
292 });
293 extensionTokenInfos_.erase(itr, extensionTokenInfos_.end());
294 }
295
OnNotifyAboveLockScreen()296 void SceneSession::OnNotifyAboveLockScreen()
297 {
298 CheckExtensionOnLockScreenToClose();
299 }
300
CheckExtensionOnLockScreenToClose()301 void SceneSession::CheckExtensionOnLockScreenToClose()
302 {
303 TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: %{public}d", GetPersistentId());
304
305 // 1. check sub session
306 for (auto& session : GetSubSession()) {
307 if (!session) {
308 TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: session is null");
309 continue;
310 }
311 session->CheckExtensionOnLockScreenToClose();
312 }
313
314 // 2. check self permission
315 std::vector<UIExtensionTokenInfo> tokenInfosToClose;
316 for (auto& tokenInfo : extensionTokenInfos_) {
317 if (tokenInfo.canShowOnLockScreen) {
318 continue;
319 }
320 tokenInfosToClose.push_back(tokenInfo);
321 }
322
323 // 3. close ui extension without lock screen permisson
324 std::for_each(tokenInfosToClose.rbegin(), tokenInfosToClose.rend(),
325 [this](const UIExtensionTokenInfo& tokenInfo) { CloseExtensionSync(tokenInfo); });
326 }
327
CloseExtensionSync(const UIExtensionTokenInfo & tokenInfo)328 void SceneSession::CloseExtensionSync(const UIExtensionTokenInfo& tokenInfo)
329 {
330 TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock");
331
332 // hide sub window
333 auto subSceneSessions = GetSubSession();
334 for (auto& session : subSceneSessions) {
335 if (!session) {
336 TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: session is null");
337 continue;
338 }
339 // hide sub window of ui extension
340 if (session->GetAbilityToken() == tokenInfo.abilityToken) {
341 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: hide sub window %{public}u", session->GetWindowId());
342 session->HideSync();
343 }
344 }
345
346 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: close ui extension, callerToken: %{public}u, persistent id %{public}d",
347 tokenInfo.callingTokenId, GetPersistentId());
348
349 // kill ui extension ability
350 AAFwk::AbilityManagerClient::GetInstance()->CloseUIExtensionAbilityBySCB(tokenInfo.abilityToken);
351 }
352
Foreground(sptr<WindowSessionProperty> property,bool isFromClient,const std::string & identityToken)353 WSError SceneSession::Foreground(
354 sptr<WindowSessionProperty> property, bool isFromClient, const std::string& identityToken)
355 {
356 if (!CheckPermissionWithPropertyAnimation(property)) {
357 return WSError::WS_ERROR_NOT_SYSTEM_APP;
358 }
359
360 // return when screen is locked and show without ShowWhenLocked flag
361 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
362 auto sessionProperty = GetSessionProperty();
363 if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
364 IsActivatedAfterScreenLocked() &&
365 GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED) &&
366 (sessionProperty != nullptr && defaultScreenId == sessionProperty->GetDisplayId()) &&
367 !IsShowWhenLocked()) {
368 if (SessionPermission::VerifyCallingPermission("ohos.permission.CALLED_BELOW_LOCK_SCREEN")) {
369 TLOGW(WmsLogTag::WMS_LIFE, "screen is locked, session %{public}d %{public}s permission verified",
370 GetPersistentId(), sessionInfo_.bundleName_.c_str());
371 } else {
372 TLOGW(WmsLogTag::WMS_LIFE,
373 "failed: screen is locked, session %{public}d %{public}s show without ShowWhenLocked flag",
374 GetPersistentId(), sessionInfo_.bundleName_.c_str());
375 return WSError::WS_ERROR_INVALID_SESSION;
376 }
377 }
378
379 if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
380 if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
381 TLOGW(WmsLogTag::WMS_LIFE, "check failed");
382 return WSError::WS_OK;
383 }
384 }
385 return ForegroundTask(property);
386 }
387
SetRequestNextVsyncFunc(RequestVsyncFunc && func)388 void SceneSession::SetRequestNextVsyncFunc(RequestVsyncFunc&& func)
389 {
390 if (func == nullptr) {
391 TLOGI(WmsLogTag::DEFAULT, "func is nullptr");
392 return;
393 }
394 requestNextVsyncFunc_ = std::move(func);
395 }
396
ForegroundTask(const sptr<WindowSessionProperty> & property)397 WSError SceneSession::ForegroundTask(const sptr<WindowSessionProperty>& property)
398 {
399 PostTask([weakThis = wptr(this), property, where = __func__] {
400 auto session = weakThis.promote();
401 if (!session) {
402 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
403 return WSError::WS_ERROR_DESTROYED_OBJECT;
404 }
405 auto sessionProperty = session->GetSessionProperty();
406 if (property && sessionProperty) {
407 sessionProperty->SetWindowMode(property->GetWindowMode());
408 sessionProperty->SetDecorEnable(property->IsDecorEnable());
409 session->SetFocusableOnShow(property->GetFocusableOnShow());
410 }
411 int32_t persistentId = session->GetPersistentId();
412 auto ret = session->Session::Foreground(property);
413 if (ret != WSError::WS_OK) {
414 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session foreground failed, ret=%{public}d persistentId=%{public}d",
415 where, ret, persistentId);
416 return ret;
417 }
418 session->NotifySingleHandTransformChange(session->GetSingleHandTransform());
419 auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
420 if (leashWinSurfaceNode && sessionProperty) {
421 bool lastPrivacyMode = sessionProperty->GetPrivacyMode() || sessionProperty->GetSystemPrivacyMode();
422 leashWinSurfaceNode->SetSecurityLayer(lastPrivacyMode);
423 }
424 session->MarkAvoidAreaAsDirty();
425 auto subSessions = session->GetSubSession();
426 for (const auto& subSession : subSessions) {
427 if (subSession) {
428 subSession->MarkAvoidAreaAsDirty();
429 }
430 }
431 if (session->specificCallback_ != nullptr) {
432 session->specificCallback_->onWindowInfoUpdate_(
433 persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
434 session->specificCallback_->onHandleSecureSessionShouldHide_(session);
435 session->UpdateGestureBackEnabled();
436 } else {
437 TLOGNI(WmsLogTag::WMS_LIFE,
438 "%{public}s foreground specific callback does not take effect, callback function null", where);
439 }
440 if (session->isUIFirstEnabled_) {
441 session->SetSystemSceneForceUIFirst(false);
442 session->isUIFirstEnabled_ = false;
443 }
444 return WSError::WS_OK;
445 }, __func__);
446 return WSError::WS_OK;
447 }
448
CheckAndMoveDisplayIdRecursively(uint64_t displayId)449 void SceneSession::CheckAndMoveDisplayIdRecursively(uint64_t displayId)
450 {
451 if (GetSessionProperty()->GetDisplayId() == displayId || !shouldFollowParentWhenShow_) {
452 return;
453 }
454 TLOGI(WmsLogTag::WMS_LAYOUT, "session id: %{public}d, Move display to %{public}" PRIu64,
455 GetPersistentId(), displayId);
456 SetScreenId(displayId); // notify client to update display id
457 GetSessionProperty()->SetDisplayId(displayId); // set session property
458 NotifySessionDisplayIdChange(displayId);
459 for (const auto& session : subSession_) {
460 if (session) {
461 session->CheckAndMoveDisplayIdRecursively(displayId);
462 }
463 }
464 }
465
Background(bool isFromClient,const std::string & identityToken)466 WSError SceneSession::Background(bool isFromClient, const std::string& identityToken)
467 {
468 if (!CheckPermissionWithPropertyAnimation(GetSessionProperty())) {
469 return WSError::WS_ERROR_NOT_SYSTEM_APP;
470 }
471
472 if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
473 if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
474 TLOGW(WmsLogTag::WMS_LIFE, "check failed");
475 return WSError::WS_OK;
476 }
477 }
478 return BackgroundTask(true);
479 }
480
NotifyFrameLayoutFinishFromApp(bool notifyListener,const WSRect & rect)481 WSError SceneSession::NotifyFrameLayoutFinishFromApp(bool notifyListener, const WSRect& rect)
482 {
483 TLOGI(WmsLogTag::WMS_PATTERN, "%{public}d, %{public}s", notifyListener, rect.ToString().c_str());
484 PostTask([weakThis = wptr(this), notifyListener, rect, where = __func__] {
485 auto session = weakThis.promote();
486 if (!session) {
487 TLOGNE(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s session is null", where);
488 return WSError::WS_ERROR_DESTROYED_OBJECT;
489 }
490 session->layoutRect_ = rect;
491 session->NotifyLayoutFinished();
492 if (notifyListener && session->frameLayoutFinishFunc_) {
493 TLOGND(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s id: %{public}d", where, session->GetPersistentId());
494 session->frameLayoutFinishFunc_();
495 }
496 return WSError::WS_OK;
497 }, __func__);
498 return WSError::WS_OK;
499 }
500
BackgroundTask(const bool isSaveSnapshot,ScreenLockReason reason)501 WSError SceneSession::BackgroundTask(const bool isSaveSnapshot, ScreenLockReason reason)
502 {
503 auto needSaveSnapshot = !ScenePersistentStorage::HasKey("SetImageForRecent_" + std::to_string(GetPersistentId()),
504 ScenePersistentStorageType::MAXIMIZE_STATE);
505 PostTask([weakThis = wptr(this), isSaveSnapshot, needSaveSnapshot, reason, where = __func__] {
506 auto session = weakThis.promote();
507 if (!session) {
508 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
509 return WSError::WS_ERROR_DESTROYED_OBJECT;
510 }
511 auto state = session->GetSessionState();
512 if (state == SessionState::STATE_BACKGROUND) {
513 return WSError::WS_OK;
514 }
515 auto ret = session->Session::Background();
516 if (ret != WSError::WS_OK) {
517 return ret;
518 }
519 if (WindowHelper::IsMainWindow(session->GetWindowType()) && isSaveSnapshot && needSaveSnapshot) {
520 session->SetFreeMultiWindow();
521 session->SaveSnapshot(true, true, nullptr, false, reason);
522 }
523 if (session->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
524 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
525 }
526 session->MarkAvoidAreaAsDirty();
527 if (session->specificCallback_ != nullptr) {
528 session->specificCallback_->onWindowInfoUpdate_(
529 session->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
530 session->specificCallback_->onHandleSecureSessionShouldHide_(session);
531 session->UpdateGestureBackEnabled();
532 }
533 return WSError::WS_OK;
534 }, __func__);
535 return WSError::WS_OK;
536 }
537
NotifySnapshotUpdate()538 WMError SceneSession::NotifySnapshotUpdate()
539 {
540 PostTask([weakThis = wptr(this), where = __func__] {
541 auto session = weakThis.promote();
542 if (!session) {
543 TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s: session is null", where);
544 return;
545 }
546 TLOGNI(WmsLogTag::WMS_PATTERN, "%{public}s: id: %{public}d", where, session->GetPersistentId());
547 if (WindowHelper::IsMainWindow(session->GetWindowType())) {
548 session->SaveSnapshot(true, true, nullptr, true);
549 }
550 }, __func__);
551 return WMError::WM_OK;
552 }
553
ClearSpecificSessionCbMap()554 void SceneSession::ClearSpecificSessionCbMap()
555 {
556 PostTask([weakThis = wptr(this), where = __func__] {
557 auto session = weakThis.promote();
558 if (!session) {
559 TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s: session is null", where);
560 return;
561 }
562 session->ClearJsSceneSessionCbMap(true);
563 }, __func__);
564 }
565
ClearJsSceneSessionCbMap(bool needRemove)566 void SceneSession::ClearJsSceneSessionCbMap(bool needRemove)
567 {
568 if (clearCallbackMapFunc_) {
569 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, needRemove: %{public}d", GetPersistentId(), needRemove);
570 clearCallbackMapFunc_(needRemove);
571 } else {
572 TLOGE(WmsLogTag::WMS_LIFE, "get callback failed, id: %{public}d", GetPersistentId());
573 }
574 }
575
RegisterShowWhenLockedCallback(NotifyShowWhenLockedFunc && callback)576 void SceneSession::RegisterShowWhenLockedCallback(NotifyShowWhenLockedFunc&& callback)
577 {
578 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
579 auto session = weakThis.promote();
580 if (!session) {
581 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
582 return;
583 }
584 session->onShowWhenLockedFunc_ = std::move(callback);
585 session->onShowWhenLockedFunc_(session->GetShowWhenLockedFlagValue());
586 }, __func__);
587 }
588
RegisterForceHideChangeCallback(NotifyForceHideChangeFunc && callback)589 void SceneSession::RegisterForceHideChangeCallback(NotifyForceHideChangeFunc&& callback)
590 {
591 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
592 auto session = weakThis.promote();
593 if (!session) {
594 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
595 return;
596 }
597 session->onForceHideChangeFunc_ = std::move(callback);
598 }, __func__);
599 }
600
RegisterClearCallbackMapCallback(ClearCallbackMapFunc && callback)601 void SceneSession::RegisterClearCallbackMapCallback(ClearCallbackMapFunc&& callback)
602 {
603 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
604 auto session = weakThis.promote();
605 if (!session) {
606 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
607 return;
608 }
609 session->clearCallbackMapFunc_ = std::move(callback);
610 }, __func__);
611 }
612
Disconnect(bool isFromClient,const std::string & identityToken)613 WSError SceneSession::Disconnect(bool isFromClient, const std::string& identityToken)
614 {
615 if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
616 if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
617 TLOGW(WmsLogTag::WMS_LIFE, "check failed");
618 return WSError::WS_OK;
619 }
620 }
621 return DisconnectTask(isFromClient, true);
622 }
623
DisconnectTask(bool isFromClient,bool isSaveSnapshot)624 WSError SceneSession::DisconnectTask(bool isFromClient, bool isSaveSnapshot)
625 {
626 auto needSaveSnapshot = !ScenePersistentStorage::HasKey("SetImageForRecent_" + std::to_string(GetPersistentId()),
627 ScenePersistentStorageType::MAXIMIZE_STATE);
628 PostTask([weakThis = wptr(this), isFromClient, isSaveSnapshot, needSaveSnapshot, where = __func__]()
629 THREAD_SAFETY_GUARD(SCENE_GUARD) {
630 auto session = weakThis.promote();
631 if (!session) {
632 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
633 return WSError::WS_ERROR_DESTROYED_OBJECT;
634 }
635 auto isMainWindow = SessionHelper::IsMainWindow(session->GetWindowType());
636 if (isMainWindow) {
637 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s Notify scene session id: %{public}d paused", where,
638 session->GetPersistentId());
639 session->UpdateLifecyclePausedInner();
640 }
641 if (isFromClient) {
642 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s Client need notify destroy session, id: %{public}d",
643 where, session->GetPersistentId());
644 session->SetSessionState(SessionState::STATE_DISCONNECT);
645 return WSError::WS_OK;
646 }
647 auto state = session->GetSessionState();
648 if ((session->needSnapshot_ || (state == SessionState::STATE_ACTIVE && isMainWindow)) &&
649 isSaveSnapshot && needSaveSnapshot) {
650 session->SaveSnapshot(false);
651 }
652 session->Session::Disconnect(isFromClient);
653 session->isTerminating_ = false;
654 if (session->specificCallback_ != nullptr) {
655 session->specificCallback_->onHandleSecureSessionShouldHide_(session);
656 session->isEnableGestureBack_ = true;
657 session->UpdateGestureBackEnabled();
658 session->isEnableGestureBackHadSet_ = false;
659 }
660 return WSError::WS_OK;
661 }, __func__);
662 return WSError::WS_OK;
663 }
664
UpdateActiveStatus(bool isActive)665 WSError SceneSession::UpdateActiveStatus(bool isActive)
666 {
667 PostTask([weakThis = wptr(this), isActive, where = __func__] {
668 auto session = weakThis.promote();
669 if (!session) {
670 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
671 return WSError::WS_ERROR_DESTROYED_OBJECT;
672 }
673 if (!session->IsSessionValid()) {
674 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Session is invalid, id: %{public}d state: %{public}u",
675 where, session->GetPersistentId(), session->GetSessionState());
676 return WSError::WS_ERROR_INVALID_SESSION;
677 }
678 if (isActive == session->isActive_) {
679 TLOGND(WmsLogTag::WMS_LIFE, "%{public}s Session active do not change: %{public}d",
680 where, isActive);
681 return WSError::WS_DO_NOTHING;
682 }
683
684 WSError ret = WSError::WS_DO_NOTHING;
685 if (isActive && session->GetSessionState() == SessionState::STATE_FOREGROUND) {
686 session->UpdateSessionState(SessionState::STATE_ACTIVE);
687 session->isActive_ = isActive;
688 ret = WSError::WS_OK;
689 }
690 if (!isActive && session->GetSessionState() == SessionState::STATE_ACTIVE) {
691 session->UpdateSessionState(SessionState::STATE_INACTIVE);
692 session->isActive_ = isActive;
693 ret = WSError::WS_OK;
694 }
695 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s isActive: %{public}d, state: %{public}u",
696 where, session->isActive_, session->GetSessionState());
697 return ret;
698 }, std::string(__func__) + ":" + std::to_string(isActive));
699 return WSError::WS_OK;
700 }
701
CalcRectForStatusBar()702 DMRect SceneSession::CalcRectForStatusBar()
703 {
704 DMRect statusBarRect = {0, 0, 0, 0};
705 if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_ == nullptr) {
706 TLOGE(WmsLogTag::WMS_KEYBOARD, "specificCallback is null");
707 return statusBarRect;
708 }
709 const auto& statusBarVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
710 WindowType::WINDOW_TYPE_STATUS_BAR, GetSessionProperty()->GetDisplayId());
711 for (auto& statusBar : statusBarVector) {
712 if (statusBar == nullptr) {
713 continue;
714 }
715 if (statusBar->IsVisible() &&
716 static_cast<uint32_t>(statusBar->GetSessionRect().height_) > statusBarRect.height_) {
717 statusBarRect.height_ = static_cast<uint32_t>(statusBar->GetSessionRect().height_);
718 }
719 if (static_cast<uint32_t>(statusBar->GetSessionRect().width_) > statusBarRect.width_) {
720 statusBarRect.width_ = static_cast<uint32_t>(statusBar->GetSessionRect().width_);
721 }
722 }
723 TLOGD(
724 WmsLogTag::WMS_KEYBOARD, "width: %{public}d, height: %{public}d", statusBarRect.width_, statusBarRect.height_);
725 return statusBarRect;
726 }
727
SetMoveAvailableArea(DisplayId displayId)728 WSError SceneSession::SetMoveAvailableArea(DisplayId displayId)
729 {
730 sptr<Display> display = DisplayManager::GetInstance().GetDisplayById(displayId);
731 if (display == nullptr) {
732 TLOGE(WmsLogTag::WMS_KEYBOARD, "fail to get display");
733 return WSError::WS_ERROR_INVALID_DISPLAY;
734 }
735
736 DMRect availableArea;
737 DMError ret = display->GetAvailableArea(availableArea);
738 if (ret != DMError::DM_OK) {
739 TLOGE(WmsLogTag::WMS_KEYBOARD, "Failed to get available area, ret: %{public}d", ret);
740 return WSError::WS_ERROR_INVALID_DISPLAY;
741 }
742
743 DMRect statusBarRect = CalcRectForStatusBar();
744 if (systemConfig_.IsPadWindow() || systemConfig_.IsPhoneWindow()) {
745 uint32_t statusBarHeight = statusBarRect.height_;
746 if (static_cast<int32_t>(statusBarHeight) > availableArea.posY_) {
747 availableArea.posY_ = static_cast<int32_t>(statusBarHeight);
748 }
749
750 sptr<ScreenSession> currentScreenSession =
751 ScreenSessionManagerClient::GetInstance().GetScreenSessionById(GetSessionProperty()->GetDisplayId());
752 if (currentScreenSession == nullptr) {
753 TLOGW(WmsLogTag::WMS_KEYBOARD, "Screen session is null");
754 return WSError::WS_ERROR_INVALID_DISPLAY;
755 }
756 uint32_t currentScreenHeight = currentScreenSession->GetScreenProperty().GetBounds().rect_.height_;
757 availableArea.height_ = currentScreenHeight - static_cast<uint32_t>(availableArea.posY_);
758 }
759
760 bool isFoldable = ScreenSessionManagerClient::GetInstance().IsFoldable();
761 if (systemConfig_.IsPhoneWindow() && isFoldable && statusBarRect.width_) {
762 availableArea.width_ = statusBarRect.width_;
763 }
764 TLOGD(WmsLogTag::WMS_KEYBOARD,
765 "the available area x is: %{public}d, y is: %{public}d, width is: %{public}d, height is: %{public}d",
766 availableArea.posX_, availableArea.posY_, availableArea.width_, availableArea.height_);
767 moveDragController_->SetMoveAvailableArea(availableArea);
768 return WSError::WS_OK;
769 }
770
InitializeMoveInputBar()771 WSError SceneSession::InitializeMoveInputBar()
772 {
773 auto property = GetSessionProperty();
774 WindowType windowType = property->GetWindowType();
775 if (WindowHelper::IsInputWindow(windowType)) {
776 TLOGD(WmsLogTag::WMS_KEYBOARD, "Start init move input bar param");
777 DisplayId displayId = property->GetDisplayId();
778
779 WSError ret = SetMoveAvailableArea(displayId);
780 if (ret != WSError::WS_OK) {
781 TLOGD(WmsLogTag::WMS_KEYBOARD, "set move availableArea error");
782 return WSError::WS_ERROR_INVALID_OPERATION;
783 }
784 moveDragController_->SetMoveInputBarStartDisplayId(displayId);
785 }
786 return WSError::WS_OK;
787 }
788
IsNeedConvertToRelativeRect(SizeChangeReason reason) const789 bool SceneSession::IsNeedConvertToRelativeRect(SizeChangeReason reason) const
790 {
791 if (reason == SizeChangeReason::DRAG_MOVE) {
792 return true;
793 }
794 if (WindowHelper::IsSubWindow(GetWindowType())) {
795 return IsNeedCrossDisplayRendering() ||
796 (GetWindowAnchorInfo().isAnchorEnabled_ && IsAnyParentSessionDragMoving());
797 }
798 return false;
799 }
800
IsDragMoving() const801 bool SceneSession::IsDragMoving() const
802 {
803 return moveDragController_ ? moveDragController_->GetStartMoveFlag() : false;
804 }
805
IsDragZooming() const806 bool SceneSession::IsDragZooming() const
807 {
808 return moveDragController_ ? moveDragController_->GetStartDragFlag() : false;
809 }
810
IsAnyParentSessionDragMoving() const811 bool SceneSession::IsAnyParentSessionDragMoving() const
812 {
813 if (SessionHelper::IsMainWindow(GetWindowType())) {
814 return IsDragMoving();
815 } else if (parentSession_) {
816 return parentSession_->IsDragMoving() ? true : parentSession_->IsAnyParentSessionDragMoving();
817 }
818 return false;
819 }
820
IsAnyParentSessionDragZooming() const821 bool SceneSession::IsAnyParentSessionDragZooming() const
822 {
823 if (SessionHelper::IsMainWindow(GetWindowType())) {
824 return IsDragZooming();
825 } else if (parentSession_) {
826 return parentSession_->IsDragZooming() ? true : parentSession_->IsAnyParentSessionDragZooming();
827 }
828 return false;
829 }
830
SetParentRect()831 void SceneSession::SetParentRect()
832 {
833 if ((systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode()) && moveDragController_ != nullptr) {
834 moveDragController_->SetParentRect({0, 0, 0, 0});
835 return;
836 }
837 auto mainSession = GetMainSession();
838 if (mainSession != nullptr && moveDragController_ != nullptr) {
839 Rect parentGlobalRect;
840 WMError errorCode = mainSession->GetGlobalScaledRect(parentGlobalRect);
841 if (errorCode != WMError::WM_OK) {
842 TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, errorCode:%{public}d", GetPersistentId(), errorCode);
843 return;
844 }
845 moveDragController_->SetParentRect(parentGlobalRect);
846 }
847 }
848
GetGlobalOrWinRect()849 WSRect SceneSession::GetGlobalOrWinRect()
850 {
851 if (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode()) {
852 return GetSessionRect();
853 }
854 return GetSessionGlobalRect();
855 }
856
OnSessionEvent(SessionEvent event)857 WSError SceneSession::OnSessionEvent(SessionEvent event)
858 {
859 PostTask([weakThis = wptr(this), event, where = __func__] {
860 auto session = weakThis.promote();
861 if (!session) {
862 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
863 return WSError::WS_ERROR_DESTROYED_OBJECT;
864 }
865 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s event: %{public}d", where, static_cast<int32_t>(event));
866 session->UpdateWaterfallMode(event);
867 auto property = session->GetSessionProperty();
868 bool proportionalScale = property->IsAdaptToProportionalScale();
869 if (event == SessionEvent::EVENT_START_MOVE) {
870 if (!session->IsMovable()) {
871 return WSError::WS_OK;
872 }
873 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::StartMove");
874 WSError ret = session->InitializeMoveInputBar();
875 if (ret != WSError::WS_OK) {
876 return ret;
877 }
878 session->InitializeCrossMoveDrag();
879 session->moveDragController_->InitMoveDragProperty();
880 if (session->pcFoldScreenController_) {
881 WSRect currRect;
882 session->HookStartMoveRect(currRect, session->GetSessionRect());
883 session->pcFoldScreenController_->RecordStartMoveRect(currRect, session->IsFullScreenMovable());
884 }
885 WSRect rect = session->GetGlobalOrWinRect();
886 if (session->IsFullScreenMovable()) {
887 session->UpdateFullScreenWaterfallMode(false);
888 rect = session->moveDragController_->GetFullScreenToFloatingRect(session->GetSessionRect(),
889 session->GetSessionRequestRect());
890 session->Session::UpdateRect(rect, SizeChangeReason::RECOVER, where, nullptr);
891 session->moveDragController_->SetStartMoveFlag(true);
892 session->moveDragController_->CalcFirstMoveTargetRect(rect, true);
893 } else {
894 session->SetParentRect();
895 session->moveDragController_->SetScale(session->GetScaleX(), session->GetScaleY());
896 session->moveDragController_->SetStartMoveFlag(true);
897 // use window rect when fullscreen or compatible mode
898 session->moveDragController_->CalcFirstMoveTargetRect(rect, proportionalScale);
899 }
900 session->SetSessionEventParam({session->moveDragController_->GetOriginalPointerPosX(),
901 session->moveDragController_->GetOriginalPointerPosY(), rect.width_, rect.height_});
902 }
903 session->HandleSessionDragEvent(event);
904 if (session->onSessionEvent_) {
905 session->onSessionEvent_(static_cast<uint32_t>(event), session->sessionEventParam_);
906 }
907 return WSError::WS_OK;
908 }, std::string(__func__) + ":" + std::to_string(static_cast<uint32_t>(event)));
909 return WSError::WS_OK;
910 }
911
HandleSessionDragEvent(SessionEvent event)912 void SceneSession::HandleSessionDragEvent(SessionEvent event)
913 {
914 DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
915 if (moveDragController_ &&
916 (event == SessionEvent::EVENT_DRAG || event == SessionEvent::EVENT_DRAG_START)) {
917 WSRect rect = moveDragController_->GetTargetRect(
918 MoveDragController::TargetRectCoordinate::RELATED_TO_START_DISPLAY);
919 auto property = GetSessionProperty();
920 if (event == SessionEvent::EVENT_DRAG_START && moveDragController_->GetStartDragFlag()) {
921 if (property->IsAdaptToDragScale()) {
922 dragResizeType = DragResizeType::RESIZE_SCALE;
923 } else {
924 dragResizeType = GetAppDragResizeType();
925 }
926 SetDragResizeTypeDuringDrag(dragResizeType);
927 } else if (event == SessionEvent::EVENT_DRAG) {
928 if (property->IsAdaptToDragScale()) {
929 dragResizeType = DragResizeType::RESIZE_SCALE;
930 } else {
931 dragResizeType = GetDragResizeTypeDuringDrag();
932 }
933 }
934 Gravity gravity = moveDragController_->GetGravity();
935 SetSessionEventParam({rect.posX_, rect.posY_, rect.width_, rect.height_,
936 static_cast<uint32_t>(dragResizeType), static_cast<uint32_t>(gravity)});
937 } else if (moveDragController_ && event == SessionEvent::EVENT_END_MOVE) {
938 const auto& lastDragEndRect = moveDragController_->GetLastDragEndRect();
939 SetSessionEventParam({lastDragEndRect.posX_, lastDragEndRect.posY_,
940 lastDragEndRect.width_, lastDragEndRect.height_,
941 static_cast<uint32_t>(GetDragResizeTypeDuringDrag()),
942 static_cast<uint32_t>(moveDragController_->GetGravity())});
943 SetDragResizeTypeDuringDrag(dragResizeType);
944 }
945 }
946
UpdateWaterfallMode(SessionEvent event)947 void SceneSession::UpdateWaterfallMode(SessionEvent event)
948 {
949 if (pcFoldScreenController_ == nullptr) {
950 return;
951 }
952 switch (event) {
953 case SessionEvent::EVENT_MAXIMIZE_WATERFALL:
954 UpdateFullScreenWaterfallMode(pcFoldScreenController_->IsHalfFolded(GetScreenId()));
955 break;
956 case SessionEvent::EVENT_WATERFALL_TO_MAXIMIZE:
957 case SessionEvent::EVENT_RECOVER:
958 case SessionEvent::EVENT_SPLIT_PRIMARY:
959 case SessionEvent::EVENT_SPLIT_SECONDARY:
960 UpdateFullScreenWaterfallMode(false);
961 break;
962 default:
963 break;
964 }
965 }
966
SyncSessionEvent(SessionEvent event)967 WSError SceneSession::SyncSessionEvent(SessionEvent event)
968 {
969 TLOGD(WmsLogTag::WMS_LAYOUT, "the sync session event is: %{public}d", event);
970 if (event != SessionEvent::EVENT_START_MOVE && event != SessionEvent::EVENT_END_MOVE) {
971 TLOGE(WmsLogTag::WMS_LAYOUT, "This is not start move event or end move event, "
972 "eventId=%{public}u windowId=%{public}d", event, GetPersistentId());
973 return WSError::WS_ERROR_NULLPTR;
974 }
975 return PostSyncTask([weakThis = wptr(this), event, where = __func__] {
976 auto session = weakThis.promote();
977 if (!session || !session->moveDragController_) {
978 TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s: session or moveDragController is null", where);
979 return WSError::WS_ERROR_NULLPTR;
980 }
981 if (event == SessionEvent::EVENT_END_MOVE) {
982 if (!session->moveDragController_->GetStartMoveFlag()) {
983 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s Repeat operation, window is not moving", where);
984 return WSError::WS_OK;
985 }
986 session->moveDragController_->StopMoving();
987 return WSError::WS_OK;
988 }
989 if (session->moveDragController_->GetStartMoveFlag()) {
990 TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s: Repeat operation, system window is moving", where);
991 return WSError::WS_ERROR_REPEAT_OPERATION;
992 }
993 session->OnSessionEvent(event);
994 return WSError::WS_OK;
995 }, __func__);
996 }
997
StartMovingWithCoordinate(int32_t offsetX,int32_t offsetY,int32_t pointerPosX,int32_t pointerPosY,DisplayId displayId)998 WSError SceneSession::StartMovingWithCoordinate(int32_t offsetX, int32_t offsetY,
999 int32_t pointerPosX, int32_t pointerPosY, DisplayId displayId)
1000 {
1001 return PostSyncTask([weakThis = wptr(this), offsetX, offsetY, pointerPosX, pointerPosY,
1002 displayId, where = __func__] {
1003 auto session = weakThis.promote();
1004 if (!session || !session->moveDragController_) {
1005 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s: session or moveDragController is null", where);
1006 return WSError::WS_ERROR_NULLPTR;
1007 }
1008 if (session->moveDragController_->GetStartMoveFlag()) {
1009 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s: Repeat operation, window is moving", where);
1010 return WSError::WS_ERROR_REPEAT_OPERATION;
1011 }
1012 TLOGNI(WmsLogTag::WMS_LAYOUT_PC, "%{public}s: offset:[%{public}d,%{public}d] pointer:[%{public}d,%{public}d]"
1013 " displayId:%{public}" PRIu64, where, offsetX, offsetY, pointerPosX, pointerPosY, displayId);
1014 int32_t pointerY = pointerPosY;
1015 if (displayId == VIRTUAL_DISPLAY_ID) {
1016 pointerY += PcFoldScreenManager::GetInstance().GetVirtualDisplayPosY();
1017 TLOGNI(WmsLogTag::WMS_LAYOUT_PC, "%{public}s: virtual display pointerY:%{public}d", where, pointerY);
1018 }
1019 WSRect winRect = {
1020 pointerPosX - offsetX,
1021 pointerY - offsetY,
1022 session->GetSessionRect().width_,
1023 session->GetSessionRect().height_
1024 };
1025 session->InitializeCrossMoveDrag();
1026 session->moveDragController_->InitMoveDragProperty();
1027 MoveDragController::MoveCoordinateProperty property = { offsetX, offsetY, pointerPosX,
1028 pointerY, displayId, winRect };
1029 session->moveDragController_->HandleStartMovingWithCoordinate(property);
1030 session->moveDragController_->SetSpecifyMoveStartDisplay(displayId);
1031 session->OnSessionEvent(SessionEvent::EVENT_START_MOVE);
1032 return WSError::WS_OK;
1033 }, __func__);
1034 }
1035
GetWindowDragHotAreaType(DisplayId displayId,uint32_t type,int32_t pointerX,int32_t pointerY)1036 uint32_t SceneSession::GetWindowDragHotAreaType(DisplayId displayId, uint32_t type, int32_t pointerX, int32_t pointerY)
1037 {
1038 std::shared_lock<std::shared_mutex> lock(windowDragHotAreaMutex_);
1039 if (windowDragHotAreaMap_.find(displayId) == windowDragHotAreaMap_.end()) {
1040 TLOGW(WmsLogTag::WMS_LAYOUT, "Display is invalid.");
1041 return type;
1042 }
1043 for (const auto& [key, rect] : windowDragHotAreaMap_[displayId]) {
1044 if (rect.IsInRegion(pointerX, pointerY)) {
1045 type |= key;
1046 }
1047 }
1048 return type;
1049 }
1050
AddOrUpdateWindowDragHotArea(DisplayId displayId,uint32_t type,const WSRect & area)1051 void SceneSession::AddOrUpdateWindowDragHotArea(DisplayId displayId, uint32_t type, const WSRect& area)
1052 {
1053 std::unique_lock<std::shared_mutex> lock(windowDragHotAreaMutex_);
1054 windowDragHotAreaMap_[displayId].insert_or_assign(type, area);
1055 }
1056
NotifySubModalTypeChange(SubWindowModalType subWindowModalType)1057 WSError SceneSession::NotifySubModalTypeChange(SubWindowModalType subWindowModalType)
1058 {
1059 PostTask([weakThis = wptr(this), subWindowModalType, where = __func__] {
1060 auto session = weakThis.promote();
1061 if (!session) {
1062 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1063 return;
1064 }
1065 TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s subWindowModalType: %{public}u",
1066 where, static_cast<uint32_t>(subWindowModalType));
1067 if (session->onSubModalTypeChange_) {
1068 session->onSubModalTypeChange_(subWindowModalType);
1069 }
1070 }, __func__);
1071 return WSError::WS_OK;
1072 }
1073
RegisterSubModalTypeChangeCallback(NotifySubModalTypeChangeFunc && func)1074 void SceneSession::RegisterSubModalTypeChangeCallback(NotifySubModalTypeChangeFunc&& func)
1075 {
1076 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1077 auto session = weakThis.promote();
1078 if (!session || !func) {
1079 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session or SessionModalTypeChangeFunc is null", where);
1080 return;
1081 }
1082 session->onSubModalTypeChange_ = std::move(func);
1083 TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s id: %{public}d",
1084 where, session->GetPersistentId());
1085 }, __func__);
1086 }
1087
RegisterMainModalTypeChangeCallback(NotifyMainModalTypeChangeFunc && func)1088 void SceneSession::RegisterMainModalTypeChangeCallback(NotifyMainModalTypeChangeFunc&& func)
1089 {
1090 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1091 auto session = weakThis.promote();
1092 if (!session || !func) {
1093 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session or func is null", where);
1094 return;
1095 }
1096 session->onMainModalTypeChange_ = std::move(func);
1097 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, session->GetPersistentId());
1098 }, __func__);
1099 }
1100
IsDialogWindow() const1101 bool SceneSession::IsDialogWindow() const
1102 {
1103 return WindowHelper::IsDialogWindow(GetSessionProperty()->GetWindowType());
1104 }
1105
GetSubWindowModalType() const1106 SubWindowModalType SceneSession::GetSubWindowModalType() const
1107 {
1108 SubWindowModalType modalType = SubWindowModalType::TYPE_UNDEFINED;
1109 auto property = GetSessionProperty();
1110 if (property == nullptr) {
1111 TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
1112 return modalType;
1113 }
1114 auto windowType = property->GetWindowType();
1115 if (WindowHelper::IsToastSubWindow(windowType, property->GetWindowFlags())) {
1116 return SubWindowModalType::TYPE_TOAST;
1117 }
1118 if (WindowHelper::IsTextMenuSubWindow(windowType, property->GetWindowFlags())) {
1119 return SubWindowModalType::TYPE_TEXT_MENU;
1120 }
1121 if (WindowHelper::IsDialogWindow(windowType)) {
1122 modalType = SubWindowModalType::TYPE_DIALOG;
1123 } else if (WindowHelper::IsModalSubWindow(windowType, property->GetWindowFlags())) {
1124 if (WindowHelper::IsApplicationModalSubWindow(windowType, property->GetWindowFlags())) {
1125 modalType = SubWindowModalType::TYPE_APPLICATION_MODALITY;
1126 } else {
1127 modalType = SubWindowModalType::TYPE_WINDOW_MODALITY;
1128 }
1129 } else if (WindowHelper::IsSubWindow(windowType)) {
1130 modalType = SubWindowModalType::TYPE_NORMAL;
1131 }
1132 return modalType;
1133 }
1134
SetSessionEventParam(SessionEventParam param)1135 void SceneSession::SetSessionEventParam(SessionEventParam param)
1136 {
1137 sessionEventParam_ = param;
1138 }
1139
RegisterSessionEventCallback(NotifySessionEventFunc && callback)1140 void SceneSession::RegisterSessionEventCallback(NotifySessionEventFunc&& callback)
1141 {
1142 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1143 auto session = weakThis.promote();
1144 if (!session) {
1145 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
1146 return;
1147 }
1148 session->onSessionEvent_ = std::move(callback);
1149 }, __func__);
1150 }
1151
RegisterUpdateAppUseControlCallback(UpdateAppUseControlFunc && callback)1152 void SceneSession::RegisterUpdateAppUseControlCallback(UpdateAppUseControlFunc&& callback)
1153 {
1154 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1155 auto session = weakThis.promote();
1156 if (!session) {
1157 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1158 return;
1159 }
1160 session->onUpdateAppUseControlFunc_ = std::move(callback);
1161 if (session->GetSessionInfo().hasPrivacyModeControl) {
1162 TLOGNI(WmsLogTag::WMS_LIFE, "has privacy mode control, id:%{public}d", session->GetPersistentId());
1163 ControlInfo controlInfo = { .isNeedControl = true, .isControlRecentOnly = true };
1164 session->NotifyUpdateAppUseControl(ControlAppType::PRIVACY_WINDOW, controlInfo);
1165 } else {
1166 session->UpdatePrivacyModeControlInfo();
1167 }
1168 if (!session->onGetAllAppUseControlMapFunc_) {
1169 TLOGNE(WmsLogTag::WMS_LIFE,
1170 "id: %{public}d session GetAllAppUseControlMapFunc is null", session->GetPersistentId());
1171 return;
1172 }
1173 auto& allAppUseControlMap = session->onGetAllAppUseControlMapFunc_();
1174 std::string key = SessionUtils::GetAppLockKey(session->GetSessionInfo().bundleName_,
1175 session->GetSessionInfo().appIndex_);
1176 if (allAppUseControlMap.find(key) == allAppUseControlMap.end()) {
1177 return;
1178 }
1179 bool appUseControlResult = false;
1180 for (const auto& [type, info] : allAppUseControlMap[key]) {
1181 TLOGNI(WmsLogTag::WMS_LIFE,
1182 "notify appUseControl when register, key: %{public}s, control: %{public}d, controlRecent: %{public}d",
1183 key.c_str(), info.isNeedControl, info.isControlRecentOnly);
1184 session->onUpdateAppUseControlFunc_(type, info.isNeedControl, info.isControlRecentOnly);
1185 if (info.isNeedControl && !info.isControlRecentOnly) {
1186 appUseControlResult = true;
1187 }
1188 }
1189 session->isAppUseControl_ = appUseControlResult;
1190 }, __func__);
1191 }
1192
NotifyUpdateAppUseControl(ControlAppType type,const ControlInfo & controlInfo)1193 void SceneSession::NotifyUpdateAppUseControl(ControlAppType type, const ControlInfo& controlInfo)
1194 {
1195 PostTask([weakThis = wptr(this), type, controlInfo, where = __func__] {
1196 auto session = weakThis.promote();
1197 if (!session) {
1198 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1199 return;
1200 }
1201 session->appUseControlMap_[type] = controlInfo;
1202 if (session->onUpdateAppUseControlFunc_) {
1203 bool isAppUseControl = (controlInfo.isNeedControl && !controlInfo.isControlRecentOnly);
1204 session->isAppUseControl_ = isAppUseControl;
1205 session->onUpdateAppUseControlFunc_(type, controlInfo.isNeedControl, controlInfo.isControlRecentOnly);
1206 if (session->sessionStage_ == nullptr || type == ControlAppType::PRIVACY_WINDOW) {
1207 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s sessionStage is nullptr or privacy mode control", where);
1208 return;
1209 }
1210 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s isAppUseControl: %{public}d, persistentId: %{public}d", where,
1211 isAppUseControl, session->GetPersistentId());
1212 session->sessionStage_->NotifyAppUseControlStatus(isAppUseControl);
1213 }
1214 }, __func__);
1215 }
1216
UpdatePrivacyModeControlInfo()1217 void SceneSession::UpdatePrivacyModeControlInfo()
1218 {
1219 bool isPrivacyMode = false;
1220 auto property = GetSessionProperty();
1221 if ((property && property->GetPrivacyMode()) || HasSubSessionInPrivacyMode()) {
1222 isPrivacyMode = true;
1223 }
1224 if (!isPrivacyMode && appUseControlMap_.find(ControlAppType::PRIVACY_WINDOW) == appUseControlMap_.end()) {
1225 TLOGI(WmsLogTag::WMS_LIFE, "no need to update privacy mode control info");
1226 return;
1227 }
1228 ControlInfo controlInfo = { .isNeedControl = isPrivacyMode, .isControlRecentOnly = true };
1229 NotifyUpdateAppUseControl(ControlAppType::PRIVACY_WINDOW, controlInfo);
1230 }
1231
HasSubSessionInPrivacyMode()1232 bool SceneSession::HasSubSessionInPrivacyMode()
1233 {
1234 for (const auto& subSession : GetSubSession()) {
1235 if (subSession == nullptr) {
1236 TLOGW(WmsLogTag::WMS_LIFE, "subSession is nullptr");
1237 continue;
1238 }
1239 auto property = subSession->GetSessionProperty();
1240 if (property && property->GetPrivacyMode()) {
1241 return true;
1242 }
1243 if (subSession->HasSubSessionInPrivacyMode()) {
1244 return true;
1245 }
1246 }
1247 return false;
1248 }
1249
RegisterDefaultAnimationFlagChangeCallback(NotifyWindowAnimationFlagChangeFunc && callback)1250 void SceneSession::RegisterDefaultAnimationFlagChangeCallback(NotifyWindowAnimationFlagChangeFunc&& callback)
1251 {
1252 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1253 auto session = weakThis.promote();
1254 if (!session) {
1255 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1256 return;
1257 }
1258 session->onWindowAnimationFlagChange_ = std::move(callback);
1259 session->onWindowAnimationFlagChange_(session->IsNeedDefaultAnimation());
1260 }, __func__);
1261 }
1262
RegisterDefaultDensityEnabledCallback(NotifyDefaultDensityEnabledFunc && callback)1263 void SceneSession::RegisterDefaultDensityEnabledCallback(NotifyDefaultDensityEnabledFunc&& callback)
1264 {
1265 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1266 auto session = weakThis.promote();
1267 if (!session) {
1268 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1269 return;
1270 }
1271 session->onDefaultDensityEnabledFunc_ = std::move(callback);
1272 }, __func__);
1273 }
1274
RegisterWindowShadowEnableChangeCallback(NotifyWindowShadowEnableChangeFunc && callback)1275 void SceneSession::RegisterWindowShadowEnableChangeCallback(NotifyWindowShadowEnableChangeFunc&& callback)
1276 {
1277 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1278 auto session = weakThis.promote();
1279 if (!session || !callback) {
1280 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s session or callback is null", where);
1281 return;
1282 }
1283 session->onWindowShadowEnableChangeFunc_ = std::move(callback);
1284 session->onWindowShadowEnableChangeFunc_(session->GetSessionProperty()->GetWindowShadowEnabled());
1285 }, __func__);
1286 }
1287
RegisterNeedAvoidCallback(NotifyNeedAvoidFunc && callback)1288 void SceneSession::RegisterNeedAvoidCallback(NotifyNeedAvoidFunc&& callback)
1289 {
1290 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1291 auto session = weakThis.promote();
1292 if (!session) {
1293 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
1294 return;
1295 }
1296 session->onNeedAvoid_ = std::move(callback);
1297 }, __func__);
1298 }
1299
RegisterSystemBarPropertyChangeCallback(NotifySystemBarPropertyChangeFunc && callback)1300 void SceneSession::RegisterSystemBarPropertyChangeCallback(NotifySystemBarPropertyChangeFunc&& callback)
1301 {
1302 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1303 auto session = weakThis.promote();
1304 if (!session) {
1305 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1306 return;
1307 }
1308 session->onSystemBarPropertyChange_ = std::move(callback);
1309 }, __func__);
1310 }
1311
RegisterTouchOutsideCallback(NotifyTouchOutsideFunc && callback)1312 void SceneSession::RegisterTouchOutsideCallback(NotifyTouchOutsideFunc&& callback)
1313 {
1314 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1315 auto session = weakThis.promote();
1316 if (!session) {
1317 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1318 return;
1319 }
1320 session->onTouchOutside_ = std::move(callback);
1321 }, __func__);
1322 }
1323
RegisterFollowScreenChangeCallback(NotifyFollowScreenChangeFunc && callback)1324 void SceneSession::RegisterFollowScreenChangeCallback(NotifyFollowScreenChangeFunc&& callback)
1325 {
1326 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1327 auto session = weakThis.promote();
1328 if (!session || !session->specificCallback_ || !callback) {
1329 TLOGNE(WmsLogTag::DEFAULT, "%{public}s session or specific callback or callback is null", where);
1330 return;
1331 }
1332 session->specificCallback_->onUpdateFollowScreenChange_ = std::move(callback);
1333 session->specificCallback_->onUpdateFollowScreenChange_(session->GetFollowScreenChange());
1334 }, __func__);
1335 }
1336
SetGlobalMaximizeMode(MaximizeMode mode)1337 WSError SceneSession::SetGlobalMaximizeMode(MaximizeMode mode)
1338 {
1339 return PostSyncTask([weakThis = wptr(this), mode, where = __func__] {
1340 auto session = weakThis.promote();
1341 if (!session) {
1342 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1343 return WSError::WS_ERROR_DESTROYED_OBJECT;
1344 }
1345 TLOGND(WmsLogTag::WMS_PC, "%{public}s mode: %{public}u", where, static_cast<uint32_t>(mode));
1346 session->maximizeMode_ = mode;
1347 ScenePersistentStorage::Insert("maximize_state", static_cast<int32_t>(session->maximizeMode_),
1348 ScenePersistentStorageType::MAXIMIZE_STATE);
1349 return WSError::WS_OK;
1350 }, __func__);
1351 }
1352
GetGlobalMaximizeMode(MaximizeMode & mode)1353 WSError SceneSession::GetGlobalMaximizeMode(MaximizeMode& mode)
1354 {
1355 return PostSyncTask([weakThis = wptr(this), &mode, where = __func__] {
1356 auto session = weakThis.promote();
1357 if (!session) {
1358 TLOGNE(WmsLogTag::WMS_PC, "%{public}s session is null", where);
1359 return WSError::WS_ERROR_DESTROYED_OBJECT;
1360 }
1361 mode = maximizeMode_;
1362 TLOGND(WmsLogTag::WMS_PC, "%{public}s mode: %{public}u", where, static_cast<uint32_t>(mode));
1363 return WSError::WS_OK;
1364 }, __func__);
1365 }
1366
CheckAspectRatioValid(const sptr<SceneSession> & session,float ratio,float vpr)1367 static WSError CheckAspectRatioValid(const sptr<SceneSession>& session, float ratio, float vpr)
1368 {
1369 if (MathHelper::NearZero(ratio)) {
1370 return WSError::WS_OK;
1371 }
1372 if (!session) {
1373 return WSError::WS_ERROR_INVALID_PARAM;
1374 }
1375 auto sessionProperty = session->GetSessionProperty();
1376 if (!sessionProperty) {
1377 return WSError::WS_ERROR_INVALID_PARAM;
1378 }
1379 auto limits = sessionProperty->GetWindowLimits();
1380 if (session->IsDecorEnable()) {
1381 if (limits.minWidth_ && limits.maxHeight_ &&
1382 MathHelper::LessNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.minWidth_, vpr) /
1383 SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr))) {
1384 WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
1385 return WSError::WS_ERROR_INVALID_PARAM;
1386 } else if (limits.minHeight_ && limits.maxWidth_ &&
1387 MathHelper::GreatNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr) /
1388 SessionUtils::ToLayoutHeight(limits.minHeight_, vpr))) {
1389 WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
1390 return WSError::WS_ERROR_INVALID_PARAM;
1391 }
1392 } else {
1393 if (limits.minWidth_ && limits.maxHeight_ && MathHelper::LessNotEqual(ratio,
1394 static_cast<float>(limits.minWidth_) / limits.maxHeight_)) {
1395 WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
1396 return WSError::WS_ERROR_INVALID_PARAM;
1397 } else if (limits.minHeight_ && limits.maxWidth_ && MathHelper::GreatNotEqual(ratio,
1398 static_cast<float>(limits.maxWidth_) / limits.minHeight_)) {
1399 WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
1400 return WSError::WS_ERROR_INVALID_PARAM;
1401 }
1402 }
1403 return WSError::WS_OK;
1404 }
1405
1406 /** @note @window.layout */
SetAspectRatio(float ratio)1407 WSError SceneSession::SetAspectRatio(float ratio)
1408 {
1409 return PostSyncTask([weakThis = wptr(this), ratio, where = __func__] {
1410 auto session = weakThis.promote();
1411 if (!session) {
1412 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
1413 return WSError::WS_ERROR_DESTROYED_OBJECT;
1414 }
1415 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
1416 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
1417 if (display) {
1418 vpr = display->GetVirtualPixelRatio();
1419 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s vpr=%{public}f", where, vpr);
1420 }
1421 WSError ret = CheckAspectRatioValid(session, ratio, vpr);
1422 if (ret != WSError::WS_OK) {
1423 return ret;
1424 }
1425 session->Session::SetAspectRatio(ratio);
1426 if (session->moveDragController_) {
1427 session->moveDragController_->SetAspectRatio(ratio);
1428 }
1429 session->SaveAspectRatio(session->GetAspectRatio());
1430 WSRect adjustedRect = session->GetSessionRect();
1431 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s Before adjusting, the id:%{public}d, the current rect:%{public}s, "
1432 "ratio:%{public}f", where, session->GetPersistentId(), adjustedRect.ToString().c_str(), ratio);
1433 if (session->layoutController_->AdjustRectByAspectRatio(adjustedRect, session->IsDecorEnable())) {
1434 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s After adjusting, the id:%{public}d, the adjusted rect:%{public}s",
1435 where, session->GetPersistentId(), adjustedRect.ToString().c_str());
1436 session->NotifySessionRectChange(adjustedRect, SizeChangeReason::RESIZE);
1437 }
1438 return WSError::WS_OK;
1439 }, __func__);
1440 }
1441
1442 /** @note @window.layout */
UpdateRect(const WSRect & rect,SizeChangeReason reason,const std::string & updateReason,const std::shared_ptr<RSTransaction> & rsTransaction)1443 WSError SceneSession::UpdateRect(const WSRect& rect, SizeChangeReason reason,
1444 const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction)
1445 {
1446 PostTask([weakThis = wptr(this), rect, reason, rsTransaction, updateReason, where = __func__] {
1447 auto session = weakThis.promote();
1448 if (!session) {
1449 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
1450 return;
1451 }
1452 if (session->GetSizeChangeReason() == SizeChangeReason::DRAG) {
1453 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: skip drag reason update id:%{public}d rect:%{public}s",
1454 where, session->GetPersistentId(), rect.ToString().c_str());
1455 return;
1456 }
1457 if (session->GetSessionRect() == rect && session->GetSizeChangeReason() != SizeChangeReason::DRAG_END &&
1458 (session->GetWindowType() != WindowType::WINDOW_TYPE_KEYBOARD_PANEL &&
1459 session->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT)) {
1460 if (!session->sessionStage_) {
1461 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: skip same rect update id:%{public}d rect:%{public}s",
1462 where, session->GetPersistentId(), rect.ToString().c_str());
1463 return;
1464 } else if (session->GetClientRect() == rect) {
1465 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: skip same rect update id:%{public}d rect:%{public}s "
1466 "clientRect:%{public}s", where, session->GetPersistentId(), rect.ToString().c_str(),
1467 session->GetClientRect().ToString().c_str());
1468 return;
1469 }
1470 }
1471 if (rect.IsInvalid()) {
1472 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d rect:%{public}s is invalid",
1473 where, session->GetPersistentId(), rect.ToString().c_str());
1474 return;
1475 }
1476 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::UpdateRect %d [%d, %d, %u, %u]",
1477 session->GetPersistentId(), rect.posX_, rect.posY_, rect.width_, rect.height_);
1478 // position change no need to notify client, since frame layout finish will notify
1479 if (NearEqual(rect.width_, session->GetSessionRect().width_) &&
1480 NearEqual(rect.height_, session->GetSessionRect().height_) &&
1481 (session->GetSizeChangeReason() != SizeChangeReason::DRAG_MOVE ||
1482 !session->rectChangeListenerRegistered_)) {
1483 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: position change no need notify client id:%{public}d, "
1484 "rect:%{public}s, preRect:%{public}s", where,
1485 session->GetPersistentId(), rect.ToString().c_str(), session->GetSessionRect().ToString().c_str());
1486 session->SetWinRectWhenUpdateRect(rect);
1487 } else {
1488 session->SetWinRectWhenUpdateRect(rect);
1489 session->NotifyClientToUpdateRect(updateReason, rsTransaction);
1490 }
1491 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
1492 session->AddPropertyDirtyFlags(static_cast<uint32_t>(SessionPropertyFlag::WINDOW_RECT));
1493 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, reason:%{public}d %{public}s, "
1494 "rect:%{public}s, clientRect:%{public}s",
1495 where, session->GetPersistentId(), session->GetSizeChangeReason(), updateReason.c_str(),
1496 rect.ToString().c_str(), session->GetClientRect().ToString().c_str());
1497 }, __func__ + GetRectInfo(rect));
1498 return WSError::WS_OK;
1499 }
1500
1501 /** @note @window.layout */
SetWinRectWhenUpdateRect(const WSRect & rect)1502 void SceneSession::SetWinRectWhenUpdateRect(const WSRect& rect)
1503 {
1504 WSRect newRect;
1505 if (GetIsMidScene() && rect.posX_ == 0 && rect.posY_ == 0) {
1506 WSRect curRect = GetSessionRect();
1507 newRect = { curRect.posX_, curRect.posY_, rect.width_, rect.height_ };
1508 } else {
1509 newRect = rect;
1510 }
1511 layoutController_->SetSessionRect(newRect);
1512 }
1513
NotifyClientToUpdateRectTask(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)1514 WSError SceneSession::NotifyClientToUpdateRectTask(const std::string& updateReason,
1515 std::shared_ptr<RSTransaction> rsTransaction)
1516 {
1517 WSRect winRect = GetSessionRect();
1518 SizeChangeReason reason = GetSizeChangeReason();
1519 TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, reason:%{public}d, rect:%{public}s",
1520 GetPersistentId(), reason, winRect.ToString().c_str());
1521 bool isMoveOrDrag = moveDragController_ &&
1522 (moveDragController_->GetStartDragFlag() || moveDragController_->GetStartMoveFlag());
1523 if (isMoveOrDrag && reason == SizeChangeReason::UNDEFINED) {
1524 TLOGD(WmsLogTag::WMS_LAYOUT, "skip redundant rect update!");
1525 return WSError::WS_ERROR_REPEAT_OPERATION;
1526 }
1527 if (reason != SizeChangeReason::DRAG_MOVE) {
1528 UpdateCrossAxisOfLayout(winRect);
1529 }
1530 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
1531 "SceneSession::NotifyClientToUpdateRect%d [%d, %d, %u, %u] reason:%u",
1532 GetPersistentId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_, reason);
1533
1534 std::map<AvoidAreaType, AvoidArea> avoidAreas;
1535 if (GetForegroundInteractiveStatus()) {
1536 GetAllAvoidAreas(avoidAreas);
1537 } else {
1538 TLOGD(WmsLogTag::WMS_IMMS, "win [%{public}d] avoid area update rejected by recent", GetPersistentId());
1539 }
1540 if (winRect.IsInvalid()) {
1541 TLOGE(WmsLogTag::WMS_LAYOUT, "id:%{public}d rect:%{public}s is invalid",
1542 GetPersistentId(), winRect.ToString().c_str());
1543 return WSError::WS_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
1544 }
1545 WSError ret = WSError::WS_OK;
1546 // once reason is undefined, not use rsTransaction
1547 // when rotation, sync cnt++ in marshalling. Although reason is undefined caused by resize
1548 if (reason == SizeChangeReason::UNDEFINED || reason == SizeChangeReason::RESIZE || IsMoveToOrDragMove(reason)) {
1549 ret = Session::UpdateRectWithLayoutInfo(GetSessionRect(), reason, updateReason, nullptr, avoidAreas);
1550 } else {
1551 ret = Session::UpdateRectWithLayoutInfo(GetSessionRect(), reason, updateReason, rsTransaction, avoidAreas);
1552 #ifdef DEVICE_STATUS_ENABLE
1553 // When the drag is in progress, the drag window needs to be notified to rotate.
1554 if (rsTransaction != nullptr) {
1555 RotateDragWindow(rsTransaction);
1556 }
1557 #endif // DEVICE_STATUS_ENABLE
1558 }
1559
1560 return ret;
1561 }
1562
NotifyClientToUpdateRect(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)1563 WSError SceneSession::NotifyClientToUpdateRect(const std::string& updateReason,
1564 std::shared_ptr<RSTransaction> rsTransaction)
1565 {
1566 PostTask([weakThis = wptr(this), rsTransaction, updateReason, where = __func__] {
1567 auto session = weakThis.promote();
1568 if (!session) {
1569 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
1570 return WSError::WS_ERROR_DESTROYED_OBJECT;
1571 }
1572 WSError ret = session->NotifyClientToUpdateRectTask(updateReason, rsTransaction);
1573 if (ret != WSError::WS_OK) {
1574 return ret;
1575 }
1576 return ret;
1577 }, __func__);
1578 return WSError::WS_OK;
1579 }
1580
GetScreenWidthAndHeightFromClient(const sptr<WindowSessionProperty> & sessionProperty,uint32_t & screenWidth,uint32_t & screenHeight)1581 bool SceneSession::GetScreenWidthAndHeightFromClient(const sptr<WindowSessionProperty>& sessionProperty,
1582 uint32_t& screenWidth, uint32_t& screenHeight)
1583 {
1584 auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
1585 if (defaultDisplayInfo != nullptr) {
1586 screenWidth = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
1587 screenHeight = static_cast<uint32_t>(defaultDisplayInfo->GetHeight());
1588 } else {
1589 TLOGE(WmsLogTag::WMS_KEYBOARD, "defaultDisplayInfo is null, get screenWidthAndHeight failed");
1590 return false;
1591 }
1592 if (IsSystemKeyboard() && DisplayManager::GetInstance().GetFoldStatus() == FoldStatus::HALF_FOLD) {
1593 screenHeight = static_cast<uint32_t>(defaultDisplayInfo->GetPhysicalHeight());
1594 TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d, display is half-fold", GetPersistentId());
1595 }
1596 TLOGI(WmsLogTag::WMS_KEYBOARD, "screenSize: [%{public}d, %{public}d]", screenWidth, screenHeight);
1597 return true;
1598 }
1599
SetSessionRectChangeCallback(const NotifySessionRectChangeFunc & func)1600 void SceneSession::SetSessionRectChangeCallback(const NotifySessionRectChangeFunc& func)
1601 {
1602 PostTask([weakThis = wptr(this), func, where = __func__] {
1603 auto session = weakThis.promote();
1604 if (!session) {
1605 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1606 return WSError::WS_ERROR_DESTROYED_OBJECT;
1607 }
1608 session->sessionRectChangeFunc_ = func;
1609 if (session->sessionRectChangeFunc_ && session->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1610 auto reason = SizeChangeReason::UNDEFINED;
1611 auto rect = session->GetSessionRequestRect();
1612 if (rect.width_ == 0 && rect.height_ == 0) {
1613 reason = SizeChangeReason::MOVE;
1614 }
1615 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s, winName:%{public}s, reason:%{public}d, rect:%{public}s",
1616 where, session->GetWindowName().c_str(), reason, rect.ToString().c_str());
1617 if (session->GetClientDisplayId() == VIRTUAL_DISPLAY_ID && rect.posY_ == 0) {
1618 rect.posY_ += PcFoldScreenManager::GetInstance().GetVirtualDisplayPosY();
1619 }
1620 auto rectAnimationConfig = session->GetRequestRectAnimationConfig();
1621 session->sessionRectChangeFunc_(rect, reason, DISPLAY_ID_INVALID, rectAnimationConfig);
1622 }
1623 return WSError::WS_OK;
1624 }, __func__);
1625 }
1626
SetSessionDisplayIdChangeCallback(NotifySessionDisplayIdChangeFunc && func)1627 void SceneSession::SetSessionDisplayIdChangeCallback(NotifySessionDisplayIdChangeFunc&& func)
1628 {
1629 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1630 auto session = weakThis.promote();
1631 if (!session || !func) {
1632 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session or display id is null", where);
1633 return;
1634 }
1635 session->sessionDisplayIdChangeFunc_ = std::move(func);
1636 }, __func__);
1637 }
1638
SetMainWindowTopmostChangeCallback(NotifyMainWindowTopmostChangeFunc && func)1639 void SceneSession::SetMainWindowTopmostChangeCallback(NotifyMainWindowTopmostChangeFunc&& func)
1640 {
1641 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1642 auto session = weakThis.promote();
1643 if (!session || !func) {
1644 TLOGNE(WmsLogTag::WMS_HIERARCHY, "%{public}s session or func is null", where);
1645 return;
1646 }
1647 session->mainWindowTopmostChangeFunc_ = std::move(func);
1648 }, __func__);
1649 }
1650
SetTitleAndDockHoverShowChangeCallback(NotifyTitleAndDockHoverShowChangeFunc && func)1651 void SceneSession::SetTitleAndDockHoverShowChangeCallback(NotifyTitleAndDockHoverShowChangeFunc&& func)
1652 {
1653 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1654 auto session = weakThis.promote();
1655 if (!session || !func) {
1656 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session or TitleAndDockHoverShowChangeFunc is null", where);
1657 return;
1658 }
1659 session->onTitleAndDockHoverShowChangeFunc_ = std::move(func);
1660 TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s id: %{public}d",
1661 where, session->GetPersistentId());
1662 }, __func__);
1663 }
1664
SetRestoreMainWindowCallback(NotifyRestoreMainWindowFunc && func)1665 void SceneSession::SetRestoreMainWindowCallback(NotifyRestoreMainWindowFunc&& func)
1666 {
1667 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1668 auto session = weakThis.promote();
1669 if (!session || !func) {
1670 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session or RestoreMainWindowFunc is null", where);
1671 return;
1672 }
1673 session->onRestoreMainWindowFunc_ = std::move(func);
1674 TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s id: %{public}d",
1675 where, session->GetPersistentId());
1676 }, __func__);
1677 }
1678
SetAdjustKeyboardLayoutCallback(const NotifyKeyboardLayoutAdjustFunc & func)1679 void SceneSession::SetAdjustKeyboardLayoutCallback(const NotifyKeyboardLayoutAdjustFunc& func)
1680 {
1681 PostTask([weakThis = wptr(this), func, where = __func__] {
1682 auto session = weakThis.promote();
1683 if (!session || !func) {
1684 TLOGNE(WmsLogTag::WMS_KEYBOARD, "%{public}s session or keyboardLayoutFunc is null", where);
1685 return WSError::WS_ERROR_DESTROYED_OBJECT;
1686 }
1687 session->adjustKeyboardLayoutFunc_ = func;
1688 auto property = session->GetSessionProperty();
1689 if (property == nullptr) {
1690 TLOGNE(WmsLogTag::WMS_KEYBOARD, "%{public}s property is null", where);
1691 return WSError::WS_ERROR_DESTROYED_OBJECT;
1692 }
1693 KeyboardLayoutParams params = property->GetKeyboardLayoutParams();
1694 session->adjustKeyboardLayoutFunc_(params);
1695 TLOGNI(WmsLogTag::WMS_KEYBOARD,
1696 "%{public}s Notify adjust keyboard layout when register, keyboardId: %{public}d, "
1697 "gravity: %{public}u, landscapeAvoidHeight: %{public}d, PortraitAvoidHeight: %{public}d, "
1698 "LandscapeKeyboardRect: %{public}s, PortraitKeyboardRect: %{public}s, "
1699 "LandscapePanelRect: %{public}s, PortraitPanelRect: %{public}s", where, session->GetPersistentId(),
1700 static_cast<uint32_t>(params.gravity_), params.landscapeAvoidHeight_, params.portraitAvoidHeight_,
1701 params.LandscapeKeyboardRect_.ToString().c_str(), params.PortraitKeyboardRect_.ToString().c_str(),
1702 params.LandscapePanelRect_.ToString().c_str(), params.PortraitPanelRect_.ToString().c_str());
1703 return WSError::WS_OK;
1704 }, __func__);
1705 }
1706
SetSessionPiPControlStatusChangeCallback(const NotifySessionPiPControlStatusChangeFunc & func)1707 void SceneSession::SetSessionPiPControlStatusChangeCallback(const NotifySessionPiPControlStatusChangeFunc& func)
1708 {
1709 PostTask([weakThis = wptr(this), func, where = __func__] {
1710 auto session = weakThis.promote();
1711 if (!session) {
1712 TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
1713 return WSError::WS_ERROR_DESTROYED_OBJECT;
1714 }
1715 session->sessionPiPControlStatusChangeFunc_ = func;
1716 return WSError::WS_OK;
1717 }, __func__);
1718 }
1719
SetUpdatePiPTemplateInfoCallback(NotifyUpdatePiPTemplateInfoFunc && func)1720 void SceneSession::SetUpdatePiPTemplateInfoCallback(NotifyUpdatePiPTemplateInfoFunc&& func)
1721 {
1722 auto task = [weakThis = wptr(this), func = std::move(func), where = __func__] {
1723 auto session = weakThis.promote();
1724 if (!session) {
1725 TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
1726 return;
1727 }
1728 session->updatePiPTemplateInfoCallbackFunc_ = std::move(func);
1729 };
1730 PostTask(task, __func__);
1731 }
1732
UpdatePiPTemplateInfo(PiPTemplateInfo & pipTemplateInfo)1733 WSError SceneSession::UpdatePiPTemplateInfo(PiPTemplateInfo& pipTemplateInfo)
1734 {
1735 TLOGI(WmsLogTag::WMS_PIP, "UpdatePiPTemplateInfo, pipTemplateType: %{public}u, priority: %{public}d, "
1736 "defaultWindowSizeType: %{public}d", pipTemplateInfo.pipTemplateType, pipTemplateInfo.priority,
1737 pipTemplateInfo.defaultWindowSizeType);
1738 auto task = [weakThis = wptr(this), pipTemplateInfo = std::move(pipTemplateInfo), where = __func__]() mutable {
1739 auto session = weakThis.promote();
1740 if (!session || session->isTerminating_) {
1741 TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null or is terminating", where);
1742 return;
1743 }
1744 if (session->updatePiPTemplateInfoCallbackFunc_) {
1745 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::UpdatePiPTemplateInfo");
1746 session->updatePiPTemplateInfoCallbackFunc_(pipTemplateInfo);
1747 }
1748 };
1749 PostTask(task, __func__);
1750 return WSError::WS_OK;
1751 }
1752
SetAutoStartPiPStatusChangeCallback(const NotifyAutoStartPiPStatusChangeFunc & func)1753 void SceneSession::SetAutoStartPiPStatusChangeCallback(const NotifyAutoStartPiPStatusChangeFunc& func)
1754 {
1755 PostTask([weakThis = wptr(this), func, where = __func__] {
1756 auto session = weakThis.promote();
1757 if (!session) {
1758 TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
1759 return;
1760 }
1761 session->autoStartPiPStatusChangeFunc_ = func;
1762 }, __func__);
1763 }
1764
1765 /** @note @window.layout */
UpdateSessionRectInner(const WSRect & rect,SizeChangeReason reason,const MoveConfiguration & moveConfiguration,const RectAnimationConfig & rectAnimationConfig)1766 void SceneSession::UpdateSessionRectInner(const WSRect& rect, SizeChangeReason reason,
1767 const MoveConfiguration& moveConfiguration, const RectAnimationConfig& rectAnimationConfig)
1768 {
1769 auto newWinRect = GetSessionRect();
1770 auto newRequestRect = GetSessionRequestRect();
1771 SizeChangeReason newReason = reason;
1772 if (reason == SizeChangeReason::MOVE || reason == SizeChangeReason::MOVE_WITH_ANIMATION) {
1773 newWinRect.posX_ = rect.posX_;
1774 newWinRect.posY_ = rect.posY_;
1775 newRequestRect.posX_ = rect.posX_;
1776 newRequestRect.posY_ = rect.posY_;
1777 if (!Session::IsScbCoreEnabled() && !WindowHelper::IsMainWindow(GetWindowType())) {
1778 SetSessionRect(newWinRect);
1779 }
1780 SetSessionRequestRect(newRequestRect);
1781 SetRequestRectAnimationConfig(moveConfiguration.rectAnimationConfig);
1782 NotifySessionRectChange(newRequestRect, reason, moveConfiguration.displayId,
1783 moveConfiguration.rectAnimationConfig);
1784 } else if (reason == SizeChangeReason::RESIZE || reason == SizeChangeReason::RESIZE_WITH_ANIMATION) {
1785 if (rect.width_ > 0 && rect.height_ > 0) {
1786 newWinRect.width_ = rect.width_;
1787 newWinRect.height_ = rect.height_;
1788 newRequestRect.width_ = rect.width_;
1789 newRequestRect.height_ = rect.height_;
1790 }
1791 if (!Session::IsScbCoreEnabled() && GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1792 SetSessionRect(newWinRect);
1793 }
1794 SetRequestRectAnimationConfig(rectAnimationConfig);
1795 DisplayId displayId = GetSessionProperty() != nullptr ? GetSessionProperty()->GetDisplayId() :
1796 DISPLAY_ID_INVALID;
1797 TLOGI(WmsLogTag::WMS_LAYOUT, "Get displayId: %{public}" PRIu64, displayId);
1798 auto notifyRect = newRequestRect;
1799 if (PcFoldScreenManager::GetInstance().IsHalfFolded(GetScreenId())) {
1800 notifyRect = rect;
1801 }
1802 SetSessionRequestRect(notifyRect);
1803 NotifySessionRectChange(notifyRect, newReason, displayId, rectAnimationConfig);
1804 } else {
1805 if (!Session::IsScbCoreEnabled()) {
1806 SetSessionRect(rect);
1807 }
1808 NotifySessionRectChange(rect, reason);
1809 }
1810 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d reason:%{public}d newReason:%{public}d moveConfiguration:%{public}s "
1811 "rect:%{public}s newRequestRect:%{public}s newWinRect:%{public}s", GetPersistentId(), reason, newReason,
1812 moveConfiguration.ToString().c_str(), rect.ToString().c_str(), newRequestRect.ToString().c_str(),
1813 newWinRect.ToString().c_str());
1814 }
1815
UpdateSessionRectPosYFromClient(SizeChangeReason reason,DisplayId & configDisplayId,WSRect & rect)1816 void SceneSession::UpdateSessionRectPosYFromClient(SizeChangeReason reason, DisplayId& configDisplayId, WSRect& rect)
1817 {
1818 if (!PcFoldScreenManager::GetInstance().IsHalfFolded(GetScreenId()) ||
1819 PcFoldScreenManager::GetInstance().HasSystemKeyboard()) {
1820 TLOGD(
1821 WmsLogTag::WMS_LAYOUT, "winId: %{public}d, displayId: %{public}" PRIu64, GetPersistentId(), GetScreenId());
1822 return;
1823 }
1824 if (reason != SizeChangeReason::RESIZE) {
1825 configDisplayId_ = configDisplayId;
1826 }
1827 if (configDisplayId_ != DISPLAY_ID_INVALID &&
1828 !PcFoldScreenManager::GetInstance().IsPcFoldScreen(configDisplayId_)) {
1829 TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, configDisplayId: %{public}" PRIu64,
1830 GetPersistentId(), configDisplayId_);
1831 return;
1832 }
1833 auto clientDisplayId = clientDisplayId_;
1834 TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, input: %{public}s, screenId: %{public}" PRIu64
1835 ", clientDisplayId: %{public}" PRIu64 ", configDisplayId: %{public}" PRIu64,
1836 GetPersistentId(), rect.ToString().c_str(), GetScreenId(), clientDisplayId, configDisplayId_);
1837 if (configDisplayId_ != VIRTUAL_DISPLAY_ID && clientDisplayId != VIRTUAL_DISPLAY_ID) {
1838 return;
1839 }
1840 if (rect.posY_ >= 0) {
1841 const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
1842 PcFoldScreenManager::GetInstance().GetDisplayRects();
1843 TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, defaultDisplayRect: %{public}s, virtualDisplayRect: %{public}s"
1844 ", foldCreaseRect: %{public}s", GetPersistentId(), defaultDisplayRect.ToString().c_str(),
1845 virtualDisplayRect.ToString().c_str(), foldCreaseRect.ToString().c_str());
1846 auto lowerScreenPosY = defaultDisplayRect.height_ + foldCreaseRect.height_;
1847 if (rect.posY_ < lowerScreenPosY) {
1848 rect.posY_ += lowerScreenPosY;
1849 }
1850 } else {
1851 rect.posY_ += GetSessionRect().posY_;
1852 }
1853 configDisplayId = DEFAULT_DISPLAY_ID;
1854 TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, output: %{public}s", GetPersistentId(), rect.ToString().c_str());
1855 }
1856
1857 /** @note @window.layout */
UpdateSessionRect(const WSRect & rect,SizeChangeReason reason,bool isGlobal,bool isFromMoveToGlobal,const MoveConfiguration & moveConfiguration,const RectAnimationConfig & rectAnimationConfig)1858 WSError SceneSession::UpdateSessionRect(
1859 const WSRect& rect, SizeChangeReason reason, bool isGlobal, bool isFromMoveToGlobal,
1860 const MoveConfiguration& moveConfiguration, const RectAnimationConfig& rectAnimationConfig)
1861 {
1862 bool isMoveOrResize = reason == SizeChangeReason::MOVE || reason == SizeChangeReason::RESIZE ||
1863 reason == SizeChangeReason::MOVE_WITH_ANIMATION || reason == SizeChangeReason::RESIZE_WITH_ANIMATION;
1864 if (isMoveOrResize && GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1865 return WSError::WS_DO_NOTHING;
1866 }
1867 WSRect newRect = rect;
1868 MoveConfiguration newMoveConfiguration = moveConfiguration;
1869 UpdateSessionRectPosYFromClient(reason, newMoveConfiguration.displayId, newRect);
1870 bool isAvailableWindow = (systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) && !IsFreeMultiWindowMode();
1871 if (isGlobal && WindowHelper::IsSubWindow(Session::GetWindowType()) && isAvailableWindow) {
1872 if (auto mainSession = GetMainSession()) {
1873 auto mainRect = mainSession->GetSessionRect();
1874 if (!CheckIfRectElementIsTooLarge(mainRect)) {
1875 newRect.posX_ -= mainRect.posX_;
1876 newRect.posY_ -= mainRect.posY_;
1877 }
1878 }
1879 }
1880 if (isFromMoveToGlobal && WindowHelper::IsSubWindow(Session::GetWindowType()) && isAvailableWindow) {
1881 auto mainSession = GetMainSession();
1882 if (mainSession && mainSession->GetFloatingScale() != 0) {
1883 Rect mainGlobalRect;
1884 WMError errorCode = mainSession->GetGlobalScaledRect(mainGlobalRect);
1885 newRect.posX_ = (newRect.posX_ - mainGlobalRect.posX_) / mainSession->GetFloatingScale();
1886 newRect.posY_ = (newRect.posY_ - mainGlobalRect.posY_) / mainSession->GetFloatingScale();
1887 }
1888 }
1889 PostTask([weakThis = wptr(this), newRect, reason, newMoveConfiguration, rectAnimationConfig, where = __func__] {
1890 auto session = weakThis.promote();
1891 if (!session) {
1892 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
1893 return WSError::WS_ERROR_DESTROYED_OBJECT;
1894 }
1895 session->SetRequestMoveConfiguration(newMoveConfiguration);
1896 session->UpdateSessionRectInner(newRect, reason, newMoveConfiguration, rectAnimationConfig);
1897 return WSError::WS_OK;
1898 }, __func__ + GetRectInfo(rect));
1899 return WSError::WS_OK;
1900 }
1901
UpdateGlobalDisplayRectFromClient(const WSRect & rect,SizeChangeReason reason)1902 WSError SceneSession::UpdateGlobalDisplayRectFromClient(const WSRect& rect, SizeChangeReason reason)
1903 {
1904 TLOGD(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, rect: %{public}s, reason: %{public}u",
1905 GetPersistentId(), rect.ToString().c_str(), reason);
1906 PostTask([weakThis = wptr(this), rect, reason, where = __func__] {
1907 auto session = weakThis.promote();
1908 if (!session) {
1909 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is nullptr", where);
1910 return;
1911 }
1912 if (rect == session->GetGlobalDisplayRect()) {
1913 TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s: windowId: %{public}d skip same rect",
1914 where, session->GetPersistentId());
1915 return;
1916 }
1917 // Convert global coordinates to screen-relative coordinates to be
1918 // compatible with the original logic of UpdateSessionRectInner.
1919 const auto& [screenId, screenRelativeRect] =
1920 SessionCoordinateHelper::GlobalToScreenRelativeRect(session->GetScreenId(), rect);
1921 RectAnimationConfig animConfig;
1922 MoveConfiguration moveConfig = { screenId, animConfig };
1923 session->SetRequestMoveConfiguration(moveConfig);
1924 session->UpdateSessionRectInner(screenRelativeRect, reason, moveConfig, animConfig);
1925 }, __func__ + GetRectInfo(rect));
1926 return WSError::WS_OK;
1927 }
1928
HandleCrossMoveTo(WSRect & globalRect)1929 void SceneSession::HandleCrossMoveTo(WSRect& globalRect)
1930 {
1931 HandleCrossMoveToSurfaceNode(globalRect);
1932 SetSurfaceBounds(globalRect, true, true);
1933 }
1934
UpdateCrossAxisOfLayout(const WSRect & rect)1935 void SceneSession::UpdateCrossAxisOfLayout(const WSRect& rect)
1936 {
1937 const int FOLD_CREASE_TYPE = 2;
1938 isCrossAxisOfLayout_ = rect.IsOverlap(std::get<FOLD_CREASE_TYPE>(
1939 PcFoldScreenManager::GetInstance().GetDisplayRects()));
1940 UpdateCrossAxis();
1941 }
1942
UpdateCrossAxis()1943 void SceneSession::UpdateCrossAxis()
1944 {
1945 CrossAxisState crossAxisState = CrossAxisState::STATE_INVALID;
1946 if (PcFoldScreenManager::GetInstance().GetDisplayId() == SCREEN_ID_INVALID ||
1947 PcFoldScreenManager::GetInstance().GetDisplayId() != GetSessionProperty()->GetDisplayId()) {
1948 return;
1949 }
1950 SuperFoldStatus foldStatus = PcFoldScreenManager::GetInstance().GetScreenFoldStatus();
1951 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d, status %{public}d, cross %{public}d", GetPersistentId(),
1952 foldStatus, isCrossAxisOfLayout_.load());
1953 if (foldStatus != SuperFoldStatus::UNKNOWN) {
1954 if (foldStatus == SuperFoldStatus::HALF_FOLDED && isCrossAxisOfLayout_) {
1955 crossAxisState = CrossAxisState::STATE_CROSS;
1956 } else {
1957 crossAxisState = CrossAxisState::STATE_NO_CROSS;
1958 }
1959 }
1960 if (crossAxisState_ != static_cast<uint32_t>(crossAxisState) && sessionStage_ != nullptr) {
1961 crossAxisState_ = static_cast<uint32_t>(crossAxisState);
1962 sessionStage_->NotifyWindowCrossAxisChange(crossAxisState);
1963 } else if (sessionStage_ == nullptr) {
1964 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "sessionStage_ is nullptr, id: %{public}d", GetPersistentId());
1965 }
1966 }
1967
GetCrossAxisState(CrossAxisState & state)1968 WSError SceneSession::GetCrossAxisState(CrossAxisState& state)
1969 {
1970 state = static_cast<CrossAxisState>(crossAxisState_.load());
1971 return WSError::WS_OK;
1972 }
1973
1974 /** @note @window.layout */
UpdateClientRect(const WSRect & rect)1975 WSError SceneSession::UpdateClientRect(const WSRect& rect)
1976 {
1977 PostTask([weakThis = wptr(this), rect, funcName = __func__] {
1978 auto session = weakThis.promote();
1979 if (!session) {
1980 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", funcName);
1981 return;
1982 }
1983 if (rect.IsInvalid()) {
1984 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d rect:%{public}s is invalid",
1985 funcName, session->GetPersistentId(), rect.ToString().c_str());
1986 return;
1987 }
1988 if (rect == session->GetClientRect()) {
1989 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d skip same rect",
1990 funcName, session->GetPersistentId());
1991 return;
1992 }
1993 session->SetClientRect(rect);
1994 }, __func__ + GetRectInfo(rect));
1995 return WSError::WS_OK;
1996 }
1997
NotifySingleHandTransformChange(const SingleHandTransform & singleHandTransform)1998 void SceneSession::NotifySingleHandTransformChange(const SingleHandTransform& singleHandTransform)
1999 {
2000 if (!IsSessionForeground() && !IsVisible()) {
2001 TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, session is not foreground and not visible!", GetPersistentId());
2002 return;
2003 }
2004 if (sessionStage_ != nullptr) {
2005 sessionStage_->NotifySingleHandTransformChange(singleHandTransform);
2006 }
2007 }
2008
RegisterRaiseToTopCallback(NotifyRaiseToTopFunc && callback)2009 void SceneSession::RegisterRaiseToTopCallback(NotifyRaiseToTopFunc&& callback)
2010 {
2011 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
2012 auto session = weakThis.promote();
2013 if (!session) {
2014 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
2015 return;
2016 }
2017 session->onRaiseToTop_ = std::move(callback);
2018 }, __func__);
2019 }
2020
RegisterRaiseAboveTargetCallback(NotifyRaiseAboveTargetFunc && callback)2021 void SceneSession::RegisterRaiseAboveTargetCallback(NotifyRaiseAboveTargetFunc&& callback)
2022 {
2023 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
2024 auto session = weakThis.promote();
2025 if (!session) {
2026 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
2027 return;
2028 }
2029 session->onRaiseAboveTarget_ = std::move(callback);
2030 }, __func__);
2031 }
2032
RegisterRaiseMainWindowAboveTargetCallback(NotifyRaiseMainWindowAboveTargetFunc && callback)2033 void SceneSession::RegisterRaiseMainWindowAboveTargetCallback(NotifyRaiseMainWindowAboveTargetFunc&& callback)
2034 {
2035 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
2036 auto session = weakThis.promote();
2037 if (!session) {
2038 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
2039 return;
2040 }
2041 session->onRaiseMainWindowAboveTarget_ = std::move(callback);
2042 }, __func__);
2043 }
2044
RegisterSessionTopmostChangeCallback(NotifySessionTopmostChangeFunc && callback)2045 void SceneSession::RegisterSessionTopmostChangeCallback(NotifySessionTopmostChangeFunc&& callback)
2046 {
2047 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
2048 auto session = weakThis.promote();
2049 if (!session) {
2050 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
2051 return;
2052 }
2053 session->onSessionTopmostChange_ = std::move(callback);
2054 session->onSessionTopmostChange_(session->IsTopmost());
2055 }, __func__);
2056 }
2057
2058 /** @note @window.hierarchy */
RegisterSubSessionZLevelChangeCallback(NotifySubSessionZLevelChangeFunc && callback)2059 void SceneSession::RegisterSubSessionZLevelChangeCallback(NotifySubSessionZLevelChangeFunc&& callback)
2060 {
2061 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
2062 auto session = weakThis.promote();
2063 if (!session) {
2064 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
2065 return;
2066 }
2067 session->onSubSessionZLevelChange_ = std::move(callback);
2068 session->onSubSessionZLevelChange_(session->GetSubWindowZLevel());
2069 }, __func__);
2070 }
2071
2072 /** @note @window.hierarchy */
RaiseToAppTop()2073 WSError SceneSession::RaiseToAppTop()
2074 {
2075 return PostSyncTask([weakThis = wptr(this), where = __func__] {
2076 auto session = weakThis.promote();
2077 if (!session) {
2078 TLOGNE(WmsLogTag::WMS_HIERARCHY, "%{public}s session is null", where);
2079 return WSError::WS_ERROR_DESTROYED_OBJECT;
2080 }
2081 if (session->onRaiseToTop_) {
2082 TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s id: %{public}d", where, session->GetPersistentId());
2083 session->onRaiseToTop_();
2084 session->SetMainSessionUIStateDirty(true);
2085 }
2086 return WSError::WS_OK;
2087 }, __func__);
2088 }
2089
2090 /** @note @window.hierarchy */
RaiseAboveTarget(int32_t subWindowId)2091 WSError SceneSession::RaiseAboveTarget(int32_t subWindowId)
2092 {
2093 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2094 WLOGFE("RaiseAboveTarget permission denied!");
2095 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2096 }
2097 auto subSession = std::find_if(subSession_.begin(), subSession_.end(), [subWindowId](sptr<SceneSession> session) {
2098 bool res = (session != nullptr && session->GetWindowId() == subWindowId) ? true : false;
2099 return res;
2100 });
2101 int32_t callingPid = IPCSkeleton::GetCallingPid();
2102 if (subSession != subSession_.end() && callingPid != (*subSession)->GetCallingPid()) {
2103 TLOGE(WmsLogTag::WMS_HIERARCHY, "permission denied! id: %{public}d", subWindowId);
2104 return WSError::WS_ERROR_INVALID_CALLING;
2105 }
2106 return PostSyncTask([weakThis = wptr(this), subWindowId, where = __func__] {
2107 auto session = weakThis.promote();
2108 if (!session) {
2109 TLOGNE(WmsLogTag::WMS_HIERARCHY, "%{public}s session is null", where);
2110 return WSError::WS_ERROR_DESTROYED_OBJECT;
2111 }
2112 if (session->onRaiseAboveTarget_) {
2113 session->onRaiseAboveTarget_(subWindowId);
2114 }
2115 return WSError::WS_OK;
2116 }, __func__);
2117 }
2118
2119 /** @note @window.hierarchy */
RaiseMainWindowAboveTarget(int32_t targetId)2120 WSError SceneSession::RaiseMainWindowAboveTarget(int32_t targetId)
2121 {
2122 TLOGI(WmsLogTag::WMS_HIERARCHY, "[SceneSession] source id: %{public}u, target id: %{public}u ",
2123 GetWindowId(), targetId);
2124 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2125 TLOGE(WmsLogTag::WMS_HIERARCHY, "server permission denied, require system application");
2126 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2127 }
2128 auto targetSession = GetSceneSessionById(targetId);
2129 if (targetSession == nullptr) {
2130 TLOGE(WmsLogTag::WMS_HIERARCHY, "target session is null");
2131 return WSError::WS_ERROR_NULLPTR;
2132 }
2133 if (GetCallingPid() != targetSession->GetCallingPid()) {
2134 TLOGE(WmsLogTag::WMS_HIERARCHY, "calling pid inconsistecy");
2135 return WSError::WS_ERROR_INVALID_CALLING;
2136 }
2137 if ((GetSessionProperty()->GetDisplayId() != targetSession->GetSessionProperty()->GetDisplayId()) &&
2138 !(PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(GetSessionProperty()->GetDisplayId()) &&
2139 PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(targetSession->
2140 GetSessionProperty()->GetDisplayId()))) {
2141 TLOGE(WmsLogTag::WMS_HIERARCHY, "source window and target window are not on the same screen");
2142 return WSError::WS_ERROR_INVALID_CALLING;
2143 }
2144 if (GetZOrder() > SCREEN_LOCK_Z_ORDER || targetSession->GetZOrder() > SCREEN_LOCK_Z_ORDER) {
2145 TLOGE(WmsLogTag::WMS_HIERARCHY, "window above screenlock is not supported");
2146 return WSError::WS_ERROR_INVALID_CALLING;
2147 }
2148 return PostSyncTask([weakThis = wptr(this), targetId, where = __func__] {
2149 auto session = weakThis.promote();
2150 if (!session) {
2151 TLOGNE(WmsLogTag::WMS_HIERARCHY, "%{public}s session is null", where);
2152 return WSError::WS_ERROR_DESTROYED_OBJECT;
2153 }
2154 if (session->onRaiseMainWindowAboveTarget_) {
2155 TLOGNI(WmsLogTag::WMS_HIERARCHY, "id: %{public}d, raise main window above target: %{public}d",
2156 session->GetPersistentId(), targetId);
2157 session->onRaiseMainWindowAboveTarget_(targetId);
2158 }
2159 return WSError::WS_OK;
2160 }, __func__);
2161 }
2162
BindDialogSessionTarget(const sptr<SceneSession> & sceneSession)2163 WSError SceneSession::BindDialogSessionTarget(const sptr<SceneSession>& sceneSession)
2164 {
2165 if (sceneSession == nullptr) {
2166 TLOGE(WmsLogTag::WMS_DIALOG, "dialog session is null");
2167 return WSError::WS_ERROR_NULLPTR;
2168 }
2169 if (onBindDialogTarget_) {
2170 TLOGI(WmsLogTag::WMS_DIALOG, "id: %{public}d", sceneSession->GetPersistentId());
2171 onBindDialogTarget_(sceneSession);
2172 }
2173 return WSError::WS_OK;
2174 }
2175
SetSystemBarProperty(WindowType type,SystemBarProperty systemBarProperty)2176 WSError SceneSession::SetSystemBarProperty(WindowType type, SystemBarProperty systemBarProperty)
2177 {
2178 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u type %{public}u "
2179 "%{public}u %{public}x %{public}x %{public}u settingFlag %{public}u",
2180 GetPersistentId(), static_cast<uint32_t>(type),
2181 systemBarProperty.enable_, systemBarProperty.backgroundColor_, systemBarProperty.contentColor_,
2182 systemBarProperty.enableAnimation_, systemBarProperty.settingFlag_);
2183 auto property = GetSessionProperty();
2184 property->SetSystemBarProperty(type, systemBarProperty);
2185 if (type == WindowType::WINDOW_TYPE_STATUS_BAR && systemBarProperty.enable_) {
2186 SetIsDisplayStatusBarTemporarily(false);
2187 }
2188 if (onSystemBarPropertyChange_) {
2189 onSystemBarPropertyChange_(property->GetSystemBarProperty());
2190 if (specificCallback_ != nullptr && specificCallback_->onNotifyWindowSystemBarPropertyChangeFunc_ != nullptr) {
2191 specificCallback_->onNotifyWindowSystemBarPropertyChangeFunc_(type, systemBarProperty);
2192 }
2193 }
2194 return WSError::WS_OK;
2195 }
2196
SetIsStatusBarVisible(bool isVisible)2197 void SceneSession::SetIsStatusBarVisible(bool isVisible)
2198 {
2199 PostTask([weakThis = wptr(this), isVisible, where = __func__] {
2200 sptr<SceneSession> sceneSession = weakThis.promote();
2201 if (sceneSession == nullptr) {
2202 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
2203 return;
2204 }
2205 sceneSession->SetIsStatusBarVisibleInner(isVisible);
2206 }, __func__);
2207 }
2208
SetIsStatusBarVisibleInner(bool isVisible)2209 WSError SceneSession::SetIsStatusBarVisibleInner(bool isVisible)
2210 {
2211 bool isNeedNotify = isStatusBarVisible_ != isVisible;
2212 TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}d, %{public}s] visible %{public}u need notify %{public}u",
2213 GetPersistentId(), GetWindowName().c_str(), isVisible, isNeedNotify);
2214 isStatusBarVisible_ = isVisible;
2215 if (!isNeedNotify) {
2216 return WSError::WS_OK;
2217 }
2218 return HandleLayoutAvoidAreaUpdate(AvoidAreaType::TYPE_SYSTEM);
2219 }
2220
HandleLayoutAvoidAreaUpdate(AvoidAreaType avoidAreaType)2221 WSError SceneSession::HandleLayoutAvoidAreaUpdate(AvoidAreaType avoidAreaType)
2222 {
2223 if (isLastFrameLayoutFinishedFunc_ == nullptr) {
2224 TLOGE(WmsLogTag::WMS_IMMS, "isLastFrameLayoutFinishedFunc is null, win %{public}d", GetPersistentId());
2225 return WSError::WS_ERROR_NULLPTR;
2226 }
2227 bool isLayoutFinished = false;
2228 WSError ret = isLastFrameLayoutFinishedFunc_(isLayoutFinished);
2229 if (ret != WSError::WS_OK) {
2230 TLOGE(WmsLogTag::WMS_IMMS, "isLastFrameLayoutFinishedFunc failed, ret %{public}d", ret);
2231 return ret;
2232 }
2233 if (!isLayoutFinished) {
2234 MarkAvoidAreaAsDirty();
2235 return WSError::WS_OK;
2236 }
2237 if (avoidAreaType != AvoidAreaType::TYPE_END) {
2238 auto area = GetAvoidAreaByType(avoidAreaType);
2239 // code below aims to check if ai bar avoid area reaches window rect's bottom
2240 // it should not be removed until unexpected window rect update issues were solved
2241 if (avoidAreaType == AvoidAreaType::TYPE_NAVIGATION_INDICATOR && isAINavigationBarAvoidAreaValid_ &&
2242 !isAINavigationBarAvoidAreaValid_(area, GetSessionRect().height_)) {
2243 TLOGE(WmsLogTag::WMS_IMMS, "ai bar avoid area dose not reach the bottom of the rect");
2244 return WSError::WS_OK;
2245 }
2246 UpdateAvoidArea(new AvoidArea(area), avoidAreaType);
2247 return WSError::WS_OK;
2248 } else {
2249 // avoidAreaType equal to TYPE_END means traversing and updating all avoid area types
2250 using T = std::underlying_type_t<AvoidAreaType>;
2251 for (T avoidType = static_cast<T>(AvoidAreaType::TYPE_START);
2252 avoidType < static_cast<T>(AvoidAreaType::TYPE_END); avoidType++) {
2253 auto type = static_cast<AvoidAreaType>(avoidType);
2254 auto area = GetAvoidAreaByType(type);
2255 // code below aims to check if ai bar avoid area reaches window rect's bottom
2256 // it should not be removed until unexpected window rect update issues were solved
2257 if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR && isAINavigationBarAvoidAreaValid_ &&
2258 !isAINavigationBarAvoidAreaValid_(area, GetSessionRect().height_)) {
2259 TLOGE(WmsLogTag::WMS_IMMS, "ai bar avoid area dose not reach the bottom "
2260 "of the rect while traversing all avoid area type");
2261 continue;
2262 }
2263 UpdateAvoidArea(new AvoidArea(area), type);
2264 }
2265 }
2266 return WSError::WS_OK;
2267 }
2268
NotifyPropertyWhenConnect()2269 void SceneSession::NotifyPropertyWhenConnect()
2270 {
2271 WLOGFI("Notify property when connect.");
2272 auto property = GetSessionProperty();
2273 if (property == nullptr) {
2274 WLOGFD("id: %{public}d property is nullptr", persistentId_);
2275 return;
2276 }
2277 NotifySessionFocusableChange(property->GetFocusable());
2278 NotifySessionTouchableChange(property->GetTouchable());
2279 OnShowWhenLocked(GetShowWhenLockedFlagValue());
2280 }
2281
2282 /** @note @window.hierarchy */
RaiseAppMainWindowToTop()2283 WSError SceneSession::RaiseAppMainWindowToTop()
2284 {
2285 PostTask([weakThis = wptr(this), where = __func__] {
2286 auto session = weakThis.promote();
2287 if (!session) {
2288 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
2289 return WSError::WS_ERROR_DESTROYED_OBJECT;
2290 }
2291 if (session->IsFocusedOnShow()) {
2292 FocusChangeReason reason = FocusChangeReason::MOVE_UP;
2293 session->NotifyRequestFocusStatusNotifyManager(true, true, reason);
2294 session->NotifyClick(true, false);
2295 } else {
2296 session->SetFocusedOnShow(true);
2297 }
2298 return WSError::WS_OK;
2299 }, __func__);
2300 return WSError::WS_OK;
2301 }
2302
OnNeedAvoid(bool status)2303 WSError SceneSession::OnNeedAvoid(bool status)
2304 {
2305 PostTask([weakThis = wptr(this), status, where = __func__] {
2306 auto session = weakThis.promote();
2307 if (!session) {
2308 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
2309 return WSError::WS_ERROR_DESTROYED_OBJECT;
2310 }
2311 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d status %{public}d",
2312 where, session->GetPersistentId(), static_cast<int32_t>(status));
2313 if (session->onNeedAvoid_) {
2314 session->onNeedAvoid_(status);
2315 }
2316 return WSError::WS_OK;
2317 }, __func__);
2318 return WSError::WS_OK;
2319 }
2320
OnShowWhenLocked(bool showWhenLocked)2321 WSError SceneSession::OnShowWhenLocked(bool showWhenLocked)
2322 {
2323 WLOGFD("SceneSession ShowWhenLocked status:%{public}d", static_cast<int32_t>(showWhenLocked));
2324 if (onShowWhenLockedFunc_) {
2325 onShowWhenLockedFunc_(showWhenLocked);
2326 }
2327 return WSError::WS_OK;
2328 }
2329
IsShowWhenLocked() const2330 bool SceneSession::IsShowWhenLocked() const
2331 {
2332 return (GetSessionProperty()->GetWindowFlags() &
2333 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) || IsTemporarilyShowWhenLocked();
2334 }
2335
GetShowWhenLockedFlagValue() const2336 bool SceneSession::GetShowWhenLockedFlagValue() const
2337 {
2338 return GetSessionProperty()->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
2339 }
2340
PrintAvoidAreaInfo(DisplayId displayId,AvoidAreaType type,const WSRect & rect,const WSRect & avoidRect) const2341 void SceneSession::PrintAvoidAreaInfo(DisplayId displayId,
2342 AvoidAreaType type, const WSRect& rect, const WSRect& avoidRect) const
2343 {
2344 std::tuple<DisplayId, WSRect, WSRect> inputParamters(displayId, rect, avoidRect);
2345 auto iter = lastAvoidAreaInputParamtersMap_.find(type);
2346 if (iter != lastAvoidAreaInputParamtersMap_.end() && iter->second == inputParamters) {
2347 return;
2348 }
2349 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d dispaly %{public}" PRIu64 ""
2350 "type %{public}d rect %{public}s bar %{public}s",
2351 GetPersistentId(), displayId, type, rect.ToString().c_str(), avoidRect.ToString().c_str());
2352 }
2353
CalculateAvoidAreaByType(AvoidAreaType type,const WSRect & winRect,const WSRect & avoidRect,AvoidArea & avoidArea)2354 void SceneSession::CalculateAvoidAreaByType(AvoidAreaType type,
2355 const WSRect& winRect, const WSRect& avoidRect, AvoidArea& avoidArea)
2356 {
2357 auto displayId = GetSessionProperty()->GetDisplayId();
2358 PrintAvoidAreaInfo(displayId, type, winRect, avoidRect);
2359 CalculateAvoidAreaRect(winRect, avoidRect, avoidArea);
2360 lastAvoidAreaInputParamtersMap_[type] = std::make_tuple(displayId, winRect, avoidRect);
2361 }
2362
CalculateAvoidAreaRect(const WSRect & rect,const WSRect & avoidRect,AvoidArea & avoidArea) const2363 void SceneSession::CalculateAvoidAreaRect(const WSRect& rect, const WSRect& avoidRect, AvoidArea& avoidArea) const
2364 {
2365 if (SessionHelper::IsEmptyRect(rect) || SessionHelper::IsEmptyRect(avoidRect)) {
2366 return;
2367 }
2368 Rect avoidAreaRect = SessionHelper::TransferToRect(
2369 SessionHelper::GetOverlap(rect, avoidRect, rect.posX_, rect.posY_));
2370 if (WindowHelper::IsEmptyRect(avoidAreaRect)) {
2371 return;
2372 }
2373
2374 uint32_t avoidAreaCenterX = static_cast<uint32_t>(avoidAreaRect.posX_) + (avoidAreaRect.width_ >> 1);
2375 uint32_t avoidAreaCenterY = static_cast<uint32_t>(avoidAreaRect.posY_) + (avoidAreaRect.height_ >> 1);
2376 float res1 = float(avoidAreaCenterY) - float(rect.height_) / float(rect.width_) *
2377 float(avoidAreaCenterX);
2378 float res2 = float(avoidAreaCenterY) + float(rect.height_) / float(rect.width_) *
2379 float(avoidAreaCenterX) - float(rect.height_);
2380 if (res1 < 0) {
2381 if (res2 < 0) {
2382 avoidArea.topRect_ = avoidAreaRect;
2383 } else {
2384 avoidArea.rightRect_ = avoidAreaRect;
2385 }
2386 } else {
2387 if (res2 < 0) {
2388 avoidArea.leftRect_ = avoidAreaRect;
2389 } else {
2390 avoidArea.bottomRect_ = avoidAreaRect;
2391 }
2392 }
2393 }
2394
GetSystemAvoidArea(WSRect & rect,AvoidArea & avoidArea)2395 void SceneSession::GetSystemAvoidArea(WSRect& rect, AvoidArea& avoidArea)
2396 {
2397 auto sessionProperty = GetSessionProperty();
2398 bool isNeedAvoid = sessionProperty->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID);
2399 if (isNeedAvoid && WindowHelper::IsAppWindow(GetWindowType())) {
2400 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d type %{public}u flag %{public}d",
2401 GetPersistentId(), static_cast<uint32_t>(GetWindowType()), sessionProperty->GetWindowFlags());
2402 return;
2403 }
2404 if (sessionProperty->IsAdaptToImmersive()) {
2405 HookAvoidAreaInCompatibleMode(rect, AvoidAreaType::TYPE_SYSTEM, avoidArea);
2406 return;
2407 }
2408 WindowMode windowMode = Session::GetWindowMode();
2409 bool isWindowFloatingOrSplit = windowMode == WindowMode::WINDOW_MODE_FLOATING ||
2410 windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
2411 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY;
2412 WindowType windowType = Session::GetWindowType();
2413 bool isAvailableSystemWindow = WindowHelper::IsSystemWindow(windowType) &&
2414 (GetSessionProperty()->GetAvoidAreaOption() & static_cast<uint32_t>(AvoidAreaOption::ENABLE_SYSTEM_WINDOW));
2415 bool isAvailableAppSubWindow = WindowHelper::IsSubWindow(windowType) &&
2416 (GetSessionProperty()->GetAvoidAreaOption() & static_cast<uint32_t>(AvoidAreaOption::ENABLE_APP_SUB_WINDOW));
2417 bool isAvailableWindowType = WindowHelper::IsMainWindow(windowType) || isAvailableSystemWindow ||
2418 isAvailableAppSubWindow;
2419 bool isAvailableDevice = (systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) &&
2420 !IsFreeMultiWindowMode();
2421 DisplayId displayId = sessionProperty->GetDisplayId();
2422 auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
2423 bool isAvailableScreen = !screenSession || (screenSession->GetName() != "HiCar");
2424 if (isWindowFloatingOrSplit && isAvailableWindowType && isAvailableDevice && isAvailableScreen) {
2425 // mini floating scene no need avoid
2426 if (LessOrEqual(Session::GetFloatingScale(), MINI_FLOAT_SCALE)) {
2427 return;
2428 }
2429 float vpr = 3.5f; // 3.5f: default pixel ratio
2430 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
2431 if (display == nullptr) {
2432 TLOGE(WmsLogTag::WMS_IMMS, "display is null");
2433 return;
2434 }
2435 vpr = display->GetVirtualPixelRatio();
2436 bool isFloat = windowMode == WindowMode::WINDOW_MODE_FLOATING && !GetIsMidScene();
2437 int32_t height = isFloat ? GetStatusBarHeight() : vpr * MULTI_WINDOW_TITLE_BAR_DEFAULT_HEIGHT_VP;
2438 avoidArea.topRect_.height_ = static_cast<uint32_t>(height);
2439 avoidArea.topRect_.width_ = static_cast<uint32_t>(display->GetWidth());
2440 return;
2441 }
2442 std::vector<sptr<SceneSession>> statusBarVector;
2443 if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_) {
2444 statusBarVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
2445 WindowType::WINDOW_TYPE_STATUS_BAR, sessionProperty->GetDisplayId());
2446 }
2447 for (auto& statusBar : statusBarVector) {
2448 if (statusBar == nullptr) {
2449 continue;
2450 }
2451 bool isVisible = statusBar->isVisible_;
2452 if (onGetStatusBarConstantlyShowFunc_) {
2453 onGetStatusBarConstantlyShowFunc_(displayId, isVisible);
2454 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d displayId %{public}" PRIu64 " constantly isVisible %{public}d",
2455 GetPersistentId(), displayId, isVisible);
2456 }
2457 bool isStatusBarVisible = WindowHelper::IsMainWindow(Session::GetWindowType()) ?
2458 isStatusBarVisible_ : isVisible;
2459 if (!isStatusBarVisible) {
2460 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d status bar not visible", GetPersistentId());
2461 continue;
2462 }
2463 WSRect statusBarRect = statusBar->GetSessionRect();
2464 if (onGetStatusBarAvoidHeightFunc_) {
2465 onGetStatusBarAvoidHeightFunc_(displayId, statusBarRect);
2466 }
2467 CalculateAvoidAreaByType(AvoidAreaType::TYPE_SYSTEM, rect, statusBarRect, avoidArea);
2468 }
2469 return;
2470 }
2471
GetKeyboardAvoidArea(WSRect & rect,AvoidArea & avoidArea)2472 void SceneSession::GetKeyboardAvoidArea(WSRect& rect, AvoidArea& avoidArea)
2473 {
2474 if (!keyboardAvoidAreaActive_) {
2475 TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d, isSystemKeyboard: %{public}d, state: %{public}d, "
2476 "gravity: %{public}d", GetPersistentId(), IsSystemKeyboard(), GetSessionState(), GetKeyboardGravity());
2477 return;
2478 }
2479 if (Session::CheckEmptyKeyboardAvoidAreaIfNeeded()) {
2480 TLOGD(WmsLogTag::WMS_IMMS, "Keyboard avoid area needs to be empty in floating mode");
2481 return;
2482 }
2483 std::vector<sptr<SceneSession>> inputMethodVector;
2484 if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByType_) {
2485 inputMethodVector = specificCallback_->onGetSceneSessionVectorByType_(
2486 WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
2487 }
2488 for (auto& inputMethod : inputMethodVector) {
2489 if (inputMethod->GetSessionState() != SessionState::STATE_FOREGROUND &&
2490 inputMethod->GetSessionState() != SessionState::STATE_ACTIVE) {
2491 continue;
2492 }
2493 SessionGravity gravity = inputMethod->GetKeyboardGravity();
2494 if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT || !inputMethod->IsKeyboardAvoidAreaActive()) {
2495 continue;
2496 }
2497 if (isKeyboardPanelEnabled_) {
2498 WSRect keyboardRect = {0, 0, 0, 0};
2499 if (inputMethod && inputMethod->GetKeyboardPanelSession()) {
2500 keyboardRect = inputMethod->GetKeyboardPanelSession()->GetSessionRect();
2501 inputMethod->RecalculatePanelRectForAvoidArea(keyboardRect);
2502 }
2503 CalculateAvoidAreaByType(AvoidAreaType::TYPE_KEYBOARD, rect, keyboardRect, avoidArea);
2504 } else {
2505 WSRect inputMethodRect = inputMethod->GetSessionRect();
2506 CalculateAvoidAreaByType(AvoidAreaType::TYPE_KEYBOARD, rect, inputMethodRect, avoidArea);
2507 }
2508 }
2509 return;
2510 }
2511
GetKeyboardOccupiedAreaWithRotation(int32_t persistentId,Rotation rotation,std::vector<std::pair<bool,WSRect>> & avoidAreas)2512 void SceneSession::GetKeyboardOccupiedAreaWithRotation(
2513 int32_t persistentId, Rotation rotation, std::vector<std::pair<bool, WSRect>>& avoidAreas)
2514 {
2515 TLOGI(WmsLogTag::WMS_KEYBOARD, "In");
2516 if (!specificCallback_ || !specificCallback_->onKeyboardRotationChange_) {
2517 TLOGE(WmsLogTag::WMS_KEYBOARD, "specificCallback_ or onKeyboardRotationChange_ is nullptr");
2518 return;
2519 }
2520 specificCallback_->onKeyboardRotationChange_(persistentId, rotation, avoidAreas);
2521 }
2522
GetCutoutAvoidArea(WSRect & rect,AvoidArea & avoidArea)2523 void SceneSession::GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea)
2524 {
2525 auto display = DisplayManager::GetInstance().GetDisplayById(GetSessionProperty()->GetDisplayId());
2526 if (display == nullptr) {
2527 TLOGE(WmsLogTag::WMS_IMMS, "Failed to get display");
2528 return;
2529 }
2530 sptr<CutoutInfo> cutoutInfo = display->GetCutoutInfo();
2531 if (cutoutInfo == nullptr) {
2532 TLOGI(WmsLogTag::WMS_IMMS, "There is no cutout info");
2533 return;
2534 }
2535 std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
2536 if (cutoutAreas.empty()) {
2537 TLOGI(WmsLogTag::WMS_IMMS, "There is no cutout area");
2538 return;
2539 }
2540 for (auto& cutoutArea : cutoutAreas) {
2541 WSRect cutoutAreaRect = {
2542 cutoutArea.posX_,
2543 cutoutArea.posY_,
2544 cutoutArea.width_,
2545 cutoutArea.height_
2546 };
2547 CalculateAvoidAreaByType(AvoidAreaType::TYPE_CUTOUT, rect, cutoutAreaRect, avoidArea);
2548 }
2549
2550 return;
2551 }
2552
GetAINavigationBarArea(WSRect & rect,AvoidArea & avoidArea)2553 void SceneSession::GetAINavigationBarArea(WSRect& rect, AvoidArea& avoidArea)
2554 {
2555 if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
2556 TLOGD(WmsLogTag::WMS_IMMS, "window mode pip return");
2557 return;
2558 }
2559 // compatibleMode app need to hook avoidArea in pc
2560 if (GetSessionProperty()->IsAdaptToImmersive()) {
2561 HookAvoidAreaInCompatibleMode(rect, AvoidAreaType::TYPE_NAVIGATION_INDICATOR, avoidArea);
2562 return;
2563 }
2564 WSRect barArea;
2565 if (specificCallback_ != nullptr && specificCallback_->onGetAINavigationBarArea_) {
2566 barArea = specificCallback_->onGetAINavigationBarArea_(GetSessionProperty()->GetDisplayId());
2567 }
2568 CalculateAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR, rect, barArea, avoidArea);
2569 }
2570
HookAvoidAreaInCompatibleMode(const WSRect & rect,AvoidAreaType avoidAreaType,AvoidArea & avoidArea) const2571 void SceneSession::HookAvoidAreaInCompatibleMode(const WSRect& rect, AvoidAreaType avoidAreaType,
2572 AvoidArea& avoidArea) const
2573 {
2574 WindowMode mode = GetWindowMode();
2575 if (!GetSessionProperty()->IsAdaptToImmersive() || mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2576 return;
2577 }
2578 float vpr = 1.9f; // 3.5f: default pixel ratio
2579 DMHookInfo hookInfo;
2580 ScreenSessionManagerClient::GetInstance().GetDisplayHookInfo(GetCallingUid(), hookInfo);
2581 if (hookInfo.density_) {
2582 vpr = hookInfo.density_;
2583 }
2584 switch (avoidAreaType) {
2585 case AvoidAreaType::TYPE_SYSTEM: {
2586 avoidArea.topRect_.posX_ = 0;
2587 avoidArea.topRect_.posY_ = 0;
2588 avoidArea.topRect_.height_ = HOOK_SYSTEM_BAR_HEIGHT * vpr;
2589 avoidArea.topRect_.width_ = rect.width_;
2590 return;
2591 }
2592 case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
2593 avoidArea.bottomRect_.posX_ = 0;
2594 avoidArea.bottomRect_.posY_ = rect.height_ - HOOK_AI_BAR_HEIGHT * vpr;
2595 avoidArea.bottomRect_.width_ = rect.width_;
2596 avoidArea.bottomRect_.height_ = HOOK_AI_BAR_HEIGHT * vpr;
2597 return;
2598 }
2599 default: {
2600 TLOGE(WmsLogTag::WMS_IMMS, "cannot find win %{public}d type %{public}u", GetPersistentId(), avoidAreaType);
2601 return;
2602 }
2603 }
2604 }
2605
CheckGetSubWindowAvoidAreaAvailable(WindowMode winMode,AvoidAreaType type)2606 bool SceneSession::CheckGetSubWindowAvoidAreaAvailable(WindowMode winMode, AvoidAreaType type)
2607 {
2608 if (GetSessionProperty()->GetAvoidAreaOption() & static_cast<uint32_t>(AvoidAreaOption::ENABLE_APP_SUB_WINDOW)) {
2609 return true;
2610 }
2611 if (winMode == WindowMode::WINDOW_MODE_FLOATING && IsFreeMultiWindowMode()) {
2612 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d type pad free multi window mode, return 0", GetPersistentId());
2613 return false;
2614 }
2615 auto parentSession = GetParentSession();
2616 if (!parentSession) {
2617 TLOGE(WmsLogTag::WMS_IMMS, "win %{public}d parent session is nullptr", GetPersistentId());
2618 return false;
2619 }
2620 if (parentSession->GetSessionRect() != GetSessionRect()) {
2621 TLOGE(WmsLogTag::WMS_IMMS, "rect mismatch: win %{public}d parent %{public}d",
2622 GetPersistentId(), parentSession->GetPersistentId());
2623 return false;
2624 }
2625 return parentSession->CheckGetAvoidAreaAvailable(type);
2626 }
2627
CheckGetMainWindowAvoidAreaAvailable(WindowMode winMode,AvoidAreaType type)2628 bool SceneSession::CheckGetMainWindowAvoidAreaAvailable(WindowMode winMode, AvoidAreaType type)
2629 {
2630 // compatibleMode app in pc,need use avoid Area
2631 if (GetSessionProperty()->IsAdaptToImmersive()) {
2632 return true;
2633 }
2634 if (winMode == WindowMode::WINDOW_MODE_FLOATING && type != AvoidAreaType::TYPE_SYSTEM) {
2635 return false;
2636 }
2637 if (winMode == WindowMode::WINDOW_MODE_FLOATING && IsFreeMultiWindowMode()) {
2638 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d type pad free multi window mode, return 0", GetPersistentId());
2639 return false;
2640 }
2641 if (winMode != WindowMode::WINDOW_MODE_FLOATING || systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) {
2642 return true;
2643 }
2644 return false;
2645 }
2646
CheckGetSystemWindowAvoidAreaAvailable()2647 bool SceneSession::CheckGetSystemWindowAvoidAreaAvailable()
2648 {
2649 if (GetSessionProperty()->GetAvoidAreaOption() &
2650 static_cast<uint32_t>(AvoidAreaOption::ENABLE_SYSTEM_WINDOW)) {
2651 return systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
2652 }
2653 return false;
2654 }
2655
CheckGetAvoidAreaAvailable(AvoidAreaType type)2656 bool SceneSession::CheckGetAvoidAreaAvailable(AvoidAreaType type)
2657 {
2658 if (type == AvoidAreaType::TYPE_KEYBOARD) {
2659 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d type 3, return 1", GetPersistentId());
2660 return true;
2661 }
2662 WindowMode winMode = GetWindowMode();
2663 WindowType winType = GetWindowType();
2664 bool isAvailable = false;
2665 if (WindowHelper::IsSubWindow(winType)) {
2666 isAvailable = CheckGetSubWindowAvoidAreaAvailable(winMode, type);
2667 } else if (WindowHelper::IsMainWindow(winType)) {
2668 isAvailable = CheckGetMainWindowAvoidAreaAvailable(winMode, type);
2669 } else if (WindowHelper::IsSystemWindow(winType)) {
2670 isAvailable = CheckGetSystemWindowAvoidAreaAvailable();
2671 }
2672 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d type %{public}u avoidAreaType %{public}u "
2673 "windowMode %{public}u avoidAreaOption %{public}u, return %{public}d",
2674 GetPersistentId(), static_cast<uint32_t>(winType), static_cast<uint32_t>(type),
2675 static_cast<uint32_t>(winMode), GetSessionProperty()->GetAvoidAreaOption(), isAvailable);
2676 return isAvailable;
2677 }
2678
AddNormalModalUIExtension(const ExtensionWindowEventInfo & extensionInfo)2679 void SceneSession::AddNormalModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)
2680 {
2681 TLOGD(WmsLogTag::WMS_UIEXT, "parentId=%{public}d, persistentId=%{public}d, pid=%{public}d", GetPersistentId(),
2682 extensionInfo.persistentId, extensionInfo.pid);
2683 {
2684 std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
2685 modalUIExtensionInfoList_.push_back(extensionInfo);
2686 }
2687 NotifySessionInfoChange();
2688 }
2689
UpdateNormalModalUIExtension(const ExtensionWindowEventInfo & extensionInfo)2690 void SceneSession::UpdateNormalModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)
2691 {
2692 TLOGD(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d,pid=%{public}d,"
2693 "Rect:[%{public}d %{public}d %{public}d %{public}d]",
2694 extensionInfo.persistentId, extensionInfo.pid, extensionInfo.windowRect.posX_,
2695 extensionInfo.windowRect.posY_, extensionInfo.windowRect.width_, extensionInfo.windowRect.height_);
2696 {
2697 std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
2698 auto iter = std::find_if(modalUIExtensionInfoList_.begin(), modalUIExtensionInfoList_.end(),
2699 [extensionInfo](const ExtensionWindowEventInfo& eventInfo) {
2700 return extensionInfo.persistentId == eventInfo.persistentId && extensionInfo.pid == eventInfo.pid;
2701 });
2702 if (iter == modalUIExtensionInfoList_.end()) {
2703 return;
2704 }
2705 iter->windowRect = extensionInfo.windowRect;
2706 iter->uiExtRect = extensionInfo.uiExtRect;
2707 iter->hasUpdatedRect = extensionInfo.hasUpdatedRect;
2708 }
2709 NotifySessionInfoChange();
2710 }
2711
RemoveNormalModalUIExtension(int32_t persistentId)2712 void SceneSession::RemoveNormalModalUIExtension(int32_t persistentId)
2713 {
2714 TLOGI(WmsLogTag::WMS_UIEXT, "parentId=%{public}d, persistentId=%{public}d", GetPersistentId(), persistentId);
2715 {
2716 std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
2717 auto iter = std::find_if(modalUIExtensionInfoList_.begin(), modalUIExtensionInfoList_.end(),
2718 [persistentId](const ExtensionWindowEventInfo& extensionInfo) {
2719 return extensionInfo.persistentId == persistentId;
2720 });
2721 if (iter == modalUIExtensionInfoList_.end()) {
2722 return;
2723 }
2724 modalUIExtensionInfoList_.erase(iter);
2725 }
2726 NotifySessionInfoChange();
2727 }
2728
RegisterGetConstrainedModalExtWindowInfo(GetConstrainedModalExtWindowInfoFunc && callback)2729 void SceneSession::RegisterGetConstrainedModalExtWindowInfo(GetConstrainedModalExtWindowInfoFunc&& callback)
2730 {
2731 onGetConstrainedModalExtWindowInfoFunc_ = std::move(callback);
2732 }
2733
GetLastModalUIExtensionEventInfo()2734 std::optional<ExtensionWindowEventInfo> SceneSession::GetLastModalUIExtensionEventInfo()
2735 {
2736 // Priority query constrained modal UIExt, if unavailable, then query normal modal UIExt
2737 if (onGetConstrainedModalExtWindowInfoFunc_) {
2738 if (auto constrainedExtEventInfo = onGetConstrainedModalExtWindowInfoFunc_(this)) {
2739 TLOGD(WmsLogTag::WMS_UIEXT, "get constrained UIExt eventInfo, id: %{public}d",
2740 constrainedExtEventInfo->persistentId);
2741 return constrainedExtEventInfo;
2742 }
2743 }
2744 std::shared_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
2745 return modalUIExtensionInfoList_.empty() ? std::nullopt :
2746 std::make_optional<ExtensionWindowEventInfo>(modalUIExtensionInfoList_.back());
2747 }
2748
GetSessionGlobalPosition(bool useUIExtension)2749 Vector2f SceneSession::GetSessionGlobalPosition(bool useUIExtension)
2750 {
2751 WSRect windowRect = GetSessionGlobalRect();
2752 if (useUIExtension) {
2753 if (auto modalUIExtensionEventInfo = GetLastModalUIExtensionEventInfo()) {
2754 const auto& rect = modalUIExtensionEventInfo.value().windowRect;
2755 windowRect.posX_ = rect.posX_;
2756 windowRect.posY_ = rect.posY_;
2757 }
2758 }
2759 Vector2f position(windowRect.posX_, windowRect.posY_);
2760 return position;
2761 }
2762
GetSessionGlobalRectWithSingleHandScale()2763 WSRect SceneSession::GetSessionGlobalRectWithSingleHandScale()
2764 {
2765 WSRect rectWithTransform = GetSessionGlobalRect();
2766 const SingleHandTransform& transform = GetSingleHandTransform();
2767 if (transform.posX == 0 && transform.posY == 0) {
2768 return rectWithTransform;
2769 }
2770 rectWithTransform.posX_ =
2771 static_cast<int32_t>(static_cast<float>(rectWithTransform.posX_) * transform.scaleX) + transform.posX;
2772 rectWithTransform.posY_ =
2773 static_cast<int32_t>(static_cast<float>(rectWithTransform.posY_) * transform.scaleY) + transform.posY;
2774 rectWithTransform.width_ =
2775 static_cast<int32_t>(static_cast<float>(rectWithTransform.width_) * transform.scaleX);
2776 rectWithTransform.height_ =
2777 static_cast<int32_t>(static_cast<float>(rectWithTransform.height_) * transform.scaleY);
2778 return rectWithTransform;
2779 }
2780
AddUIExtSurfaceNodeId(uint64_t surfaceNodeId,int32_t persistentId)2781 void SceneSession::AddUIExtSurfaceNodeId(uint64_t surfaceNodeId, int32_t persistentId)
2782 {
2783 std::unique_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
2784 TLOGI(WmsLogTag::WMS_UIEXT, "Add uiExtension pair surfaceNodeId=%{public}" PRIu64 ", persistentId=%{public}d",
2785 surfaceNodeId, persistentId);
2786 uiExtNodeIdToPersistentIdMap_.insert(std::make_pair(surfaceNodeId, persistentId));
2787 }
2788
RemoveUIExtSurfaceNodeId(int32_t persistentId)2789 void SceneSession::RemoveUIExtSurfaceNodeId(int32_t persistentId)
2790 {
2791 std::unique_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
2792 TLOGI(WmsLogTag::WMS_UIEXT, "Remove uiExtension by persistentId=%{public}d", persistentId);
2793 auto pairIter = std::find_if(uiExtNodeIdToPersistentIdMap_.begin(), uiExtNodeIdToPersistentIdMap_.end(),
2794 [persistentId](const auto& entry) { return entry.second == persistentId; });
2795 if (pairIter != uiExtNodeIdToPersistentIdMap_.end()) {
2796 TLOGI(WmsLogTag::WMS_UIEXT,
2797 "Successfully removed uiExtension pair surfaceNodeId=%{public}" PRIu64 ", persistentId=%{public}d",
2798 pairIter->first, persistentId);
2799 uiExtNodeIdToPersistentIdMap_.erase(pairIter);
2800 return;
2801 }
2802 TLOGE(WmsLogTag::WMS_UIEXT, "Failed to remove uiExtension by persistentId=%{public}d", persistentId);
2803 }
2804
GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const2805 int32_t SceneSession::GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const
2806 {
2807 std::shared_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
2808 auto ret = uiExtNodeIdToPersistentIdMap_.find(surfaceNodeId);
2809 if (ret == uiExtNodeIdToPersistentIdMap_.end()) {
2810 TLOGE(WmsLogTag::WMS_UIEXT, "Failed to find uiExtension by surfaceNodeId=%{public}" PRIu64 "", surfaceNodeId);
2811 return 0;
2812 }
2813 return ret->second;
2814 }
2815
GetAvoidAreaByTypeInner(AvoidAreaType type,const WSRect & rect)2816 AvoidArea SceneSession::GetAvoidAreaByTypeInner(AvoidAreaType type, const WSRect& rect)
2817 {
2818 if (!CheckGetAvoidAreaAvailable(type)) {
2819 return {};
2820 }
2821
2822 AvoidArea avoidArea;
2823 WSRect sessionRect = rect.IsEmpty() ? GetSessionRect() : rect;
2824 switch (type) {
2825 case AvoidAreaType::TYPE_SYSTEM: {
2826 GetSystemAvoidArea(sessionRect, avoidArea);
2827 return avoidArea;
2828 }
2829 case AvoidAreaType::TYPE_CUTOUT: {
2830 GetCutoutAvoidArea(sessionRect, avoidArea);
2831 return avoidArea;
2832 }
2833 case AvoidAreaType::TYPE_SYSTEM_GESTURE: {
2834 return avoidArea;
2835 }
2836 case AvoidAreaType::TYPE_KEYBOARD: {
2837 GetKeyboardAvoidArea(sessionRect, avoidArea);
2838 return avoidArea;
2839 }
2840 case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
2841 GetAINavigationBarArea(sessionRect, avoidArea);
2842 return avoidArea;
2843 }
2844 default: {
2845 TLOGE(WmsLogTag::WMS_IMMS, "cannot find win %{public}d type %{public}u",
2846 GetPersistentId(), type);
2847 return avoidArea;
2848 }
2849 }
2850 }
2851
GetAvoidAreaByType(AvoidAreaType type,const WSRect & rect,int32_t apiVersion)2852 AvoidArea SceneSession::GetAvoidAreaByType(AvoidAreaType type, const WSRect& rect, int32_t apiVersion)
2853 {
2854 return PostSyncTask([weakThis = wptr(this), type, rect, where = __func__]() -> AvoidArea {
2855 auto session = weakThis.promote();
2856 if (!session) {
2857 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
2858 return {};
2859 }
2860 return session->GetAvoidAreaByTypeInner(type, rect);
2861 }, __func__);
2862 }
2863
GetAllAvoidAreas(std::map<AvoidAreaType,AvoidArea> & avoidAreas)2864 WSError SceneSession::GetAllAvoidAreas(std::map<AvoidAreaType, AvoidArea>& avoidAreas)
2865 {
2866 return PostSyncTask([weakThis = wptr(this), &avoidAreas, where = __func__] {
2867 auto session = weakThis.promote();
2868 if (!session) {
2869 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
2870 return WSError::WS_ERROR_NULLPTR;
2871 }
2872
2873 using T = std::underlying_type_t<AvoidAreaType>;
2874 for (T avoidType = static_cast<T>(AvoidAreaType::TYPE_START);
2875 avoidType < static_cast<T>(AvoidAreaType::TYPE_END); avoidType++) {
2876 auto type = static_cast<AvoidAreaType>(avoidType);
2877 auto area = session->GetAvoidAreaByTypeInner(type);
2878 // code below aims to check if ai bar avoid area reaches window rect's bottom
2879 // it should not be removed until unexpected window rect update issues were solved
2880 if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
2881 if (session->isAINavigationBarAvoidAreaValid_ &&
2882 !session->isAINavigationBarAvoidAreaValid_(area, session->GetSessionRect().height_)) {
2883 continue;
2884 }
2885 }
2886 avoidAreas[type] = area;
2887 }
2888 return WSError::WS_OK;
2889 }, __func__);
2890 }
2891
GetAvoidAreasByRotation(Rotation rotation,const WSRect & rect,const std::map<WindowType,SystemBarProperty> & properties,std::map<AvoidAreaType,AvoidArea> & avoidAreas)2892 WSError SceneSession::GetAvoidAreasByRotation(Rotation rotation, const WSRect& rect,
2893 const std::map<WindowType, SystemBarProperty>& properties, std::map<AvoidAreaType, AvoidArea>& avoidAreas)
2894 {
2895 if (!WindowHelper::IsMainFullScreenWindow(GetWindowType(), GetWindowMode())) {
2896 TLOGI(WmsLogTag::WMS_IMMS, "window is no support, type %{public}d, mode %{public}d",
2897 GetWindowType(), GetWindowMode());
2898 return WSError::WS_DO_NOTHING;
2899 }
2900 return PostSyncTask([weakThis = wptr(this), rotation, &rect, &properties, &avoidAreas, where = __func__] {
2901 auto session = weakThis.promote();
2902 if (!session) {
2903 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
2904 return WSError::WS_ERROR_NULLPTR;
2905 }
2906 using T = std::underlying_type_t<AvoidAreaType>;
2907 for (T avoidType = static_cast<T>(AvoidAreaType::TYPE_START);
2908 avoidType < static_cast<T>(AvoidAreaType::TYPE_END); avoidType++) {
2909 auto type = static_cast<AvoidAreaType>(avoidType);
2910 avoidAreas[type] = session->GetAvoidAreaByRotation(rotation, rect, properties, type);
2911 }
2912 return WSError::WS_OK;
2913 }, __func__);
2914 }
2915
GetAvoidAreaByRotation(Rotation rotation,const WSRect & rect,const std::map<WindowType,SystemBarProperty> & properties,AvoidAreaType type)2916 AvoidArea SceneSession::GetAvoidAreaByRotation(Rotation rotation, const WSRect& rect,
2917 const std::map<WindowType, SystemBarProperty>& properties, AvoidAreaType type)
2918 {
2919 AvoidArea avoidArea;
2920 switch (type) {
2921 case AvoidAreaType::TYPE_SYSTEM:
2922 case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
2923 GetSystemBarAvoidAreaByRotation(rotation, type, rect, properties, avoidArea);
2924 break;
2925 }
2926 case AvoidAreaType::TYPE_CUTOUT: {
2927 GetCutoutAvoidAreaByRotation(rotation, rect, avoidArea);
2928 break;
2929 }
2930 case AvoidAreaType::TYPE_KEYBOARD: {
2931 GetKeyboardAvoidAreaByRotation(rotation, rect, avoidArea);
2932 break;
2933 }
2934 default: {
2935 TLOGE(WmsLogTag::WMS_IMMS, "cannot find win %{public}d type %{public}u", GetPersistentId(), type);
2936 break;
2937 }
2938 }
2939 return avoidArea;
2940 }
2941
GetSystemBarAvoidAreaByRotation(Rotation rotation,AvoidAreaType type,const WSRect & rect,const std::map<WindowType,SystemBarProperty> & properties,AvoidArea & avoidArea)2942 void SceneSession::GetSystemBarAvoidAreaByRotation(Rotation rotation, AvoidAreaType type, const WSRect& rect,
2943 const std::map<WindowType, SystemBarProperty>& properties, AvoidArea& avoidArea)
2944 {
2945 DisplayId displayId = GetSessionProperty()->GetDisplayId();
2946 std::pair<WSRect, WSRect> nextSystemBarAvoidAreaRectInfo;
2947 if (specificCallback_ == nullptr ||
2948 specificCallback_->onGetNextAvoidAreaRectInfo_(
2949 displayId, type, nextSystemBarAvoidAreaRectInfo) != WSError::WS_OK) {
2950 TLOGE(WmsLogTag::WMS_IMMS, "get nextSystemBarAvoidAreaRectInfo failed.");
2951 return;
2952 }
2953 WindowType winType = (type == AvoidAreaType::TYPE_SYSTEM) ? WindowType::WINDOW_TYPE_STATUS_BAR :
2954 WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR;
2955 if (auto iter = properties.find(winType); iter == properties.end()) {
2956 TLOGE(WmsLogTag::WMS_IMMS, "win [%{public}d] properties is empty, type %{public}d", GetPersistentId(), type);
2957 return;
2958 }
2959 bool isStatusBarAvoidAreaEmpty = winType == WindowType::WINDOW_TYPE_STATUS_BAR &&
2960 (rotation == Rotation::ROTATION_90 || rotation == Rotation::ROTATION_270) &&
2961 !(static_cast<bool>(static_cast<uint32_t>(properties.at(winType).settingFlag_) &
2962 static_cast<uint32_t>(SystemBarSettingFlag::ENABLE_SETTING)));
2963 if (!properties.at(winType).enable_ || isStatusBarAvoidAreaEmpty) {
2964 TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}d] avoid area is empty, type %{public}d", GetPersistentId(), type);
2965 return;
2966 }
2967 WSRect avoidRect = (rotation == Rotation::ROTATION_0 || rotation == Rotation::ROTATION_180) ?
2968 nextSystemBarAvoidAreaRectInfo.first : nextSystemBarAvoidAreaRectInfo.second;
2969 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d tyep %{public}d rect %{public}s bar %{public}s",
2970 GetPersistentId(), type, rect.ToString().c_str(), avoidRect.ToString().c_str());
2971 CalculateAvoidAreaRect(rect, avoidRect, avoidArea);
2972 }
2973
GetCutoutAvoidAreaByRotation(Rotation rotation,const WSRect & rect,AvoidArea & avoidArea)2974 void SceneSession::GetCutoutAvoidAreaByRotation(Rotation rotation, const WSRect& rect, AvoidArea& avoidArea)
2975 {
2976 auto cutoutInfo = DisplayManager::GetInstance().GetCutoutInfoWithRotation(rotation);
2977 if (cutoutInfo == nullptr) {
2978 TLOGI(WmsLogTag::WMS_IMMS, "There is no cutout info");
2979 return;
2980 }
2981 std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
2982 if (cutoutAreas.empty()) {
2983 TLOGI(WmsLogTag::WMS_IMMS, "There is no cutout area");
2984 return;
2985 }
2986 for (auto& cutoutArea : cutoutAreas) {
2987 WSRect cutoutAreaRect = {
2988 cutoutArea.posX_,
2989 cutoutArea.posY_,
2990 cutoutArea.width_,
2991 cutoutArea.height_
2992 };
2993 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}s cutout %{public}s",
2994 rect.ToString().c_str(), cutoutAreaRect.ToString().c_str());
2995 CalculateAvoidAreaRect(rect, cutoutAreaRect, avoidArea);
2996 }
2997 }
2998
GetKeyboardAvoidAreaByRotation(Rotation rotation,const WSRect & rect,AvoidArea & avoidArea)2999 void SceneSession::GetKeyboardAvoidAreaByRotation(Rotation rotation, const WSRect& rect, AvoidArea& avoidArea)
3000 {
3001 std::vector<std::pair<bool, WSRect>> avoidInfoVector;
3002 GetKeyboardOccupiedAreaWithRotation(GetPersistentId(), rotation, avoidInfoVector);
3003 for (auto avoidInfo : avoidInfoVector) {
3004 if (!avoidInfo.first) {
3005 TLOGI(WmsLogTag::WMS_IMMS, "keyboard avoid area is empty id: %{public}d", GetPersistentId());
3006 continue;
3007 }
3008 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}s keyboard %{public}s",
3009 rect.ToString().c_str(), avoidInfo.second.ToString().c_str());
3010 CalculateAvoidAreaRect(rect, avoidInfo.second, avoidArea);
3011 }
3012 }
3013
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)3014 WSError SceneSession::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
3015 {
3016 if (!sessionStage_) {
3017 return WSError::WS_ERROR_NULLPTR;
3018 }
3019 if (!GetForegroundInteractiveStatus()) {
3020 TLOGD(WmsLogTag::WMS_IMMS, "win [%{public}d] avoid area update rejected by recent", GetPersistentId());
3021 return WSError::WS_DO_NOTHING;
3022 }
3023 return sessionStage_->UpdateAvoidArea(avoidArea, type);
3024 }
3025
SetPipActionEvent(const std::string & action,int32_t status)3026 WSError SceneSession::SetPipActionEvent(const std::string& action, int32_t status)
3027 {
3028 TLOGI(WmsLogTag::WMS_PIP, "action: %{public}s, status: %{public}d", action.c_str(), status);
3029 if (!sessionStage_) {
3030 return WSError::WS_ERROR_NULLPTR;
3031 }
3032 return sessionStage_->SetPipActionEvent(action, status);
3033 }
3034
SetPiPControlEvent(WsPiPControlType controlType,WsPiPControlStatus status)3035 WSError SceneSession::SetPiPControlEvent(WsPiPControlType controlType, WsPiPControlStatus status)
3036 {
3037 TLOGI(WmsLogTag::WMS_PIP, "controlType: %{public}u, status: %{public}u", controlType, status);
3038 if (GetWindowType() != WindowType::WINDOW_TYPE_PIP || GetWindowMode() != WindowMode::WINDOW_MODE_PIP) {
3039 return WSError::WS_ERROR_INVALID_TYPE;
3040 }
3041 if (!sessionStage_) {
3042 return WSError::WS_ERROR_NULLPTR;
3043 }
3044 return sessionStage_->SetPiPControlEvent(controlType, status);
3045 }
3046
NotifyPipWindowSizeChange(double width,double height,double scale)3047 WSError SceneSession::NotifyPipWindowSizeChange(double width, double height, double scale)
3048 {
3049 TLOGI(WmsLogTag::WMS_PIP, "width: %{public}f, height: %{public}f scale: %{public}f", width, height, scale);
3050 if (!sessionStage_) {
3051 return WSError::WS_ERROR_NULLPTR;
3052 }
3053 return sessionStage_->NotifyPipWindowSizeChange(width, height, scale);
3054 }
3055
RegisterProcessPrepareClosePiPCallback(NotifyPrepareClosePiPSessionFunc && callback)3056 void SceneSession::RegisterProcessPrepareClosePiPCallback(NotifyPrepareClosePiPSessionFunc&& callback)
3057 {
3058 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
3059 auto session = weakThis.promote();
3060 if (!session) {
3061 TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
3062 return;
3063 }
3064 session->onPrepareClosePiPSession_ = std::move(callback);
3065 }, __func__);
3066 }
3067
ProcessPointDownSession(int32_t posX,int32_t posY)3068 WSError SceneSession::ProcessPointDownSession(int32_t posX, int32_t posY)
3069 {
3070 const auto& id = GetPersistentId();
3071 TLOGD(WmsLogTag::WMS_INPUT_KEY_FLOW, "id:%{public}d, type:%{public}d", id, GetWindowType());
3072
3073 if (static_cast<MMI::WindowInputType>(GetSessionInfo().windowInputType_) == MMI::WindowInputType::TRANSMIT_ALL) {
3074 TLOGD(WmsLogTag::WMS_INPUT_KEY_FLOW, "Cancel the double_send mechanism window response touchoutside.");
3075 return WSError::WS_ERROR_INVALID_TYPE;
3076 }
3077
3078 // notify touch outside
3079 if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ &&
3080 sessionInfo_.bundleName_.find("SCBGestureBack") == std::string::npos) {
3081 specificCallback_->onSessionTouchOutside_(id, GetDisplayId());
3082 }
3083
3084 // notify outside down event
3085 if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
3086 specificCallback_->onOutsideDownEvent_(posX, posY);
3087 }
3088 return WSError::WS_OK;
3089 }
3090
SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool isExecuteDelayRaise)3091 WSError SceneSession::SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
3092 bool isExecuteDelayRaise)
3093 {
3094 NotifyOutsideDownEvent(pointerEvent);
3095 TransferPointerEvent(pointerEvent, false, isExecuteDelayRaise);
3096 return WSError::WS_OK;
3097 }
3098
SendPointerEventForHover(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3099 WSError SceneSession::SendPointerEventForHover(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3100 {
3101 if (!IsSystemSession() && !IsSessionValid()) {
3102 return WSError::WS_ERROR_INVALID_SESSION;
3103 }
3104 HandlePointerEventForFocus(pointerEvent, false);
3105 return WSError::WS_OK;
3106 }
3107
NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3108 void SceneSession::NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3109 {
3110 // notify touchOutside and touchDown event
3111 if (static_cast<MMI::WindowInputType>(GetSessionInfo().windowInputType_) == MMI::WindowInputType::TRANSMIT_ALL) {
3112 TLOGD(WmsLogTag::WMS_INPUT_KEY_FLOW, "Cancel the double_send mechanism window response touchoutside.");
3113 return;
3114 }
3115
3116 int32_t action = pointerEvent->GetPointerAction();
3117 if (action != MMI::PointerEvent::POINTER_ACTION_DOWN &&
3118 action != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
3119 return;
3120 }
3121
3122 MMI::PointerEvent::PointerItem pointerItem;
3123 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
3124 return;
3125 }
3126
3127 // notify touch outside
3128 if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ &&
3129 sessionInfo_.bundleName_.find("SCBGestureBack") == std::string::npos) {
3130 specificCallback_->onSessionTouchOutside_(GetPersistentId(), GetDisplayId());
3131 }
3132
3133 // notify outside down event
3134 if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
3135 specificCallback_->onOutsideDownEvent_(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
3136 }
3137 }
3138
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool needNotifyClient,bool isExecuteDelayRaise)3139 WSError SceneSession::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
3140 bool needNotifyClient, bool isExecuteDelayRaise)
3141 {
3142 PostTask([weakThis = wptr(this), pointerEvent, needNotifyClient, isExecuteDelayRaise, where = __func__] {
3143 auto session = weakThis.promote();
3144 if (!session) {
3145 TLOGNE(WmsLogTag::DEFAULT, "%{public}s session is null", where);
3146 return WSError::WS_ERROR_DESTROYED_OBJECT;
3147 }
3148 return session->TransferPointerEventInner(pointerEvent, needNotifyClient, isExecuteDelayRaise);
3149 }, __func__);
3150 return WSError::WS_OK;
3151 }
3152
TransferPointerEventInner(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool needNotifyClient,bool isExecuteDelayRaise)3153 WSError SceneSession::TransferPointerEventInner(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
3154 bool needNotifyClient, bool isExecuteDelayRaise)
3155 {
3156 WLOGFD("[WMSCom] TransferPointEvent, id: %{public}d, type: %{public}d, needNotifyClient: %{public}d",
3157 GetPersistentId(), GetWindowType(), needNotifyClient);
3158 if (pointerEvent == nullptr) {
3159 WLOGFE("pointerEvent is null");
3160 return WSError::WS_ERROR_NULLPTR;
3161 }
3162
3163 int32_t action = pointerEvent->GetPointerAction();
3164
3165 if (!CheckPointerEventDispatch(pointerEvent)) {
3166 WLOGFI("Do not dispatch this pointer event");
3167 return WSError::WS_DO_NOTHING;
3168 }
3169
3170 bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
3171 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
3172
3173 auto property = GetSessionProperty();
3174 if (property == nullptr) {
3175 return Session::TransferPointerEvent(pointerEvent, needNotifyClient, isExecuteDelayRaise);
3176 }
3177 auto windowType = property->GetWindowType();
3178 bool isMovableWindowType = IsMovableWindowType();
3179 bool isMainWindow = WindowHelper::IsMainWindow(windowType);
3180 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
3181 bool isDialog = WindowHelper::IsDialogWindow(windowType);
3182 bool isMaxModeAvoidSysBar = property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR;
3183 bool isDragAccessibleSystemWindow = WindowHelper::IsSystemWindow(windowType) && IsDragAccessible() &&
3184 !isDialog;
3185 bool isMovableSystemWindow = WindowHelper::IsSystemWindow(windowType) && !isDialog;
3186 TLOGD(WmsLogTag::WMS_EVENT, "%{public}s: %{public}d && %{public}d", property->GetWindowName().c_str(),
3187 WindowHelper::IsSystemWindow(windowType), IsDragAccessible());
3188 if (isMovableWindowType && !isMaxModeAvoidSysBar &&
3189 (isMainWindow || isSubWindow || isDialog || isDragAccessibleSystemWindow || isMovableSystemWindow)) {
3190 if (CheckDialogOnForeground() && isPointDown) {
3191 HandlePointDownDialog();
3192 pointerEvent->MarkProcessed();
3193 TLOGI(WmsLogTag::WMS_DIALOG, "There is dialog window foreground");
3194 return WSError::WS_OK;
3195 }
3196 if (!moveDragController_) {
3197 TLOGD(WmsLogTag::WMS_LAYOUT, "moveDragController_ is null");
3198 return Session::TransferPointerEvent(pointerEvent, needNotifyClient, isExecuteDelayRaise);
3199 }
3200 moveDragController_->SetScale(GetScaleX(), GetScaleY()); // need scale ratio to calculate translate
3201 SetParentRect();
3202 if (IsDraggable() &&
3203 moveDragController_->ConsumeDragEvent(pointerEvent, GetGlobalOrWinRect(), property, systemConfig_)) {
3204 auto surfaceNode = GetSurfaceNode();
3205 moveDragController_->UpdateGravityWhenDrag(pointerEvent, surfaceNode);
3206 PresentFocusIfNeed(pointerEvent->GetPointerAction());
3207 pointerEvent->MarkProcessed();
3208 return WSError::WS_OK;
3209 }
3210 if ((WindowHelper::IsMainWindow(windowType) ||
3211 WindowHelper::IsSubWindow(windowType) ||
3212 WindowHelper::IsSystemWindow(windowType)) && !isFollowParentLayout_ &&
3213 moveDragController_->ConsumeMoveEvent(pointerEvent, GetSessionRect())) {
3214 PresentFocusIfNeed(pointerEvent->GetPointerAction());
3215 pointerEvent->MarkProcessed();
3216 Session::TransferPointerEvent(pointerEvent, needNotifyClient, isExecuteDelayRaise);
3217 ProcessWindowMoving(pointerEvent);
3218 return WSError::WS_OK;
3219 }
3220 }
3221 return Session::TransferPointerEvent(pointerEvent, needNotifyClient, isExecuteDelayRaise);
3222 }
3223
NotifyUpdateGravity()3224 void SceneSession::NotifyUpdateGravity()
3225 {
3226 std::unordered_map<int32_t, NotifySurfaceBoundsChangeFunc> funcMap;
3227 {
3228 std::lock_guard lock(registerNotifySurfaceBoundsChangeMutex_);
3229 funcMap = notifySurfaceBoundsChangeFuncMap_;
3230 }
3231 for (const auto& [sessionId, _] : funcMap) {
3232 auto subSession = GetSceneSessionById(sessionId);
3233 if (!subSession || !subSession->GetIsFollowParentLayout()) {
3234 return;
3235 }
3236 auto surfaceNode = subSession->GetSurfaceNode();
3237 auto subController = subSession->GetMoveDragController();
3238 if (subController && surfaceNode) {
3239 subController->UpdateSubWindowGravityWhenFollow(moveDragController_, surfaceNode);
3240 }
3241 }
3242 }
3243
ProcessWindowMoving(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3244 void SceneSession::ProcessWindowMoving(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3245 {
3246 if (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_MOVE) {
3247 return;
3248 }
3249 MMI::PointerEvent::PointerItem pointerItem;
3250 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
3251 return;
3252 }
3253 if (notifyWindowMovingFunc_) {
3254 notifyWindowMovingFunc_(static_cast<DisplayId>(pointerEvent->GetTargetDisplayId()),
3255 pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
3256 }
3257 }
3258
SetWindowMovingCallback(NotifyWindowMovingFunc && func)3259 void SceneSession::SetWindowMovingCallback(NotifyWindowMovingFunc&& func)
3260 {
3261 PostTask([weakThis = wptr(this), where = __func__, func = std::move(func)] {
3262 auto session = weakThis.promote();
3263 if (!session || !func) {
3264 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session or func is null", where);
3265 return;
3266 }
3267 session->notifyWindowMovingFunc_ = std::move(func);
3268 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where,
3269 session->GetPersistentId());
3270 }, __func__);
3271 }
3272
SetTransitionAnimationCallback(UpdateTransitionAnimationFunc && func)3273 void SceneSession::SetTransitionAnimationCallback(UpdateTransitionAnimationFunc&& func)
3274 {
3275 PostTask([weakThis = wptr(this), where = __func__, func = std::move(func)] {
3276 auto session = weakThis.promote();
3277 if (!session || !func) {
3278 TLOGNE(WmsLogTag::WMS_ANIMATION, "%{public}s: session or func is null", where);
3279 return;
3280 }
3281 session->updateTransitionAnimationFunc_ = std::move(func);
3282 TLOGNI(WmsLogTag::WMS_ANIMATION, "%{public}s id: %{public}d", where, session->GetPersistentId());
3283 }, __func__);
3284 }
3285
IsMovableWindowType() const3286 bool SceneSession::IsMovableWindowType() const
3287 {
3288 auto property = GetSessionProperty();
3289 if (property == nullptr) {
3290 TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
3291 return false;
3292 }
3293
3294 return property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ||
3295 property->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
3296 property->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
3297 IsFullScreenMovable();
3298 }
3299
IsFullScreenMovable() const3300 bool SceneSession::IsFullScreenMovable() const
3301 {
3302 auto property = GetSessionProperty();
3303 if (property == nullptr) {
3304 TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
3305 return false;
3306 }
3307 return property->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
3308 WindowHelper::IsWindowModeSupported(property->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING);
3309 }
3310
IsMovable() const3311 bool SceneSession::IsMovable() const
3312 {
3313 if (!moveDragController_) {
3314 TLOGW(WmsLogTag::WMS_LAYOUT, "moveDragController_ is null, id: %{public}d", GetPersistentId());
3315 return false;
3316 }
3317
3318 bool windowIsMovable = !moveDragController_->GetStartDragFlag() && IsMovableWindowType() &&
3319 moveDragController_->HasPointDown() && moveDragController_->GetMovable() &&
3320 !GetWindowAnchorInfo().isAnchorEnabled_;
3321 auto property = GetSessionProperty();
3322 if (property->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR &&
3323 property->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3324 windowIsMovable = windowIsMovable && IsFocused();
3325 }
3326 if (!windowIsMovable) {
3327 TLOGW(WmsLogTag::WMS_LAYOUT, "Window is not movable, id: %{public}d, startDragFlag: %{public}d, "
3328 "isFocused: %{public}d, movableWindowType: %{public}d, hasPointDown: %{public}d, movable: %{public}d",
3329 GetPersistentId(), moveDragController_->GetStartDragFlag(), IsFocused(), IsMovableWindowType(),
3330 moveDragController_->HasPointDown(), moveDragController_->GetMovable());
3331 return false;
3332 }
3333 return true;
3334 }
3335
IsDraggable() const3336 bool SceneSession::IsDraggable() const
3337 {
3338 if (!moveDragController_) {
3339 TLOGD(WmsLogTag::WMS_LAYOUT, "moveDragController is null, id:%{public}d", GetPersistentId());
3340 return false;
3341 }
3342 auto windowType = GetWindowType();
3343 bool isMainWindow = WindowHelper::IsMainWindow(windowType);
3344 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
3345 bool isSystemWindow = WindowHelper::IsSystemWindow(windowType);
3346 bool isDialog = WindowHelper::IsDialogWindow(windowType);
3347 bool isDragAccessibleSystemWindow = isSystemWindow && IsDragAccessible() && !isDialog;
3348 bool isFloatingDragAccessible = GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && IsDragAccessible();
3349
3350 bool isPcOrFreeMultiWindowCanDrag = (isFloatingDragAccessible || isDragAccessibleSystemWindow) &&
3351 (systemConfig_.IsPcWindow() || IsFreeMultiWindowMode() ||
3352 (GetSessionProperty()->GetIsPcAppInPad() && !isMainWindow));
3353 bool isPhoneWindowCanDrag = isFloatingDragAccessible && (isSystemWindow || isSubWindow) &&
3354 (systemConfig_.IsPhoneWindow() || (systemConfig_.IsPadWindow() && !IsFreeMultiWindowMode()));
3355 return isPcOrFreeMultiWindowCanDrag || isPhoneWindowCanDrag;
3356 }
3357
RequestSessionBack(bool needMoveToBackground)3358 WSError SceneSession::RequestSessionBack(bool needMoveToBackground)
3359 {
3360 PostTask([weakThis = wptr(this), needMoveToBackground, where = __func__] {
3361 auto session = weakThis.promote();
3362 if (!session) {
3363 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
3364 return WSError::WS_ERROR_DESTROYED_OBJECT;
3365 }
3366 if (!session->backPressedFunc_) {
3367 TLOGNW(WmsLogTag::WMS_EVENT, "%{public}s Session didn't register back event consumer!", where);
3368 return WSError::WS_DO_NOTHING;
3369 }
3370 if (g_enableForceUIFirst) {
3371 AutoRSTransaction trans(session->GetRSUIContext());
3372 auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
3373 if (leashWinSurfaceNode) {
3374 leashWinSurfaceNode->SetForceUIFirst(true);
3375 session->isUIFirstEnabled_ = true;
3376 TLOGNI(WmsLogTag::WMS_EVENT, "%{public}s leashWinSurfaceNode_ SetForceUIFirst id:%{public}u!",
3377 where, session->GetPersistentId());
3378 } else {
3379 TLOGNI(WmsLogTag::WMS_EVENT, "%{public}s failed, leashWinSurfaceNode_ null id:%{public}u",
3380 where, session->GetPersistentId());
3381 }
3382 }
3383 session->backPressedFunc_(needMoveToBackground);
3384 return WSError::WS_OK;
3385 }, std::string(__func__) + ":" + std::to_string(needMoveToBackground));
3386 return WSError::WS_OK;
3387 }
3388
3389 #ifdef DEVICE_STATUS_ENABLE
RotateDragWindow(std::shared_ptr<RSTransaction> rsTransaction)3390 void SceneSession::RotateDragWindow(std::shared_ptr<RSTransaction> rsTransaction)
3391 {
3392 Msdp::DeviceStatus::DragState state = Msdp::DeviceStatus::DragState::STOP;
3393 Msdp::DeviceStatus::InteractionManager::GetInstance()->GetDragState(state);
3394 if (state == Msdp::DeviceStatus::DragState::START) {
3395 Msdp::DeviceStatus::InteractionManager::GetInstance()->RotateDragWindowSync(rsTransaction);
3396 }
3397 }
3398 #endif // DEVICE_STATUS_ENABLE
3399
3400 /** @note @window.layout */
NotifySessionRectChange(const WSRect & rect,SizeChangeReason reason,DisplayId displayId,const RectAnimationConfig & rectAnimationConfig)3401 void SceneSession::NotifySessionRectChange(const WSRect& rect,
3402 SizeChangeReason reason, DisplayId displayId, const RectAnimationConfig& rectAnimationConfig)
3403 {
3404 if (IsDragResizeScale(reason)) {
3405 TLOGE(WmsLogTag::WMS_COMPAT, "compatiblemode drag scale no need notify rect change");
3406 return;
3407 }
3408 PostTask([weakThis = wptr(this), rect, reason, displayId, rectAnimationConfig, where = __func__] {
3409 auto session = weakThis.promote();
3410 if (!session) {
3411 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
3412 return;
3413 }
3414 if (session->sessionRectChangeFunc_) {
3415 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::NotifySessionRectChange");
3416 session->sessionRectChangeFunc_(rect, reason, displayId, rectAnimationConfig);
3417 }
3418 }, __func__ + GetRectInfo(rect));
3419 }
3420
3421 /** @note @window.layout */
NotifySessionDisplayIdChange(uint64_t displayId)3422 void SceneSession::NotifySessionDisplayIdChange(uint64_t displayId)
3423 {
3424 PostTask([weakThis = wptr(this), displayId] {
3425 auto session = weakThis.promote();
3426 if (!session) {
3427 TLOGNE(WmsLogTag::WMS_LAYOUT, "session is null");
3428 return;
3429 }
3430 if (session->sessionDisplayIdChangeFunc_) {
3431 session->sessionDisplayIdChangeFunc_(displayId);
3432 }
3433 }, __func__);
3434 }
3435
CheckSubSessionShouldFollowParent(uint64_t displayId)3436 void SceneSession::CheckSubSessionShouldFollowParent(uint64_t displayId)
3437 {
3438 for (const auto& session : subSession_) {
3439 if (session && session->IsSessionForeground() && session->GetSessionProperty()->GetDisplayId() != displayId) {
3440 session->SetShouldFollowParentWhenShow(false);
3441 }
3442 }
3443 }
3444
IsDecorEnable() const3445 bool SceneSession::IsDecorEnable() const
3446 {
3447 auto property = GetSessionProperty();
3448 if (property == nullptr) {
3449 WLOGE("property is nullptr");
3450 return false;
3451 }
3452 auto windowType = property->GetWindowType();
3453 bool isMainWindow = WindowHelper::IsMainWindow(windowType);
3454 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
3455 bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
3456 bool isValidWindow = isMainWindow ||
3457 ((isSubWindow || isDialogWindow) && property->IsDecorEnable());
3458 bool isWindowModeSupported = WindowHelper::IsWindowModeSupported(
3459 systemConfig_.decorWindowModeSupportType_, property->GetWindowMode());
3460 bool enable = isValidWindow && systemConfig_.isSystemDecorEnable_ && isWindowModeSupported;
3461 return enable;
3462 }
3463
GetRatioPreferenceKey()3464 std::string SceneSession::GetRatioPreferenceKey()
3465 {
3466 std::string key = sessionInfo_.bundleName_ + sessionInfo_.moduleName_ + sessionInfo_.abilityName_;
3467 if (key.length() > ScenePersistentStorage::MAX_KEY_LEN) {
3468 return key.substr(key.length() - ScenePersistentStorage::MAX_KEY_LEN);
3469 }
3470 return key;
3471 }
3472
SaveAspectRatio(float ratio)3473 bool SceneSession::SaveAspectRatio(float ratio)
3474 {
3475 std::string key = GetRatioPreferenceKey();
3476 if (!key.empty()) {
3477 ScenePersistentStorage::Insert(key, ratio, ScenePersistentStorageType::ASPECT_RATIO);
3478 WLOGD("SceneSession save aspectRatio , key %{public}s, value: %{public}f", key.c_str(), GetAspectRatio());
3479 return true;
3480 }
3481 return false;
3482 }
3483
SetMoveDragCallback()3484 void SceneSession::SetMoveDragCallback()
3485 {
3486 if (moveDragController_) {
3487 MoveDragCallback callBack = [this](SizeChangeReason reason) {
3488 this->OnMoveDragCallback(reason);
3489 };
3490 moveDragController_->RegisterMoveDragCallback(callBack);
3491 }
3492 }
3493
3494 /** @note @window.drag */
InitializeCrossMoveDrag()3495 void SceneSession::InitializeCrossMoveDrag()
3496 {
3497 auto movedSurfaceNode = GetSurfaceNodeForMoveDrag();
3498 if (!movedSurfaceNode) {
3499 return;
3500 }
3501 auto parentNode = movedSurfaceNode->GetParent();
3502 if (!parentNode) {
3503 return;
3504 }
3505 auto property = GetSessionProperty();
3506 if (!property) {
3507 return;
3508 }
3509 auto originalPositionZ = movedSurfaceNode->GetStagingProperties().GetPositionZ();
3510 moveDragController_->SetOriginalPositionZ(originalPositionZ);
3511 moveDragController_->InitCrossDisplayProperty(property->GetDisplayId(), parentNode->GetId());
3512 }
3513
3514 /** @note @window.drag */
HandleMoveDragSurfaceBounds(WSRect & rect,WSRect & globalRect,SizeChangeReason reason)3515 void SceneSession::HandleMoveDragSurfaceBounds(WSRect& rect, WSRect& globalRect, SizeChangeReason reason)
3516 {
3517 bool isGlobal = (reason != SizeChangeReason::DRAG_END);
3518 bool needFlush = (reason != SizeChangeReason::DRAG_END);
3519 bool needSetBoundsNextVsync = false;
3520 throwSlipToFullScreenAnimCount_.store(0);
3521 UpdateSizeChangeReason(reason);
3522 if (moveDragController_ && moveDragController_->GetPointerType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN &&
3523 pcFoldScreenController_ && pcFoldScreenController_->IsAllowThrowSlip(GetScreenId()) &&
3524 (reason == SizeChangeReason::DRAG_MOVE || reason == SizeChangeReason::DRAG_END)) {
3525 if (pcFoldScreenController_->NeedFollowHandAnimation()) {
3526 auto movingPair = std::make_pair(pcFoldScreenController_->GetMovingTimingProtocol(),
3527 pcFoldScreenController_->GetMovingTimingCurve());
3528 SetSurfaceBoundsWithAnimation(movingPair, globalRect, nullptr, isGlobal);
3529 } else if (reason != SizeChangeReason::DRAG_START) {
3530 SetSurfaceBounds(globalRect, isGlobal, needFlush);
3531 }
3532 pcFoldScreenController_->RecordMoveRects(rect);
3533 } else {
3534 if (reason != SizeChangeReason::DRAG || keyFramePolicy_.running_) {
3535 SetSurfaceBounds(globalRect, isGlobal, needFlush);
3536 } else {
3537 needSetBoundsNextVsync = true;
3538 }
3539 }
3540 if (reason != SizeChangeReason::DRAG_MOVE && !KeyFrameNotifyFilter(rect, reason)) {
3541 UpdateRectForDrag(rect);
3542 std::shared_ptr<VsyncCallback> nextVsyncDragCallback = std::make_shared<VsyncCallback>();
3543 nextVsyncDragCallback->onCallback = [weakThis = wptr(this),
3544 globalRect, isGlobal, needFlush, needSetBoundsNextVsync, where = __func__](int64_t, int64_t) {
3545 auto session = weakThis.promote();
3546 if (!session) {
3547 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
3548 return;
3549 }
3550 session->OnNextVsyncReceivedWhenDrag(globalRect, isGlobal, needFlush, needSetBoundsNextVsync);
3551 };
3552 if (requestNextVsyncFunc_) {
3553 requestNextVsyncFunc_(nextVsyncDragCallback);
3554 } else {
3555 TLOGNE(WmsLogTag::WMS_LAYOUT, "Func is null, could not request vsync");
3556 }
3557 }
3558 }
3559
OnNextVsyncReceivedWhenDrag(const WSRect & globalRect,bool isGlobal,bool needFlush,bool needSetBoundsNextVsync)3560 void SceneSession::OnNextVsyncReceivedWhenDrag(const WSRect& globalRect,
3561 bool isGlobal, bool needFlush, bool needSetBoundsNextVsync)
3562 {
3563 PostTask([weakThis = wptr(this), globalRect, isGlobal, needFlush, needSetBoundsNextVsync, where = __func__] {
3564 auto session = weakThis.promote();
3565 if (!session) {
3566 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
3567 return;
3568 }
3569 if (session->IsDirtyDragWindow()) {
3570 WSRect winRect = session->GetSessionRect();
3571 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
3572 "SceneSession::OnNextVsyncReceivedWhenDrag id:%d [%d, %d, %d, %d] reason:%u",
3573 session->GetPersistentId(), winRect.posX_, winRect.posY_,
3574 winRect.width_, winRect.height_, session->GetSizeChangeReason());
3575 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}u, winRect:%{public}s",
3576 where, session->GetPersistentId(), winRect.ToString().c_str());
3577 session->NotifyClientToUpdateRect("OnMoveDragCallback", nullptr);
3578 if (!session->moveDragController_) {
3579 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session moveDragController is null", where);
3580 } else if (needSetBoundsNextVsync && session->moveDragController_->GetStartDragFlag()) {
3581 session->SetSurfaceBounds(globalRect, isGlobal, needFlush);
3582 }
3583 session->ResetDirtyDragFlags();
3584 }
3585 });
3586 }
3587
3588 /** @note @window.drag */
HandleMoveDragEnd(WSRect & rect,SizeChangeReason reason)3589 void SceneSession::HandleMoveDragEnd(WSRect& rect, SizeChangeReason reason)
3590 {
3591 if (GetOriPosYBeforeRaisedByKeyboard() != 0) {
3592 TLOGI(WmsLogTag::WMS_KEYBOARD, "Calling session is moved and reset oriPosYBeforeRaisedByKeyboard");
3593 SetOriPosYBeforeRaisedByKeyboard(0);
3594 }
3595 if (moveDragController_->GetPointerType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN &&
3596 MoveUnderInteriaAndNotifyRectChange(rect, reason)) {
3597 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "set full screen after throw slip");
3598 }
3599
3600 uint64_t endDisplayId = moveDragController_->GetMoveDragEndDisplayId();
3601 if ((endDisplayId == moveDragController_->GetMoveDragStartDisplayId() ||
3602 !moveDragController_->IsSupportWindowDragCrossDisplay()) && !WindowHelper::IsInputWindow(GetWindowType())) {
3603 NotifySessionRectChange(rect, reason);
3604 NotifySubSessionRectChangeByAnchor(rect, SizeChangeReason::UNDEFINED);
3605 } else {
3606 NotifySessionRectChange(rect, reason, endDisplayId);
3607 NotifySubSessionRectChangeByAnchor(rect, SizeChangeReason::UNDEFINED, endDisplayId);
3608 CheckSubSessionShouldFollowParent(endDisplayId);
3609 }
3610 moveDragController_->SetLastDragEndRect(rect);
3611 moveDragController_->ResetCrossMoveDragProperty();
3612 OnSessionEvent(SessionEvent::EVENT_END_MOVE);
3613 }
3614
3615 /**
3616 * the window is transformed according to the scale ratio
3617 */
WindowScaleTransfer(WSRect & rect,float scaleX,float scaleY)3618 void SceneSession::WindowScaleTransfer(WSRect& rect, float scaleX, float scaleY)
3619 {
3620 const float HALF = 0.5f;
3621 auto curWidth = rect.width_;
3622 auto curHeight = rect.height_;
3623 rect.width_ = static_cast<int32_t>(curWidth * scaleX);
3624 rect.height_ = static_cast<int32_t>(curHeight * scaleY);
3625 auto widthDifference = static_cast<int32_t>((curWidth - rect.width_) * HALF);
3626 auto heightDifference = static_cast<int32_t>((curHeight - rect.height_) * HALF);
3627 rect.posX_ = rect.posX_ + widthDifference;
3628 rect.posY_ = rect.posY_ + heightDifference;
3629 TLOGI(WmsLogTag::WMS_LAYOUT, "scaleX: %{public}f, scaleY: %{public}f, sizeDifference: [%{public}d, "
3630 "%{public}d], rect: %{public}s", scaleX, scaleY, widthDifference, heightDifference, rect.ToString().c_str());
3631 }
3632
3633 /**
3634 * hook startMoveRect with showRect
3635 */
HookStartMoveRect(WSRect & newRect,const WSRect & sessionRect)3636 void SceneSession::HookStartMoveRect(WSRect& newRect, const WSRect& sessionRect)
3637 {
3638 newRect = sessionRect;
3639 if (!WindowHelper::IsMainWindow(GetWindowType())) {
3640 TLOGD(WmsLogTag::WMS_LAYOUT, "is not mainWindow");
3641 return;
3642 }
3643 auto scaleX = GetScaleX();
3644 auto scaleY = GetScaleY();
3645 if (IsCompatibilityModeScale(scaleX, scaleY)) {
3646 WindowScaleTransfer(newRect, scaleX, scaleY);
3647 }
3648 }
3649
3650 /**
3651 * check compatible mode application that includes scale ratio
3652 * @return true: compatible mode application with scale ratio
3653 */
IsCompatibilityModeScale(float scaleX,float scaleY)3654 bool SceneSession::IsCompatibilityModeScale(float scaleX, float scaleY)
3655 {
3656 auto property = GetSessionProperty();
3657 if (property->IsAdaptToProportionalScale() && MathHelper::GreatNotEqual(scaleX, 0.0f) &&
3658 MathHelper::GreatNotEqual(scaleY, 0.0f) && (!NearEqual(scaleX, 1.0f) || !NearEqual(scaleY, 1.0f))) {
3659 return true;
3660 }
3661 return false;
3662 }
3663
IsInCompatScaleStatus() const3664 bool SceneSession::IsInCompatScaleStatus() const
3665 {
3666 auto property = GetSessionProperty();
3667 if (property->IsAdaptToProportionalScale() || property->IsAdaptToSimulationScale()) {
3668 return !NearEqual(GetScaleX(), COMPACT_NORMAL_SCALE) || !NearEqual(GetScaleY(), COMPACT_NORMAL_SCALE);
3669 }
3670 return false;
3671 }
3672
IsInCompatScaleMode() const3673 bool SceneSession::IsInCompatScaleMode() const
3674 {
3675 auto property = GetSessionProperty();
3676 return property->IsAdaptToProportionalScale() || property->IsAdaptToSimulationScale();
3677 }
3678
3679 /**
3680 * throw slip to full screen
3681 */
ThrowSlipToFullScreen(WSRect & endRect,WSRect & rect)3682 void SceneSession::ThrowSlipToFullScreen(WSRect& endRect, WSRect& rect)
3683 {
3684 if (pcFoldScreenController_ == nullptr) {
3685 return;
3686 }
3687
3688 int32_t statusBarHeight = IsLayoutFullScreen() ? 0 : GetStatusBarHeight();
3689 int32_t dockHeight = IsLayoutFullScreen() ? 0 : GetDockHeight();
3690 // maximize end rect and notify last rect
3691 throwSlipToFullScreenAnimCount_.fetch_add(1);
3692 pcFoldScreenController_->ResizeToFullScreen(endRect, statusBarHeight, dockHeight);
3693 if (pcFoldScreenController_->IsThrowSlipDirectly()) {
3694 pcFoldScreenController_->ThrowSlipFloatingRectDirectly(
3695 rect, GetSessionRequestRect(), GetStatusBarHeight(), GetDockHeight());
3696 }
3697 }
3698
3699 /**
3700 * the compatible mode window is being scaled and transformed
3701 */
CompatibilityModeWindowScaleTransfer(WSRect & rect,bool isScale)3702 void SceneSession::CompatibilityModeWindowScaleTransfer(WSRect& rect, bool isScale)
3703 {
3704 if (!WindowHelper::IsMainWindow(GetWindowType())) {
3705 TLOGD(WmsLogTag::WMS_LAYOUT, "is not mainWindow");
3706 return;
3707 }
3708 auto scaleX = GetScaleX();
3709 auto scaleY = GetScaleY();
3710 if (MathHelper::NearZero(scaleX) || MathHelper::NearZero(scaleY)) {
3711 TLOGE(WmsLogTag::WMS_LAYOUT, "scale ratio is 0");
3712 return;
3713 }
3714 if (!isScale) {
3715 if (!MathHelper::NearZero(scaleX)) {
3716 scaleX = 1 / scaleX;
3717 }
3718 if (!MathHelper::NearZero(scaleY)) {
3719 scaleY = 1 / scaleY;
3720 }
3721 }
3722 if (IsCompatibilityModeScale(scaleX, scaleY)) {
3723 WindowScaleTransfer(rect, scaleX, scaleY);
3724 }
3725 }
3726
3727 /**
3728 * move with init velocity
3729 * @return true: successfully throw slip
3730 */
MoveUnderInteriaAndNotifyRectChange(WSRect & rect,SizeChangeReason reason)3731 bool SceneSession::MoveUnderInteriaAndNotifyRectChange(WSRect& rect, SizeChangeReason reason)
3732 {
3733 if (pcFoldScreenController_ == nullptr) {
3734 return false;
3735 }
3736 CompatibilityModeWindowScaleTransfer(rect, true);
3737 int32_t statusBarHeight = IsLayoutFullScreen() ? 0 : GetStatusBarHeight();
3738 int32_t dockHeight = IsLayoutFullScreen() ? 0 : GetDockHeight();
3739 bool ret = pcFoldScreenController_->ThrowSlip(GetScreenId(), rect, statusBarHeight, dockHeight);
3740 if (!ret) {
3741 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "no throw slip");
3742 pcFoldScreenController_->ResetRecords();
3743 CompatibilityModeWindowScaleTransfer(rect, false);
3744 return false;
3745 }
3746 CompatibilityModeWindowScaleTransfer(rect, false);
3747 WSRect endRect = rect;
3748 std::function<void()> finishCallback = nullptr;
3749 bool needSetFullScreen = pcFoldScreenController_->IsStartFullScreen();
3750 if (needSetFullScreen) {
3751 ThrowSlipToFullScreen(endRect, rect);
3752 finishCallback = [weakThis = wptr(this), rect, where = __func__] {
3753 auto session = weakThis.promote();
3754 if (session == nullptr) {
3755 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is nullptr", where);
3756 return;
3757 }
3758 session->OnThrowSlipAnimationStateChange(false, true);
3759 session->NotifyFullScreenAfterThrowSlip(rect);
3760 };
3761 } else {
3762 finishCallback = [weakThis = wptr(this), rect, where = __func__] {
3763 auto session = weakThis.promote();
3764 if (session == nullptr) {
3765 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is nullptr", where);
3766 return;
3767 }
3768 session->OnThrowSlipAnimationStateChange(false, false);
3769 };
3770 }
3771 auto throwSlipPair = std::make_pair(pcFoldScreenController_->GetThrowSlipTimingProtocol(),
3772 pcFoldScreenController_->GetThrowSlipTimingCurve());
3773 SetSurfaceBoundsWithAnimation(throwSlipPair, endRect, finishCallback);
3774 OnThrowSlipAnimationStateChange(true, needSetFullScreen);
3775 rect = endRect;
3776 pcFoldScreenController_->ResetRecords();
3777 return true;
3778 }
3779
OnThrowSlipAnimationStateChange(bool isAnimating,bool isFullScreen)3780 void SceneSession::OnThrowSlipAnimationStateChange(bool isAnimating, bool isFullScreen)
3781 {
3782 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "status: %{public}d", isAnimating);
3783 if (isAnimating) {
3784 StartAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(AsyncTraceTaskId::THROW_SLIP_ANIMATION),
3785 "SceneSession::ThrowSlipAnimation(id:%d)", GetPersistentId());
3786 } else {
3787 FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(AsyncTraceTaskId::THROW_SLIP_ANIMATION),
3788 "SceneSession::ThrowSlipAnimation(id:%d)", GetPersistentId());
3789 }
3790 auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3791 if (leashWinSurfaceNode) {
3792 leashWinSurfaceNode->SetUIFirstSwitch(isAnimating ? RSUIFirstSwitch::FORCE_DISABLE : RSUIFirstSwitch::NONE);
3793 }
3794 if (onThrowSlipAnimationStateChangeFunc_) {
3795 onThrowSlipAnimationStateChangeFunc_(isAnimating, isFullScreen);
3796 }
3797 }
3798
NotifyFullScreenAfterThrowSlip(const WSRect & rect)3799 void SceneSession::NotifyFullScreenAfterThrowSlip(const WSRect& rect)
3800 {
3801 PostTask([weakThis = wptr(this), rect, where = __func__] {
3802 auto session = weakThis.promote();
3803 if (session == nullptr) {
3804 TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s session is nullptr", where);
3805 return;
3806 }
3807 if (!session->IsVisibleForeground()) {
3808 TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s session go background when throw", where);
3809 return;
3810 }
3811 if (session->throwSlipToFullScreenAnimCount_.load() == 0) {
3812 TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s session moved when throw", where);
3813 return;
3814 }
3815 if (session->throwSlipToFullScreenAnimCount_.load() > 1) {
3816 TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s throw-slip fullscreen animation count: %{public}u",
3817 where, session->throwSlipToFullScreenAnimCount_.load());
3818 session->throwSlipToFullScreenAnimCount_.fetch_sub(1);
3819 return;
3820 }
3821 session->throwSlipToFullScreenAnimCount_.fetch_sub(1);
3822 if (!session->onSessionEvent_) {
3823 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s invalid callback", where);
3824 return;
3825 }
3826 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s rect: %{public}s", where, rect.ToString().c_str());
3827 session->onSessionEvent_(
3828 static_cast<uint32_t>(SessionEvent::EVENT_MAXIMIZE_WITHOUT_ANIMATION),
3829 SessionEventParam {rect.posX_, rect.posY_, rect.width_, rect.height_});
3830 }, __func__);
3831 }
3832
ThrowSlipDirectly(ThrowSlipMode throwSlipMode,const WSRectF & velocity)3833 void SceneSession::ThrowSlipDirectly(ThrowSlipMode throwSlipMode, const WSRectF& velocity)
3834 {
3835 const char* const where = __func__;
3836 PostTask([weakThis = wptr(this), throwSlipMode, velocity, where] {
3837 auto session = weakThis.promote();
3838 if (session == nullptr) {
3839 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is nullptr", where);
3840 return;
3841 }
3842 auto controller = session->pcFoldScreenController_;
3843 TLOGNI(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session: %{public}d, velocity: %{public}s",
3844 where, session->GetPersistentId(), velocity.ToString().c_str());
3845 if (!(controller && controller->IsAllowThrowSlip(session->GetScreenId()))) {
3846 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s not allow throw slip", where);
3847 return;
3848 }
3849 if (!session->IsMovableWindowType()) {
3850 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s not movable", where);
3851 return;
3852 }
3853 bool isFullScreen = session->IsFullScreenMovable();
3854 WSRect currRect;
3855 session->HookStartMoveRect(currRect, session->GetSessionRect());
3856 controller->RecordStartMoveRectDirectly(currRect, throwSlipMode, velocity, isFullScreen);
3857 const WSRect& oriGlobalRect = session->GetSessionGlobalRect();
3858 WSRect globalRect = oriGlobalRect;
3859 if (!session->MoveUnderInteriaAndNotifyRectChange(globalRect, SizeChangeReason::UNDEFINED)) {
3860 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s no throw", where);
3861 return;
3862 }
3863 if (isFullScreen) {
3864 session->UpdateFullScreenWaterfallMode(false);
3865 }
3866 WSRect rect = session->GetSessionRect();
3867 rect.posX_ += globalRect.posX_ - oriGlobalRect.posX_;
3868 rect.posY_ += globalRect.posY_ - oriGlobalRect.posY_;
3869 session->NotifySessionRectChange(globalRect, SizeChangeReason::UNDEFINED);
3870 }, __func__);
3871 }
3872
3873 /** @note @window.drag */
OnMoveDragCallback(SizeChangeReason reason)3874 void SceneSession::OnMoveDragCallback(SizeChangeReason reason)
3875 {
3876 if (!moveDragController_) {
3877 WLOGE("moveDragController_ is null");
3878 return;
3879 }
3880 auto property = GetSessionProperty();
3881 if (property == nullptr) {
3882 TLOGE(WmsLogTag::WMS_SCB, "property is null");
3883 return;
3884 }
3885 if (reason == SizeChangeReason::DRAG_START) {
3886 InitializeCrossMoveDrag();
3887 }
3888 bool isMainWindow = WindowHelper::IsMainWindow(property->GetWindowType());
3889 WSRect rect = moveDragController_->GetTargetRect(
3890 MoveDragController::TargetRectCoordinate::RELATED_TO_START_DISPLAY);
3891 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
3892 "SceneSession::OnMoveDragCallback id:%d [%d, %d, %d, %d] reason:%u", GetPersistentId(), rect.posX_, rect.posY_,
3893 rect.width_, rect.height_, reason);
3894 if (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_END) {
3895 UpdateWinRectForSystemBar(rect);
3896 }
3897 HandleSubSessionCrossNode(reason);
3898 moveDragController_->SetTargetRect(rect);
3899 if (DragResizeWhenEndFilter(reason)) {
3900 return;
3901 }
3902 UpdateKeyFrameState(reason, rect);
3903 WSRect relativeRect = moveDragController_->GetTargetRect(reason == SizeChangeReason::DRAG_END ?
3904 MoveDragController::TargetRectCoordinate::RELATED_TO_END_DISPLAY :
3905 MoveDragController::TargetRectCoordinate::RELATED_TO_START_DISPLAY);
3906 WSRect globalRect = moveDragController_->GetTargetRect(reason == SizeChangeReason::DRAG_END ?
3907 MoveDragController::TargetRectCoordinate::RELATED_TO_END_DISPLAY :
3908 MoveDragController::TargetRectCoordinate::GLOBAL);
3909 HandleMoveDragSurfaceNode(reason);
3910 HandleMoveDragSurfaceBounds(relativeRect, globalRect, reason);
3911 if (reason == SizeChangeReason::DRAG_END) {
3912 HandleMoveDragEnd(relativeRect, reason);
3913 SetUIFirstSwitch(RSUIFirstSwitch::NONE);
3914 } else if (reason == SizeChangeReason::DRAG_START) {
3915 OnSessionEvent(SessionEvent::EVENT_DRAG_START);
3916 NotifyUpdateGravity();
3917 SetUIFirstSwitch(RSUIFirstSwitch::FORCE_DISABLE);
3918 }
3919 }
3920
HandleSubSessionCrossNode(SizeChangeReason reason)3921 void SceneSession::HandleSubSessionCrossNode(SizeChangeReason reason)
3922 {
3923 if (IsDraggingReason(reason) && !Session::IsDragStart()) {
3924 Session::SetDragStart(true);
3925 if (!subSession_.empty()) {
3926 HandleSubSessionSurfaceNode(true, GetDisplayId());
3927 }
3928 } else if (reason == SizeChangeReason::DRAG_END) {
3929 Session::SetDragStart(false);
3930 if (!subSession_.empty()) {
3931 HandleSubSessionSurfaceNode(false, GetDisplayId());
3932 }
3933 }
3934 }
3935
DragResizeWhenEndFilter(SizeChangeReason reason)3936 bool SceneSession::DragResizeWhenEndFilter(SizeChangeReason reason)
3937 {
3938 auto property = GetSessionProperty();
3939 if (property == nullptr || moveDragController_ == nullptr) {
3940 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "property or controller is null");
3941 return true;
3942 }
3943 bool isPcOrPcModeMainWindow = (systemConfig_.IsPcWindow() || IsFreeMultiWindowMode()) &&
3944 WindowHelper::IsMainWindow(property->GetWindowType());
3945 bool isReasonMatched = reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_END;
3946 bool isResizeWhenEnd = (isReasonMatched && isPcOrPcModeMainWindow &&
3947 GetDragResizeTypeDuringDrag() == DragResizeType::RESIZE_WHEN_DRAG_END) || IsDragResizeScale(reason);
3948 if (isResizeWhenEnd) {
3949 UpdateSizeChangeReason(reason);
3950 if (reason == SizeChangeReason::DRAG) {
3951 HandleMoveDragEvent(reason);
3952 } else {
3953 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "trigger client rect change by scb");
3954 WSRect relativeRect = moveDragController_->GetTargetRect(
3955 MoveDragController::TargetRectCoordinate::RELATED_TO_END_DISPLAY);
3956 HandleMoveDragEnd(relativeRect, reason);
3957 SetUIFirstSwitch(RSUIFirstSwitch::NONE);
3958 }
3959 }
3960 return isResizeWhenEnd;
3961 }
3962
HandleMoveDragEvent(SizeChangeReason reason)3963 void SceneSession::HandleMoveDragEvent(SizeChangeReason reason)
3964 {
3965 if (!IsDragResizeScale(reason)) {
3966 OnSessionEvent(SessionEvent::EVENT_DRAG);
3967 return;
3968 }
3969 compatibleDragScaleFlags_ = true;
3970 std::shared_ptr<VsyncCallback> nextVsyncDragCallback = std::make_shared<VsyncCallback>();
3971 nextVsyncDragCallback->onCallback = [weakThis = wptr(this), where = __func__](int64_t, int64_t) {
3972 auto session = weakThis.promote();
3973 if (!session) {
3974 TLOGNE(WmsLogTag::WMS_COMPAT, "%{public}s: session is null", where);
3975 return;
3976 }
3977 if (session->IsCompatibleModeDirtyDragScaleWindow()) {
3978 session->OnSessionEvent(SessionEvent::EVENT_DRAG);
3979 session->ResetCompatibleModeDragScaleFlags();
3980 }
3981 };
3982 if (requestNextVsyncFunc_) {
3983 requestNextVsyncFunc_(nextVsyncDragCallback);
3984 } else {
3985 TLOGE(WmsLogTag::WMS_COMPAT, "Func is null, could not request vsync");
3986 }
3987 }
3988
IsDragResizeScale(SizeChangeReason reason)3989 bool SceneSession::IsDragResizeScale(SizeChangeReason reason)
3990 {
3991 auto property = GetSessionProperty();
3992 if (property == nullptr) {
3993 TLOGE(WmsLogTag::WMS_COMPAT, "property is null");
3994 return false;
3995 }
3996 bool isPcOrPcModeMainWindow = (systemConfig_.IsPcWindow() || IsFreeMultiWindowMode()) &&
3997 WindowHelper::IsMainWindow(property->GetWindowType());
3998 bool result = (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_END) &&
3999 isPcOrPcModeMainWindow && GetDragResizeTypeDuringDrag() == DragResizeType::RESIZE_SCALE;
4000 return result;
4001 }
4002
UpdateKeyFrameCloneNode(std::shared_ptr<RSCanvasNode> & rsCanvasNode,std::shared_ptr<RSTransaction> & rsTransaction)4003 WSError SceneSession::UpdateKeyFrameCloneNode(std::shared_ptr<RSCanvasNode>& rsCanvasNode,
4004 std::shared_ptr<RSTransaction>& rsTransaction)
4005 {
4006 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "in");
4007 if (keyFrameCloneNode_) {
4008 TLOGW(WmsLogTag::WMS_LAYOUT_PC, "keyFrameCloneNode_ already exist");
4009 return WSError::WS_OK;
4010 }
4011 if (!rsCanvasNode || !sessionStage_) {
4012 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "get nullptr");
4013 return WSError::WS_ERROR_NULLPTR;
4014 }
4015 auto rsUIContext = GetRSUIContext();
4016 RSAdapterUtil::SetRSUIContext(rsCanvasNode, rsUIContext, true);
4017 RSAdapterUtil::SetRSTransactionHandler(rsTransaction, rsUIContext);
4018 if (rsTransaction != nullptr) {
4019 rsTransaction->Begin();
4020 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "begin rsTransaction");
4021 }
4022 keyFrameCloneNode_ = rsCanvasNode;
4023 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "change key frame node to %{public}" PRIu64 "", keyFrameCloneNode_->GetId());
4024 sessionStage_->LinkKeyFrameCanvasNode(keyFrameCloneNode_);
4025 if (rsTransaction != nullptr) {
4026 rsTransaction->Commit();
4027 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "commit rsTransaction");
4028 }
4029 return WSError::WS_OK;
4030 }
4031
SetKeyFramePolicy(const KeyFramePolicy & keyFramePolicy)4032 void SceneSession::SetKeyFramePolicy(const KeyFramePolicy& keyFramePolicy)
4033 {
4034 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "in");
4035 bool running = keyFramePolicy_.running_;
4036 bool stopping = keyFramePolicy_.stopping_;
4037 keyFramePolicy_ = keyFramePolicy;
4038 keyFramePolicy_.running_ = running;
4039 keyFramePolicy_.stopping_ = stopping;
4040 }
4041
SetDragKeyFramePolicy(const KeyFramePolicy & keyFramePolicy)4042 WSError SceneSession::SetDragKeyFramePolicy(const KeyFramePolicy& keyFramePolicy)
4043 {
4044 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "in");
4045 bool running = keyFramePolicy_.running_;
4046 bool stopping = keyFramePolicy_.stopping_;
4047 keyFramePolicy_ = keyFramePolicy;
4048 keyFramePolicy_.running_ = running;
4049 keyFramePolicy_.stopping_ = stopping;
4050 return WSError::WS_OK;
4051 }
4052
UpdateKeyFrameState(SizeChangeReason reason,const WSRect & rect)4053 void SceneSession::UpdateKeyFrameState(SizeChangeReason reason, const WSRect& rect)
4054 {
4055 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d rect: %{public}s reason: %{public}d",
4056 GetPersistentId(), rect.ToString().c_str(), reason);
4057 if (!moveDragController_ || !sessionStage_) {
4058 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "no moveDragController or sessionStage");
4059 return;
4060 }
4061 if (reason == SizeChangeReason::DRAG_START && moveDragController_->GetStartDragFlag()) {
4062 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "key frame start check");
4063 if (!keyFramePolicy_.enabled() || GetAppDragResizeType() == DragResizeType::RESIZE_WHEN_DRAG_END) {
4064 keyFramePolicy_.running_ = false;
4065 return;
4066 }
4067 return InitKeyFrameState(rect);
4068 }
4069 if (!keyFramePolicy_.running_ || !keyFrameCloneNode_) {
4070 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "key frame not start");
4071 return;
4072 }
4073 if (reason == SizeChangeReason::DRAG) {
4074 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "reset gravity and resize clone node");
4075 uint64_t timeStamp = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
4076 std::chrono::system_clock::now().time_since_epoch()).count());
4077 if (keyFrameDragPauseNoticed_) {
4078 lastKeyFrameStamp_ = timeStamp;
4079 }
4080 lastKeyFrameDragStamp_ = timeStamp;
4081 lastKeyFrameDragRect_ = rect;
4082 keyFrameDragPauseNoticed_ = false;
4083 SetFrameGravity(Gravity::DEFAULT);
4084 keyFrameCloneNode_->SetBounds(0, 0, rect.width_, rect.height_);
4085 keyFrameCloneNode_->SetFrame(0, 0, rect.width_, rect.height_);
4086 RSTransactionAdapter::FlushImplicitTransaction(GetRSUIContext());
4087 } else if (reason == SizeChangeReason::DRAG_END) {
4088 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "key frame stopping");
4089 keyFramePolicy_.running_ = false;
4090 keyFramePolicy_.stopping_ = true;
4091 sessionStage_->SetKeyFramePolicy(keyFramePolicy_);
4092 keyFrameCloneNode_ = nullptr;
4093 }
4094 }
4095
InitKeyFrameState(const WSRect & rect)4096 void SceneSession::InitKeyFrameState(const WSRect& rect)
4097 {
4098 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "key frame start init");
4099 uint64_t timeStamp = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
4100 std::chrono::system_clock::now().time_since_epoch()).count());
4101 keyFramePolicy_.running_ = true;
4102 keyFramePolicy_.stopping_ = false;
4103 keyFrameAnimating_ = false;
4104 lastKeyFrameStamp_ = timeStamp;
4105 lastKeyFrameRect_ = rect;
4106 lastKeyFrameDragRect_ = rect;
4107 keyFrameVsyncRequestStamp_ = timeStamp;
4108 lastKeyFrameDragStamp_ = timeStamp;
4109 keyFrameDragPauseNoticed_ = false;
4110 sessionStage_->SetKeyFramePolicy(keyFramePolicy_);
4111 RequestKeyFrameNextVsync(keyFrameVsyncRequestStamp_, 0);
4112 }
4113
RequestKeyFrameNextVsync(uint64_t requestStamp,uint64_t count)4114 void SceneSession::RequestKeyFrameNextVsync(uint64_t requestStamp, uint64_t count)
4115 {
4116 std::shared_ptr<VsyncCallback> callback = std::make_shared<VsyncCallback>();
4117 const char* const where = __func__;
4118 callback->onCallback = [weakThis = wptr(this), requestStamp, count, where](int64_t, int64_t) {
4119 auto session = weakThis.promote();
4120 if (!session) {
4121 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is nullptr", where);
4122 return;
4123 }
4124 session->OnKeyFrameNextVsync(count);
4125 session->RequestKeyFrameNextVsync(requestStamp, count + 1);
4126 };
4127 if (keyFramePolicy_.running_ && requestNextVsyncFunc_ && requestStamp == keyFrameVsyncRequestStamp_) {
4128 requestNextVsyncFunc_(callback);
4129 } else {
4130 TLOGI(WmsLogTag::WMS_LAYOUT, "%{public}s stop", where);
4131 }
4132 }
4133
OnKeyFrameNextVsync(uint64_t count)4134 void SceneSession::OnKeyFrameNextVsync(uint64_t count)
4135 {
4136 TLOGD(WmsLogTag::WMS_LAYOUT, "get vsync %{public}" PRIu64, count);
4137 uint64_t nowTimeStamp = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
4138 std::chrono::system_clock::now().time_since_epoch()).count());
4139 uint64_t duration = nowTimeStamp - lastKeyFrameDragStamp_;
4140 const uint64_t minDelay = 100;
4141 if (!keyFrameDragPauseNoticed_ && !keyFrameAnimating_ && duration >= minDelay) {
4142 bool isToNotice = true;
4143 if (KeyFrameRectAlmostSame(lastKeyFrameRect_, lastKeyFrameDragRect_)) {
4144 isToNotice = false;
4145 }
4146 keyFrameDragPauseNoticed_ = true;
4147 lastKeyFrameDragStamp_ = nowTimeStamp;
4148 lastKeyFrameStamp_ = nowTimeStamp;
4149 layoutController_->SetSessionRect(lastKeyFrameDragRect_);
4150 lastKeyFrameRect_ = lastKeyFrameDragRect_;
4151 if (isToNotice) {
4152 NotifyClientToUpdateRect("OnMoveDragCallback", nullptr);
4153 }
4154 TLOGNI(WmsLogTag::WMS_LAYOUT, "to notice for key frame drag paused: %{public}d", isToNotice);
4155 }
4156 }
4157
KeyFrameNotifyFilter(const WSRect & rect,SizeChangeReason reason)4158 bool SceneSession::KeyFrameNotifyFilter(const WSRect& rect, SizeChangeReason reason)
4159 {
4160 TLOGD(WmsLogTag::WMS_LAYOUT, "reason in: %{public}d", reason);
4161 if (!keyFramePolicy_.running_) {
4162 TLOGD(WmsLogTag::WMS_LAYOUT, "skip filter for not running");
4163 return false;
4164 }
4165 if (reason == SizeChangeReason::DRAG_START) {
4166 TLOGD(WmsLogTag::WMS_LAYOUT, "ensure start reason send");
4167 NotifyClientToUpdateRect("OnMoveDragCallback", nullptr);
4168 return true;
4169 }
4170 if (reason != SizeChangeReason::DRAG) {
4171 TLOGD(WmsLogTag::WMS_LAYOUT, "skip filter for not drag");
4172 return false;
4173 }
4174 if (keyFrameAnimating_) {
4175 TLOGD(WmsLogTag::WMS_LAYOUT, "filter for animating");
4176 return true;
4177 }
4178 bool isToFilter = true;
4179 uint64_t nowTimeStamp = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
4180 std::chrono::system_clock::now().time_since_epoch()).count());
4181 uint64_t interval = nowTimeStamp - lastKeyFrameStamp_;
4182 bool intervalCheckPass = interval >= keyFramePolicy_.interval_;
4183 bool distanceCheckPass = false;
4184 double distance = 0;
4185 if (keyFramePolicy_.distance_ > 0) {
4186 distance = sqrt(pow(rect.width_ - lastKeyFrameRect_.width_, POW_DOUBLE) +
4187 pow(rect.height_ - lastKeyFrameRect_.height_, POW_DOUBLE));
4188 distanceCheckPass = distance >= keyFramePolicy_.distance_;
4189 }
4190 TLOGI(WmsLogTag::WMS_LAYOUT, "key frame checking: %{public}" PRIu64 "[%{public}d], %{public}f[%{public}d]",
4191 interval, intervalCheckPass, distance, distanceCheckPass);
4192 if (intervalCheckPass || distanceCheckPass) {
4193 isToFilter = false;
4194 }
4195 if (!isToFilter && KeyFrameRectAlmostSame(lastKeyFrameRect_, rect)) {
4196 isToFilter = true;
4197 lastKeyFrameStamp_ = nowTimeStamp;
4198 lastKeyFrameRect_ = rect;
4199 }
4200 if (!isToFilter) {
4201 lastKeyFrameStamp_ = nowTimeStamp;
4202 lastKeyFrameRect_ = rect;
4203 keyFrameAnimating_ = true;
4204 }
4205 return isToFilter;
4206 }
4207
KeyFrameRectAlmostSame(const WSRect & rect1,const WSRect & rect2)4208 bool SceneSession::KeyFrameRectAlmostSame(const WSRect& rect1, const WSRect& rect2)
4209 {
4210 const int32_t MAX_DIFF_THREDHOLD_FOR_TOUCH_EVENT = 3;
4211 if (rect1.isNearEqual(rect2, MAX_DIFF_THREDHOLD_FOR_TOUCH_EVENT)) {
4212 TLOGD(WmsLogTag::WMS_LAYOUT, "rect almost same: %{public}s -> %{public}s",
4213 rect1.ToString().c_str(), rect2.ToString().c_str());
4214 return true;
4215 }
4216 return false;
4217 }
4218
KeyFrameAnimateEnd()4219 WSError SceneSession::KeyFrameAnimateEnd()
4220 {
4221 TLOGD(WmsLogTag::WMS_LAYOUT, "in");
4222 keyFrameAnimating_ = false;
4223 return WSError::WS_OK;
4224 }
4225
4226 /** @note @window.drag */
HandleMoveDragSurfaceNode(SizeChangeReason reason)4227 void SceneSession::HandleMoveDragSurfaceNode(SizeChangeReason reason)
4228 {
4229 auto movedSurfaceNode = GetSurfaceNodeForMoveDrag();
4230 if (movedSurfaceNode == nullptr) {
4231 TLOGD(WmsLogTag::WMS_LAYOUT, "SurfaceNode is null");
4232 return;
4233 }
4234 const auto startDisplayId = moveDragController_->GetMoveDragStartDisplayId();
4235 auto startScreenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(startDisplayId);
4236 if (startScreenSession == nullptr) {
4237 TLOGE(WmsLogTag::WMS_LAYOUT, "startScreenSession is null, startDisplayId: %{public}" PRIu64, startDisplayId);
4238 return;
4239 }
4240 if (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_MOVE) {
4241 for (const auto displayId : moveDragController_->GetNewAddedDisplayIdsDuringMoveDrag()) {
4242 if (displayId == moveDragController_->GetMoveDragStartDisplayId()) {
4243 continue;
4244 }
4245 auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
4246 if (screenSession == nullptr) {
4247 TLOGD(WmsLogTag::WMS_LAYOUT, "ScreenSession is null");
4248 continue;
4249 }
4250 bool isStartScreenMainOrExtend = startScreenSession->GetSourceMode() == ScreenSourceMode::SCREEN_MAIN
4251 || startScreenSession->GetSourceMode() == ScreenSourceMode::SCREEN_EXTEND;
4252 bool isDestScreenMainOrExtend = screenSession->GetSourceMode() == ScreenSourceMode::SCREEN_MAIN
4253 || screenSession->GetSourceMode() == ScreenSourceMode::SCREEN_EXTEND;
4254 // Not main to extend or extend to main or extend to extend, no need to add cross parent child
4255 if (!(isStartScreenMainOrExtend && isDestScreenMainOrExtend)) {
4256 TLOGD(WmsLogTag::WMS_LAYOUT, "No need to add cross-parent child elements for out-of-scope situations, "
4257 "DisplayId: %{public}" PRIu64, displayId);
4258 continue;
4259 }
4260
4261 {
4262 AutoRSTransaction trans(movedSurfaceNode->GetRSUIContext());
4263 movedSurfaceNode->SetPositionZ(MOVE_DRAG_POSITION_Z);
4264 movedSurfaceNode->SetIsCrossNode(true);
4265 }
4266
4267 {
4268 AutoRSTransaction trans(screenSession->GetRSUIContext());
4269 TLOGI(WmsLogTag::WMS_LAYOUT, "Add window to display: %{public}" PRIu64, displayId);
4270 screenSession->GetDisplayNode()->AddCrossScreenChild(movedSurfaceNode, -1, true);
4271 }
4272 HandleSubSessionSurfaceNodeByWindowAnchor(reason, screenSession);
4273 }
4274 } else if (reason == SizeChangeReason::DRAG_END) {
4275 for (const auto displayId : moveDragController_->GetDisplayIdsDuringMoveDrag()) {
4276 if (displayId == moveDragController_->GetMoveDragStartDisplayId()) {
4277 continue;
4278 }
4279 auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
4280 if (screenSession == nullptr) {
4281 TLOGD(WmsLogTag::WMS_LAYOUT, "ScreenSession is null");
4282 continue;
4283 }
4284 bool isStartScreenMainOrExtend = startScreenSession->GetSourceMode() == ScreenSourceMode::SCREEN_MAIN
4285 || startScreenSession->GetSourceMode() == ScreenSourceMode::SCREEN_EXTEND;
4286 bool isDestScreenMainOrExtend = screenSession->GetSourceMode() == ScreenSourceMode::SCREEN_MAIN
4287 || screenSession->GetSourceMode() == ScreenSourceMode::SCREEN_EXTEND;
4288 // Not main to extend or extend to main or extend to extend, no need to add cross parent child
4289 if (!(isStartScreenMainOrExtend && isDestScreenMainOrExtend)) {
4290 TLOGD(WmsLogTag::WMS_LAYOUT, "No need to add cross-parent child elements for out-of-scope situations, "
4291 "DisplayId: %{public}" PRIu64, displayId);
4292 continue;
4293 }
4294 movedSurfaceNode->SetPositionZ(moveDragController_->GetOriginalPositionZ());
4295 screenSession->GetDisplayNode()->RemoveCrossScreenChild(movedSurfaceNode);
4296 movedSurfaceNode->SetIsCrossNode(false);
4297 TLOGI(WmsLogTag::WMS_LAYOUT, "Remove window from display: %{public}" PRIu64, displayId);
4298 HandleSubSessionSurfaceNodeByWindowAnchor(reason, screenSession);
4299 }
4300 }
4301 }
4302
HandleSubSessionSurfaceNode(bool isAdd,DisplayId draggingOrMovingParentDisplayId)4303 void SceneSession::HandleSubSessionSurfaceNode(bool isAdd, DisplayId draggingOrMovingParentDisplayId)
4304 {
4305 for (const auto& session : subSession_) {
4306 if (session) {
4307 session->HandleSubSessionSurfaceNode(isAdd, draggingOrMovingParentDisplayId);
4308 }
4309 }
4310
4311 if (WindowHelper::IsSubWindow(GetWindowType()) &&
4312 (IsFollowParentMultiScreenPolicy() || (!isAdd && cloneNodeCount_ > 0))) {
4313 WSRect targetRect = isAdd ? layoutController_->ConvertRelativeRectToGlobal(GetSessionRect(), GetScreenId()) :
4314 layoutController_->ConvertGlobalRectToRelative(GetSessionRect(), GetScreenId());
4315 TLOGI(WmsLogTag::WMS_LAYOUT, "isAdd:%{public}d targetRect:%{public}s", isAdd, targetRect.ToString().c_str());
4316 if (isAdd) {
4317 AddSurfaceNodeToScreen(draggingOrMovingParentDisplayId);
4318 SetSurfaceBounds(targetRect, true, true);
4319 } else {
4320 RemoveSurfaceNodeFromScreen();
4321 SetSurfaceBounds(targetRect, false, false);
4322 {
4323 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveToMutex_);
4324 displayIdSetDuringMoveTo_.clear();
4325 }
4326 auto lastRect = GetRequestRectWhenFollowParent();
4327 if (lastRect.IsInvalid()) {
4328 return;
4329 }
4330 auto moveConfiguration = GetRequestMoveConfiguration();
4331 NotifySessionRectChange(lastRect, SizeChangeReason::UNDEFINED, moveConfiguration.displayId);
4332 SetRequestRectWhenFollowParent({0, 0, 0, 0});
4333 SetRequestMoveConfiguration({DISPLAY_ID_INVALID});
4334 cloneNodeCount_ = 0;
4335 }
4336 }
4337 }
4338
4339 /** @note @window.drag */
UpdateRectForDrag(const WSRect & rect)4340 WSError SceneSession::UpdateRectForDrag(const WSRect& rect)
4341 {
4342 return PostSyncTask([weakThis = wptr(this), rect, where = __func__] {
4343 auto sceneSession = weakThis.promote();
4344 if (!sceneSession) {
4345 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
4346 return WSError::WS_ERROR_DESTROYED_OBJECT;
4347 }
4348 sceneSession->GetLayoutController()->SetSessionRect(rect);
4349 sceneSession->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::DRAG_RECT);
4350 sceneSession->isDragging_ = true; // isDrag only reset by Vsync, not flushuiparam
4351 return WSError::WS_OK;
4352 }, __func__);
4353 }
4354
4355 /** @note @window.drag */
UpdateWinRectForSystemBar(WSRect & rect)4356 void SceneSession::UpdateWinRectForSystemBar(WSRect& rect)
4357 {
4358 if (!specificCallback_) {
4359 WLOGFE("specificCallback_ is null!");
4360 return;
4361 }
4362 auto sessionProperty = GetSessionProperty();
4363 float tmpPosY = 0.0;
4364 std::vector<sptr<SceneSession>> statusBarVector;
4365 if (specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_) {
4366 statusBarVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
4367 WindowType::WINDOW_TYPE_STATUS_BAR, sessionProperty->GetDisplayId());
4368 }
4369 for (auto& statusBar : statusBarVector) {
4370 if (!(statusBar->isVisible_)) {
4371 continue;
4372 }
4373 WSRect statusBarRect = statusBar->GetSessionRect();
4374 if ((rect.posY_ < statusBarRect.posY_ + static_cast<int32_t>(statusBarRect.height_)) &&
4375 (rect.height_ != GetSessionRect().height_ || rect.width_ != GetSessionRect().width_)) {
4376 tmpPosY = rect.posY_ + rect.height_;
4377 rect.posY_ = statusBarRect.posY_ + statusBarRect.height_;
4378 rect.height_ = tmpPosY - rect.posY_;
4379 }
4380 }
4381 WLOGFD("after UpdateWinRectForSystemBar rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
4382 rect.posX_, rect.posY_, rect.width_, rect.height_);
4383 }
4384
SetSurfaceBoundsWithAnimation(const std::pair<RSAnimationTimingProtocol,RSAnimationTimingCurve> & animationParam,const WSRect & rect,const std::function<void ()> & finishCallback,bool isGlobal)4385 void SceneSession::SetSurfaceBoundsWithAnimation(
4386 const std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve>& animationParam,
4387 const WSRect& rect, const std::function<void()>& finishCallback, bool isGlobal)
4388 {
4389 RSNode::Animate(GetRSUIContext(), animationParam.first, animationParam.second,
4390 [weakThis = wptr(this), rect, isGlobal, where = __func__] {
4391 auto session = weakThis.promote();
4392 if (session == nullptr) {
4393 TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s session is nullptr", where);
4394 return;
4395 }
4396 session->SetSurfaceBounds(rect, isGlobal, false);
4397 RSTransactionAdapter::FlushImplicitTransaction(session->GetRSUIContext());
4398 }, finishCallback);
4399 }
4400
SetSurfaceBounds(const WSRect & rect,bool isGlobal,bool needFlush)4401 void SceneSession::SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush)
4402 {
4403 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetSurfaceBounds id:%d [%d, %d, %d, %d] reason:%u",
4404 GetPersistentId(), rect.posX_, rect.posY_, rect.width_, rect.height_, GetSizeChangeReason());
4405 TLOGD(WmsLogTag::WMS_LAYOUT, "id: %{public}d, rect: %{public}s isGlobal: %{public}d needFlush: %{public}d",
4406 GetPersistentId(), rect.ToString().c_str(), isGlobal, needFlush);
4407 AutoRSTransaction trans(GetRSUIContext(), needFlush);
4408 auto surfaceNode = GetSurfaceNode();
4409 auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
4410 NotifySubAndDialogFollowRectChange(rect, isGlobal, needFlush);
4411 SetSubWindowBoundsDuringCross(rect, isGlobal, needFlush);
4412 if (surfaceNode && leashWinSurfaceNode) {
4413 leashWinSurfaceNode->SetGlobalPositionEnabled(isGlobal);
4414 leashWinSurfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
4415 leashWinSurfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
4416 surfaceNode->SetBounds(0, 0, rect.width_, rect.height_);
4417 surfaceNode->SetFrame(0, 0, rect.width_, rect.height_);
4418 } else if (WindowHelper::IsPipWindow(GetWindowType()) && surfaceNode) {
4419 TLOGD(WmsLogTag::WMS_PIP, "PipWindow setSurfaceBounds");
4420 surfaceNode->SetGlobalPositionEnabled(isGlobal);
4421 surfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
4422 surfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
4423 } else if (WindowHelper::IsSubWindow(GetWindowType()) && surfaceNode) {
4424 WLOGFD("subwindow setSurfaceBounds");
4425 surfaceNode->SetGlobalPositionEnabled(isGlobal);
4426 surfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
4427 surfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
4428 } else if (WindowHelper::IsDialogWindow(GetWindowType()) && surfaceNode) {
4429 TLOGD(WmsLogTag::WMS_DIALOG, "dialogWindow setSurfaceBounds");
4430 surfaceNode->SetGlobalPositionEnabled(isGlobal);
4431 surfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
4432 surfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
4433 } else if (WindowHelper::IsSystemWindow(GetWindowType()) && surfaceNode) {
4434 TLOGD(WmsLogTag::WMS_SYSTEM, "system window setSurfaceBounds");
4435 surfaceNode->SetGlobalPositionEnabled(isGlobal);
4436 surfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
4437 surfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
4438 } else {
4439 WLOGE("SetSurfaceBounds surfaceNode is null!");
4440 }
4441 }
4442
SetZOrder(uint32_t zOrder)4443 void SceneSession::SetZOrder(uint32_t zOrder)
4444 {
4445 PostTask([weakThis = wptr(this), zOrder, where = __func__] {
4446 auto session = weakThis.promote();
4447 if (session == nullptr) {
4448 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
4449 return;
4450 }
4451 if (session->zOrder_ != zOrder) {
4452 session->Session::SetZOrder(zOrder);
4453 if (session->specificCallback_ != nullptr) {
4454 session->specificCallback_->onWindowInfoUpdate_(session->GetPersistentId(),
4455 WindowUpdateType::WINDOW_UPDATE_PROPERTY);
4456 }
4457 }
4458 }, __func__);
4459 }
4460
SetFloatingScale(float floatingScale)4461 void SceneSession::SetFloatingScale(float floatingScale)
4462 {
4463 if (floatingScale_ != floatingScale) {
4464 Session::SetFloatingScale(floatingScale);
4465 NotifySessionPropertyChange(WindowInfoKey::FLOATING_SCALE);
4466 if (specificCallback_ != nullptr) {
4467 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
4468 }
4469 MarkAvoidAreaAsDirty();
4470 }
4471 }
4472
SetParentPersistentId(int32_t parentId)4473 void SceneSession::SetParentPersistentId(int32_t parentId)
4474 {
4475 auto property = GetSessionProperty();
4476 if (property) {
4477 property->SetParentPersistentId(parentId);
4478 }
4479 }
4480
GetParentPersistentId() const4481 int32_t SceneSession::GetParentPersistentId() const
4482 {
4483 auto property = GetSessionProperty();
4484 if (property) {
4485 return property->GetParentPersistentId();
4486 }
4487 return INVALID_SESSION_ID;
4488 }
4489
GetMainSessionId()4490 int32_t SceneSession::GetMainSessionId()
4491 {
4492 const auto& mainSession = GetMainSession();
4493 if (mainSession) {
4494 return mainSession->GetPersistentId();
4495 }
4496 return INVALID_SESSION_ID;
4497 }
4498
GetWindowNameAllType() const4499 std::string SceneSession::GetWindowNameAllType() const
4500 {
4501 if (GetSessionInfo().isSystem_) {
4502 return GetSessionInfo().abilityName_;
4503 } else {
4504 return GetWindowName();
4505 }
4506 }
4507
SetTurnScreenOn(bool turnScreenOn)4508 WSError SceneSession::SetTurnScreenOn(bool turnScreenOn)
4509 {
4510 GetSessionProperty()->SetTurnScreenOn(turnScreenOn);
4511 return WSError::WS_OK;
4512 }
4513
IsTurnScreenOn() const4514 bool SceneSession::IsTurnScreenOn() const
4515 {
4516 return GetSessionProperty()->IsTurnScreenOn();
4517 }
4518
SetKeepScreenOn(bool keepScreenOn)4519 WSError SceneSession::SetKeepScreenOn(bool keepScreenOn)
4520 {
4521 GetSessionProperty()->SetKeepScreenOn(keepScreenOn);
4522 return WSError::WS_OK;
4523 }
4524
IsKeepScreenOn() const4525 bool SceneSession::IsKeepScreenOn() const
4526 {
4527 return GetSessionProperty()->IsKeepScreenOn();
4528 }
4529
SetViewKeepScreenOn(bool keepScreenOn)4530 WSError SceneSession::SetViewKeepScreenOn(bool keepScreenOn)
4531 {
4532 GetSessionProperty()->SetViewKeepScreenOn(keepScreenOn);
4533 return WSError::WS_OK;
4534 }
4535
IsViewKeepScreenOn() const4536 bool SceneSession::IsViewKeepScreenOn() const
4537 {
4538 return GetSessionProperty()->IsViewKeepScreenOn();
4539 }
4540
SetWindowShadowEnabled(bool isEnabled)4541 WSError SceneSession::SetWindowShadowEnabled(bool isEnabled)
4542 {
4543 GetSessionProperty()->SetWindowShadowEnabled(isEnabled);
4544 PostTask([weakThis = wptr(this), isEnabled, where = __func__] {
4545 auto session = weakThis.promote();
4546 if (!session) {
4547 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s session is null", where);
4548 return;
4549 }
4550 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s isEnabled: %{public}u", where, isEnabled);
4551 if (session->onWindowShadowEnableChangeFunc_) {
4552 session->onWindowShadowEnableChangeFunc_(isEnabled);
4553 }
4554 }, __func__);
4555 return WSError::WS_OK;
4556 }
4557
GetWindowShadowEnabled() const4558 bool SceneSession::GetWindowShadowEnabled() const
4559 {
4560 return GetSessionProperty()->GetWindowShadowEnabled();
4561 }
4562
SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap> & icon)4563 void SceneSession::SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap>& icon)
4564 {
4565 WLOGFI("run SaveUpdatedIcon");
4566 if (scenePersistence_ != nullptr) {
4567 scenePersistence_->SaveUpdatedIcon(icon);
4568 }
4569 }
4570
GetUpdatedIconPath() const4571 std::string SceneSession::GetUpdatedIconPath() const
4572 {
4573 WLOGFI("run GetUpdatedIconPath");
4574 if (scenePersistence_ != nullptr) {
4575 return scenePersistence_->GetUpdatedIconPath();
4576 }
4577 return "";
4578 }
4579
UpdateNativeVisibility(bool visible)4580 void SceneSession::UpdateNativeVisibility(bool visible)
4581 {
4582 PostTask([weakThis = wptr(this), visible, where = __func__]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
4583 auto session = weakThis.promote();
4584 if (!session) {
4585 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
4586 return;
4587 }
4588 int32_t persistentId = session->GetPersistentId();
4589 TLOGNI(WmsLogTag::WMS_SCB, "%{public}s name: %{public}s, id: %{public}u, visible: %{public}u",
4590 where, session->sessionInfo_.bundleName_.c_str(), persistentId, visible);
4591 SceneSessionChangeInfo changeInfo {
4592 .persistentId_ = persistentId,
4593 .changeInfo_ = "Visibility change to " + std::to_string(visible),
4594 .logTag_ = WmsLogTag::WMS_ATTRIBUTE,
4595 };
4596 SessionChangeRecorder::GetInstance().RecordSceneSessionChange(RecordType::VISIBLE_RECORD, changeInfo);
4597 bool oldVisibleState = session->isVisible_;
4598 session->isVisible_ = visible;
4599 if (session->visibilityChangedDetectFunc_) {
4600 session->visibilityChangedDetectFunc_(session->GetCallingPid(), oldVisibleState, visible);
4601 }
4602 if (session->specificCallback_ == nullptr) {
4603 TLOGNW(WmsLogTag::WMS_SCB, "%{public}s specific callback is null.", where);
4604 return;
4605 }
4606 if (visible) {
4607 session->specificCallback_->onWindowInfoUpdate_(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
4608 } else {
4609 session->specificCallback_->onWindowInfoUpdate_(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
4610 }
4611 session->NotifyAccessibilityVisibilityChange();
4612 session->specificCallback_->onUpdateAvoidArea_(persistentId);
4613 // update private state
4614 if (!session->GetSessionProperty()) {
4615 TLOGNE(WmsLogTag::WMS_SCB, "%{public}s property is null", where);
4616 return;
4617 }
4618 if (session->updatePrivateStateAndNotifyFunc_ != nullptr) {
4619 session->updatePrivateStateAndNotifyFunc_(persistentId);
4620 }
4621 }, __func__);
4622 }
4623
UpdateRotationAvoidArea()4624 void SceneSession::UpdateRotationAvoidArea()
4625 {
4626 if (specificCallback_) {
4627 if (Session::IsScbCoreEnabled()) {
4628 MarkAvoidAreaAsDirty();
4629 } else {
4630 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
4631 }
4632 }
4633 }
4634
SetPrivacyMode(bool isPrivacy)4635 void SceneSession::SetPrivacyMode(bool isPrivacy)
4636 {
4637 auto property = GetSessionProperty();
4638 if (!property) {
4639 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "property is null");
4640 return;
4641 }
4642 auto surfaceNode = GetSurfaceNode();
4643 if (!surfaceNode) {
4644 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode_ is null");
4645 return;
4646 }
4647 bool lastPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
4648 if (lastPrivacyMode == isPrivacy) {
4649 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "mode is same as: %{public}d", isPrivacy);
4650 return;
4651 }
4652 property->SetPrivacyMode(isPrivacy);
4653 property->SetSystemPrivacyMode(isPrivacy);
4654 {
4655 AutoRSTransaction trans(GetRSUIContext());
4656 surfaceNode->SetSecurityLayer(isPrivacy);
4657 auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
4658 if (leashWinSurfaceNode != nullptr) {
4659 leashWinSurfaceNode->SetSecurityLayer(isPrivacy);
4660 }
4661 }
4662 NotifyPrivacyModeChange();
4663 auto mainSession = GetMainSession();
4664 if (mainSession) {
4665 ControlInfo controlInfo = { .isNeedControl = isPrivacy, .isControlRecentOnly = true };
4666 mainSession->NotifyUpdateAppUseControl(ControlAppType::PRIVACY_WINDOW, controlInfo);
4667 }
4668 }
4669
NotifyPrivacyModeChange()4670 void SceneSession::NotifyPrivacyModeChange()
4671 {
4672 bool isPrivacyMode = GetSessionProperty()->GetPrivacyMode();
4673 bool currExtPrivacyMode = combinedExtWindowFlags_.privacyModeFlag;
4674 TLOGD(WmsLogTag::WMS_SCB, "id:%{public}d, currExtPrivacyMode:%{public}d, session property privacyMode: %{public}d, "
4675 "last privacyMode:%{public}d",
4676 GetPersistentId(), currExtPrivacyMode, isPrivacyMode, isPrivacyMode_);
4677 bool mixedPrivacyMode = currExtPrivacyMode || isPrivacyMode;
4678 if (mixedPrivacyMode != isPrivacyMode_) {
4679 isPrivacyMode_ = mixedPrivacyMode;
4680 if (privacyModeChangeNotifyFunc_) {
4681 privacyModeChangeNotifyFunc_(isPrivacyMode_);
4682 }
4683 }
4684 }
4685
NotifyExtensionSecureLimitChange(bool isLimit)4686 void SceneSession::NotifyExtensionSecureLimitChange(bool isLimit)
4687 {
4688 if (!sessionStage_) {
4689 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage is nullptr");
4690 return;
4691 }
4692 sessionStage_->NotifyExtensionSecureLimitChange(isLimit);
4693 }
4694
SetSnapshotSkip(bool isSkip)4695 WMError SceneSession::SetSnapshotSkip(bool isSkip)
4696 {
4697 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4698 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, permission denied!", GetPersistentId());
4699 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4700 }
4701 auto property = GetSessionProperty();
4702 if (!property) {
4703 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "property is null");
4704 return WMError::WM_ERROR_DESTROYED_OBJECT;
4705 }
4706 auto surfaceNode = GetSurfaceNode();
4707 if (!surfaceNode) {
4708 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode_ is null");
4709 return WMError::WM_ERROR_DESTROYED_OBJECT;
4710 }
4711 bool lastSnapshotSkip = property->GetSnapshotSkip();
4712 if (lastSnapshotSkip == isSkip) {
4713 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "Snapshot skip does not change, do nothing, isSkip: %{public}d, "
4714 "id: %{public}d", isSkip, GetPersistentId());
4715 return WMError::WM_OK;
4716 }
4717 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, isSkip: %{public}d", GetWindowId(), isSkip);
4718 property->SetSnapshotSkip(isSkip);
4719 {
4720 AutoRSTransaction trans(GetRSUIContext());
4721 surfaceNode->SetSkipLayer(isSkip);
4722 auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
4723 if (leashWinSurfaceNode != nullptr) {
4724 leashWinSurfaceNode->SetSkipLayer(isSkip);
4725 }
4726 }
4727 return WMError::WM_OK;
4728 }
4729
SetWatermarkEnabled(const std::string & watermarkName,bool isEnabled)4730 void SceneSession::SetWatermarkEnabled(const std::string& watermarkName, bool isEnabled)
4731 {
4732 auto surfaceNode = GetSurfaceNode();
4733 if (!surfaceNode) {
4734 TLOGE(WmsLogTag::DEFAULT, "surfaceNode is null");
4735 return;
4736 }
4737 TLOGI(WmsLogTag::DEFAULT, "watermarkName:%{public}s, isEnabled:%{public}d, wid:%{public}d",
4738 watermarkName.c_str(), isEnabled, GetPersistentId());
4739 {
4740 AutoRSTransaction trans(GetRSUIContext());
4741 surfaceNode->SetWatermarkEnabled(watermarkName, isEnabled);
4742 if (auto leashWinSurfaceNode = GetLeashWinSurfaceNode()) {
4743 leashWinSurfaceNode->SetWatermarkEnabled(watermarkName, isEnabled);
4744 }
4745 }
4746 }
4747
SetPiPTemplateInfo(const PiPTemplateInfo & pipTemplateInfo)4748 void SceneSession::SetPiPTemplateInfo(const PiPTemplateInfo& pipTemplateInfo)
4749 {
4750 pipTemplateInfo_ = pipTemplateInfo;
4751 }
4752
SetSystemSceneOcclusionAlpha(double alpha)4753 void SceneSession::SetSystemSceneOcclusionAlpha(double alpha)
4754 {
4755 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetAbilityBGAlpha");
4756 if (alpha < 0 || alpha > 1.0) {
4757 WLOGFE("OnSetSystemSceneOcclusionAlpha property is null");
4758 return;
4759 }
4760 auto surfaceNode = GetSurfaceNode();
4761 if (!surfaceNode) {
4762 WLOGFE("surfaceNode_ is null");
4763 return;
4764 }
4765 uint8_t alpha8bit = static_cast<uint8_t>(alpha * 255);
4766 WLOGFI("SetAbilityBGAlpha alpha8bit=%{public}u.", alpha8bit);
4767 {
4768 AutoRSTransaction trans(GetRSUIContext());
4769 surfaceNode->SetAbilityBGAlpha(alpha8bit);
4770 }
4771 }
4772
ResetOcclusionAlpha()4773 void SceneSession::ResetOcclusionAlpha()
4774 {
4775 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::ResetAbilityBGAlpha");
4776 auto surfaceNode = GetSurfaceNode();
4777 if (!surfaceNode) {
4778 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode_ is null");
4779 return;
4780 }
4781 uint8_t alpha8bit = GetSessionProperty()->GetBackgroundAlpha();
4782 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "alpha8bit=%{public}u, windowId=%{public}d", alpha8bit, GetPersistentId());
4783 {
4784 AutoRSTransaction trans(GetRSUIContext());
4785 surfaceNode->SetAbilityBGAlpha(alpha8bit);
4786 }
4787 }
4788
SetSystemSceneForceUIFirst(bool forceUIFirst)4789 void SceneSession::SetSystemSceneForceUIFirst(bool forceUIFirst)
4790 {
4791 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetForceUIFirst");
4792 auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
4793 auto surfaceNode = GetSurfaceNode();
4794 if (leashWinSurfaceNode == nullptr && surfaceNode == nullptr) {
4795 TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
4796 return;
4797 }
4798 AutoRSTransaction trans(GetRSUIContext());
4799 if (leashWinSurfaceNode != nullptr) {
4800 TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " forceUIFirst=%{public}d.",
4801 leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), forceUIFirst);
4802 leashWinSurfaceNode->SetForceUIFirst(forceUIFirst);
4803 } else if (surfaceNode != nullptr) {
4804 TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " forceUIFirst=%{public}d.",
4805 surfaceNode->GetName().c_str(), surfaceNode->GetId(), forceUIFirst);
4806 surfaceNode->SetForceUIFirst(forceUIFirst);
4807 }
4808 }
4809
SetUIFirstSwitch(RSUIFirstSwitch uiFirstSwitch)4810 void SceneSession::SetUIFirstSwitch(RSUIFirstSwitch uiFirstSwitch)
4811 {
4812 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetUIFirstSwitch");
4813 AutoRSTransaction trans(GetRSUIContext());
4814 auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
4815 auto surfaceNode = GetSurfaceNode();
4816 if (leashWinSurfaceNode != nullptr) {
4817 TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " uiFirstSwitch=%{public}d",
4818 leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), uiFirstSwitch);
4819 leashWinSurfaceNode->SetUIFirstSwitch(uiFirstSwitch);
4820 } else if (surfaceNode != nullptr) {
4821 TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " uiFirstSwitch=%{public}d",
4822 surfaceNode->GetName().c_str(), surfaceNode->GetId(), uiFirstSwitch);
4823 surfaceNode->SetUIFirstSwitch(uiFirstSwitch);
4824 } else {
4825 TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
4826 }
4827 }
4828
CloneWindow(NodeId surfaceNodeId,bool needOffScreen)4829 void SceneSession::CloneWindow(NodeId surfaceNodeId, bool needOffScreen)
4830 {
4831 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::CloneWindow");
4832 AutoRSTransaction trans(GetRSUIContext());
4833 if (auto surfaceNode = GetSurfaceNode()) {
4834 TLOGI(WmsLogTag::WMS_PC, "%{public}s this: %{public}" PRIu64 " cloned: %{public}" PRIu64,
4835 surfaceNode->GetName().c_str(), surfaceNode->GetId(), surfaceNodeId);
4836 surfaceNode->SetClonedNodeInfo(surfaceNodeId, needOffScreen);
4837 }
4838 }
4839
MarkSystemSceneUIFirst(bool isForced,bool isUIFirstEnabled)4840 void SceneSession::MarkSystemSceneUIFirst(bool isForced, bool isUIFirstEnabled)
4841 {
4842 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::MarkSystemSceneUIFirst");
4843 auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
4844 auto surfaceNode = GetSurfaceNode();
4845 if (leashWinSurfaceNode == nullptr && surfaceNode == nullptr) {
4846 TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
4847 return;
4848 }
4849 if (leashWinSurfaceNode != nullptr) {
4850 TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " isForced=%{public}d. isUIFirstEnabled=%{public}d",
4851 leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), isForced, isUIFirstEnabled);
4852 leashWinSurfaceNode->MarkUifirstNode(isForced, isUIFirstEnabled);
4853 } else {
4854 TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " isForced=%{public}d. isUIFirstEnabled=%{public}d",
4855 surfaceNode->GetName().c_str(), surfaceNode->GetId(), isForced, isUIFirstEnabled);
4856 surfaceNode->MarkUifirstNode(isForced, isUIFirstEnabled);
4857 }
4858 }
4859
UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)4860 WSError SceneSession::UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)
4861 {
4862 return PostSyncTask([weakThis = wptr(this), needDefaultAnimationFlag, where = __func__] {
4863 auto session = weakThis.promote();
4864 if (!session) {
4865 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
4866 return WSError::WS_ERROR_DESTROYED_OBJECT;
4867 }
4868 session->needDefaultAnimationFlag_ = needDefaultAnimationFlag;
4869 if (session->onWindowAnimationFlagChange_) {
4870 session->onWindowAnimationFlagChange_(needDefaultAnimationFlag);
4871 }
4872 return WSError::WS_OK;
4873 }, __func__);
4874 }
4875
SetWindowAnimationFlag(bool needDefaultAnimationFlag)4876 void SceneSession::SetWindowAnimationFlag(bool needDefaultAnimationFlag)
4877 {
4878 needDefaultAnimationFlag_ = needDefaultAnimationFlag;
4879 if (onWindowAnimationFlagChange_) {
4880 onWindowAnimationFlagChange_(needDefaultAnimationFlag);
4881 }
4882 return;
4883 }
4884
IsNeedDefaultAnimation() const4885 bool SceneSession::IsNeedDefaultAnimation() const
4886 {
4887 return needDefaultAnimationFlag_;
4888 }
4889
GetFollowScreenChange() const4890 bool SceneSession::GetFollowScreenChange() const
4891 {
4892 return isFollowScreenChange_;
4893 }
4894
SetFollowScreenChange(bool isFollowScreenChange)4895 void SceneSession::SetFollowScreenChange(bool isFollowScreenChange)
4896 {
4897 isFollowScreenChange_ = isFollowScreenChange;
4898 }
4899
IsAppSession() const4900 bool SceneSession::IsAppSession() const
4901 {
4902 if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4903 return true;
4904 }
4905 if (GetMainSession()) {
4906 return true;
4907 }
4908 return false;
4909 }
4910
4911 /** @note @window.focus */
IsAppOrLowerSystemSession() const4912 bool SceneSession::IsAppOrLowerSystemSession() const
4913 {
4914 WindowType windowType = GetWindowType();
4915 if (windowType == WindowType::WINDOW_TYPE_NEGATIVE_SCREEN ||
4916 windowType == WindowType::WINDOW_TYPE_GLOBAL_SEARCH ||
4917 windowType == WindowType::WINDOW_TYPE_DESKTOP) {
4918 return true;
4919 }
4920 return IsAppSession();
4921 }
4922
4923 /** @note @window.focus */
IsSystemSessionAboveApp() const4924 bool SceneSession::IsSystemSessionAboveApp() const
4925 {
4926 WindowType windowType = GetWindowType();
4927 if (windowType == WindowType::WINDOW_TYPE_DIALOG || windowType == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
4928 return true;
4929 }
4930 if (windowType == WindowType::WINDOW_TYPE_PANEL &&
4931 sessionInfo_.bundleName_.find("SCBDropdownPanel") != std::string::npos) {
4932 return true;
4933 }
4934 if (windowType == WindowType::WINDOW_TYPE_FLOAT &&
4935 sessionInfo_.bundleName_.find("SCBGestureDock") != std::string::npos) {
4936 return true;
4937 }
4938 return false;
4939 }
4940
4941 /** @note @window.focus */
IsSameMainSession(const sptr<SceneSession> & prevSession)4942 bool SceneSession::IsSameMainSession(const sptr<SceneSession>& prevSession)
4943 {
4944 if (prevSession == nullptr) {
4945 TLOGE(WmsLogTag::WMS_FOCUS, "prevSession is nullptr");
4946 return false;
4947 }
4948 int32_t currSessionId = GetMainSessionId();
4949 int32_t prevSessionId = prevSession->GetMainSessionId();
4950 return currSessionId == prevSessionId && prevSessionId != INVALID_SESSION_ID;
4951 }
4952
4953 /* @note @window.focus */
IsDelayFocusChange()4954 bool SceneSession::IsDelayFocusChange()
4955 {
4956 return GetHidingStartingWindow();
4957 }
4958
NotifyIsCustomAnimationPlaying(bool isPlaying)4959 void SceneSession::NotifyIsCustomAnimationPlaying(bool isPlaying)
4960 {
4961 WLOGFI("id %{public}d %{public}u", GetPersistentId(), isPlaying);
4962 if (onIsCustomAnimationPlaying_) {
4963 onIsCustomAnimationPlaying_(isPlaying);
4964 }
4965 }
4966
UpdateWindowSceneAfterCustomAnimation(bool isAdd)4967 WSError SceneSession::UpdateWindowSceneAfterCustomAnimation(bool isAdd)
4968 {
4969 if (!SessionPermission::IsSystemCalling()) {
4970 TLOGE(WmsLogTag::WMS_SYSTEM, "failed to update with id:%{public}u!", GetPersistentId());
4971 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4972 }
4973 PostTask([weakThis = wptr(this), isAdd, where = __func__] {
4974 auto session = weakThis.promote();
4975 if (!session) {
4976 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
4977 return WSError::WS_ERROR_DESTROYED_OBJECT;
4978 }
4979 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s id %{public}d, isAdd: %{public}d",
4980 where, session->GetPersistentId(), isAdd);
4981 if (isAdd) {
4982 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s SetOpacityFunc not register %{public}d",
4983 where, session->GetPersistentId());
4984 return WSError::WS_ERROR_INVALID_OPERATION;
4985 } else {
4986 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s background after custom animation id %{public}d",
4987 where, session->GetPersistentId());
4988 // since background will remove surfaceNode
4989 session->Background();
4990 session->NotifyIsCustomAnimationPlaying(false);
4991 }
4992 return WSError::WS_OK;
4993 }, std::string(__func__) + ":" + std::to_string(isAdd));
4994 return WSError::WS_OK;
4995 }
4996
IsFloatingWindowAppType() const4997 bool SceneSession::IsFloatingWindowAppType() const
4998 {
4999 auto property = GetSessionProperty();
5000 if (property == nullptr) {
5001 return false;
5002 }
5003 return property->IsFloatingWindowAppType();
5004 }
5005
GetTouchHotAreas() const5006 std::vector<Rect> SceneSession::GetTouchHotAreas() const
5007 {
5008 std::vector<Rect> touchHotAreas;
5009 auto property = GetSessionProperty();
5010 if (property) {
5011 property->GetTouchHotAreas(touchHotAreas);
5012 }
5013 return touchHotAreas;
5014 }
5015
GetPiPTemplateInfo() const5016 PiPTemplateInfo SceneSession::GetPiPTemplateInfo() const
5017 {
5018 return pipTemplateInfo_;
5019 }
5020
DumpSessionElementInfo(const std::vector<std::string> & params)5021 void SceneSession::DumpSessionElementInfo(const std::vector<std::string>& params)
5022 {
5023 if (!sessionStage_) {
5024 return;
5025 }
5026 return sessionStage_->DumpSessionElementInfo(params);
5027 }
5028
NotifyTouchOutside()5029 void SceneSession::NotifyTouchOutside()
5030 {
5031 WLOGFI("id: %{public}d, type: %{public}d", GetPersistentId(), GetWindowType());
5032 if (sessionStage_) {
5033 WLOGFD("Notify sessionStage TouchOutside");
5034 sessionStage_->NotifyTouchOutside();
5035 }
5036 if (onTouchOutside_) {
5037 WLOGFD("Notify sessionChangeCallback TouchOutside");
5038 onTouchOutside_();
5039 }
5040 }
5041
NotifyWindowVisibility()5042 void SceneSession::NotifyWindowVisibility()
5043 {
5044 if (sessionStage_) {
5045 sessionStage_->NotifyWindowVisibility(GetRSVisible());
5046 } else {
5047 WLOGFE("Notify window(id:%{public}d) visibility failed, for this session stage is nullptr", GetPersistentId());
5048 }
5049 }
5050
CheckTouchOutsideCallbackRegistered()5051 bool SceneSession::CheckTouchOutsideCallbackRegistered()
5052 {
5053 return onTouchOutside_ != nullptr;
5054 }
5055
SetRequestedOrientation(Orientation orientation,bool needAnimation)5056 void SceneSession::SetRequestedOrientation(Orientation orientation, bool needAnimation)
5057 {
5058 WLOGFI("id: %{public}d orientation: %{public}u", GetPersistentId(), static_cast<uint32_t>(orientation));
5059 GetSessionProperty()->SetRequestedOrientation(orientation, needAnimation);
5060 if (onRequestedOrientationChange_) {
5061 onRequestedOrientationChange_(static_cast<uint32_t>(orientation), needAnimation);
5062 }
5063 }
5064
SetDefaultRequestedOrientation(Orientation orientation)5065 WSError SceneSession::SetDefaultRequestedOrientation(Orientation orientation)
5066 {
5067 return PostSyncTask([weakThis = wptr(this), orientation, where = __func__]() -> WSError {
5068 auto session = weakThis.promote();
5069 if (!session) {
5070 TLOGNE(WmsLogTag::DEFAULT, "%{public}s session is null", where);
5071 return WSError::WS_ERROR_NULLPTR;
5072 }
5073 TLOGNI(WmsLogTag::DEFAULT, "%{public}s id: %{public}d defaultRequestedOrientation: %{public}u",
5074 where, session->GetPersistentId(), static_cast<uint32_t>(orientation));
5075 auto property = session->GetSessionProperty();
5076 property->SetRequestedOrientation(orientation);
5077 property->SetDefaultRequestedOrientation(orientation);
5078 property->SetUserRequestedOrientation(orientation);
5079 return WSError::WS_OK;
5080 }, __func__);
5081 }
5082
NotifyForceHideChange(bool hide)5083 void SceneSession::NotifyForceHideChange(bool hide)
5084 {
5085 WLOGFI("id: %{public}d forceHide: %{public}u", persistentId_, hide);
5086 auto property = GetSessionProperty();
5087 if (property == nullptr) {
5088 WLOGFD("id: %{public}d property is nullptr", persistentId_);
5089 return;
5090 }
5091 property->SetForceHide(hide);
5092 if (onForceHideChangeFunc_) {
5093 onForceHideChangeFunc_(hide);
5094 }
5095 SetForceTouchable(!hide);
5096 if (hide) {
5097 if (isFocused_) {
5098 FocusChangeReason reason = FocusChangeReason::DEFAULT;
5099 NotifyRequestFocusStatusNotifyManager(false, true, reason);
5100 SetForceHideState(ForceHideState::HIDDEN_WHEN_FOCUSED);
5101 } else if (forceHideState_ == ForceHideState::NOT_HIDDEN) {
5102 SetForceHideState(ForceHideState::HIDDEN_WHEN_UNFOCUSED);
5103 }
5104 } else {
5105 if (forceHideState_ == ForceHideState::HIDDEN_WHEN_FOCUSED) {
5106 SetForceHideState(ForceHideState::NOT_HIDDEN);
5107 FocusChangeReason reason = FocusChangeReason::DEFAULT;
5108 NotifyRequestFocusStatusNotifyManager(true, true, reason);
5109 } else {
5110 SetForceHideState(ForceHideState::NOT_HIDDEN);
5111 }
5112 }
5113 }
5114
GetRequestedOrientation() const5115 Orientation SceneSession::GetRequestedOrientation() const
5116 {
5117 return GetSessionProperty()->GetRequestedOrientation();
5118 }
5119
IsAnco() const5120 bool SceneSession::IsAnco() const
5121 {
5122 return collaboratorType_ == static_cast<int32_t>(CollaboratorType::RESERVE_TYPE);
5123 }
5124
SetBlank(bool isAddBlank)5125 void SceneSession::SetBlank(bool isAddBlank)
5126 {
5127 isAddBlank_ = isAddBlank;
5128 }
5129
GetBlank() const5130 bool SceneSession::GetBlank() const
5131 {
5132 return isAddBlank_;
5133 }
5134
SetBufferAvailableCallbackEnable(bool enable)5135 void SceneSession::SetBufferAvailableCallbackEnable(bool enable)
5136 {
5137 bufferAvailableCallbackEnable_ = enable;
5138 }
5139
GetBufferAvailableCallbackEnable() const5140 bool SceneSession::GetBufferAvailableCallbackEnable() const
5141 {
5142 return bufferAvailableCallbackEnable_;
5143 }
5144
GetCollaboratorType() const5145 int32_t SceneSession::GetCollaboratorType() const
5146 {
5147 return collaboratorType_;
5148 }
5149
SetCollaboratorType(int32_t collaboratorType)5150 void SceneSession::SetCollaboratorType(int32_t collaboratorType)
5151 {
5152 collaboratorType_ = collaboratorType;
5153 sessionInfo_.collaboratorType_ = collaboratorType;
5154 }
5155
GetClientIdentityToken() const5156 std::string SceneSession::GetClientIdentityToken() const
5157 {
5158 return clientIdentityToken_;
5159 }
5160
SetClientIdentityToken(const std::string & clientIdentityToken)5161 void SceneSession::SetClientIdentityToken(const std::string& clientIdentityToken)
5162 {
5163 clientIdentityToken_ = clientIdentityToken;
5164 }
5165
DumpSessionInfo(std::vector<std::string> & info) const5166 void SceneSession::DumpSessionInfo(std::vector<std::string>& info) const
5167 {
5168 std::string dumpInfo = " Session ID #" + std::to_string(persistentId_);
5169 info.push_back(dumpInfo);
5170 dumpInfo = " session name [" + SessionUtils::ConvertSessionName(sessionInfo_.bundleName_,
5171 sessionInfo_.abilityName_, sessionInfo_.moduleName_, sessionInfo_.appIndex_) + "]";
5172 info.push_back(dumpInfo);
5173 dumpInfo = " runningState [" + std::string(isActive_ ? "FOREGROUND" : "BACKGROUND") + "]";
5174 info.push_back(dumpInfo);
5175 dumpInfo = " lockedState [" + std::to_string(sessionInfo_.lockedState) + "]";
5176 info.push_back(dumpInfo);
5177 auto abilityInfo = sessionInfo_.abilityInfo;
5178 dumpInfo = " continuable [" + (abilityInfo ? std::to_string(abilityInfo->continuable) : " ") + "]";
5179 info.push_back(dumpInfo);
5180 dumpInfo = " timeStamp [" + sessionInfo_.time + "]";
5181 info.push_back(dumpInfo);
5182 dumpInfo = " label [" + (abilityInfo ? abilityInfo->label : " ") + "]";
5183 info.push_back(dumpInfo);
5184 dumpInfo = " iconPath [" + (abilityInfo ? abilityInfo->iconPath : " ") + "]";
5185 info.push_back(dumpInfo);
5186 dumpInfo = " want [" + (sessionInfo_.want ? sessionInfo_.want->ToUri() : " ") + "]";
5187 info.push_back(dumpInfo);
5188 }
5189
GetAbilityInfo() const5190 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSession::GetAbilityInfo() const
5191 {
5192 return GetSessionInfo().abilityInfo;
5193 }
5194
SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)5195 void SceneSession::SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
5196 {
5197 SetSessionInfoAbilityInfo(abilityInfo);
5198 }
5199
SetSessionState(SessionState state)5200 void SceneSession::SetSessionState(SessionState state)
5201 {
5202 Session::SetSessionState(state);
5203 NotifyAccessibilityVisibilityChange();
5204 }
5205
UpdateSessionState(SessionState state)5206 void SceneSession::UpdateSessionState(SessionState state)
5207 {
5208 Session::UpdateSessionState(state);
5209 NotifyAccessibilityVisibilityChange();
5210 }
5211
IsVisibleForAccessibility() const5212 bool SceneSession::IsVisibleForAccessibility() const
5213 {
5214 if (Session::IsScbCoreEnabled()) {
5215 return GetSystemTouchable() && GetForegroundInteractiveStatus() && IsVisibleForeground();
5216 }
5217 return GetSystemTouchable() && GetForegroundInteractiveStatus() &&
5218 (IsVisible() || state_ == SessionState::STATE_ACTIVE || state_ == SessionState::STATE_FOREGROUND);
5219 }
5220
SetForegroundInteractiveStatus(bool interactive)5221 void SceneSession::SetForegroundInteractiveStatus(bool interactive)
5222 {
5223 Session::SetForegroundInteractiveStatus(interactive);
5224 NotifyAccessibilityVisibilityChange();
5225 if (interactive) {
5226 return;
5227 }
5228 for (auto toastSession : toastSession_) {
5229 if (toastSession == nullptr) {
5230 TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
5231 continue;
5232 }
5233 auto state = toastSession->GetSessionState();
5234 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5235 continue;
5236 }
5237 toastSession->SetActive(false);
5238 toastSession->BackgroundTask();
5239 }
5240 }
5241
NotifyAccessibilityVisibilityChange()5242 void SceneSession::NotifyAccessibilityVisibilityChange()
5243 {
5244 bool isVisibleForAccessibilityNew = IsVisibleForAccessibility();
5245 if (isVisibleForAccessibilityNew == isVisibleForAccessibility_.load()) {
5246 return;
5247 }
5248 WLOGFD("[WMSAccess] NotifyAccessibilityVisibilityChange id: %{public}d, access: %{public}d ",
5249 GetPersistentId(), isVisibleForAccessibilityNew);
5250 isVisibleForAccessibility_.store(isVisibleForAccessibilityNew);
5251 if (specificCallback_ && specificCallback_->onWindowInfoUpdate_) {
5252 if (isVisibleForAccessibilityNew) {
5253 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5254 } else {
5255 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
5256 }
5257 } else {
5258 WLOGFD("specificCallback_->onWindowInfoUpdate_ not exist, persistent id: %{public}d", GetPersistentId());
5259 }
5260 }
5261
SetSystemTouchable(bool touchable)5262 void SceneSession::SetSystemTouchable(bool touchable)
5263 {
5264 Session::SetSystemTouchable(touchable);
5265 NotifyAccessibilityVisibilityChange();
5266 }
5267
ChangeSessionVisibilityWithStatusBar(const sptr<AAFwk::SessionInfo> abilitySessionInfo,bool visible)5268 WSError SceneSession::ChangeSessionVisibilityWithStatusBar(
5269 const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool visible)
5270 {
5271 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
5272 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
5273 return WSError::WS_ERROR_INVALID_PERMISSION;
5274 }
5275 PostTask([weakThis = wptr(this), abilitySessionInfo, visible, where = __func__] {
5276 auto session = weakThis.promote();
5277 if (!session) {
5278 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
5279 return WSError::WS_ERROR_DESTROYED_OBJECT;
5280 }
5281 if (abilitySessionInfo == nullptr) {
5282 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s abilitySessionInfo is null", where);
5283 return WSError::WS_ERROR_NULLPTR;
5284 }
5285
5286 SessionInfo info;
5287 info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
5288 info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
5289 info.moduleName_ = abilitySessionInfo->want.GetModuleName();
5290 int32_t appCloneIndex = abilitySessionInfo->want.GetIntParam(APP_CLONE_INDEX, 0);
5291 info.appIndex_ = appCloneIndex == 0 ? abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0) : appCloneIndex;
5292 info.persistentId_ = abilitySessionInfo->persistentId;
5293 info.callerPersistentId_ = session->GetPersistentId();
5294 info.callerBundleName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_BUNDLE_NAME);
5295 info.callerAbilityName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_ABILITY_NAME);
5296 info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
5297 info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
5298 info.requestId = abilitySessionInfo->requestId;
5299 info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
5300 info.requestCode = abilitySessionInfo->requestCode;
5301 info.callerToken_ = abilitySessionInfo->callerToken;
5302 info.startSetting = abilitySessionInfo->startSetting;
5303 info.callingTokenId_ = abilitySessionInfo->callingTokenId;
5304 info.reuse = abilitySessionInfo->reuse;
5305 info.processOptions = abilitySessionInfo->processOptions;
5306
5307 if (session->changeSessionVisibilityWithStatusBarFunc_) {
5308 session->changeSessionVisibilityWithStatusBarFunc_(info, visible);
5309 }
5310
5311 return WSError::WS_OK;
5312 }, __func__);
5313 return WSError::WS_OK;
5314 }
5315
SetAtomicServiceInfo(SessionInfo & sessionInfo)5316 static void SetAtomicServiceInfo(SessionInfo& sessionInfo)
5317 {
5318 #ifdef ACE_ENGINE_PLUGIN_PATH
5319 AtomicServiceInfo* atomicServiceInfo = AtomicServiceBasicEnginePlugin::GetInstance().
5320 GetParamsFromAtomicServiceBasicEngine(sessionInfo.bundleName_);
5321 if (atomicServiceInfo != nullptr) {
5322 sessionInfo.atomicServiceInfo_.appNameInfo_ = atomicServiceInfo->GetAppName();
5323 sessionInfo.atomicServiceInfo_.circleIcon_ = atomicServiceInfo->GetCircleIcon();
5324 sessionInfo.atomicServiceInfo_.eyelashRingIcon_ = atomicServiceInfo->GetEyelashRingIcon();
5325 sessionInfo.atomicServiceInfo_.deviceTypes_ = atomicServiceInfo->GetDeviceTypes();
5326 sessionInfo.atomicServiceInfo_.resizable_ = atomicServiceInfo->GetResizable();
5327 sessionInfo.atomicServiceInfo_.supportWindowMode_ = atomicServiceInfo->GetSupportWindowMode();
5328 }
5329 AtomicServiceBasicEnginePlugin::GetInstance().ReleaseData();
5330 #endif
5331 }
5332
MakeSessionInfoDuringPendingActivation(const sptr<AAFwk::SessionInfo> & abilitySessionInfo,const sptr<SceneSession> & session,bool isFoundationCall)5333 static SessionInfo MakeSessionInfoDuringPendingActivation(const sptr<AAFwk::SessionInfo>& abilitySessionInfo,
5334 const sptr<SceneSession>& session, bool isFoundationCall)
5335 {
5336 SessionInfo info;
5337 info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
5338 info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
5339 info.moduleName_ = abilitySessionInfo->want.GetModuleName();
5340 int32_t appCloneIndex = abilitySessionInfo->want.GetIntParam(APP_CLONE_INDEX, 0);
5341 info.appIndex_ = appCloneIndex == 0 ? abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0) : appCloneIndex;
5342 info.persistentId_ = abilitySessionInfo->persistentId;
5343 info.callerPersistentId_ = session->GetPersistentId();
5344 info.callerBundleName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_BUNDLE_NAME);
5345 info.callerAbilityName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_ABILITY_NAME);
5346 info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
5347 info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
5348 info.requestId = abilitySessionInfo->requestId;
5349 info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
5350 info.requestCode = abilitySessionInfo->requestCode;
5351 info.callerToken_ = abilitySessionInfo->callerToken;
5352 info.startSetting = abilitySessionInfo->startSetting;
5353 info.callingTokenId_ = abilitySessionInfo->callingTokenId;
5354 info.reuse = abilitySessionInfo->reuse;
5355 info.processOptions = abilitySessionInfo->processOptions;
5356 info.isAtomicService_ = abilitySessionInfo->isAtomicService;
5357 info.isBackTransition_ = abilitySessionInfo->isBackTransition;
5358 info.needClearInNotShowRecent_ = abilitySessionInfo->needClearInNotShowRecent;
5359 info.appInstanceKey_ = abilitySessionInfo->instanceKey;
5360 info.isFromIcon_ = abilitySessionInfo->isFromIcon;
5361 info.isPcOrPadEnableActivation_ = session->IsPcOrPadEnableActivation();
5362 info.canStartAbilityFromBackground_ = abilitySessionInfo->canStartAbilityFromBackground;
5363 info.isFoundationCall_ = isFoundationCall;
5364 info.specifiedFlag_ = abilitySessionInfo->specifiedFlag;
5365 info.reuseDelegatorWindow = abilitySessionInfo->reuseDelegatorWindow;
5366 if (session->IsPcOrPadEnableActivation()) {
5367 info.startWindowOption = abilitySessionInfo->startWindowOption;
5368 int32_t maxWindowWidth = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_RESV_MAX_WINDOW_WIDTH, 0);
5369 info.windowSizeLimits.maxWindowWidth = static_cast<std::uint32_t>(maxWindowWidth > 0 ? maxWindowWidth : 0);
5370 int32_t minWindowWidth = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_RESV_MIN_WINDOW_WIDTH, 0);
5371 info.windowSizeLimits.minWindowWidth = static_cast<std::uint32_t>(minWindowWidth > 0 ? minWindowWidth : 0);
5372 int32_t maxWindowHeight = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_RESV_MAX_WINDOW_HEIGHT, 0);
5373 info.windowSizeLimits.maxWindowHeight = static_cast<std::uint32_t>(maxWindowHeight > 0 ? maxWindowHeight : 0);
5374 int32_t minWindowHeight = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_RESV_MIN_WINDOW_HEIGHT, 0);
5375 info.windowSizeLimits.minWindowHeight = static_cast<std::uint32_t>(minWindowHeight > 0 ? minWindowHeight : 0);
5376 if (!abilitySessionInfo->supportWindowModes.empty()) {
5377 info.supportedWindowModes.assign(abilitySessionInfo->supportWindowModes.begin(),
5378 abilitySessionInfo->supportWindowModes.end());
5379 }
5380 }
5381 if (info.isAtomicService_ && info.want != nullptr &&
5382 (info.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) == AAFwk::Want::FLAG_INSTALL_ON_DEMAND) {
5383 SetAtomicServiceInfo(info);
5384 }
5385 if (info.want != nullptr) {
5386 info.windowMode = info.want->GetIntParam(AAFwk::Want::PARAM_RESV_WINDOW_MODE, 0);
5387 info.sessionAffinity = info.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
5388 info.screenId_ = static_cast<uint64_t>(info.want->GetIntParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, -1));
5389 TLOGI(WmsLogTag::WMS_LIFE, "want: screenId %{public}" PRIu64, info.screenId_);
5390 }
5391 if (info.windowMode == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN)) {
5392 info.fullScreenStart_ = true;
5393 }
5394 info.scenarios = abilitySessionInfo->scenarios;
5395 session->CalculatedStartWindowType(info, abilitySessionInfo->hideStartWindow);
5396 if (abilitySessionInfo->windowCreateParams) {
5397 if (abilitySessionInfo->windowCreateParams->animationSystemParams &&
5398 SessionPermission::IsSystemAppCallByCallingTokenID(info.callingTokenId_)) {
5399 info.startAnimationSystemOptions = abilitySessionInfo->windowCreateParams->animationSystemParams;
5400 }
5401 info.startAnimationOptions = abilitySessionInfo->windowCreateParams->animationParams;
5402 }
5403 TLOGI(WmsLogTag::WMS_LIFE, "bundleName:%{public}s, moduleName:%{public}s, abilityName:%{public}s, "
5404 "appIndex:%{public}d, affinity:%{public}s. callState:%{public}d, want persistentId:%{public}d, "
5405 "uiAbilityId:%{public}" PRIu64 ", windowMode:%{public}d, callerId:%{public}d, "
5406 "needClearInNotShowRecent:%{public}u, appInstanceKey: %{public}s, isFromIcon:%{public}d, "
5407 "supportedWindowModes.size:%{public}zu, requestId:%{public}d, "
5408 "maxWindowWidth:%{public}d, minWindowWidth:%{public}d, maxWindowHeight:%{public}d, minWindowHeight:%{public}d, "
5409 "reuseDelegatorWindow:%{public}d, startWindowType:%{public}d",
5410 info.bundleName_.c_str(), info.moduleName_.c_str(), info.abilityName_.c_str(), info.appIndex_,
5411 info.sessionAffinity.c_str(), info.callState_, info.persistentId_, info.uiAbilityId_, info.windowMode,
5412 info.callerPersistentId_, info.needClearInNotShowRecent_, info.appInstanceKey_.c_str(), info.isFromIcon_,
5413 info.supportedWindowModes.size(), info.requestId,
5414 info.windowSizeLimits.maxWindowWidth, info.windowSizeLimits.minWindowWidth,
5415 info.windowSizeLimits.maxWindowHeight, info.windowSizeLimits.minWindowHeight,
5416 info.reuseDelegatorWindow, info.startWindowType_);
5417 return info;
5418 }
5419
CalculatedStartWindowType(SessionInfo & info,bool hideStartWindow)5420 void SceneSession::CalculatedStartWindowType(SessionInfo& info, bool hideStartWindow)
5421 {
5422 if (getStartWindowConfigFunc_ == nullptr || GetSessionInfo().bundleName_ != info.bundleName_) {
5423 TLOGI(WmsLogTag::WMS_LIFE, "only same app in pc or pcMode.");
5424 return;
5425 }
5426 std::string startWindowType;
5427 getStartWindowConfigFunc_(info, startWindowType);
5428 if (startWindowType == OPTIONAL_SHOW) {
5429 info.startWindowType_ = StartWindowType::DEFAULT;
5430 if (hideStartWindow) {
5431 info.startWindowType_ = StartWindowType::RETAIN_AND_INVISIBLE;
5432 SetHidingStartingWindow(true);
5433 }
5434 info.isSetStartWindowType_ = true;
5435 }
5436 }
5437
RegisterGetStartWindowConfigFunc(GetStartWindowTypeFunc && func)5438 void SceneSession::RegisterGetStartWindowConfigFunc(GetStartWindowTypeFunc&& func)
5439 {
5440 getStartWindowConfigFunc_ = std::move(func);
5441 }
5442
PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)5443 WSError SceneSession::PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
5444 {
5445 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
5446 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
5447 return WSError::WS_ERROR_INVALID_PERMISSION;
5448 }
5449 bool isFoundationCall = SessionPermission::IsFoundationCall();
5450 PostTask([weakThis = wptr(this), abilitySessionInfo, isFoundationCall, where = __func__] {
5451 OHOS::HiviewDFX::HiTraceId hiTraceId = OHOS::HiviewDFX::HiTraceChain::GetId();
5452 bool isValid = hiTraceId.IsValid();
5453 if (!isValid) {
5454 hiTraceId = OHOS::HiviewDFX::HiTraceChain::Begin("WindowCreateOnCall",
5455 HiTraceFlag::HITRACE_FLAG_INCLUDE_ASYNC | HiTraceFlag::HITRACE_FLAG_NO_BE_INFO |
5456 HiTraceFlag::HITRACE_FLAG_DONOT_CREATE_SPAN);
5457 }
5458 auto session = weakThis.promote();
5459 if (!session) {
5460 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
5461 if (!isValid) {
5462 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
5463 }
5464 return WSError::WS_ERROR_DESTROYED_OBJECT;
5465 }
5466 if (abilitySessionInfo == nullptr) {
5467 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s abilitySessionInfo is null", where);
5468 if (!isValid) {
5469 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
5470 }
5471 return WSError::WS_ERROR_NULLPTR;
5472 }
5473 bool isFromAncoAndToAnco = session->IsAnco() && AbilityInfoManager::GetInstance().IsAnco(
5474 abilitySessionInfo->want.GetElement().GetBundleName(),
5475 abilitySessionInfo->want.GetElement().GetAbilityName(), abilitySessionInfo->want.GetModuleName());
5476 if (session->DisallowActivationFromPendingBackground(session->IsPcOrPadEnableActivation(), isFoundationCall,
5477 abilitySessionInfo->canStartAbilityFromBackground, isFromAncoAndToAnco)) {
5478 if (!isValid) {
5479 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
5480 }
5481 return WSError::WS_ERROR_INVALID_OPERATION;
5482 }
5483 session->sessionInfo_.startMethod = StartMethod::START_CALL;
5484 SessionInfo info = MakeSessionInfoDuringPendingActivation(abilitySessionInfo, session, isFoundationCall);
5485 if (MultiInstanceManager::IsSupportMultiInstance(session->systemConfig_) &&
5486 MultiInstanceManager::GetInstance().IsMultiInstance(info.bundleName_)) {
5487 if (!MultiInstanceManager::GetInstance().MultiInstancePendingSessionActivation(info)) {
5488 TLOGNE(WmsLogTag::WMS_LIFE,
5489 "%{public}s multi instance start fail, id:%{public}d instanceKey:%{public}s",
5490 where, session->GetPersistentId(), info.appInstanceKey_.c_str());
5491 if (!isValid) {
5492 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
5493 }
5494 return WSError::WS_ERROR_INVALID_PARAM;
5495 }
5496 }
5497 session->HandleCastScreenConnection(info, session);
5498 if (info.reuseDelegatorWindow) {
5499 if (!session->hookSceneSessionActivationFunc_) {
5500 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s hookSceneSessionActivationFunc is null, id: %{public}d",
5501 where, session->persistentId_);
5502 if (!isValid) {
5503 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
5504 }
5505 return WSError::WS_ERROR_NULLPTR;
5506 }
5507 session->hookSceneSessionActivationFunc_(session, false);
5508 if (!isValid) {
5509 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
5510 }
5511 return WSError::WS_OK;
5512 }
5513 if (session->pendingSessionActivationFunc_) {
5514 session->pendingSessionActivationFunc_(info);
5515 }
5516 if (!isValid) {
5517 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
5518 }
5519 return WSError::WS_OK;
5520 }, __func__);
5521 return WSError::WS_OK;
5522 }
5523
DoBatchPendingSessionsActivation(const std::vector<sptr<AAFwk::SessionInfo>> & abilitySessionInfos,sptr<SceneSession> & session,bool isFoundationCall)5524 WSError SceneSession::DoBatchPendingSessionsActivation(
5525 const std::vector<sptr<AAFwk::SessionInfo>>& abilitySessionInfos,
5526 sptr<SceneSession>& session, bool isFoundationCall)
5527 {
5528 std::vector<std::shared_ptr<SessionInfo>> sessionInfos;
5529 for (auto& abilitySessionInfo : abilitySessionInfos) {
5530 if (abilitySessionInfo == nullptr) {
5531 TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
5532 return WSError::WS_ERROR_NULLPTR;
5533 }
5534 bool isFromAncoAndToAnco = session->IsAnco() && AbilityInfoManager::GetInstance().IsAnco(
5535 abilitySessionInfo->want.GetElement().GetBundleName(),
5536 abilitySessionInfo->want.GetElement().GetAbilityName(), abilitySessionInfo->want.GetModuleName());
5537 if (session->DisallowActivationFromPendingBackground(session->IsPcOrPadEnableActivation(), isFoundationCall,
5538 abilitySessionInfo->canStartAbilityFromBackground, isFromAncoAndToAnco)) {
5539 return WSError::WS_ERROR_INVALID_OPERATION;
5540 }
5541 std::shared_ptr<SessionInfo> info =
5542 std::make_shared<SessionInfo>(
5543 MakeSessionInfoDuringPendingActivation(abilitySessionInfo, session, isFoundationCall));
5544 sessionInfos.emplace_back(info);
5545 if (MultiInstanceManager::IsSupportMultiInstance(session->systemConfig_) &&
5546 MultiInstanceManager::GetInstance().IsMultiInstance(info->bundleName_)) {
5547 if (!MultiInstanceManager::GetInstance().MultiInstancePendingSessionActivation(*info)) {
5548 TLOGE(WmsLogTag::WMS_LIFE,
5549 "multi instance start fail, id:%{public}d instanceKey:%{public}s",
5550 session->GetPersistentId(), info->appInstanceKey_.c_str());
5551 return WSError::WS_ERROR_INVALID_PARAM;
5552 }
5553 }
5554 session->sessionInfo_.reuseDelegatorWindow = abilitySessionInfo->reuseDelegatorWindow;
5555 session->HandleCastScreenConnection(*info, session);
5556 }
5557 session->sessionInfo_.startMethod = StartMethod::START_CALL;
5558 if (session->batchPendingSessionsActivationFunc_) {
5559 session->batchPendingSessionsActivationFunc_(sessionInfos);
5560 }
5561 return WSError::WS_OK;
5562 }
5563
BatchPendingSessionsActivation(const std::vector<sptr<AAFwk::SessionInfo>> & abilitySessionInfos)5564 WSError SceneSession::BatchPendingSessionsActivation(const std::vector<sptr<AAFwk::SessionInfo>>& abilitySessionInfos)
5565 {
5566 TLOGI(WmsLogTag::WMS_LIFE, "Batch pending session activations size: %{public}zu", abilitySessionInfos.size());
5567 if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
5568 TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
5569 return WSError::WS_ERROR_INVALID_PERMISSION;
5570 }
5571 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
5572 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
5573 return WSError::WS_ERROR_INVALID_PERMISSION;
5574 }
5575
5576 bool isFoundationCall = SessionPermission::IsFoundationCall();
5577 PostTask([weakThis = wptr(this), abilitySessionInfos, isFoundationCall, where = __func__] {
5578 auto session = weakThis.promote();
5579 if (!session) {
5580 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
5581 return WSError::WS_ERROR_DESTROYED_OBJECT;
5582 }
5583 if (abilitySessionInfos.empty()) {
5584 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s abilitySessionInfo is null", where);
5585 return WSError::WS_ERROR_NULLPTR;
5586 }
5587 return session->DoBatchPendingSessionsActivation(abilitySessionInfos, session, isFoundationCall);
5588 }, __func__);
5589 return WSError::WS_OK;
5590 }
5591
DisallowActivationFromPendingBackground(bool isPcOrPadEnableActivation,bool isFoundationCall,bool canStartAbilityFromBackground,bool isFromAncoAndToAnco)5592 bool SceneSession::DisallowActivationFromPendingBackground(bool isPcOrPadEnableActivation, bool isFoundationCall,
5593 bool canStartAbilityFromBackground, bool isFromAncoAndToAnco)
5594 {
5595 if (isPcOrPadEnableActivation || !WindowHelper::IsMainWindow(GetWindowType())) {
5596 return false;
5597 }
5598 bool isPendingToBackgroundState = GetIsPendingToBackgroundState();
5599 bool foregroundInteractiveStatus = GetForegroundInteractiveStatus();
5600 TLOGI(WmsLogTag::WMS_LIFE, "session state:%{public}d, isFoundationCall:%{public}u, "
5601 "canStartAbilityFromBackground:%{public}u, foregroundInteractiveStatus:%{public}u, "
5602 "isPendingToBackgroundState:%{public}u, isFromAncoAndToAnco:%{public}u",
5603 GetSessionState(), isFoundationCall, canStartAbilityFromBackground, foregroundInteractiveStatus,
5604 isPendingToBackgroundState, isFromAncoAndToAnco);
5605 bool isSessionForeground = GetSessionState() == SessionState::STATE_FOREGROUND ||
5606 GetSessionState() == SessionState::STATE_ACTIVE;
5607 if (isSessionForeground) {
5608 if (isPendingToBackgroundState) {
5609 if (!(isFoundationCall && canStartAbilityFromBackground) && !isFromAncoAndToAnco) {
5610 TLOGW(WmsLogTag::WMS_LIFE, "no permission to start ability from PendingBackground, id:%{public}d",
5611 GetPersistentId());
5612 return true;
5613 }
5614 } else if (!foregroundInteractiveStatus) {
5615 TLOGW(WmsLogTag::WMS_LIFE, "start ability invalid, session in a non interactive state");
5616 return true;
5617 }
5618 } else if (!(isFoundationCall && canStartAbilityFromBackground) && !isFromAncoAndToAnco) {
5619 TLOGW(WmsLogTag::WMS_LIFE, "no permission to start ability from Background, id:%{public}d",
5620 GetPersistentId());
5621 return true;
5622 }
5623 return false;
5624 }
5625
HandleCastScreenConnection(SessionInfo & info,sptr<SceneSession> session)5626 void SceneSession::HandleCastScreenConnection(SessionInfo& info, sptr<SceneSession> session)
5627 {
5628 ScreenId defScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5629 if (defScreenId == info.screenId_) {
5630 return;
5631 }
5632 auto flag = Rosen::ScreenManager::GetInstance().GetVirtualScreenFlag(info.screenId_);
5633 if (flag != VirtualScreenFlag::CAST) {
5634 return;
5635 }
5636 TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state :%{public}d persistentId:%{public}d",
5637 session->GetSessionState(), info.callerPersistentId_);
5638 if (session->GetSessionState() != SessionState::STATE_FOREGROUND &&
5639 session->GetSessionState() != SessionState::STATE_ACTIVE) {
5640 TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state is not foreground");
5641 return;
5642 }
5643 info.isCastSession_ = true;
5644 std::vector<uint64_t> mirrorIds { info.screenId_ };
5645 Rosen::DMError ret = Rosen::ScreenManager::GetInstance().MakeUniqueScreen(mirrorIds);
5646 if (ret != Rosen::DMError::DM_OK) {
5647 TLOGE(WmsLogTag::WMS_LIFE, "MakeUniqueScreen failed,ret: %{public}d", ret);
5648 return;
5649 }
5650 }
5651
IsNeedSystemPermissionByAction(WSPropertyChangeAction action,const sptr<WindowSessionProperty> & property,const sptr<WindowSessionProperty> & sessionProperty)5652 static bool IsNeedSystemPermissionByAction(WSPropertyChangeAction action,
5653 const sptr<WindowSessionProperty>& property, const sptr<WindowSessionProperty>& sessionProperty)
5654 {
5655 switch (action) {
5656 case WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON:
5657 case WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP:
5658 case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
5659 case WSPropertyChangeAction::ACTION_UPDATE_TOPMOST:
5660 case WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE:
5661 case WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO:
5662 return true;
5663 case WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG:
5664 return property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM);
5665 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS: {
5666 uint32_t oldFlags = sessionProperty->GetWindowFlags();
5667 uint32_t flags = property->GetWindowFlags();
5668 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) {
5669 return true;
5670 }
5671 break;
5672 }
5673 default:
5674 break;
5675 }
5676 return false;
5677 }
5678
UpdateSessionPropertyByAction(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5679 WMError SceneSession::UpdateSessionPropertyByAction(const sptr<WindowSessionProperty>& property,
5680 WSPropertyChangeAction action)
5681 {
5682 if (property == nullptr) {
5683 TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
5684 return WMError::WM_ERROR_NULLPTR;
5685 }
5686 auto sessionProperty = GetSessionProperty();
5687 if (sessionProperty == nullptr) {
5688 TLOGE(WmsLogTag::DEFAULT, "get session property failed");
5689 return WMError::WM_ERROR_NULLPTR;
5690 }
5691 if (action == WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE) {
5692 if (!SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
5693 return WMError::WM_ERROR_INVALID_PERMISSION;
5694 }
5695 }
5696 if (action == WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST) {
5697 uint32_t accessTokenId = property->GetAccessTokenId();
5698 if (!SessionPermission::VerifyPermissionByCallerToken(accessTokenId,
5699 PermissionConstants::PERMISSION_MAIN_WINDOW_TOPMOST)) {
5700 TLOGE(WmsLogTag::WMS_HIERARCHY, "The caller has no permission granted.");
5701 return WMError::WM_ERROR_INVALID_PERMISSION;
5702 }
5703 }
5704
5705 bool isSystemCalling = SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd();
5706 if (!isSystemCalling && IsNeedSystemPermissionByAction(action, property, sessionProperty)) {
5707 TLOGE(WmsLogTag::DEFAULT, "permission denied! action: %{public}" PRIu64, action);
5708 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5709 }
5710 property->SetSystemCalling(isSystemCalling);
5711 auto task = [weak = wptr(this), property, action, where = __func__]() -> WMError {
5712 auto sceneSession = weak.promote();
5713 if (sceneSession == nullptr) {
5714 TLOGNE(WmsLogTag::DEFAULT, "%{public}s the session is nullptr", where);
5715 return WMError::WM_DO_NOTHING;
5716 }
5717 TLOGND(WmsLogTag::DEFAULT, "%{public}s Id: %{public}d, action: %{public}" PRIu64,
5718 where, sceneSession->GetPersistentId(), action);
5719 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession:UpdateProperty");
5720 return sceneSession->HandleUpdatePropertyByAction(property, action);
5721 };
5722 if (AppExecFwk::EventRunner::IsAppMainThread()) {
5723 PostTask(std::move(task), __func__);
5724 return WMError::WM_OK;
5725 }
5726 return PostSyncTask(std::move(task), __func__);
5727 }
5728
SetGestureBackEnabled(bool isEnabled)5729 WMError SceneSession::SetGestureBackEnabled(bool isEnabled)
5730 {
5731 PostTask([weakThis = wptr(this), isEnabled, where = __func__] {
5732 auto sceneSession = weakThis.promote();
5733 if (!sceneSession) {
5734 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is invalid", where);
5735 return;
5736 }
5737 if (sceneSession->isEnableGestureBack_ == isEnabled) {
5738 TLOGND(WmsLogTag::WMS_IMMS, "%{public}s isEnabled equals last", where);
5739 return;
5740 }
5741 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d isEnabled %{public}d",
5742 where, sceneSession->GetPersistentId(), isEnabled);
5743 sceneSession->isEnableGestureBack_ = isEnabled;
5744 sceneSession->isEnableGestureBackHadSet_ = true;
5745 sceneSession->UpdateGestureBackEnabled();
5746 }, __func__);
5747 return WMError::WM_OK;
5748 }
5749
GetGestureBackEnabled()5750 bool SceneSession::GetGestureBackEnabled()
5751 {
5752 return isEnableGestureBack_;
5753 }
5754
GetEnableGestureBackHadSet()5755 bool SceneSession::GetEnableGestureBackHadSet()
5756 {
5757 return isEnableGestureBackHadSet_;
5758 }
5759
UpdateFullScreenWaterfallMode(bool isWaterfallMode)5760 void SceneSession::UpdateFullScreenWaterfallMode(bool isWaterfallMode)
5761 {
5762 PostTask([weakThis = wptr(this), isWaterfallMode, where = __func__] {
5763 auto session = weakThis.promote();
5764 if (session == nullptr) {
5765 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is nullptr", where);
5766 return;
5767 }
5768 if (session->pcFoldScreenController_ == nullptr) {
5769 return;
5770 }
5771 session->pcFoldScreenController_->UpdateFullScreenWaterfallMode(isWaterfallMode);
5772 }, __func__);
5773 }
5774
IsFullScreenWaterfallMode()5775 bool SceneSession::IsFullScreenWaterfallMode()
5776 {
5777 if (pcFoldScreenController_ == nullptr) {
5778 return false;
5779 }
5780 return pcFoldScreenController_->IsFullScreenWaterfallMode();
5781 }
5782
SetFullScreenWaterfallMode(bool isFullScreenWaterfallMode)5783 void SceneSession::SetFullScreenWaterfallMode(bool isFullScreenWaterfallMode)
5784 {
5785 if (pcFoldScreenController_ == nullptr) {
5786 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d pcFoldScreenController is null", GetPersistentId());
5787 return;
5788 }
5789 return pcFoldScreenController_->SetFullScreenWaterfallMode(isFullScreenWaterfallMode);
5790 }
5791
GetWaterfallMode(bool & isWaterfallMode)5792 WSError SceneSession::GetWaterfallMode(bool& isWaterfallMode)
5793 {
5794 isWaterfallMode = IsFullScreenWaterfallMode();
5795 return WSError::WS_OK;
5796 }
5797
IsMainWindowFullScreenAcrossDisplays(bool & isAcrossDisplays)5798 WMError SceneSession::IsMainWindowFullScreenAcrossDisplays(bool& isAcrossDisplays)
5799 {
5800 if (!SessionPermission::IsSystemCalling()) {
5801 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d permission denied!", GetPersistentId());
5802 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5803 }
5804 if (!WindowHelper::IsAppWindow(GetWindowType())) {
5805 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid window: %{public}d type %{public}u",
5806 GetPersistentId(), GetWindowType());
5807 return WMError::WM_ERROR_INVALID_CALLING;
5808 }
5809 auto parentSession = GetSceneSessionById(GetMainSessionId());
5810 if (!parentSession) {
5811 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d parent session is null", GetPersistentId());
5812 return WMError::WM_ERROR_NULLPTR;
5813 }
5814 isAcrossDisplays = parentSession->IsFullScreenWaterfallMode();
5815 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d isAcrossDisplays: %{public}u",
5816 GetPersistentId(), isAcrossDisplays);
5817 return WMError::WM_OK;
5818 }
5819
NotifySubSessionAcrossDisplaysChange(bool isAcrossDisplays)5820 WMError SceneSession::NotifySubSessionAcrossDisplaysChange(bool isAcrossDisplays)
5821 {
5822 std::vector<sptr<SceneSession>> subSessionVec = GetSubSession();
5823 for (const auto& subSession : subSessionVec) {
5824 if (subSession == nullptr) {
5825 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "subsession is null");
5826 continue;
5827 }
5828 subSession->NotifySubSessionAcrossDisplaysChange(isAcrossDisplays);
5829 if (!subSession->GetIsRegisterAcrossMultiDisplayChanged()) {
5830 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "subsession: %{public}d not register", subSession->GetPersistentId());
5831 continue;
5832 }
5833 NotifySessionAcrossDisplaysChange(subSession, isAcrossDisplays);
5834 }
5835 return WMError::WM_OK;
5836 }
5837
NotifyFollowedParentWindowAcrossDisplaysChange(bool isAcrossDisplays)5838 WMError SceneSession::NotifyFollowedParentWindowAcrossDisplaysChange(bool isAcrossDisplays)
5839 {
5840 std::unordered_map<int32_t, NotifySurfaceBoundsChangeFunc> funcMap;
5841 {
5842 std::lock_guard lock(registerNotifySurfaceBoundsChangeMutex_);
5843 funcMap = notifySurfaceBoundsChangeFuncMap_;
5844 }
5845 for (const auto& [sessionId, _] : funcMap) {
5846 auto subSession = GetSceneSessionById(sessionId);
5847 if (subSession == nullptr) {
5848 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "subsession is null");
5849 continue;
5850 }
5851 if (!subSession->GetIsFollowParentLayout()) {
5852 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "subsession: %{public}d not follow", subSession->GetPersistentId());
5853 continue;
5854 }
5855 NotifySessionAcrossDisplaysChange(subSession, isAcrossDisplays);
5856 }
5857 return WMError::WM_OK;
5858 }
5859
NotifySessionAcrossDisplaysChange(const sptr<SceneSession> & sceneSession,bool isAcrossDisplays)5860 void SceneSession::NotifySessionAcrossDisplaysChange(const sptr<SceneSession>& sceneSession, bool isAcrossDisplays)
5861 {
5862 if (sceneSession->sessionStage_ == nullptr) {
5863 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "%{public}d: sessionStage is null", sceneSession->GetPersistentId());
5864 return;
5865 }
5866 sceneSession->sessionStage_->SetFullScreenWaterfallMode(isAcrossDisplays);
5867 sceneSession->SetFullScreenWaterfallMode(isAcrossDisplays);
5868 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d isAcrossDisplays: %{public}u",
5869 sceneSession->GetPersistentId(), isAcrossDisplays);
5870 }
5871
RegisterFullScreenWaterfallModeChangeCallback(std::function<void (bool isWaterfallMode)> && func)5872 void SceneSession::RegisterFullScreenWaterfallModeChangeCallback(std::function<void(bool isWaterfallMode)>&& func)
5873 {
5874 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__]() mutable {
5875 auto session = weakThis.promote();
5876 if (session == nullptr) {
5877 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is nullptr", where);
5878 return;
5879 }
5880 if (session->pcFoldScreenController_ == nullptr) {
5881 return;
5882 }
5883 session->pcFoldScreenController_->RegisterFullScreenWaterfallModeChangeCallback(std::move(func));
5884 }, __func__);
5885 }
5886
RegisterThrowSlipAnimationStateChangeCallback(std::function<void (bool isAnimating,bool isFullScreen)> && func)5887 void SceneSession::RegisterThrowSlipAnimationStateChangeCallback(
5888 std::function<void(bool isAnimating, bool isFullScreen)>&& func)
5889 {
5890 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__]() mutable {
5891 auto session = weakThis.promote();
5892 if (session == nullptr) {
5893 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is nullptr", where);
5894 return;
5895 }
5896 session->onThrowSlipAnimationStateChangeFunc_ = std::move(func);
5897 }, __func__);
5898 }
5899
IsMissionHighlighted()5900 bool SceneSession::IsMissionHighlighted()
5901 {
5902 if (!SessionHelper::IsMainWindow(GetWindowType())) {
5903 return false;
5904 }
5905 if (IsFocused()) {
5906 return true;
5907 }
5908 return std::any_of(subSession_.begin(), subSession_.end(),
5909 [](const sptr<SceneSession>& sceneSession) {
5910 return sceneSession != nullptr && sceneSession->IsMissionHighlighted();
5911 });
5912 }
5913
IsPcFoldDevice()5914 bool SceneSession::IsPcFoldDevice()
5915 {
5916 return (pcFoldScreenController_ != nullptr);
5917 }
5918
MaskSupportEnterWaterfallMode()5919 void SceneSession::MaskSupportEnterWaterfallMode()
5920 {
5921 if (pcFoldScreenController_ == nullptr) {
5922 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "pcFoldScreenController is null");
5923 return;
5924 }
5925 pcFoldScreenController_->MaskSupportEnterWaterfallMode();
5926 }
5927
SetSupportEnterWaterfallMode(bool isSupportEnter)5928 void SceneSession::SetSupportEnterWaterfallMode(bool isSupportEnter)
5929 {
5930 if (!sessionStage_) {
5931 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sessionStage is nullptr");
5932 return;
5933 }
5934 sessionStage_->SetSupportEnterWaterfallMode(isSupportEnter);
5935 }
5936
SetSessionChangeByActionNotifyManagerListener(const SessionChangeByActionNotifyManagerFunc & func)5937 void SceneSession::SetSessionChangeByActionNotifyManagerListener(const SessionChangeByActionNotifyManagerFunc& func)
5938 {
5939 TLOGD(WmsLogTag::DEFAULT, "setListener success");
5940 sessionChangeByActionNotifyManagerFunc_ = func;
5941 }
5942
HandleUpdatePropertyByAction(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5943 WMError SceneSession::HandleUpdatePropertyByAction(const sptr<WindowSessionProperty>& property,
5944 WSPropertyChangeAction action)
5945 {
5946 if (property == nullptr) {
5947 TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
5948 return WMError::WM_ERROR_NULLPTR;
5949 }
5950
5951 return ProcessUpdatePropertyByAction(property, action);
5952 }
5953
ProcessUpdatePropertyByAction(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5954 WMError SceneSession::ProcessUpdatePropertyByAction(const sptr<WindowSessionProperty>& property,
5955 WSPropertyChangeAction action)
5956 {
5957 switch (static_cast<uint64_t>(action)) {
5958 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON):
5959 return HandleActionUpdateTurnScreenOn(property, action);
5960 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON):
5961 return HandleActionUpdateKeepScreenOn(property, action);
5962 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_VIEW_KEEP_SCREEN_ON):
5963 return HandleActionUpdateViewKeepScreenOn(property, action);
5964 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE):
5965 return HandleActionUpdateFocusable(property, action);
5966 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE):
5967 return HandleActionUpdateTouchable(property, action);
5968 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS):
5969 return HandleActionUpdateSetBrightness(property, action);
5970 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_ORIENTATION):
5971 return HandleActionUpdateOrientation(property, action);
5972 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE):
5973 return HandleActionUpdatePrivacyMode(property, action);
5974 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE):
5975 return HandleActionUpdatePrivacyMode(property, action);
5976 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP):
5977 return HandleActionUpdateSnapshotSkip(property, action);
5978 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE):
5979 return HandleActionUpdateMaximizeState(property, action);
5980 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS):
5981 return HandleActionUpdateOtherProps(property, action);
5982 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS):
5983 return HandleActionUpdateStatusProps(property, action);
5984 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS):
5985 return HandleActionUpdateNavigationProps(property, action);
5986 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS):
5987 return HandleActionUpdateNavigationIndicatorProps(property, action);
5988 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_FLAGS):
5989 return HandleActionUpdateFlags(property, action);
5990 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_MODE):
5991 return HandleActionUpdateMode(property, action);
5992 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG):
5993 return HandleActionUpdateAnimationFlag(property, action);
5994 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA):
5995 return HandleActionUpdateTouchHotArea(property, action);
5996 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_KEYBOARD_TOUCH_HOT_AREA):
5997 return HandleActionUpdateKeyboardTouchHotArea(property, action);
5998 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE):
5999 return HandleActionUpdateDecorEnable(property, action);
6000 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS):
6001 return HandleActionUpdateWindowLimits(property, action);
6002 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED):
6003 return HandleActionUpdateDragenabled(property, action);
6004 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED):
6005 return HandleActionUpdateRaiseenabled(property, action);
6006 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS):
6007 return HandleActionUpdateHideNonSystemFloatingWindows(property, action);
6008 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO):
6009 return HandleActionUpdateTextfieldAvoidInfo(property, action);
6010 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK):
6011 return HandleActionUpdateWindowMask(property, action);
6012 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TOPMOST):
6013 return HandleActionUpdateTopmost(property, action);
6014 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST):
6015 return HandleActionUpdateMainWindowTopmost(property, action);
6016 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_SUB_WINDOW_Z_LEVEL):
6017 return HandleActionUpdateSubWindowZLevel(property, action);
6018 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO):
6019 return HandleActionUpdateWindowModeSupportType(property, action);
6020 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_AVOID_AREA_OPTION):
6021 return HandleActionUpdateAvoidAreaOption(property, action);
6022 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_BACKGROUND_ALPHA):
6023 return HandleBackgroundAlpha(property, action);
6024 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_EXCLUSIVE_HIGHLIGHTED):
6025 return HandleActionUpdateExclusivelyHighlighted(property, action);
6026 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_FOLLOW_SCREEN_CHANGE):
6027 return HandleActionUpdateFollowScreenChange(property, action);
6028 case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_SHADOW_ENABLED):
6029 return HandleActionUpdateWindowShadowEnabled(property, action);
6030 default:
6031 TLOGE(WmsLogTag::DEFAULT, "Failed to find func handler!");
6032 return WMError::WM_DO_NOTHING;
6033 }
6034 }
6035
HandleActionUpdateTurnScreenOn(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6036 WMError SceneSession::HandleActionUpdateTurnScreenOn(const sptr<WindowSessionProperty>& property,
6037 WSPropertyChangeAction action)
6038 {
6039 SetTurnScreenOn(property->IsTurnScreenOn());
6040 #ifdef POWER_MANAGER_ENABLE
6041 PostExportTask([weakThis = wptr(this), where = __func__] {
6042 auto sceneSession = weakThis.promote();
6043 if (!sceneSession) {
6044 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s session is invalid", where);
6045 return;
6046 }
6047 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s Win: %{public}s, is turn on: %{public}d",
6048 where, sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
6049 std::string identity = IPCSkeleton::ResetCallingIdentity();
6050 if (sceneSession->IsTurnScreenOn()) {
6051 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s turn screen on", where);
6052 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
6053 }
6054 // set ipc identity to raw
6055 IPCSkeleton::SetCallingIdentity(identity);
6056 }, __func__);
6057 #else
6058 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
6059 #endif
6060 return WMError::WM_OK;
6061 }
6062
HandleActionUpdateKeepScreenOn(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6063 WMError SceneSession::HandleActionUpdateKeepScreenOn(const sptr<WindowSessionProperty>& property,
6064 WSPropertyChangeAction action)
6065 {
6066 SetKeepScreenOn(property->IsKeepScreenOn());
6067 NotifySessionChangeByActionNotifyManager(property, action);
6068 return WMError::WM_OK;
6069 }
6070
HandleActionUpdateViewKeepScreenOn(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6071 WMError SceneSession::HandleActionUpdateViewKeepScreenOn(const sptr<WindowSessionProperty>& property,
6072 WSPropertyChangeAction action)
6073 {
6074 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, enabled: %{public}u",
6075 GetPersistentId(), property->IsViewKeepScreenOn());
6076 SetViewKeepScreenOn(property->IsViewKeepScreenOn());
6077 NotifySessionChangeByActionNotifyManager(property, action);
6078 return WMError::WM_OK;
6079 }
6080
HandleActionUpdateWindowShadowEnabled(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6081 WMError SceneSession::HandleActionUpdateWindowShadowEnabled(const sptr<WindowSessionProperty>& property,
6082 WSPropertyChangeAction action)
6083 {
6084 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, enabled: %{public}u",
6085 GetPersistentId(), property->GetWindowShadowEnabled());
6086 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WINDOW_TRANSPARENT) &&
6087 containerColorList_.count(GetSessionInfo().bundleName_) == 0) {
6088 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d: permission denied", GetPersistentId());
6089 return WMError::WM_ERROR_INVALID_PERMISSION;
6090 }
6091 if (!WindowHelper::IsMainWindow(GetWindowType())) {
6092 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, type is not supported", GetPersistentId());
6093 return WMError::WM_ERROR_INVALID_CALLING;
6094 }
6095 SetWindowShadowEnabled(property->GetWindowShadowEnabled());
6096 return WMError::WM_OK;
6097 }
6098
HandleActionUpdateFocusable(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6099 WMError SceneSession::HandleActionUpdateFocusable(const sptr<WindowSessionProperty>& property,
6100 WSPropertyChangeAction action)
6101 {
6102 SetFocusable(property->GetFocusable());
6103 NotifySessionChangeByActionNotifyManager(property, action);
6104 return WMError::WM_OK;
6105 }
6106
HandleActionUpdateTouchable(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6107 WMError SceneSession::HandleActionUpdateTouchable(const sptr<WindowSessionProperty>& property,
6108 WSPropertyChangeAction action)
6109 {
6110 SetTouchable(property->GetTouchable());
6111 NotifySessionChangeByActionNotifyManager(property, action);
6112 return WMError::WM_OK;
6113 }
6114
HandleActionUpdateSetBrightness(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6115 WMError SceneSession::HandleActionUpdateSetBrightness(const sptr<WindowSessionProperty>& property,
6116 WSPropertyChangeAction action)
6117 {
6118 if (GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
6119 GetWindowType() != WindowType::WINDOW_TYPE_WALLET_SWIPE_CARD) {
6120 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window or wallet swipe card can set brightness");
6121 return WMError::WM_OK;
6122 }
6123 if (!IsSessionValid()) {
6124 TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
6125 GetPersistentId(), GetSessionState());
6126 return WMError::WM_ERROR_INVALID_SESSION;
6127 }
6128 float brightness = property->GetBrightness();
6129 if (std::abs(brightness - GetBrightness()) < std::numeric_limits<float>::epsilon()) {
6130 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Session brightness do not change: [%{public}f]", brightness);
6131 return WMError::WM_OK;
6132 }
6133 SetBrightness(brightness);
6134 NotifySessionChangeByActionNotifyManager(property, action);
6135 return WMError::WM_OK;
6136 }
6137
HandleActionUpdateOrientation(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6138 WMError SceneSession::HandleActionUpdateOrientation(const sptr<WindowSessionProperty>& property,
6139 WSPropertyChangeAction action)
6140 {
6141 SetRequestedOrientation(property->GetRequestedOrientation(), property->GetRequestedAnimation());
6142 SceneSessionChangeInfo changeInfo {
6143 .persistentId_ = property->GetPersistentId(),
6144 .changeInfo_ = "Orientation change to " +
6145 std::to_string(static_cast<uint32_t>(property->GetRequestedOrientation())) + ", animation change to "+
6146 std::to_string(static_cast<uint32_t>(property->GetRequestedAnimation())),
6147 .logTag_ = WmsLogTag::WMS_ROTATION,
6148 };
6149 SessionChangeRecorder::GetInstance().RecordSceneSessionChange(RecordType::ORIENTAION_RECORD, changeInfo);
6150 return WMError::WM_OK;
6151 }
6152
HandleActionUpdatePrivacyMode(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6153 WMError SceneSession::HandleActionUpdatePrivacyMode(const sptr<WindowSessionProperty>& property,
6154 WSPropertyChangeAction action)
6155 {
6156 bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
6157 SetPrivacyMode(isPrivacyMode);
6158 NotifySessionChangeByActionNotifyManager(property, action);
6159 SceneSessionChangeInfo changeInfo {
6160 .persistentId_ = property->GetPersistentId(),
6161 .changeInfo_ = "Privacy mode change to " + std::to_string(isPrivacyMode),
6162 .logTag_ = WmsLogTag::WMS_ATTRIBUTE,
6163 };
6164 SessionChangeRecorder::GetInstance().RecordSceneSessionChange(RecordType::PRIVACY_MODE, changeInfo);
6165 return WMError::WM_OK;
6166 }
6167
HandleActionUpdateSnapshotSkip(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6168 WMError SceneSession::HandleActionUpdateSnapshotSkip(const sptr<WindowSessionProperty>& property,
6169 WSPropertyChangeAction action)
6170 {
6171 return SetSnapshotSkip(property->GetSnapshotSkip());
6172 }
6173
HandleActionUpdateMaximizeState(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6174 WMError SceneSession::HandleActionUpdateMaximizeState(const sptr<WindowSessionProperty>& property,
6175 WSPropertyChangeAction action)
6176 {
6177 auto sessionProperty = GetSessionProperty();
6178 if (sessionProperty != nullptr) {
6179 sessionProperty->SetMaximizeMode(property->GetMaximizeMode());
6180 sessionProperty->SetIsLayoutFullScreen(property->IsLayoutFullScreen());
6181 }
6182 return WMError::WM_OK;
6183 }
6184
HandleActionUpdateOtherProps(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6185 WMError SceneSession::HandleActionUpdateOtherProps(const sptr<WindowSessionProperty>& property,
6186 WSPropertyChangeAction action)
6187 {
6188 auto systemBarProperties = property->GetSystemBarProperty();
6189 for (auto iter : systemBarProperties) {
6190 SetSystemBarProperty(iter.first, iter.second);
6191 }
6192 NotifySessionChangeByActionNotifyManager(property, action);
6193 return WMError::WM_OK;
6194 }
6195
HandleActionUpdateStatusProps(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6196 WMError SceneSession::HandleActionUpdateStatusProps(const sptr<WindowSessionProperty>& property,
6197 WSPropertyChangeAction action)
6198 {
6199 HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, property);
6200 NotifySessionChangeByActionNotifyManager(property, action);
6201 return WMError::WM_OK;
6202 }
6203
HandleActionUpdateNavigationProps(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6204 WMError SceneSession::HandleActionUpdateNavigationProps(const sptr<WindowSessionProperty>& property,
6205 WSPropertyChangeAction action)
6206 {
6207 HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, property);
6208 NotifySessionChangeByActionNotifyManager(property, action);
6209 return WMError::WM_OK;
6210 }
6211
HandleActionUpdateNavigationIndicatorProps(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6212 WMError SceneSession::HandleActionUpdateNavigationIndicatorProps(const sptr<WindowSessionProperty>& property,
6213 WSPropertyChangeAction action)
6214 {
6215 HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, property);
6216 NotifySessionChangeByActionNotifyManager(property, action);
6217 return WMError::WM_OK;
6218 }
6219
HandleActionUpdateFlags(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6220 WMError SceneSession::HandleActionUpdateFlags(const sptr<WindowSessionProperty>& property,
6221 WSPropertyChangeAction action)
6222 {
6223 SetWindowFlags(property);
6224 NotifySessionChangeByActionNotifyManager(property, action);
6225 return WMError::WM_OK;
6226 }
6227
HandleActionUpdateMode(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6228 WMError SceneSession::HandleActionUpdateMode(const sptr<WindowSessionProperty>& property,
6229 WSPropertyChangeAction action)
6230 {
6231 auto sessionProperty = GetSessionProperty();
6232 if (sessionProperty != nullptr) {
6233 sessionProperty->SetWindowMode(property->GetWindowMode());
6234 }
6235 NotifySessionChangeByActionNotifyManager(property, action);
6236 return WMError::WM_OK;
6237 }
6238
HandleActionUpdateAnimationFlag(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6239 WMError SceneSession::HandleActionUpdateAnimationFlag(const sptr<WindowSessionProperty>& property,
6240 WSPropertyChangeAction action)
6241 {
6242 auto sessionProperty = GetSessionProperty();
6243 if (sessionProperty != nullptr) {
6244 sessionProperty->SetAnimationFlag(property->GetAnimationFlag());
6245 }
6246 return WMError::WM_OK;
6247 }
6248
HandleActionUpdateTouchHotArea(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6249 WMError SceneSession::HandleActionUpdateTouchHotArea(const sptr<WindowSessionProperty>& property,
6250 WSPropertyChangeAction action)
6251 {
6252 std::vector<Rect> touchHotAreas;
6253 property->GetTouchHotAreas(touchHotAreas);
6254 GetSessionProperty()->SetTouchHotAreas(touchHotAreas);
6255 if (specificCallback_ != nullptr && specificCallback_->onWindowInfoUpdate_ != nullptr) {
6256 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "id=%{public}d", GetPersistentId());
6257 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
6258 }
6259 return WMError::WM_OK;
6260 }
6261
HandleActionUpdateKeyboardTouchHotArea(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6262 WMError SceneSession::HandleActionUpdateKeyboardTouchHotArea(const sptr<WindowSessionProperty>& property,
6263 WSPropertyChangeAction action)
6264 {
6265 if (GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
6266 return WMError::WM_ERROR_INVALID_TYPE;
6267 }
6268 GetSessionProperty()->SetKeyboardTouchHotAreas(property->GetKeyboardTouchHotAreas());
6269 return WMError::WM_OK;
6270 }
6271
HandleActionUpdateDecorEnable(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6272 WMError SceneSession::HandleActionUpdateDecorEnable(const sptr<WindowSessionProperty>& property,
6273 WSPropertyChangeAction action)
6274 {
6275 if (property != nullptr && !property->GetSystemCalling()) {
6276 TLOGE(WmsLogTag::DEFAULT, "update decor enable permission denied!");
6277 return WMError::WM_ERROR_NOT_SYSTEM_APP;
6278 }
6279 auto sessionProperty = GetSessionProperty();
6280 if (sessionProperty != nullptr) {
6281 sessionProperty->SetDecorEnable(property->IsDecorEnable());
6282 }
6283 return WMError::WM_OK;
6284 }
6285
HandleActionUpdateWindowLimits(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6286 WMError SceneSession::HandleActionUpdateWindowLimits(const sptr<WindowSessionProperty>& property,
6287 WSPropertyChangeAction action)
6288 {
6289 auto sessionProperty = GetSessionProperty();
6290 if (sessionProperty != nullptr) {
6291 sessionProperty->SetWindowLimits(property->GetWindowLimits());
6292 WindowLimits windowLimits = sessionProperty->GetWindowLimits();
6293 TLOGI(WmsLogTag::WMS_LAYOUT, "UpdateWindowLimits minWidth:%{public}u, minHeight:%{public}u, "
6294 "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", windowLimits.minWidth_,
6295 windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
6296 }
6297 return WMError::WM_OK;
6298 }
6299
HandleActionUpdateDragenabled(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6300 WMError SceneSession::HandleActionUpdateDragenabled(const sptr<WindowSessionProperty>& property,
6301 WSPropertyChangeAction action)
6302 {
6303 auto sessionProperty = GetSessionProperty();
6304 if (sessionProperty != nullptr) {
6305 sessionProperty->SetDragEnabled(property->GetDragEnabled());
6306 }
6307 return WMError::WM_OK;
6308 }
6309
HandleActionUpdateRaiseenabled(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6310 WMError SceneSession::HandleActionUpdateRaiseenabled(const sptr<WindowSessionProperty>& property,
6311 WSPropertyChangeAction action)
6312 {
6313 auto sessionProperty = GetSessionProperty();
6314 if (sessionProperty != nullptr) {
6315 TLOGI(WmsLogTag::WMS_HIERARCHY, "id: %{public}d, raise enabled: %{public}d", GetPersistentId(),
6316 property->GetRaiseEnabled());
6317 sessionProperty->SetRaiseEnabled(property->GetRaiseEnabled());
6318 }
6319 return WMError::WM_OK;
6320 }
6321
HandleActionUpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6322 WMError SceneSession::HandleActionUpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
6323 WSPropertyChangeAction action)
6324 {
6325 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6326 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Update property hideNonSystemFloatingWindows permission denied!");
6327 return WMError::WM_OK;
6328 }
6329 auto currentProperty = GetSessionProperty();
6330 if (currentProperty != nullptr) {
6331 NotifySessionChangeByActionNotifyManager(property, action);
6332 currentProperty->SetHideNonSystemFloatingWindows(property->GetHideNonSystemFloatingWindows());
6333 }
6334 return WMError::WM_OK;
6335 }
6336
HandleActionUpdateTextfieldAvoidInfo(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6337 WMError SceneSession::HandleActionUpdateTextfieldAvoidInfo(const sptr<WindowSessionProperty>& property,
6338 WSPropertyChangeAction action)
6339 {
6340 auto sessionProperty = GetSessionProperty();
6341 if (sessionProperty != nullptr) {
6342 sessionProperty->SetTextFieldPositionY(property->GetTextFieldPositionY());
6343 sessionProperty->SetTextFieldHeight(property->GetTextFieldHeight());
6344 }
6345 return WMError::WM_OK;
6346 }
6347
HandleActionUpdateWindowMask(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6348 WMError SceneSession::HandleActionUpdateWindowMask(const sptr<WindowSessionProperty>& property,
6349 WSPropertyChangeAction action)
6350 {
6351 auto sessionProperty = GetSessionProperty();
6352 if (sessionProperty != nullptr) {
6353 sessionProperty->SetWindowMask(property->GetWindowMask());
6354 sessionProperty->SetIsShaped(property->GetIsShaped());
6355 NotifySessionChangeByActionNotifyManager(property, action);
6356 }
6357 return WMError::WM_OK;
6358 }
6359
HandleActionUpdateTopmost(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6360 WMError SceneSession::HandleActionUpdateTopmost(const sptr<WindowSessionProperty>& property,
6361 WSPropertyChangeAction action)
6362 {
6363 if (!SessionPermission::IsSystemCalling()) {
6364 TLOGE(WmsLogTag::WMS_HIERARCHY, "UpdateTopmostProperty permission denied!");
6365 return WMError::WM_ERROR_NOT_SYSTEM_APP;
6366 }
6367
6368 SetTopmost(property->IsTopmost());
6369 return WMError::WM_OK;
6370 }
6371
HandleActionUpdateMainWindowTopmost(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6372 WMError SceneSession::HandleActionUpdateMainWindowTopmost(const sptr<WindowSessionProperty>& property,
6373 WSPropertyChangeAction action)
6374 {
6375 SetMainWindowTopmost(property->IsMainWindowTopmost());
6376 return WMError::WM_OK;
6377 }
6378
HandleActionUpdateSubWindowZLevel(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6379 WMError SceneSession::HandleActionUpdateSubWindowZLevel(const sptr<WindowSessionProperty>& property,
6380 WSPropertyChangeAction action)
6381 {
6382 SetSubWindowZLevel(property->GetSubWindowZLevel());
6383 return WMError::WM_OK;
6384 }
6385
HandleActionUpdateAvoidAreaOption(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6386 WMError SceneSession::HandleActionUpdateAvoidAreaOption(const sptr<WindowSessionProperty>& property,
6387 WSPropertyChangeAction action)
6388 {
6389 auto sessionProperty = GetSessionProperty();
6390 if (!SessionHelper::IsSubWindow(sessionProperty->GetWindowType()) &&
6391 !SessionHelper::IsSystemWindow(sessionProperty->GetWindowType())) {
6392 return WMError::WM_ERROR_INVALID_WINDOW;
6393 }
6394 sessionProperty->SetAvoidAreaOption(property->GetAvoidAreaOption());
6395 return WMError::WM_OK;
6396 }
6397
HandleBackgroundAlpha(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6398 WMError SceneSession::HandleBackgroundAlpha(const sptr<WindowSessionProperty>& property,
6399 WSPropertyChangeAction action)
6400 {
6401 auto sessionProperty = GetSessionProperty();
6402 if (!sessionProperty) {
6403 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "property is null");
6404 return WMError::WM_ERROR_INVALID_PARAM;
6405 }
6406 sessionProperty->SetBackgroundAlpha(property->GetBackgroundAlpha());
6407 return WMError::WM_OK;
6408 }
6409
HandleActionUpdateExclusivelyHighlighted(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6410 WMError SceneSession::HandleActionUpdateExclusivelyHighlighted(const sptr<WindowSessionProperty>& property,
6411 WSPropertyChangeAction action)
6412 {
6413 auto sessionProperty = GetSessionProperty();
6414 if (!sessionProperty) {
6415 TLOGE(WmsLogTag::WMS_FOCUS, "property is null");
6416 return WMError::WM_ERROR_INVALID_PARAM;
6417 }
6418 sessionProperty->SetExclusivelyHighlighted(property->GetExclusivelyHighlighted());
6419 return WMError::WM_OK;
6420 }
6421
HandleActionUpdateFollowScreenChange(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6422 WMError SceneSession::HandleActionUpdateFollowScreenChange(const sptr<WindowSessionProperty>& property,
6423 WSPropertyChangeAction action)
6424 {
6425 UpdateFollowScreenChange(property->GetFollowScreenChange());
6426 NotifySessionChangeByActionNotifyManager(property, action);
6427 return WMError::WM_OK;
6428 }
6429
UpdateFollowScreenChange(bool isFollowScreenChange)6430 WSError SceneSession::UpdateFollowScreenChange(bool isFollowScreenChange)
6431 {
6432 SetFollowScreenChange(isFollowScreenChange);
6433 auto task = [weakThis = wptr(this), isFollowScreenChange] {
6434 auto session = weakThis.promote();
6435 if (!session || !session->specificCallback_) {
6436 TLOGNE(WmsLogTag::DEFAULT, "session or specific callback is null");
6437 return;
6438 }
6439 if (session->specificCallback_->onUpdateFollowScreenChange_) {
6440 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession:UpdateFollowScreenChange");
6441 session->specificCallback_->onUpdateFollowScreenChange_(isFollowScreenChange);
6442 }
6443 };
6444 PostTask(std::move(task), "UpdateFollowScreenChange");
6445 return WSError::WS_OK;
6446 }
6447
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property)6448 void SceneSession::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property)
6449 {
6450 auto systemBarProperties = property->GetSystemBarProperty();
6451 if (auto iter = systemBarProperties.find(type); iter != systemBarProperties.end()) {
6452 SetSystemBarProperty(iter->first, iter->second);
6453 TLOGD(WmsLogTag::WMS_IMMS, "type %{public}d enable %{public}d",
6454 static_cast<int32_t>(iter->first), iter->second.enable_);
6455 }
6456 }
6457
SetWindowFlags(const sptr<WindowSessionProperty> & property)6458 void SceneSession::SetWindowFlags(const sptr<WindowSessionProperty>& property)
6459 {
6460 auto sessionProperty = GetSessionProperty();
6461 if (sessionProperty == nullptr) {
6462 TLOGE(WmsLogTag::DEFAULT, "get session property failed");
6463 return;
6464 }
6465 uint32_t flags = property->GetWindowFlags();
6466 uint32_t oldFlags = sessionProperty->GetWindowFlags();
6467 if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
6468 (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
6469 !property->GetSystemCalling()) {
6470 TLOGE(WmsLogTag::DEFAULT, "Set window flags permission denied");
6471 return;
6472 }
6473 sessionProperty->SetWindowFlags(flags);
6474 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
6475 OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
6476 }
6477 TLOGI(WmsLogTag::DEFAULT, "%{public}u", flags);
6478 }
6479
NotifySessionChangeByActionNotifyManager(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6480 void SceneSession::NotifySessionChangeByActionNotifyManager(const sptr<WindowSessionProperty>& property,
6481 WSPropertyChangeAction action)
6482 {
6483 TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, action: %{public}" PRIu64, GetPersistentId(), action);
6484 if (sessionChangeByActionNotifyManagerFunc_ == nullptr) {
6485 TLOGW(WmsLogTag::DEFAULT, "func is null");
6486 return;
6487 }
6488 sessionChangeByActionNotifyManagerFunc_(this, property, action);
6489 }
6490
TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)6491 WSError SceneSession::TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
6492 {
6493 PostLifeCycleTask([weakThis = wptr(this), abilitySessionInfo, where = __func__] {
6494 auto session = weakThis.promote();
6495 if (!session) {
6496 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
6497 return WSError::WS_ERROR_DESTROYED_OBJECT;
6498 }
6499 if (abilitySessionInfo == nullptr) {
6500 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s abilitySessionInfo is null", where);
6501 session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
6502 return WSError::WS_ERROR_NULLPTR;
6503 }
6504 if (session->isTerminating_) {
6505 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s is terminating, return!", where);
6506 session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
6507 return WSError::WS_ERROR_INVALID_OPERATION;
6508 }
6509 session->isTerminating_ = true;
6510 SessionInfo info;
6511 info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
6512 info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
6513 info.callerToken_ = abilitySessionInfo->callerToken;
6514 info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
6515 {
6516 std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
6517 session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
6518 session->sessionInfo_.resultCode = abilitySessionInfo->resultCode;
6519 }
6520 if (session->terminateSessionFunc_) {
6521 session->terminateSessionFunc_(info);
6522 }
6523 return WSError::WS_OK;
6524 }, __func__, LifeCycleTaskType::STOP);
6525 return WSError::WS_OK;
6526 }
6527
NotifySessionExceptionInner(const sptr<AAFwk::SessionInfo> abilitySessionInfo,const ExceptionInfo & exceptionInfo,bool isFromClient,bool startFail)6528 WSError SceneSession::NotifySessionExceptionInner(const sptr<AAFwk::SessionInfo> abilitySessionInfo,
6529 const ExceptionInfo& exceptionInfo, bool isFromClient, bool startFail)
6530 {
6531 PostLifeCycleTask([weakThis = wptr(this), abilitySessionInfo, exceptionInfo,
6532 isFromClient, startFail, where = __func__] {
6533 auto session = weakThis.promote();
6534 if (!session) {
6535 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
6536 return WSError::WS_ERROR_DESTROYED_OBJECT;
6537 }
6538 if (abilitySessionInfo == nullptr) {
6539 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s abilitySessionInfo is null", where);
6540 session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
6541 return WSError::WS_ERROR_NULLPTR;
6542 }
6543 if (SessionHelper::IsMainWindow(session->GetWindowType()) && !session->clientIdentityToken_.empty() &&
6544 isFromClient && (abilitySessionInfo->errorReason != ERROR_REASON_LOW_MEMORY_KILL &&
6545 session->clientIdentityToken_ != abilitySessionInfo->identityToken)) {
6546 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s client exception not matched: %{public}s, %{public}s",
6547 where, session->clientIdentityToken_.c_str(), abilitySessionInfo->identityToken.c_str());
6548 session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
6549 return WSError::WS_ERROR_INVALID_PARAM;
6550 }
6551 if (session->isTerminating_) {
6552 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s is terminating, return!", where);
6553 session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
6554 return WSError::WS_ERROR_INVALID_OPERATION;
6555 }
6556 session->isTerminating_ = true;
6557 SessionInfo info;
6558 info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
6559 info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
6560 info.callerToken_ = abilitySessionInfo->callerToken;
6561 info.errorCode = abilitySessionInfo->errorCode;
6562 info.errorReason = abilitySessionInfo->errorReason;
6563 info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
6564 {
6565 std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
6566 session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
6567 session->sessionInfo_.errorCode = abilitySessionInfo->errorCode;
6568 session->sessionInfo_.errorReason = abilitySessionInfo->errorReason;
6569 }
6570 if (session->sessionExceptionFunc_) {
6571 session->sessionExceptionFunc_(info, exceptionInfo, false);
6572 }
6573 if (session->jsSceneSessionExceptionFunc_) {
6574 session->jsSceneSessionExceptionFunc_(info, exceptionInfo, startFail);
6575 }
6576 return WSError::WS_OK;
6577 }, __func__, LifeCycleTaskType::STOP);
6578 return WSError::WS_OK;
6579 }
6580
NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo,const ExceptionInfo & exceptionInfo)6581 WSError SceneSession::NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo,
6582 const ExceptionInfo& exceptionInfo)
6583 {
6584 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6585 TLOGE(WmsLogTag::WMS_LIFE, "permission failed.");
6586 return WSError::WS_ERROR_INVALID_PERMISSION;
6587 }
6588 return NotifySessionExceptionInner(abilitySessionInfo, exceptionInfo, true);
6589 }
6590
GetLastSafeRect() const6591 WSRect SceneSession::GetLastSafeRect() const
6592 {
6593 return lastSafeRect;
6594 }
6595
SetLastSafeRect(WSRect rect)6596 void SceneSession::SetLastSafeRect(WSRect rect)
6597 {
6598 lastSafeRect.posX_ = rect.posX_;
6599 lastSafeRect.posY_ = rect.posY_;
6600 lastSafeRect.width_ = rect.width_;
6601 lastSafeRect.height_ = rect.height_;
6602 return;
6603 }
6604
SetMovable(bool movable)6605 void SceneSession::SetMovable(bool movable)
6606 {
6607 PostTask([weakThis = wptr(this), movable, where = __func__] {
6608 auto session = weakThis.promote();
6609 if (!session) {
6610 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
6611 return;
6612 }
6613 if (session->moveDragController_) {
6614 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s id: %{public}d, isMovable: %{public}d",
6615 where, session->GetPersistentId(), movable);
6616 session->moveDragController_->SetMovable(movable);
6617 }
6618 }, __func__);
6619 }
6620
SetSplitButtonVisible(bool isVisible)6621 WSError SceneSession::SetSplitButtonVisible(bool isVisible)
6622 {
6623 TLOGI(WmsLogTag::WMS_LAYOUT, "isVisible: %{public}d", isVisible);
6624 if (!sessionStage_) {
6625 TLOGE(WmsLogTag::WMS_LAYOUT, "sessionStage is null");
6626 return WSError::WS_ERROR_NULLPTR;
6627 }
6628 return sessionStage_->SetSplitButtonVisible(isVisible);
6629 }
6630
SendContainerModalEvent(const std::string & eventName,const std::string & eventValue)6631 WSError SceneSession::SendContainerModalEvent(const std::string& eventName, const std::string& eventValue)
6632 {
6633 TLOGI(WmsLogTag::WMS_EVENT, "name: %{public}s, value: %{public}s", eventName.c_str(), eventValue.c_str());
6634 if (!sessionStage_) {
6635 TLOGE(WmsLogTag::WMS_EVENT, "sessionStage is null");
6636 return WSError::WS_ERROR_NULLPTR;
6637 }
6638 return sessionStage_->SendContainerModalEvent(eventName, eventValue);
6639 }
6640
OnContainerModalEvent(const std::string & eventName,const std::string & eventValue)6641 WSError SceneSession::OnContainerModalEvent(const std::string& eventName, const std::string& eventValue)
6642 {
6643 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "name: %{public}s, value: %{public}s", eventName.c_str(), eventValue.c_str());
6644 if (eventName == WINDOW_RELOCATION_EVENT) {
6645 if (eventValue == "true") {
6646 ThrowSlipDirectly(ThrowSlipMode::BUTTON, VELOCITY_RELOCATION_TO_TOP);
6647 } else {
6648 ThrowSlipDirectly(ThrowSlipMode::BUTTON, VELOCITY_RELOCATION_TO_BOTTOM);
6649 }
6650 }
6651 return WSError::WS_OK;
6652 }
6653
RegisterSetLandscapeMultiWindowFunc(NotifyLandscapeMultiWindowSessionFunc && callback)6654 void SceneSession::RegisterSetLandscapeMultiWindowFunc(NotifyLandscapeMultiWindowSessionFunc&& callback)
6655 {
6656 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
6657 auto session = weakThis.promote();
6658 if (!session) {
6659 TLOGNE(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s session is null", where);
6660 return;
6661 }
6662 session->onSetLandscapeMultiWindowFunc_ = std::move(callback);
6663 }, __func__);
6664 }
6665
GetOriPosYBeforeRaisedByKeyboard() const6666 int32_t SceneSession::GetOriPosYBeforeRaisedByKeyboard() const
6667 {
6668 return oriPosYBeforeRaisedByKeyboard_;
6669 }
6670
SetOriPosYBeforeRaisedByKeyboard(int32_t posY)6671 void SceneSession::SetOriPosYBeforeRaisedByKeyboard(int32_t posY)
6672 {
6673 oriPosYBeforeRaisedByKeyboard_ = posY;
6674 }
6675
AddSubSession(const sptr<SceneSession> & subSession)6676 bool SceneSession::AddSubSession(const sptr<SceneSession>& subSession)
6677 {
6678 if (subSession == nullptr) {
6679 TLOGE(WmsLogTag::WMS_SUB, "subSession is nullptr");
6680 return false;
6681 }
6682 const auto& persistentId = subSession->GetPersistentId();
6683 auto iter = std::find_if(subSession_.begin(), subSession_.end(),
6684 [persistentId](sptr<SceneSession> session) {
6685 bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
6686 return res;
6687 });
6688 if (iter != subSession_.end()) {
6689 TLOGE(WmsLogTag::WMS_SUB, "Sub ession is already exists, id: %{public}d, parentId: %{public}d",
6690 subSession->GetPersistentId(), GetPersistentId());
6691 return false;
6692 }
6693 TLOGD(WmsLogTag::WMS_SUB, "Success, id: %{public}d, parentId: %{public}d",
6694 subSession->GetPersistentId(), GetPersistentId());
6695 subSession_.push_back(subSession);
6696 return true;
6697 }
6698
RemoveSubSession(int32_t persistentId)6699 bool SceneSession::RemoveSubSession(int32_t persistentId)
6700 {
6701 auto iter = std::find_if(subSession_.begin(), subSession_.end(),
6702 [persistentId](sptr<SceneSession> session) {
6703 bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
6704 return res;
6705 });
6706 if (iter == subSession_.end()) {
6707 TLOGE(WmsLogTag::WMS_SUB, "Could not find subsession, id: %{public}d, parentId: %{public}d",
6708 persistentId, GetPersistentId());
6709 return false;
6710 }
6711 TLOGD(WmsLogTag::WMS_SUB, "Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
6712 subSession_.erase(iter);
6713 return true;
6714 }
6715
AddToastSession(const sptr<SceneSession> & toastSession)6716 bool SceneSession::AddToastSession(const sptr<SceneSession>& toastSession)
6717 {
6718 if (toastSession == nullptr) {
6719 TLOGE(WmsLogTag::WMS_TOAST, "toastSession is nullptr");
6720 return false;
6721 }
6722 const auto& persistentId = toastSession->GetPersistentId();
6723 auto iter = std::find_if(toastSession_.begin(), toastSession_.end(),
6724 [persistentId](sptr<SceneSession> session) {
6725 bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
6726 return res;
6727 });
6728 if (iter != toastSession_.end()) {
6729 TLOGE(WmsLogTag::WMS_TOAST, "Toast ession is already exists, id: %{public}d, parentId: %{public}d",
6730 toastSession->GetPersistentId(), GetPersistentId());
6731 return false;
6732 }
6733 TLOGD(WmsLogTag::WMS_TOAST, "Success, id: %{public}d, parentId: %{public}d",
6734 toastSession->GetPersistentId(), GetPersistentId());
6735 toastSession_.push_back(toastSession);
6736 return true;
6737 }
6738
RemoveToastSession(int32_t persistentId)6739 bool SceneSession::RemoveToastSession(int32_t persistentId)
6740 {
6741 auto iter = std::find_if(toastSession_.begin(), toastSession_.end(),
6742 [persistentId](sptr<SceneSession> session) {
6743 bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
6744 return res;
6745 });
6746 if (iter == toastSession_.end()) {
6747 TLOGE(WmsLogTag::WMS_TOAST, "Could not find toastSession, id: %{public}d, parentId: %{public}d",
6748 persistentId, GetPersistentId());
6749 return false;
6750 }
6751 TLOGD(WmsLogTag::WMS_TOAST, "Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
6752 toastSession_.erase(iter);
6753 return true;
6754 }
6755
NotifyPiPWindowPrepareClose()6756 void SceneSession::NotifyPiPWindowPrepareClose()
6757 {
6758 TLOGD(WmsLogTag::WMS_PIP, "in");
6759 int32_t callingPid = IPCSkeleton::GetCallingPid();
6760 PostTask([weakThis = wptr(this), callingPid, where = __func__] {
6761 auto session = weakThis.promote();
6762 if (!session) {
6763 TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
6764 return;
6765 }
6766 if (callingPid != session->GetCallingPid()) {
6767 TLOGNW(WmsLogTag::WMS_PIP, "%{public}s permission denied, not call by the same process", where);
6768 return;
6769 }
6770 if (session->onPrepareClosePiPSession_) {
6771 session->onPrepareClosePiPSession_();
6772 }
6773 TLOGND(WmsLogTag::WMS_PIP, "%{public}s id: %{public}d", where, session->GetPersistentId());
6774 }, __func__);
6775 }
6776
SetLandscapeMultiWindow(bool isLandscapeMultiWindow)6777 WSError SceneSession::SetLandscapeMultiWindow(bool isLandscapeMultiWindow)
6778 {
6779 TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
6780 int32_t callingPid = IPCSkeleton::GetCallingPid();
6781 PostTask([weakThis = wptr(this), isLandscapeMultiWindow, callingPid, where = __func__] {
6782 auto session = weakThis.promote();
6783 if (!session) {
6784 TLOGNE(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s session is null", where);
6785 return WSError::WS_ERROR_DESTROYED_OBJECT;
6786 }
6787 if (callingPid != session->GetCallingPid()) {
6788 TLOGNE(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s premission denied, not call by the same process", where);
6789 return WSError::WS_ERROR_INVALID_PERMISSION;
6790 }
6791 if (session->onSetLandscapeMultiWindowFunc_) {
6792 session->onSetLandscapeMultiWindowFunc_(isLandscapeMultiWindow);
6793 }
6794 TLOGND(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s id: %{public}d, isLandscapeMultiWindow: %{public}u",
6795 where, session->GetPersistentId(), isLandscapeMultiWindow);
6796 return WSError::WS_OK;
6797 }, __func__);
6798 return WSError::WS_OK;
6799 }
6800
GetSubSession() const6801 std::vector<sptr<SceneSession>> SceneSession::GetSubSession() const
6802 {
6803 return subSession_;
6804 }
6805
GetToastSession() const6806 std::vector<sptr<SceneSession>> SceneSession::GetToastSession() const
6807 {
6808 return toastSession_;
6809 }
6810
GetSessionTargetRectByDisplayId(DisplayId displayId) const6811 WSRect SceneSession::GetSessionTargetRectByDisplayId(DisplayId displayId) const
6812 {
6813 WSRect rect;
6814 if (moveDragController_) {
6815 rect = moveDragController_->GetTargetRectByDisplayId(displayId);
6816 } else {
6817 WLOGFI("moveDragController_ is null");
6818 }
6819 return rect;
6820 }
6821
SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc & func)6822 void SceneSession::SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc& func)
6823 {
6824 if (moveDragController_) {
6825 moveDragController_->SetWindowDragHotAreaFunc(func);
6826 }
6827 }
6828
NotifySessionForeground(uint32_t reason,bool withAnimation)6829 void SceneSession::NotifySessionForeground(uint32_t reason, bool withAnimation)
6830 {
6831 if (!sessionStage_) {
6832 return;
6833 }
6834 return sessionStage_->NotifySessionForeground(reason, withAnimation);
6835 }
6836
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)6837 void SceneSession::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
6838 {
6839 if (!sessionStage_) {
6840 return;
6841 }
6842 return sessionStage_->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
6843 }
6844
NotifySessionFullScreen(bool fullScreen)6845 void SceneSession::NotifySessionFullScreen(bool fullScreen)
6846 {
6847 if (!sessionStage_) {
6848 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sessionStage is null");
6849 return;
6850 }
6851 sessionStage_->NotifySessionFullScreen(fullScreen);
6852 }
6853
UpdatePiPRect(const Rect & rect,SizeChangeReason reason)6854 WSError SceneSession::UpdatePiPRect(const Rect& rect, SizeChangeReason reason)
6855 {
6856 if (!WindowHelper::IsPipWindow(GetWindowType())) {
6857 return WSError::WS_DO_NOTHING;
6858 }
6859 int32_t callingPid = IPCSkeleton::GetCallingPid();
6860 auto task = [weakThis = wptr(this), rect, reason, callingPid, where = __func__] {
6861 auto session = weakThis.promote();
6862 if (!session || session->isTerminating_) {
6863 TLOGNE(WmsLogTag::WMS_PIP,
6864 "%{public}s session is null or is terminating", where);
6865 return WSError::WS_ERROR_INVALID_OPERATION;
6866 }
6867 if (callingPid != session->GetCallingPid()) {
6868 TLOGNW(WmsLogTag::WMS_PIP, "%{public}s permission denied, not call by the same process", where);
6869 return WSError::WS_ERROR_INVALID_PERMISSION;
6870 }
6871 WSRect wsRect = SessionHelper::TransferToWSRect(rect);
6872 if (reason == SizeChangeReason::PIP_START) {
6873 session->SetSessionRequestRect(wsRect);
6874 }
6875 TLOGNI(WmsLogTag::WMS_PIP, "%{public}s rect:%{public}s, reason:%{public}u", where, wsRect.ToString().c_str(),
6876 static_cast<uint32_t>(reason));
6877 session->NotifySessionRectChange(wsRect, reason);
6878 return WSError::WS_OK;
6879 };
6880 if (mainHandler_ != nullptr) {
6881 mainHandler_->PostTask(std::move(task), __func__, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
6882 } else {
6883 PostTask(std::move(task), __func__);
6884 }
6885 return WSError::WS_OK;
6886 }
6887
UpdatePiPControlStatus(WsPiPControlType controlType,WsPiPControlStatus status)6888 WSError SceneSession::UpdatePiPControlStatus(WsPiPControlType controlType, WsPiPControlStatus status)
6889 {
6890 TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, status:%{public}d", controlType, status);
6891 if (!WindowHelper::IsPipWindow(GetWindowType())) {
6892 return WSError::WS_DO_NOTHING;
6893 }
6894 int32_t callingPid = IPCSkeleton::GetCallingPid();
6895 PostTask([weakThis = wptr(this), controlType, status, callingPid, where = __func__] {
6896 auto session = weakThis.promote();
6897 if (!session || session->isTerminating_) {
6898 TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null or is terminating", where);
6899 return WSError::WS_ERROR_INVALID_OPERATION;
6900 }
6901 if (callingPid != session->GetCallingPid()) {
6902 TLOGNW(WmsLogTag::WMS_PIP, "%{public}s permission denied, not call by the same process", where);
6903 return WSError::WS_ERROR_INVALID_PERMISSION;
6904 }
6905 if (session->sessionPiPControlStatusChangeFunc_) {
6906 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::UpdatePiPControlStatus");
6907 session->sessionPiPControlStatusChangeFunc_(controlType, status);
6908 }
6909 return WSError::WS_OK;
6910 }, __func__);
6911 return WSError::WS_OK;
6912 }
6913
SetAutoStartPiP(bool isAutoStart,uint32_t priority,uint32_t width,uint32_t height)6914 WSError SceneSession::SetAutoStartPiP(bool isAutoStart, uint32_t priority, uint32_t width, uint32_t height)
6915 {
6916 TLOGI(WmsLogTag::WMS_PIP, "isAutoStart:%{public}u priority:%{public}u width:%{public}u height:%{public}u",
6917 isAutoStart, priority, width, height);
6918 PostTask([weakThis = wptr(this), isAutoStart, priority, width, height, where = __func__] {
6919 auto session = weakThis.promote();
6920 if (!session || session->isTerminating_) {
6921 TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null or is terminating", where);
6922 return;
6923 }
6924 if (session->autoStartPiPStatusChangeFunc_) {
6925 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetAutoStartPiP");
6926 session->autoStartPiPStatusChangeFunc_(isAutoStart, priority, width, height);
6927 }
6928 }, __func__);
6929 return WSError::WS_OK;
6930 }
6931
SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)6932 void SceneSession::SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)
6933 {
6934 NotifySystemSessionPointerEventFunc systemSessionPointerEventFunc = nullptr;
6935 {
6936 std::lock_guard<std::mutex> lock(pointerEventMutex_);
6937 systemSessionPointerEventFunc = systemSessionPointerEventFunc_;
6938 }
6939 if (systemSessionPointerEventFunc != nullptr) {
6940 systemSessionPointerEventFunc(pointerEvent);
6941 } else {
6942 TLOGE(WmsLogTag::WMS_EVENT, "PointerEventFunc_ nullptr, id:%{public}d", pointerEvent->GetId());
6943 pointerEvent->MarkProcessed();
6944 }
6945 }
6946
SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent,bool isPreImeEvent)6947 bool SceneSession::SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent, bool isPreImeEvent)
6948 {
6949 NotifySystemSessionKeyEventFunc systemSessionKeyEventFunc = nullptr;
6950 {
6951 std::shared_lock<std::shared_mutex> lock(keyEventMutex_);
6952 systemSessionKeyEventFunc = systemSessionKeyEventFunc_;
6953 }
6954 if (systemSessionKeyEventFunc != nullptr) {
6955 return systemSessionKeyEventFunc(keyEvent, isPreImeEvent);
6956 }
6957 return false;
6958 }
6959
UpdateSizeChangeReason(SizeChangeReason reason)6960 WSError SceneSession::UpdateSizeChangeReason(SizeChangeReason reason)
6961 {
6962 PostTask([weakThis = wptr(this), reason, where = __func__] {
6963 auto session = weakThis.promote();
6964 if (!session) {
6965 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
6966 return WSError::WS_ERROR_DESTROYED_OBJECT;
6967 }
6968 session->Session::UpdateSizeChangeReason(reason);
6969 if (reason != SizeChangeReason::UNDEFINED) {
6970 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
6971 "SceneSession::UpdateSizeChangeReason%d reason:%d",
6972 session->GetPersistentId(), static_cast<uint32_t>(reason));
6973 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s Id: %{public}d, reason: %{public}d",
6974 where, session->GetPersistentId(), reason);
6975 }
6976 return WSError::WS_OK;
6977 }, __func__);
6978 return WSError::WS_OK;
6979 }
6980
ResetSizeChangeReasonIfDirty()6981 void SceneSession::ResetSizeChangeReasonIfDirty()
6982 {
6983 auto reason = GetSizeChangeReason();
6984 if (IsDirtyWindow() &&
6985 reason != SizeChangeReason::DRAG &&
6986 reason != SizeChangeReason::DRAG_END &&
6987 reason != SizeChangeReason::DRAG_START &&
6988 reason != SizeChangeReason::DRAG_MOVE) {
6989 UpdateSizeChangeReason(SizeChangeReason::UNDEFINED);
6990 }
6991 }
6992
IsDirtyWindow()6993 bool SceneSession::IsDirtyWindow()
6994 {
6995 return dirtyFlags_ & static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
6996 }
6997
IsDirtyDragWindow()6998 bool SceneSession::IsDirtyDragWindow()
6999 {
7000 return dirtyFlags_ & static_cast<uint32_t>(SessionUIDirtyFlag::DRAG_RECT) || isDragging_;
7001 }
7002
ResetDirtyDragFlags()7003 void SceneSession::ResetDirtyDragFlags()
7004 {
7005 dirtyFlags_ &= ~static_cast<uint32_t>(SessionUIDirtyFlag::DRAG_RECT);
7006 isDragging_ = false;
7007 }
7008
IsCompatibleModeDirtyDragScaleWindow() const7009 bool SceneSession::IsCompatibleModeDirtyDragScaleWindow() const
7010 {
7011 return compatibleDragScaleFlags_;
7012 }
7013
ResetCompatibleModeDragScaleFlags()7014 void SceneSession::ResetCompatibleModeDragScaleFlags()
7015 {
7016 compatibleDragScaleFlags_ = false;
7017 }
7018
NotifyUILostFocus()7019 void SceneSession::NotifyUILostFocus()
7020 {
7021 if (moveDragController_) {
7022 moveDragController_->OnLostFocus();
7023 }
7024 Session::NotifyUILostFocus();
7025 }
7026
SetScale(float scaleX,float scaleY,float pivotX,float pivotY)7027 void SceneSession::SetScale(float scaleX, float scaleY, float pivotX, float pivotY)
7028 {
7029 if (GetScaleX() != scaleX || GetScaleY() != scaleY || GetPivotX() != pivotX || GetPivotY() != pivotY) {
7030 Session::SetScale(scaleX, scaleY, pivotX, pivotY);
7031 if (specificCallback_ != nullptr) {
7032 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
7033 }
7034 if (sessionStage_ != nullptr) {
7035 Transform transform;
7036 transform.scaleX_ = scaleX;
7037 transform.scaleY_ = scaleY;
7038 transform.pivotX_ = pivotX;
7039 transform.pivotY_ = pivotY;
7040 sessionStage_->NotifyTransformChange(transform);
7041 } else {
7042 WLOGFE("sessionStage_ is nullptr");
7043 }
7044 }
7045 }
7046
RequestHideKeyboard(bool isAppColdStart)7047 void SceneSession::RequestHideKeyboard(bool isAppColdStart)
7048 {
7049 #ifdef IMF_ENABLE
7050 PostExportTask([weakThis = wptr(this), isAppColdStart, where = __func__] {
7051 auto session = weakThis.promote();
7052 if (!session) {
7053 TLOGNE(WmsLogTag::WMS_KEYBOARD,
7054 "%{public}s Session is null, notify inputMethod framework hide keyboard failed!", where);
7055 return;
7056 }
7057 TLOGNI(WmsLogTag::WMS_KEYBOARD, "%{public}s Notify inputMethod framework hide keyboard start, id: %{public}d,"
7058 "isAppColdStart: %{public}d", where, session->GetPersistentId(), isAppColdStart);
7059 if (MiscServices::InputMethodController::GetInstance()) {
7060 MiscServices::InputMethodController::GetInstance()->RequestHideInput();
7061 TLOGNI(WmsLogTag::WMS_KEYBOARD, "%{public}s Notify InputMethod framework hide keyboard end. id: %{public}d",
7062 where, session->GetPersistentId());
7063 }
7064 }, __func__);
7065 #endif
7066 }
7067
IsStartMoving()7068 bool SceneSession::IsStartMoving()
7069 {
7070 return isStartMoving_.load();
7071 }
7072
SetIsStartMoving(bool startMoving)7073 void SceneSession::SetIsStartMoving(bool startMoving)
7074 {
7075 isStartMoving_.store(startMoving);
7076 }
7077
SetShouldHideNonSecureWindows(bool shouldHide)7078 void SceneSession::SetShouldHideNonSecureWindows(bool shouldHide)
7079 {
7080 shouldHideNonSecureWindows_.store(shouldHide);
7081 }
7082
CalculateCombinedExtWindowFlags()7083 void SceneSession::CalculateCombinedExtWindowFlags()
7084 {
7085 // Only correct when each flag is true when active, and once a uiextension is active, the host is active
7086 ExtensionWindowFlags combinedExtWindowOldFlag = combinedExtWindowFlags_;
7087 combinedExtWindowFlags_.bitData = 0;
7088 for (const auto& iter: extWindowFlagsMap_) {
7089 combinedExtWindowFlags_.bitData |= iter.second.bitData;
7090 }
7091 if (combinedExtWindowOldFlag.hideNonSecureWindowsFlag != combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
7092 NotifyExtensionSecureLimitChange(static_cast<bool>(combinedExtWindowFlags_.hideNonSecureWindowsFlag));
7093 }
7094
7095 NotifyPrivacyModeChange();
7096 }
7097
UpdateExtWindowFlags(int32_t extPersistentId,const ExtensionWindowFlags & extWindowFlags,const ExtensionWindowFlags & extWindowActions)7098 void SceneSession::UpdateExtWindowFlags(int32_t extPersistentId, const ExtensionWindowFlags& extWindowFlags,
7099 const ExtensionWindowFlags& extWindowActions)
7100 {
7101 auto iter = extWindowFlagsMap_.find(extPersistentId);
7102 // Each flag is false when inactive, 0 means all flags are inactive
7103 auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
7104 ExtensionWindowFlags newFlags((extWindowFlags.bitData & extWindowActions.bitData) |
7105 (oldFlags.bitData & ~extWindowActions.bitData));
7106 if (newFlags.bitData == 0) {
7107 extWindowFlagsMap_.erase(extPersistentId);
7108 } else {
7109 extWindowFlagsMap_[extPersistentId] = newFlags;
7110 }
7111 CalculateCombinedExtWindowFlags();
7112 }
7113
GetCombinedExtWindowFlags()7114 ExtensionWindowFlags SceneSession::GetCombinedExtWindowFlags()
7115 {
7116 auto combinedExtWindowFlags = combinedExtWindowFlags_;
7117 combinedExtWindowFlags.hideNonSecureWindowsFlag = IsSessionForeground() &&
7118 (combinedExtWindowFlags.hideNonSecureWindowsFlag || shouldHideNonSecureWindows_.load());
7119 return combinedExtWindowFlags;
7120 }
7121
NotifyDisplayMove(DisplayId from,DisplayId to)7122 void SceneSession::NotifyDisplayMove(DisplayId from, DisplayId to)
7123 {
7124 if (sessionStage_) {
7125 sessionStage_->NotifyDisplayMove(from, to);
7126 } else {
7127 WLOGFE("Notify display move failed, sessionStage is null");
7128 }
7129 }
7130
RemoveExtWindowFlags(int32_t extPersistentId)7131 void SceneSession::RemoveExtWindowFlags(int32_t extPersistentId)
7132 {
7133 extWindowFlagsMap_.erase(extPersistentId);
7134 CalculateCombinedExtWindowFlags();
7135 }
7136
ClearExtWindowFlags()7137 void SceneSession::ClearExtWindowFlags()
7138 {
7139 extWindowFlagsMap_.clear();
7140 combinedExtWindowFlags_.bitData = 0;
7141 }
7142
UpdateRectChangeListenerRegistered(bool isRegister)7143 WSError SceneSession::UpdateRectChangeListenerRegistered(bool isRegister)
7144 {
7145 PostTask([weakThis = wptr(this), isRegister, where = __func__] {
7146 auto session = weakThis.promote();
7147 if (!session) {
7148 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
7149 return WSError::WS_ERROR_DESTROYED_OBJECT;
7150 }
7151 session->rectChangeListenerRegistered_ = isRegister;
7152 return WSError::WS_OK;
7153 }, __func__);
7154 return WSError::WS_OK;
7155 }
7156
SetIsLayoutFullScreen(bool isLayoutFullScreen)7157 void SceneSession::SetIsLayoutFullScreen(bool isLayoutFullScreen)
7158 {
7159 isLayoutFullScreen_ = isLayoutFullScreen;
7160 }
7161
IsLayoutFullScreen() const7162 bool SceneSession::IsLayoutFullScreen() const
7163 {
7164 return isLayoutFullScreen_;
7165 }
7166
OnLayoutFullScreenChange(bool isLayoutFullScreen)7167 WSError SceneSession::OnLayoutFullScreenChange(bool isLayoutFullScreen)
7168 {
7169 PostTask([weakThis = wptr(this), isLayoutFullScreen, where = __func__] {
7170 auto session = weakThis.promote();
7171 if (!session) {
7172 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is null", where);
7173 return WSError::WS_ERROR_DESTROYED_OBJECT;
7174 }
7175 TLOGNI(WmsLogTag::WMS_LAYOUT_PC, "%{public}s isLayoutFullScreen: %{public}d", where, isLayoutFullScreen);
7176 if (session->onLayoutFullScreenChangeFunc_) {
7177 session->SetIsLayoutFullScreen(isLayoutFullScreen);
7178 session->onLayoutFullScreenChangeFunc_(isLayoutFullScreen);
7179 }
7180 return WSError::WS_OK;
7181 }, __func__);
7182 return WSError::WS_OK;
7183 }
7184
OnDefaultDensityEnabled(bool isDefaultDensityEnabled)7185 WSError SceneSession::OnDefaultDensityEnabled(bool isDefaultDensityEnabled)
7186 {
7187 PostTask([weakThis = wptr(this), isDefaultDensityEnabled, where = __func__] {
7188 auto session = weakThis.promote();
7189 if (!session) {
7190 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
7191 return;
7192 }
7193 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s isDefaultDensityEnabled: %{public}d",
7194 where, isDefaultDensityEnabled);
7195 session->isDefaultDensityEnabled_ = isDefaultDensityEnabled;
7196 if (session->onDefaultDensityEnabledFunc_) {
7197 session->onDefaultDensityEnabledFunc_(isDefaultDensityEnabled);
7198 }
7199 }, __func__);
7200 return WSError::WS_OK;
7201 }
7202
7203 /** @note @Window.Layout */
UpdateWindowModeForUITest(int32_t updateMode)7204 WMError SceneSession::UpdateWindowModeForUITest(int32_t updateMode)
7205 {
7206 TLOGD(WmsLogTag::WMS_LAYOUT, "in");
7207 if (sessionStage_ == nullptr) {
7208 TLOGE(WmsLogTag::WMS_LAYOUT, "sessionStage is nullptr");
7209 return WMError::WM_ERROR_NULLPTR;
7210 }
7211 TLOGI(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, updateMode: %{public}d", GetPersistentId(), updateMode);
7212 return sessionStage_->UpdateWindowModeForUITest(updateMode);
7213 }
7214
SetForceHideState(ForceHideState forceHideState)7215 void SceneSession::SetForceHideState(ForceHideState forceHideState)
7216 {
7217 forceHideState_ = forceHideState;
7218 }
7219
GetForceHideState() const7220 ForceHideState SceneSession::GetForceHideState() const
7221 {
7222 return forceHideState_;
7223 }
7224
SetIsDisplayStatusBarTemporarily(bool isTemporary)7225 void SceneSession::SetIsDisplayStatusBarTemporarily(bool isTemporary)
7226 {
7227 isDisplayStatusBarTemporarily_.store(isTemporary);
7228 }
7229
GetIsDisplayStatusBarTemporarily() const7230 bool SceneSession::GetIsDisplayStatusBarTemporarily() const
7231 {
7232 return isDisplayStatusBarTemporarily_.load();
7233 }
7234
RetrieveStatusBarDefaultVisibility()7235 void SceneSession::RetrieveStatusBarDefaultVisibility()
7236 {
7237 if (specificCallback_ && specificCallback_->onGetStatusBarDefaultVisibilityByDisplayId_) {
7238 isStatusBarVisible_ = specificCallback_->onGetStatusBarDefaultVisibilityByDisplayId_(
7239 GetSessionProperty()->GetDisplayId());
7240 }
7241 }
7242
SetIsLastFrameLayoutFinishedFunc(IsLastFrameLayoutFinishedFunc && func)7243 void SceneSession::SetIsLastFrameLayoutFinishedFunc(IsLastFrameLayoutFinishedFunc&& func)
7244 {
7245 isLastFrameLayoutFinishedFunc_ = std::move(func);
7246 }
7247
SetIsAINavigationBarAvoidAreaValidFunc(IsAINavigationBarAvoidAreaValidFunc && func)7248 void SceneSession::SetIsAINavigationBarAvoidAreaValidFunc(IsAINavigationBarAvoidAreaValidFunc&& func)
7249 {
7250 isAINavigationBarAvoidAreaValid_ = std::move(func);
7251 }
7252
SetStartingWindowExitAnimationFlag(bool enable)7253 void SceneSession::SetStartingWindowExitAnimationFlag(bool enable)
7254 {
7255 TLOGI(WmsLogTag::WMS_PATTERN, "SetStartingWindowExitAnimationFlag %{public}d", enable);
7256 needStartingWindowExitAnimation_.store(enable);
7257 }
7258
NeedStartingWindowExitAnimation() const7259 bool SceneSession::NeedStartingWindowExitAnimation() const
7260 {
7261 return needStartingWindowExitAnimation_.load();
7262 }
7263
IsSystemSpecificSession() const7264 bool SceneSession::IsSystemSpecificSession() const
7265 {
7266 return isSystemSpecificSession_;
7267 }
7268
SetIsSystemSpecificSession(bool isSystemSpecificSession)7269 void SceneSession::SetIsSystemSpecificSession(bool isSystemSpecificSession)
7270 {
7271 isSystemSpecificSession_ = isSystemSpecificSession;
7272 }
7273
SetTemporarilyShowWhenLocked(bool isTemporarilyShowWhenLocked)7274 void SceneSession::SetTemporarilyShowWhenLocked(bool isTemporarilyShowWhenLocked)
7275 {
7276 if (isTemporarilyShowWhenLocked_.load() == isTemporarilyShowWhenLocked) {
7277 return;
7278 }
7279 isTemporarilyShowWhenLocked_.store(isTemporarilyShowWhenLocked);
7280 TLOGI(WmsLogTag::WMS_SCB, "SetTemporarilyShowWhenLocked successfully, target:%{public}u",
7281 isTemporarilyShowWhenLocked);
7282 }
7283
IsTemporarilyShowWhenLocked() const7284 bool SceneSession::IsTemporarilyShowWhenLocked() const
7285 {
7286 return isTemporarilyShowWhenLocked_.load();
7287 }
7288
SetSkipDraw(bool skip)7289 void SceneSession::SetSkipDraw(bool skip)
7290 {
7291 auto surfaceNode = GetSurfaceNode();
7292 if (!surfaceNode) {
7293 WLOGFE("surfaceNode_ is null");
7294 return;
7295 }
7296 AutoRSTransaction trans(GetRSUIContext());
7297 surfaceNode->SetSkipDraw(skip);
7298 if (auto leashWinSurfaceNode = GetLeashWinSurfaceNode()) {
7299 leashWinSurfaceNode->SetSkipDraw(skip);
7300 }
7301 }
7302
SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)7303 void SceneSession::SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)
7304 {
7305 TLOGD(WmsLogTag::WMS_SCB, "Set skip Self, isSkip: %{public}d", isSkip);
7306 PostTask([weakThis = wptr(this), isSkip, where = __func__]() {
7307 auto session = weakThis.promote();
7308 if (!session) {
7309 TLOGNE(WmsLogTag::WMS_SCB, "%{public}s session is null", where);
7310 return;
7311 }
7312 session->GetSessionProperty()->SetSkipSelfWhenShowOnVirtualScreen(isSkip);
7313 std::shared_ptr<RSSurfaceNode> surfaceNode = session->GetSurfaceNode();
7314 if (!surfaceNode) {
7315 TLOGNE(WmsLogTag::WMS_SCB, "%{public}s surfaceNode_ is null", where);
7316 return;
7317 }
7318 std::shared_ptr<RSSurfaceNode> leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
7319 if (session->specificCallback_ != nullptr &&
7320 session->specificCallback_->onSetSkipSelfWhenShowOnVirtualScreen_ != nullptr) {
7321 if (WindowHelper::IsPipWindow(session->GetWindowType())) {
7322 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s session is pip", where);
7323 session->specificCallback_->onSetSkipSelfWhenShowOnVirtualScreen_(surfaceNode->GetId(), isSkip);
7324 } else {
7325 session->specificCallback_->onSetSkipSelfWhenShowOnVirtualScreen_(session->GetMissionId(), isSkip);
7326 }
7327 }
7328 return;
7329 }, __func__);
7330 }
7331
SetSkipEventOnCastPlus(bool isSkip)7332 void SceneSession::SetSkipEventOnCastPlus(bool isSkip)
7333 {
7334 TLOGD(WmsLogTag::WMS_SCB, "Set skip event on cast plus, wid: %{public}d, isSkip: %{public}d",
7335 GetPersistentId(), isSkip);
7336 PostTask([weakThis = wptr(this), isSkip, where = __func__]() {
7337 auto session = weakThis.promote();
7338 if (!session) {
7339 TLOGNE(WmsLogTag::WMS_SCB, "%{public}s session is null", where);
7340 return;
7341 }
7342 if (session->specificCallback_ != nullptr &&
7343 session->specificCallback_->onSetSkipEventOnCastPlus_ != nullptr) {
7344 session->specificCallback_->onSetSkipEventOnCastPlus_(session->GetPersistentId(), isSkip);
7345 }
7346 return;
7347 }, __func__);
7348 }
7349
SetUniqueDensityDpi(bool useUnique,float dpi)7350 WMError SceneSession::SetUniqueDensityDpi(bool useUnique, float dpi)
7351 {
7352 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "SceneSession set unique dpi: id=%{public}d, dpi=%{public}f",
7353 GetPersistentId(), dpi);
7354 if (useUnique && (dpi > DOT_PER_INCH_MAXIMUM_VALUE || dpi < DOT_PER_INCH_MINIMUM_VALUE)) {
7355 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Invalid input dpi value, valid input range: %{public}u ~ %{public}u",
7356 DOT_PER_INCH_MINIMUM_VALUE, DOT_PER_INCH_MAXIMUM_VALUE);
7357 return WMError::WM_ERROR_INVALID_PARAM;
7358 }
7359 float density = static_cast<float>(dpi) / 160; // 160 is the coefficient between density and dpi;
7360 if (!IsSessionValid()) {
7361 return WMError::WM_ERROR_INVALID_SESSION;
7362 }
7363 if (!sessionStage_) {
7364 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionStage_ is nullptr");
7365 return WMError::WM_ERROR_NULLPTR;
7366 }
7367 sessionStage_->SetUniqueVirtualPixelRatio(useUnique, density);
7368 return WMError::WM_OK;
7369 }
7370
SetSystemWindowEnableDrag(bool enableDrag)7371 WMError SceneSession::SetSystemWindowEnableDrag(bool enableDrag)
7372 {
7373 if (!WindowHelper::IsSubWindow(GetWindowType()) && !WindowHelper::IsSystemWindow(GetWindowType())) {
7374 TLOGE(WmsLogTag::WMS_LAYOUT, "id:%{public}d, not set enable drag", GetPersistentId());
7375 return WMError::WM_ERROR_INVALID_CALLING;
7376 }
7377
7378 PostTask([weakThis = wptr(this), enableDrag, where = __func__] {
7379 auto session = weakThis.promote();
7380 if (!session) {
7381 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
7382 return;
7383 }
7384 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, enableDrag:%{public}d",
7385 where, session->GetPersistentId(), enableDrag);
7386 session->GetSessionProperty()->SetDragEnabled(enableDrag);
7387 session->NotifySessionInfoChange();
7388 }, __func__);
7389 return WMError::WM_OK;
7390 }
7391
SetWindowEnableDragBySystem(bool enableDrag)7392 WMError SceneSession::SetWindowEnableDragBySystem(bool enableDrag)
7393 {
7394 TLOGI(WmsLogTag::WMS_LAYOUT, "enableDrag: %{public}d", enableDrag);
7395 PostTask([weakThis = wptr(this), enableDrag, where = __func__] {
7396 auto session = weakThis.promote();
7397 if (!session) {
7398 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
7399 return;
7400 }
7401 session->SetClientDragEnable(enableDrag);
7402 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s id: %{public}d, enableDrag: %{public}d",
7403 where, session->GetPersistentId(), enableDrag);
7404 session->GetSessionProperty()->SetDragEnabled(enableDrag);
7405 if (session->sessionStage_) {
7406 session->sessionStage_->SetEnableDragBySystem(enableDrag);
7407 }
7408 }, __func__);
7409 return WMError::WM_OK;
7410 }
7411
ActivateDragBySystem(bool activateDrag)7412 WMError SceneSession::ActivateDragBySystem(bool activateDrag)
7413 {
7414 PostTask([weakThis = wptr(this), activateDrag, where = __func__] {
7415 auto session = weakThis.promote();
7416 if (!session) {
7417 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
7418 return;
7419 }
7420 session->SetDragActivated(activateDrag);
7421 session->NotifySessionInfoChange();
7422 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s id: %{public}d, activate drag: %{public}d",
7423 where, session->GetPersistentId(), activateDrag);
7424 if (session->sessionStage_) {
7425 session->sessionStage_->SetDragActivated(activateDrag);
7426 }
7427 }, __func__);
7428 return WMError::WM_OK;
7429 }
7430
HandleActionUpdateWindowModeSupportType(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)7431 WMError SceneSession::HandleActionUpdateWindowModeSupportType(const sptr<WindowSessionProperty>& property,
7432 WSPropertyChangeAction action)
7433 {
7434 if (!property->GetSystemCalling()) {
7435 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
7436 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7437 }
7438
7439 auto sessionProperty = GetSessionProperty();
7440 if (sessionProperty != nullptr) {
7441 sessionProperty->SetWindowModeSupportType(property->GetWindowModeSupportType());
7442 }
7443 return WMError::WM_OK;
7444 }
7445
RegisterForceSplitListener(const NotifyForceSplitFunc & func)7446 void SceneSession::RegisterForceSplitListener(const NotifyForceSplitFunc& func)
7447 {
7448 forceSplitFunc_ = func;
7449 }
7450
RegisterAppHookWindowInfoFunc(GetHookWindowInfoFunc && func)7451 void SceneSession::RegisterAppHookWindowInfoFunc(GetHookWindowInfoFunc&& func)
7452 {
7453 if (!func) {
7454 TLOGW(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, func is null", GetPersistentId());
7455 return;
7456 }
7457 getHookWindowInfoFunc_ = std::move(func);
7458 }
7459
RegisterRequestedOrientationChangeCallback(NotifyReqOrientationChangeFunc && callback)7460 void SceneSession::RegisterRequestedOrientationChangeCallback(NotifyReqOrientationChangeFunc&& callback)
7461 {
7462 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
7463 auto session = weakThis.promote();
7464 if (!session) {
7465 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
7466 return;
7467 }
7468 session->onRequestedOrientationChange_ = std::move(callback);
7469 }, __func__);
7470 }
7471
RegisterBindDialogSessionCallback(const NotifyBindDialogSessionFunc & callback)7472 void SceneSession::RegisterBindDialogSessionCallback(const NotifyBindDialogSessionFunc& callback)
7473 {
7474 onBindDialogTarget_ = callback;
7475 }
7476
RegisterIsCustomAnimationPlayingCallback(NotifyIsCustomAnimationPlayingCallback && callback)7477 void SceneSession::RegisterIsCustomAnimationPlayingCallback(NotifyIsCustomAnimationPlayingCallback&& callback)
7478 {
7479 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
7480 auto session = weakThis.promote();
7481 if (!session) {
7482 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
7483 return;
7484 }
7485 session->onIsCustomAnimationPlaying_ = std::move(callback);
7486 }, __func__);
7487 }
7488
RegisterLayoutFullScreenChangeCallback(NotifyLayoutFullScreenChangeFunc && callback)7489 void SceneSession::RegisterLayoutFullScreenChangeCallback(NotifyLayoutFullScreenChangeFunc&& callback)
7490 {
7491 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
7492 auto session = weakThis.promote();
7493 if (!session) {
7494 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
7495 return;
7496 }
7497 session->onLayoutFullScreenChangeFunc_ = std::move(callback);
7498 }, __func__);
7499 }
7500
RegisterGetStatusBarAvoidHeightFunc(GetStatusBarAvoidHeightFunc && callback)7501 void SceneSession::RegisterGetStatusBarAvoidHeightFunc(GetStatusBarAvoidHeightFunc&& callback)
7502 {
7503 onGetStatusBarAvoidHeightFunc_ = std::move(callback);
7504 }
7505
RegisterGetStatusBarConstantlyShowFunc(GetStatusBarConstantlyShowFunc && callback)7506 void SceneSession::RegisterGetStatusBarConstantlyShowFunc(GetStatusBarConstantlyShowFunc&& callback)
7507 {
7508 onGetStatusBarConstantlyShowFunc_ = std::move(callback);
7509 }
7510
GetAppForceLandscapeConfig(AppForceLandscapeConfig & config)7511 WMError SceneSession::GetAppForceLandscapeConfig(AppForceLandscapeConfig& config)
7512 {
7513 if (forceSplitFunc_ == nullptr) {
7514 return WMError::WM_ERROR_NULLPTR;
7515 }
7516 config = forceSplitFunc_(sessionInfo_.bundleName_);
7517 return WMError::WM_OK;
7518 }
7519
GetAppHookWindowInfoFromServer(HookWindowInfo & hookWindowInfo)7520 WMError SceneSession::GetAppHookWindowInfoFromServer(HookWindowInfo& hookWindowInfo)
7521 {
7522 return PostSyncTask([weakThis = wptr(this), &hookWindowInfo, where = __func__]() -> WMError {
7523 auto session = weakThis.promote();
7524 if (!session) {
7525 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
7526 return WMError::WM_ERROR_INVALID_SESSION;
7527 }
7528 if (!session->getHookWindowInfoFunc_) {
7529 TLOGW(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, func is null", session->GetPersistentId());
7530 return WMError::WM_ERROR_NULLPTR;
7531 }
7532 hookWindowInfo = session->getHookWindowInfoFunc_(session->GetSessionInfo().bundleName_);
7533 return WMError::WM_OK;
7534 }, __func__);
7535 }
7536
SetUpdatePrivateStateAndNotifyFunc(const UpdatePrivateStateAndNotifyFunc & func)7537 void SceneSession::SetUpdatePrivateStateAndNotifyFunc(const UpdatePrivateStateAndNotifyFunc& func)
7538 {
7539 updatePrivateStateAndNotifyFunc_ = func;
7540 }
7541
SetNotifyScreenshotAppEventRegisteredFunc(UpdateScreenshotAppEventRegisteredFunc && func)7542 void SceneSession::SetNotifyScreenshotAppEventRegisteredFunc(UpdateScreenshotAppEventRegisteredFunc&& func)
7543 {
7544 updateScreenshotAppEventRegisteredFunc_ = std::move(func);
7545 }
7546
SetNotifyVisibleChangeFunc(const NotifyVisibleChangeFunc & func)7547 void SceneSession::SetNotifyVisibleChangeFunc(const NotifyVisibleChangeFunc& func)
7548 {
7549 notifyVisibleChangeFunc_ = func;
7550 }
7551
SetPrivacyModeChangeNotifyFunc(NotifyPrivacyModeChangeFunc && func)7552 void SceneSession::SetPrivacyModeChangeNotifyFunc(NotifyPrivacyModeChangeFunc&& func)
7553 {
7554 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
7555 auto session = weakThis.promote();
7556 if (!session) {
7557 TLOGNE(WmsLogTag::WMS_SCB, "%{public}s session is null", where);
7558 return;
7559 }
7560 session->privacyModeChangeNotifyFunc_ = std::move(func);
7561 }, __func__);
7562 }
7563
SetHighlightChangeNotifyFunc(const NotifyHighlightChangeFunc & func)7564 void SceneSession::SetHighlightChangeNotifyFunc(const NotifyHighlightChangeFunc& func)
7565 {
7566 std::lock_guard lock(highlightChangeFuncMutex_);
7567 highlightChangeFunc_ = func;
7568 }
7569
RegisterNotifySurfaceBoundsChangeFunc(int32_t sessionId,NotifySurfaceBoundsChangeFunc && func)7570 void SceneSession::RegisterNotifySurfaceBoundsChangeFunc(int32_t sessionId, NotifySurfaceBoundsChangeFunc&& func)
7571 {
7572 if (!func) {
7573 TLOGE(WmsLogTag::WMS_SUB, "func is null");
7574 return;
7575 }
7576 std::lock_guard lock(registerNotifySurfaceBoundsChangeMutex_);
7577 notifySurfaceBoundsChangeFuncMap_[sessionId] = func;
7578 NotifyFollowedParentWindowAcrossDisplaysChange(IsFullScreenWaterfallMode());
7579 }
7580
UnregisterNotifySurfaceBoundsChangeFunc(int32_t sessionId)7581 void SceneSession::UnregisterNotifySurfaceBoundsChangeFunc(int32_t sessionId)
7582 {
7583 std::lock_guard lock(registerNotifySurfaceBoundsChangeMutex_);
7584 notifySurfaceBoundsChangeFuncMap_.erase(sessionId);
7585 }
7586
GetSceneSessionById(int32_t sessionId) const7587 sptr<SceneSession> SceneSession::GetSceneSessionById(int32_t sessionId) const
7588 {
7589 if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionByIdCallback_ == nullptr) {
7590 TLOGE(WmsLogTag::WMS_LAYOUT, "specificCallback or onGetSceneSessionByIdCallback is null");
7591 return nullptr;
7592 }
7593 return specificCallback_->onGetSceneSessionByIdCallback_(sessionId);
7594 }
7595
SetWindowAnchorInfoChangeFunc(NotifyWindowAnchorInfoChangeFunc && func)7596 void SceneSession::SetWindowAnchorInfoChangeFunc(NotifyWindowAnchorInfoChangeFunc&& func)
7597 {
7598 if (!func) {
7599 TLOGW(WmsLogTag::WMS_SUB, "func is null");
7600 return;
7601 }
7602 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
7603 auto session = weakThis.promote();
7604 if (!session) {
7605 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is null", where);
7606 return;
7607 }
7608 func(session->windowAnchorInfo_);
7609 session->onWindowAnchorInfoChangeFunc_ = std::move(func);
7610 });
7611 }
7612
SetWindowAnchorInfo(const WindowAnchorInfo & windowAnchorInfo)7613 WSError SceneSession::SetWindowAnchorInfo(const WindowAnchorInfo& windowAnchorInfo)
7614 {
7615 auto property = GetSessionProperty();
7616 if (!property || property->GetSubWindowLevel() > 1) {
7617 TLOGE(WmsLogTag::WMS_SUB, "property is null or not surppot more than 1 level window");
7618 return WSError::WS_ERROR_INVALID_OPERATION;
7619 }
7620 if (!WindowHelper::IsSubWindow(property->GetWindowType())) {
7621 TLOGE(WmsLogTag::WMS_SUB, "only sub window is valid");
7622 return WSError::WS_ERROR_INVALID_OPERATION;
7623 }
7624 if (GetIsFollowParentLayout()) {
7625 TLOGE(WmsLogTag::WMS_SUB, "current sub window follow parent layout");
7626 return WSError::WS_ERROR_INVALID_OPERATION;
7627 }
7628 if (windowAnchorInfo.windowAnchor_ > WindowAnchor::BOTTOM_END ||
7629 windowAnchorInfo.windowAnchor_ < WindowAnchor::TOP_START) {
7630 TLOGE(WmsLogTag::WMS_SUB, "Unknown window anchor");
7631 return WSError::WS_ERROR_INVALID_OPERATION;
7632 }
7633 if (!systemConfig_.supportFollowRelativePositionToParent_) {
7634 TLOGI(WmsLogTag::WMS_SUB, "not support device");
7635 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
7636 }
7637 PostTask([weakThis = wptr(this), windowAnchorInfo, where = __func__] {
7638 auto session = weakThis.promote();
7639 if (!session) {
7640 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is null", where);
7641 return;
7642 }
7643 session->windowAnchorInfo_ = windowAnchorInfo;
7644 if (session->onWindowAnchorInfoChangeFunc_) {
7645 session->onWindowAnchorInfoChangeFunc_(windowAnchorInfo);
7646 } else {
7647 TLOGI(WmsLogTag::WMS_SUB, "func is null");
7648 }
7649 });
7650 return WSError::WS_OK;
7651 }
7652
CalcSubWindowRectByAnchor(const WSRect & parentRect,WSRect & subRect)7653 void SceneSession::CalcSubWindowRectByAnchor(const WSRect& parentRect, WSRect& subRect)
7654 {
7655 if (SessionHelper::IsEmptyRect(parentRect) || SessionHelper::IsEmptyRect(subRect)) {
7656 TLOGE(WmsLogTag::WMS_SUB, "parent or sub window rect is invalid");
7657 return;
7658 }
7659 if (!windowAnchorInfo_.isAnchorEnabled_) {
7660 TLOGI(WmsLogTag::WMS_SUB, "sub window anchor disabled");
7661 return;
7662 }
7663
7664 WindowAnchor anchorMode = windowAnchorInfo_.windowAnchor_;
7665 int32_t offsetX = windowAnchorInfo_.offsetX_;
7666 int32_t offsetY = windowAnchorInfo_.offsetY_;
7667 switch (anchorMode) {
7668 case WindowAnchor::TOP_START:
7669 subRect.posX_ = parentRect.posX_;
7670 subRect.posY_ = parentRect.posY_;
7671 break;
7672 case WindowAnchor::TOP:
7673 subRect.posX_ = parentRect.posX_ + (parentRect.width_ - subRect.width_) / HALF_VALUE;
7674 subRect.posY_ = parentRect.posY_;
7675 break;
7676 case WindowAnchor::TOP_END:
7677 subRect.posX_ = parentRect.posX_ + parentRect.width_ - subRect.width_;
7678 subRect.posY_ = parentRect.posY_;
7679 break;
7680 case WindowAnchor::START:
7681 subRect.posX_ = parentRect.posX_;
7682 subRect.posY_ = parentRect.posY_ + (parentRect.height_ - subRect.height_) / HALF_VALUE;
7683 break;
7684 case WindowAnchor::CENTER:
7685 subRect.posX_ = parentRect.posX_ + (parentRect.width_ - subRect.width_) / HALF_VALUE;
7686 subRect.posY_ = parentRect.posY_ + (parentRect.height_ - subRect.height_) / HALF_VALUE;
7687 break;
7688 case WindowAnchor::END:
7689 subRect.posX_ = parentRect.posX_ + parentRect.width_ - subRect.width_;
7690 subRect.posY_ = parentRect.posY_ + (parentRect.height_ - subRect.height_) / HALF_VALUE;
7691 break;
7692 case WindowAnchor::BOTTOM_START:
7693 subRect.posX_ = parentRect.posX_;
7694 subRect.posY_ = parentRect.posY_ + parentRect.height_ - subRect.height_;
7695 break;
7696 case WindowAnchor::BOTTOM:
7697 subRect.posX_ = parentRect.posX_ + (parentRect.width_ - subRect.width_) / HALF_VALUE;
7698 subRect.posY_ = parentRect.posY_ + parentRect.height_ - subRect.height_;
7699 break;
7700 case WindowAnchor::BOTTOM_END:
7701 subRect.posX_ = parentRect.posX_ + parentRect.width_ - subRect.width_;
7702 subRect.posY_ = parentRect.posY_ + parentRect.height_ - subRect.height_;
7703 break;
7704 default:
7705 TLOGE(WmsLogTag::WMS_SUB, "invalid anchor mode");
7706 return;
7707 }
7708 subRect.posX_ += offsetX;
7709 subRect.posY_ += offsetY;
7710 TLOGI(WmsLogTag::WMS_SUB, "win %{public}d, anchorMode %{public}u, rect %{public}s",
7711 GetPersistentId(), anchorMode, subRect.ToString().c_str());
7712 }
7713
SetFollowParentRectFunc(NotifyFollowParentRectFunc && func)7714 void SceneSession::SetFollowParentRectFunc(NotifyFollowParentRectFunc&& func)
7715 {
7716 if (!func) {
7717 TLOGW(WmsLogTag::WMS_SUB, "func is null");
7718 return;
7719 }
7720 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
7721 auto session = weakThis.promote();
7722 if (!session) {
7723 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is null", where);
7724 return;
7725 }
7726 func(session->isFollowParentLayout_);
7727 session->followParentRectFunc_ = std::move(func);
7728 });
7729 }
7730
SetFollowParentWindowLayoutEnabled(bool isFollow)7731 WSError SceneSession::SetFollowParentWindowLayoutEnabled(bool isFollow)
7732 {
7733 auto property = GetSessionProperty();
7734 if (!property || property->GetSubWindowLevel() > 1) {
7735 TLOGE(WmsLogTag::WMS_SUB, "property is null or not surppot more than 1 level window");
7736 return WSError::WS_ERROR_INVALID_OPERATION;
7737 }
7738 if (!WindowHelper::IsSubWindow(property->GetWindowType()) &&
7739 !WindowHelper::IsDialogWindow(property->GetWindowType())) {
7740 TLOGE(WmsLogTag::WMS_SUB, "only sub window and dialog is valid");
7741 return WSError::WS_ERROR_INVALID_OPERATION;
7742 }
7743 if (GetWindowAnchorInfo().isAnchorEnabled_) {
7744 TLOGE(WmsLogTag::WMS_SUB, "current sub window follow parent anchor");
7745 return WSError::WS_ERROR_INVALID_OPERATION;
7746 }
7747 if (!systemConfig_.supportFollowParentWindowLayout_) {
7748 TLOGI(WmsLogTag::WMS_SUB, "not support device");
7749 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
7750 }
7751 PostTask([weakThis = wptr(this), isFollow = isFollow, where = __func__] {
7752 auto session = weakThis.promote();
7753 if (!session) {
7754 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is null", where);
7755 return;
7756 }
7757 session->isFollowParentLayout_ = isFollow;
7758 if (session->followParentRectFunc_) {
7759 session->followParentRectFunc_(isFollow);
7760 } else {
7761 TLOGI(WmsLogTag::WMS_SUB, "func is null");
7762 }
7763 // if parent is null, don't need follow move drag
7764 if (!session->parentSession_) {
7765 TLOGW(WmsLogTag::WMS_SUB, "parent is null");
7766 return;
7767 }
7768 if (!isFollow) {
7769 session->parentSession_->UnregisterNotifySurfaceBoundsChangeFunc(session->GetPersistentId());
7770 return;
7771 }
7772 auto task = [weak = weakThis](const WSRect& rect, bool isGlobal, bool needFlush) {
7773 auto session = weak.promote();
7774 if (!session) {
7775 TLOGNE(WmsLogTag::WMS_SUB, "session has been destroy");
7776 return;
7777 }
7778 session->SetSurfaceBounds(rect, isGlobal, needFlush);
7779 };
7780 session->parentSession_->RegisterNotifySurfaceBoundsChangeFunc(session->GetPersistentId(), std::move(task));
7781 if (auto parentSession = session->GetSceneSessionById(session->GetMainSessionId())) {
7782 session->NotifySessionAcrossDisplaysChange(session, parentSession->IsFullScreenWaterfallMode());
7783 }
7784 });
7785 return WSError::WS_OK;
7786 }
7787
GetStatusBarHeight()7788 int32_t SceneSession::GetStatusBarHeight()
7789 {
7790 return PostSyncTask([weakThis = wptr(this), where = __func__]() -> int32_t {
7791 auto session = weakThis.promote();
7792 if (!session) {
7793 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
7794 return 0;
7795 }
7796 int32_t height = 0;
7797 if (session->specificCallback_ == nullptr ||
7798 session->specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_ == nullptr) {
7799 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s specificCallback_ or session property is null", where);
7800 return height;
7801 }
7802 const auto& statusBarVector = session->specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
7803 WindowType::WINDOW_TYPE_STATUS_BAR, session->GetSessionProperty()->GetDisplayId());
7804 DisplayId displayId = session->GetSessionProperty()->GetDisplayId();
7805 for (auto& statusBar : statusBarVector) {
7806 if (statusBar == nullptr) {
7807 continue;
7808 }
7809 WSRect statusBarRect = statusBar->GetSessionRect();
7810 if (session->onGetStatusBarAvoidHeightFunc_) {
7811 session->onGetStatusBarAvoidHeightFunc_(displayId, statusBarRect);
7812 }
7813 height = statusBarRect.height_;
7814 }
7815 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d displayId %{public}" PRIu64 " height %{public}d",
7816 where, session->GetPersistentId(), displayId, height);
7817 return height;
7818 }, __func__);
7819 }
7820
GetDockHeight()7821 int32_t SceneSession::GetDockHeight()
7822 {
7823 int32_t height = 0;
7824 if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_ == nullptr ||
7825 GetSessionProperty() == nullptr) {
7826 TLOGE(WmsLogTag::WMS_DECOR, "specificCallback_ or session property is null");
7827 return height;
7828 }
7829 const auto& dockVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
7830 WindowType::WINDOW_TYPE_LAUNCHER_DOCK, GetSessionProperty()->GetDisplayId());
7831 for (auto& dock : dockVector) {
7832 if (dock != nullptr && dock->IsVisible() && dock->GetWindowName().find("SCBSmartDock") != std::string::npos) {
7833 int32_t dockHeight = dock->GetSessionRect().height_;
7834 if (dockHeight > height) {
7835 height = dockHeight;
7836 }
7837 }
7838 }
7839 return height;
7840 }
7841
CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty> & property) const7842 bool SceneSession::CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty>& property) const
7843 {
7844 if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
7845 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7846 TLOGE(WmsLogTag::WMS_LIFE, "Not system app, no permission");
7847 return false;
7848 }
7849 }
7850 return true;
7851 }
7852
UpdatePCZOrderAndMarkDirty(const uint32_t zOrder)7853 void SceneSession::UpdatePCZOrderAndMarkDirty(const uint32_t zOrder)
7854 {
7855 dirtyFlags_ |= UpdateZOrderInner(zOrder) ? static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER) : 0;
7856 }
7857
UpdateUIParam(const SessionUIParam & uiParam)7858 uint32_t SceneSession::UpdateUIParam(const SessionUIParam& uiParam)
7859 {
7860 bool lastVisible = IsVisible();
7861 dirtyFlags_ |= UpdateInteractiveInner(uiParam.interactive_) ?
7862 static_cast<uint32_t>(SessionUIDirtyFlag::INTERACTIVE) : 0;
7863 if (!uiParam.interactive_) {
7864 // keep ui state in recent
7865 return dirtyFlags_;
7866 }
7867 dirtyFlags_ |= UpdateVisibilityInner(true) ? static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE) : 0;
7868 bool isUpdateRectDirty = UpdateRectInner(uiParam, GetSizeChangeReason());
7869 if (isUpdateRectDirty) {
7870 dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
7871 AddPropertyDirtyFlags(static_cast<uint32_t>(SessionPropertyFlag::WINDOW_RECT));
7872 }
7873 dirtyFlags_ |= UpdateScaleInner(uiParam.scaleX_, uiParam.scaleY_, uiParam.pivotX_, uiParam.pivotY_) ?
7874 static_cast<uint32_t>(SessionUIDirtyFlag::SCALE) : 0;
7875 if (!isPcScenePanel_) {
7876 dirtyFlags_ |= UpdateZOrderInner(uiParam.zOrder_) ? static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER) : 0;
7877 }
7878 if (!lastVisible && IsVisible() && !isFocused_ && !postProcessFocusState_.enabled_ &&
7879 GetForegroundInteractiveStatus()) {
7880 postProcessFocusState_.enabled_ = true;
7881 postProcessFocusState_.isFocused_ = true;
7882 postProcessFocusState_.reason_ = isStarting_ ?
7883 FocusChangeReason::SCB_START_APP : FocusChangeReason::FOREGROUND;
7884 }
7885 return dirtyFlags_;
7886 }
7887
UpdateUIParam()7888 uint32_t SceneSession::UpdateUIParam()
7889 {
7890 bool lastVisible = IsVisible();
7891 dirtyFlags_ |= UpdateVisibilityInner(false) ? static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE) : 0;
7892 if (lastVisible && !IsVisible() && isFocused_) {
7893 postProcessFocusState_.enabled_ = true;
7894 postProcessFocusState_.isFocused_ = false;
7895 postProcessFocusState_.reason_ = FocusChangeReason::BACKGROUND;
7896 }
7897 return dirtyFlags_;
7898 }
7899
UpdateVisibilityInner(bool visibility)7900 bool SceneSession::UpdateVisibilityInner(bool visibility)
7901 {
7902 if (isVisible_ == visibility) {
7903 return false;
7904 }
7905 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, visibility: %{public}u -> %{public}u",
7906 GetPersistentId(), isVisible_, visibility);
7907 if (visibilityChangedDetectFunc_) {
7908 visibilityChangedDetectFunc_(GetCallingPid(), isVisible_, visibility);
7909 }
7910 isVisible_ = visibility;
7911 if (updatePrivateStateAndNotifyFunc_ != nullptr) {
7912 updatePrivateStateAndNotifyFunc_(GetPersistentId());
7913 }
7914 if (notifyVisibleChangeFunc_ != nullptr) {
7915 notifyVisibleChangeFunc_(GetPersistentId());
7916 }
7917 SceneSessionChangeInfo changeInfo {
7918 .persistentId_ = GetPersistentId(),
7919 .changeInfo_ = "Visibility change to " + std::to_string(visibility),
7920 .logTag_ = WmsLogTag::WMS_ATTRIBUTE,
7921 };
7922 SessionChangeRecorder::GetInstance().RecordSceneSessionChange(RecordType::VISIBLE_RECORD, changeInfo);
7923 return true;
7924 }
7925
UpdateInteractiveInner(bool interactive)7926 bool SceneSession::UpdateInteractiveInner(bool interactive)
7927 {
7928 if (GetForegroundInteractiveStatus() == interactive) {
7929 return false;
7930 }
7931 NotifyAddOrRemoveSnapshotWindow(interactive);
7932 SetForegroundInteractiveStatus(interactive);
7933 NotifyClientToUpdateInteractive(interactive);
7934 return true;
7935 }
7936
NotifyAddOrRemoveSnapshotWindow(bool interactive)7937 void SceneSession::NotifyAddOrRemoveSnapshotWindow(bool interactive)
7938 {
7939 auto needSaveSnapshot = ScenePersistentStorage::HasKey("SetImageForRecent_" + std::to_string(GetPersistentId()),
7940 ScenePersistentStorageType::MAXIMIZE_STATE);
7941 // persistent imageFit exist, add snapshot when interactive is false.
7942 if (needSaveSnapshot && !GetShowRecent()) {
7943 TLOGI(WmsLogTag::WMS_PATTERN, "Add or remove static image from window, interactive:%{public}d", interactive);
7944 PostTask([weakThis = wptr(this), interactive, where = __func__] {
7945 auto session = weakThis.promote();
7946 if (session == nullptr) {
7947 TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s session is null", where);
7948 return;
7949 }
7950 interactive ? session->NotifyRemoveSnapshot() : session->NotifyAddSnapshot(false, false, false);
7951 }, __func__);
7952 }
7953 }
7954
UpdateLifecyclePausedInner()7955 void SceneSession::UpdateLifecyclePausedInner()
7956 {
7957 if (!sessionStage_) {
7958 return;
7959 }
7960 const auto state = GetSessionState();
7961 TLOGI(WmsLogTag::WMS_LIFE, "state: %{public}d", state);
7962 if (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
7963 sessionStage_->NotifyLifecyclePausedStatus();
7964 }
7965 }
7966
PipelineNeedNotifyClientToUpdateRect() const7967 bool SceneSession::PipelineNeedNotifyClientToUpdateRect() const
7968 {
7969 return IsVisibleForeground() && GetForegroundInteractiveStatus();
7970 }
7971
UpdateRectInner(const SessionUIParam & uiParam,SizeChangeReason reason)7972 bool SceneSession::UpdateRectInner(const SessionUIParam& uiParam, SizeChangeReason reason)
7973 {
7974 if (reason == SizeChangeReason::PAGE_ROTATION) {
7975 dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
7976 }
7977
7978 if (!((NotifyServerToUpdateRect(uiParam, reason) || IsDirtyWindow()) && PipelineNeedNotifyClientToUpdateRect())) {
7979 return false;
7980 }
7981 if (WindowHelper::IsSubWindow(GetWindowType())) {
7982 isSubWindowResizingOrMoving_ = false;
7983 }
7984 NotifyClientToUpdateRect("WMSPipeline", RSSyncTransactionAdapter::GetRSTransaction(GetRSUIContext()));
7985 return true;
7986 }
7987
NotifyServerToUpdateRect(const SessionUIParam & uiParam,SizeChangeReason reason)7988 bool SceneSession::NotifyServerToUpdateRect(const SessionUIParam& uiParam, SizeChangeReason reason)
7989 {
7990 if (!GetForegroundInteractiveStatus()) {
7991 TLOGD(WmsLogTag::WMS_PIPELINE, "skip recent, id:%{public}d", GetPersistentId());
7992 return false;
7993 }
7994 if (keyFramePolicy_.running_) {
7995 TLOGI(WmsLogTag::WMS_PIPELINE, "skip for key frame running, id:%{public}d", GetPersistentId());
7996 return false;
7997 }
7998 if (uiParam.rect_.IsInvalid()) {
7999 TLOGW(WmsLogTag::WMS_PIPELINE, "id:%{public}d rect:%{public}s is invalid",
8000 GetPersistentId(), uiParam.rect_.ToString().c_str());
8001 return false;
8002 }
8003 auto globalRect = GetSessionGlobalRect();
8004 SetSessionGlobalRect(uiParam.rect_);
8005 if (globalRect != uiParam.rect_) {
8006 UpdateAllModalUIExtensions(uiParam.rect_);
8007 }
8008 if (!uiParam.needSync_ || !isNeedSyncSessionRect_) {
8009 TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, scenePanelNeedSync:%{public}u needSyncSessionRect:%{public}u "
8010 "rectAfter:%{public}s preRect:%{public}s preGlobalRect:%{public}s", GetPersistentId(), uiParam.needSync_,
8011 isNeedSyncSessionRect_, uiParam.rect_.ToString().c_str(), GetSessionRect().ToString().c_str(),
8012 globalRect.ToString().c_str());
8013 return false;
8014 }
8015 WSRect rect = { uiParam.rect_.posX_ - uiParam.transX_, uiParam.rect_.posY_ - uiParam.transY_,
8016 uiParam.rect_.width_, uiParam.rect_.height_ };
8017 if (GetSessionRect() == rect && (!sessionStage_ || GetClientRect() == rect) &&
8018 reason != SizeChangeReason::SPLIT_DRAG_END) {
8019 TLOGD(WmsLogTag::WMS_PIPELINE, "skip same rect update id:%{public}d rect:%{public}s preGlobalRect:%{public}s!",
8020 GetPersistentId(), rect.ToString().c_str(), globalRect.ToString().c_str());
8021 return false;
8022 }
8023 if (rect.IsInvalid()) {
8024 TLOGE(WmsLogTag::WMS_PIPELINE, "id:%{public}d rect:%{public}s is invalid, preGlobalRect:%{public}s",
8025 GetPersistentId(), rect.ToString().c_str(), globalRect.ToString().c_str());
8026 return false;
8027 }
8028 TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, updateRect rectAfter:%{public}s preRect:%{public}s "
8029 "preGlobalRect:%{public}s clientRect:%{public}s", GetPersistentId(), rect.ToString().c_str(),
8030 GetSessionRect().ToString().c_str(), globalRect.ToString().c_str(), GetClientRect().ToString().c_str());
8031 layoutController_->SetSessionRect(rect);
8032 RectCheckProcess();
8033 return true;
8034 }
8035
PostProcessNotifyAvoidArea()8036 void SceneSession::PostProcessNotifyAvoidArea()
8037 {
8038 if (PipelineNeedNotifyClientToUpdateAvoidArea(dirtyFlags_)) {
8039 NotifyClientToUpdateAvoidArea();
8040 }
8041 }
8042
PipelineNeedNotifyClientToUpdateAvoidArea(uint32_t dirty) const8043 bool SceneSession::PipelineNeedNotifyClientToUpdateAvoidArea(uint32_t dirty) const
8044 {
8045 return ((dirty & static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE)) && IsImmersiveType()) ||
8046 ((dirty & static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) && isVisible_);
8047 }
8048
NotifyClientToUpdateAvoidArea()8049 void SceneSession::NotifyClientToUpdateAvoidArea()
8050 {
8051 if (specificCallback_ == nullptr) {
8052 return;
8053 }
8054 // flush avoid areas on (avoid area dirty && (normal session rect NOT dirty || avoid session))
8055 if ((IsImmersiveType() || !IsDirtyWindow()) && specificCallback_->onUpdateAvoidArea_) {
8056 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
8057 }
8058 }
8059
UpdateScaleInner(float scaleX,float scaleY,float pivotX,float pivotY)8060 bool SceneSession::UpdateScaleInner(float scaleX, float scaleY, float pivotX, float pivotY)
8061 {
8062 if (!layoutController_->IsTransformNeedUpdate(scaleX, scaleY, pivotX, pivotY)) {
8063 return false;
8064 }
8065 Session::SetScale(scaleX, scaleY, pivotX, pivotY);
8066 if (!IsSessionForeground()) {
8067 TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, session is not foreground!", GetPersistentId());
8068 return false;
8069 }
8070 if (sessionStage_ != nullptr) {
8071 Transform transform;
8072 transform.scaleX_ = scaleX;
8073 transform.scaleY_ = scaleY;
8074 transform.pivotX_ = pivotX;
8075 transform.pivotY_ = pivotY;
8076 sessionStage_->NotifyTransformChange(transform);
8077 Session::SetClientScale(scaleX, scaleY, pivotX, pivotY);
8078 } else {
8079 WLOGFE("sessionStage is nullptr");
8080 }
8081 return true;
8082 }
8083
UpdateZOrderInner(uint32_t zOrder)8084 bool SceneSession::UpdateZOrderInner(uint32_t zOrder)
8085 {
8086 if (zOrder_ == zOrder) {
8087 return false;
8088 }
8089 TLOGI(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}u -> %{public}u, lastZOrder: %{public}u",
8090 GetPersistentId(), zOrder_, zOrder, lastZOrder_);
8091 lastZOrder_ = zOrder_;
8092 zOrder_ = zOrder;
8093 return true;
8094 }
8095
SetPostProcessFocusState(PostProcessFocusState state)8096 void SceneSession::SetPostProcessFocusState(PostProcessFocusState state)
8097 {
8098 postProcessFocusState_ = state;
8099 }
8100
GetPostProcessFocusState() const8101 PostProcessFocusState SceneSession::GetPostProcessFocusState() const
8102 {
8103 return postProcessFocusState_;
8104 }
8105
ResetPostProcessFocusState()8106 void SceneSession::ResetPostProcessFocusState()
8107 {
8108 postProcessFocusState_.Reset();
8109 }
8110
SetPostProcessProperty(bool state)8111 void SceneSession::SetPostProcessProperty(bool state)
8112 {
8113 postProcessProperty_ = state;
8114 }
8115
GetPostProcessProperty() const8116 bool SceneSession::GetPostProcessProperty() const
8117 {
8118 return postProcessProperty_;
8119 }
8120
IsImmersiveType() const8121 bool SceneSession::IsImmersiveType() const
8122 {
8123 WindowType type = GetWindowType();
8124 return type == WindowType::WINDOW_TYPE_STATUS_BAR ||
8125 type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
8126 type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
8127 }
8128
IsPcOrPadEnableActivation() const8129 bool SceneSession::IsPcOrPadEnableActivation() const
8130 {
8131 auto property = GetSessionProperty();
8132 bool isPcAppInLargeScreenDevice = false;
8133 if (property != nullptr) {
8134 isPcAppInLargeScreenDevice = property->GetIsPcAppInPad();
8135 }
8136 return systemConfig_.IsPcWindow() || IsFreeMultiWindowMode() || isPcAppInLargeScreenDevice;
8137 }
8138
SetMinimizedFlagByUserSwitch(bool isMinimized)8139 void SceneSession::SetMinimizedFlagByUserSwitch(bool isMinimized)
8140 {
8141 TLOGI(WmsLogTag::WMS_MULTI_USER, "winId: %{public}d, isMinimized: %{public}d", GetPersistentId(), isMinimized);
8142 isMinimizedByUserSwitch_ = isMinimized;
8143 }
8144
IsMinimizedByUserSwitch() const8145 bool SceneSession::IsMinimizedByUserSwitch() const
8146 {
8147 return isMinimizedByUserSwitch_;
8148 }
8149
UnregisterSessionChangeListeners()8150 void SceneSession::UnregisterSessionChangeListeners()
8151 {
8152 PostTask([weakThis = wptr(this), where = __func__] {
8153 auto session = weakThis.promote();
8154 if (session == nullptr) {
8155 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
8156 return;
8157 }
8158 session->Session::UnregisterSessionChangeListeners();
8159 }, __func__);
8160 }
8161
SetVisibilityChangedDetectFunc(VisibilityChangedDetectFunc && func)8162 void SceneSession::SetVisibilityChangedDetectFunc(VisibilityChangedDetectFunc&& func)
8163 {
8164 LOCK_GUARD_EXPR(SCENE_GUARD, visibilityChangedDetectFunc_ = std::move(func));
8165 }
8166
SetDefaultDisplayIdIfNeed()8167 void SceneSession::SetDefaultDisplayIdIfNeed()
8168 {
8169 if (sessionInfo_.screenId_ == SCREEN_ID_INVALID) {
8170 auto defaultDisplayId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
8171 sessionInfo_.screenId_ = defaultDisplayId;
8172 TLOGI(WmsLogTag::WMS_LIFE, "winId: %{public}d, update screen id %{public}" PRIu64,
8173 GetPersistentId(), defaultDisplayId);
8174 auto sessionProperty = GetSessionProperty();
8175 if (sessionProperty) {
8176 sessionProperty->SetDisplayId(defaultDisplayId);
8177 }
8178 }
8179 }
8180
GetCustomDecorHeight() const8181 int32_t SceneSession::GetCustomDecorHeight() const
8182 {
8183 std::lock_guard lock(customDecorHeightMutex_);
8184 return customDecorHeight_;
8185 }
8186
SetCustomDecorHeight(int32_t height)8187 void SceneSession::SetCustomDecorHeight(int32_t height)
8188 {
8189 constexpr int32_t MIN_DECOR_HEIGHT = 37;
8190 constexpr int32_t MAX_DECOR_HEIGHT = 112;
8191 if (height < MIN_DECOR_HEIGHT || height > MAX_DECOR_HEIGHT) {
8192 return;
8193 }
8194 std::lock_guard lock(customDecorHeightMutex_);
8195 customDecorHeight_ = height;
8196 }
8197
UpdateGestureBackEnabled()8198 void SceneSession::UpdateGestureBackEnabled()
8199 {
8200 if (specificCallback_ != nullptr &&
8201 specificCallback_->onUpdateGestureBackEnabled_ != nullptr) {
8202 specificCallback_->onUpdateGestureBackEnabled_(GetPersistentId());
8203 }
8204 }
8205
CheckIdentityTokenIfMatched(const std::string & identityToken)8206 bool SceneSession::CheckIdentityTokenIfMatched(const std::string& identityToken)
8207 {
8208 if (!identityToken.empty() && !clientIdentityToken_.empty() && identityToken != clientIdentityToken_) {
8209 TLOGW(WmsLogTag::WMS_LIFE,
8210 "failed, clientIdentityToken: %{public}s, identityToken: %{public}s, bundleName: %{public}s",
8211 clientIdentityToken_.c_str(), identityToken.c_str(), GetSessionInfo().bundleName_.c_str());
8212 return false;
8213 }
8214 return true;
8215 }
8216
CheckPidIfMatched()8217 bool SceneSession::CheckPidIfMatched()
8218 {
8219 int32_t callingPid = IPCSkeleton::GetCallingPid();
8220 if (callingPid != -1 && callingPid != GetCallingPid()) {
8221 TLOGW(WmsLogTag::WMS_LIFE,
8222 "failed, callingPid_: %{public}d, callingPid: %{public}d, bundleName: %{public}s",
8223 GetCallingPid(), callingPid, GetSessionInfo().bundleName_.c_str());
8224 return false;
8225 }
8226 return true;
8227 }
8228
SetNeedSyncSessionRect(bool needSync)8229 void SceneSession::SetNeedSyncSessionRect(bool needSync)
8230 {
8231 PostTask([weakThis = wptr(this), needSync, where = __func__] {
8232 auto session = weakThis.promote();
8233 if (session == nullptr) {
8234 TLOGNE(WmsLogTag::WMS_PIPELINE, "%{public}s session is null", where);
8235 return;
8236 }
8237 TLOGNI(WmsLogTag::WMS_PIPELINE,
8238 "%{public}s: change applyToSubWindow from %{public}d to %{public}d, id:%{public}d",
8239 where, session->isNeedSyncSessionRect_, needSync, session->GetPersistentId());
8240 session->isNeedSyncSessionRect_ = needSync;
8241 }, __func__);
8242 }
8243
SetFrameGravity(Gravity gravity)8244 bool SceneSession::SetFrameGravity(Gravity gravity)
8245 {
8246 auto surfaceNode = GetSurfaceNode();
8247 if (surfaceNode == nullptr) {
8248 TLOGW(WmsLogTag::WMS_LAYOUT, "fail id:%{public}d gravity:%{public}d", GetPersistentId(), gravity);
8249 return false;
8250 }
8251 TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d gravity:%{public}d", GetPersistentId(), gravity);
8252 surfaceNode->SetFrameGravity(gravity);
8253 return true;
8254 }
8255
SetWindowRectAutoSaveCallback(NotifySetWindowRectAutoSaveFunc && func)8256 void SceneSession::SetWindowRectAutoSaveCallback(NotifySetWindowRectAutoSaveFunc&& func)
8257 {
8258 PostTask([weakThis = wptr(this), where = __func__, func = std::move(func)] {
8259 auto session = weakThis.promote();
8260 if (!session || !func) {
8261 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session or onSetWindowRectAutoSaveFunc is null", where);
8262 return;
8263 }
8264 session->onSetWindowRectAutoSaveFunc_ = std::move(func);
8265 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where,
8266 session->GetPersistentId());
8267 }, __func__);
8268 }
8269
SetIsSystemKeyboard(bool isSystemKeyboard)8270 void SceneSession::SetIsSystemKeyboard(bool isSystemKeyboard)
8271 {
8272 auto sessionProperty = GetSessionProperty();
8273 if (sessionProperty == nullptr) {
8274 TLOGE(WmsLogTag::WMS_KEYBOARD, "property is nullptr");
8275 return;
8276 }
8277 sessionProperty->SetIsSystemKeyboard(isSystemKeyboard);
8278 }
8279
IsSystemKeyboard() const8280 bool SceneSession::IsSystemKeyboard() const
8281 {
8282 auto sessionProperty = GetSessionProperty();
8283 if (sessionProperty == nullptr) {
8284 TLOGE(WmsLogTag::WMS_KEYBOARD, "property is nullptr");
8285 return false;
8286 }
8287 return sessionProperty->IsSystemKeyboard();
8288 }
8289
RegisterSupportWindowModesCallback(NotifySetSupportedWindowModesFunc && func)8290 void SceneSession::RegisterSupportWindowModesCallback(NotifySetSupportedWindowModesFunc&& func)
8291 {
8292 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
8293 auto session = weakThis.promote();
8294 if (!session || !func) {
8295 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session or func is null", where);
8296 return;
8297 }
8298 session->onSetSupportedWindowModesFunc_ = std::move(func);
8299 TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s id: %{public}d", where, session->GetPersistentId());
8300 }, __func__);
8301 }
8302
ActivateKeyboardAvoidArea(bool active,bool recalculateAvoid)8303 void SceneSession::ActivateKeyboardAvoidArea(bool active, bool recalculateAvoid)
8304 {
8305 if (recalculateAvoid && !active) {
8306 RestoreCallingSession(GetCallingSessionId(), nullptr);
8307 }
8308 keyboardAvoidAreaActive_ = active;
8309 if (recalculateAvoid && active) {
8310 EnableCallingSessionAvoidArea();
8311 }
8312 }
8313
IsKeyboardAvoidAreaActive() const8314 bool SceneSession::IsKeyboardAvoidAreaActive() const
8315 {
8316 return keyboardAvoidAreaActive_;
8317 }
8318
MarkAvoidAreaAsDirty()8319 void SceneSession::MarkAvoidAreaAsDirty()
8320 {
8321 dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
8322 }
8323
SetMousePointerDownEventStatus(bool mousePointerDownEventStatus)8324 void SceneSession::SetMousePointerDownEventStatus(bool mousePointerDownEventStatus)
8325 {
8326 isMousePointerDownEventStatus_ = mousePointerDownEventStatus;
8327 }
8328
GetMousePointerDownEventStatus() const8329 bool SceneSession::GetMousePointerDownEventStatus() const
8330 {
8331 return isMousePointerDownEventStatus_;
8332 }
8333
SetFingerPointerDownStatus(int32_t fingerId)8334 void SceneSession::SetFingerPointerDownStatus(int32_t fingerId)
8335 {
8336 if (fingerPointerDownStatusList_.find(fingerId) != fingerPointerDownStatusList_.end()) {
8337 TLOGE(WmsLogTag::WMS_EVENT, "wid:%{public}d fingerId:%{public}d receive twice down event",
8338 GetPersistentId(), fingerId);
8339 } else {
8340 fingerPointerDownStatusList_.insert(fingerId);
8341 }
8342 }
8343
RemoveFingerPointerDownStatus(int32_t fingerId)8344 void SceneSession::RemoveFingerPointerDownStatus(int32_t fingerId)
8345 {
8346 if (fingerPointerDownStatusList_.find(fingerId) == fingerPointerDownStatusList_.end()) {
8347 TLOGE(WmsLogTag::WMS_EVENT, "wid:%{public}d fingerId:%{public}d receive up without down event",
8348 GetPersistentId(), fingerId);
8349 } else {
8350 fingerPointerDownStatusList_.erase(fingerId);
8351 }
8352 }
8353
GetFingerPointerDownStatusList() const8354 std::unordered_set<int32_t> SceneSession::GetFingerPointerDownStatusList() const
8355 {
8356 return fingerPointerDownStatusList_;
8357 }
8358
UpdateAllModalUIExtensions(const WSRect & globalRect)8359 void SceneSession::UpdateAllModalUIExtensions(const WSRect& globalRect)
8360 {
8361 if (modalUIExtensionInfoList_.empty()) {
8362 return;
8363 }
8364 PostTask([weakThis = wptr(this), where = __func__, globalRect] {
8365 auto session = weakThis.promote();
8366 if (!session) {
8367 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is null", where);
8368 return;
8369 }
8370 auto parentTransX = globalRect.posX_ - session->GetClientRect().posX_;
8371 auto parentTransY = globalRect.posY_ - session->GetClientRect().posY_;
8372 {
8373 std::unique_lock<std::shared_mutex> lock(session->modalUIExtensionInfoListMutex_);
8374 for (auto& extensionInfo : session->modalUIExtensionInfoList_) {
8375 if (!extensionInfo.hasUpdatedRect) {
8376 continue;
8377 }
8378 extensionInfo.windowRect = extensionInfo.uiExtRect;
8379 extensionInfo.windowRect.posX_ += parentTransX;
8380 extensionInfo.windowRect.posY_ += parentTransY;
8381 WSRect transRect = { extensionInfo.windowRect.posX_, extensionInfo.windowRect.posY_,
8382 extensionInfo.windowRect.width_, extensionInfo.windowRect.height_ };
8383 session->TransformRelativeRectToGlobalRect(transRect);
8384 extensionInfo.windowRect.posY_ = transRect.posY_;
8385 }
8386 }
8387 session->NotifySessionInfoChange();
8388 TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: id: %{public}d, globalRect: %{public}s, parentTransX: %{public}d, "
8389 "parentTransY: %{public}d", where, session->GetPersistentId(), globalRect.ToString().c_str(),
8390 parentTransX, parentTransY);
8391 }, __func__);
8392 }
8393
SetWindowCornerRadiusCallback(NotifySetWindowCornerRadiusFunc && func)8394 void SceneSession::SetWindowCornerRadiusCallback(NotifySetWindowCornerRadiusFunc&& func)
8395 {
8396 const char* const where = __func__;
8397 PostTask([weakThis = wptr(this), where, func = std::move(func)] {
8398 auto session = weakThis.promote();
8399 if (!session || !func) {
8400 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session or onSetWindowCornerRadiusFunc is null");
8401 return;
8402 }
8403 session->onSetWindowCornerRadiusFunc_ = std::move(func);
8404 auto property = session->GetSessionProperty();
8405 float cornerRadius = property->GetWindowCornerRadius();
8406 if (!MathHelper::LessNotEqual(cornerRadius, 0.0f)) {
8407 // Valid corner radius menas app has set corner radius of the window, need to update to scb.
8408 session->onSetWindowCornerRadiusFunc_(cornerRadius);
8409 }
8410 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s id: %{public}d, corner radius: %{public}f", where,
8411 session->GetPersistentId(), cornerRadius);
8412 }, __func__);
8413 }
8414
SetWindowCornerRadius(float cornerRadius)8415 WSError SceneSession::SetWindowCornerRadius(float cornerRadius)
8416 {
8417 const char* const where = __func__;
8418 PostTask([weakThis = wptr(this), cornerRadius, where] {
8419 auto session = weakThis.promote();
8420 if (!session) {
8421 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is null");
8422 return;
8423 }
8424 if (session->onSetWindowCornerRadiusFunc_) {
8425 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s id %{public}d radius: %{public}f",
8426 where, session->GetPersistentId(), cornerRadius);
8427 session->onSetWindowCornerRadiusFunc_(cornerRadius);
8428 }
8429 session->GetSessionProperty()->SetWindowCornerRadius(cornerRadius);
8430 }, __func__);
8431 return WSError::WS_OK;
8432 }
8433
SetWindowShadowsCallback(NotifySetWindowShadowsFunc && func)8434 void SceneSession::SetWindowShadowsCallback(NotifySetWindowShadowsFunc&& func)
8435 {
8436 const char* const where = __func__;
8437 PostTask([weakThis = wptr(this), where, func = std::move(func)] {
8438 auto session = weakThis.promote();
8439 if (!session || !func) {
8440 TLOGNE(WmsLogTag::WMS_ANIMATION, "session or onSetWindowShadowsFunc is null");
8441 return;
8442 }
8443 session->onSetWindowShadowsFunc_ = std::move(func);
8444 auto property = session->GetSessionProperty();
8445 session->onSetWindowShadowsFunc_(property->GetWindowShadows());
8446 TLOGNI(WmsLogTag::WMS_ANIMATION, "%{public}s id: %{public}d", where,
8447 session->GetPersistentId());
8448 }, __func__);
8449 }
8450
SetWindowShadows(const ShadowsInfo & shadowsInfo)8451 WSError SceneSession::SetWindowShadows(const ShadowsInfo& shadowsInfo)
8452 {
8453 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
8454 WLOGFE("RaiseAboveTarget permission denied!");
8455 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8456 }
8457 const char* const where = __func__;
8458 PostTask([weakThis = wptr(this), shadowsInfo, where] {
8459 auto session = weakThis.promote();
8460 if (!session) {
8461 TLOGNE(WmsLogTag::WMS_ANIMATION, "session is null");
8462 return;
8463 }
8464 if (session->onSetWindowShadowsFunc_) {
8465 TLOGND(WmsLogTag::WMS_ANIMATION, "%{public}s id %{public}d shadow radius: %{public}f, "
8466 "color: %{public}s, offsetX: %{public}f, offsetY: %{public}f", where, session->GetPersistentId(),
8467 shadowsInfo.radius_, shadowsInfo.color_.c_str(), shadowsInfo.offsetX_, shadowsInfo.offsetY_);
8468 session->onSetWindowShadowsFunc_(shadowsInfo);
8469 }
8470 session->GetSessionProperty()->SetWindowShadows(shadowsInfo);
8471 }, __func__);
8472 return WSError::WS_OK;
8473 }
8474
GetTopNavDestinationName(std::string & topNavDestName)8475 WSError SceneSession::GetTopNavDestinationName(std::string& topNavDestName)
8476 {
8477 if (!sessionStage_) {
8478 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session stage is null: win=%{public}d", GetWindowId());
8479 return WSError::WS_ERROR_NULLPTR;
8480 }
8481 return sessionStage_->GetTopNavDestinationName(topNavDestName);
8482 }
8483
UpdateSubWindowLevel(uint32_t subWindowLevel)8484 void SceneSession::UpdateSubWindowLevel(uint32_t subWindowLevel)
8485 {
8486 GetSessionProperty()->SetSubWindowLevel(subWindowLevel);
8487 for (const auto& session : GetSubSession()) {
8488 if (session != nullptr) {
8489 session->UpdateSubWindowLevel(subWindowLevel + 1);
8490 }
8491 }
8492 }
8493
GetMaxSubWindowLevel() const8494 uint32_t SceneSession::GetMaxSubWindowLevel() const
8495 {
8496 uint32_t maxSubWindowLevel = 1;
8497 for (const auto& session : GetSubSession()) {
8498 if (session != nullptr) {
8499 maxSubWindowLevel = std::max(maxSubWindowLevel, session->GetMaxSubWindowLevel() + 1);
8500 }
8501 }
8502 return maxSubWindowLevel;
8503 }
8504
SetColorSpace(ColorSpace colorSpace)8505 void SceneSession::SetColorSpace(ColorSpace colorSpace)
8506 {
8507 auto surfaceNode = GetSurfaceNode();
8508 if (!surfaceNode) {
8509 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode is invalid");
8510 return;
8511 }
8512 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "SetColorSpace value=%{public}u", colorSpace);
8513 auto colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
8514 if (colorSpace == ColorSpace::COLOR_SPACE_WIDE_GAMUT) {
8515 colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3;
8516 }
8517 {
8518 AutoRSTransaction trans(GetRSUIContext());
8519 surfaceNode->SetColorSpace(colorGamut);
8520 }
8521 }
8522
AddSidebarBlur()8523 void SceneSession::AddSidebarBlur()
8524 {
8525 auto surfaceNode = GetSurfaceNode();
8526 if (!surfaceNode) {
8527 TLOGE(WmsLogTag::WMS_PC, "surfaceNode is null");
8528 return;
8529 }
8530 if (blurRadiusValue_ && blurSaturationValue_ && blurBrightnessValue_ && blurMaskColorValue_) {
8531 TLOGE(WmsLogTag::WMS_PC, "RSAnimatableProperty has value");
8532 return;
8533 }
8534 auto rsNodeTemp = RSAdapterUtil::GetRSNode(GetRSUIContext(), surfaceNode->GetId());
8535 if (rsNodeTemp) {
8536 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext =
8537 AbilityRuntime::Context::GetApplicationContext();
8538 if (appContext == nullptr) {
8539 TLOGE(WmsLogTag::WMS_PC, "app context is nullptr");
8540 return;
8541 }
8542 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
8543 if (config == nullptr) {
8544 TLOGE(WmsLogTag::WMS_PC, "app configuration is nullptr");
8545 return;
8546 }
8547 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
8548 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
8549 AddRSNodeModifier(isDark, rsNodeTemp);
8550 }
8551 }
8552
SetSessionGetTargetOrientationConfigInfoCallback(const NotifySessionGetTargetOrientationConfigInfoFunc & func)8553 void SceneSession::SetSessionGetTargetOrientationConfigInfoCallback(
8554 const NotifySessionGetTargetOrientationConfigInfoFunc& func)
8555 {
8556 PostTask(
8557 [weakThis = wptr(this), func, where = __func__] {
8558 auto session = weakThis.promote();
8559 if (!session) {
8560 TLOGNE(WmsLogTag::WMS_ROTATION, "%{public}s session is null", where);
8561 return WSError::WS_ERROR_NULLPTR;
8562 }
8563 session->sessionGetTargetOrientationConfigInfoFunc_ = func;
8564 return WSError::WS_OK;
8565 }, __func__);
8566 }
8567
GetTargetOrientationConfigInfo(Orientation targetOrientation,const std::map<Rosen::WindowType,Rosen::SystemBarProperty> & properties)8568 WSError SceneSession::GetTargetOrientationConfigInfo(Orientation targetOrientation,
8569 const std::map<Rosen::WindowType, Rosen::SystemBarProperty>& properties)
8570 {
8571 PostTask(
8572 [weakThis = wptr(this), targetOrientation, properties, where = __func__] {
8573 auto session = weakThis.promote();
8574 if (!session) {
8575 TLOGNE(WmsLogTag::WMS_ROTATION, "%{public}s session is null", where);
8576 return WSError::WS_ERROR_NULLPTR;
8577 }
8578 session->SetSystemBarPropertyForRotation(properties);
8579 if (session->sessionGetTargetOrientationConfigInfoFunc_) {
8580 session->sessionGetTargetOrientationConfigInfoFunc_(static_cast<uint32_t>(targetOrientation));
8581 }
8582 return WSError::WS_OK;
8583 }, __func__);
8584 return WSError::WS_OK;
8585 }
8586
NotifyRotationProperty(uint32_t rotation,uint32_t width,uint32_t height)8587 WSError SceneSession::NotifyRotationProperty(uint32_t rotation, uint32_t width, uint32_t height)
8588 {
8589 PostTask(
8590 [weakThis = wptr(this), rotation, width, height, where = __func__] {
8591 if (width == 0 || height == 0) {
8592 return WSError::WS_ERROR_INVALID_PARAM;
8593 }
8594 auto session = weakThis.promote();
8595 if (!session) {
8596 TLOGNE(WmsLogTag::WMS_ROTATION, "%{public}s session is null", where);
8597 return WSError::WS_ERROR_NULLPTR;
8598 }
8599 WSRect wsrect = { 0, 0, width, height };
8600 auto properties = session->GetSystemBarPropertyForRotation();
8601 std::map<AvoidAreaType, AvoidArea> avoidAreas;
8602 session->GetAvoidAreasByRotation(
8603 static_cast<Rotation>(rotation / ROTATION_DEGREE), wsrect, properties, avoidAreas);
8604 if (!session->sessionStage_) {
8605 return WSError::WS_ERROR_NULLPTR;
8606 }
8607 Rect rect = { wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
8608 OrientationInfo info = { rotation, rect, avoidAreas };
8609 session->sessionStage_->NotifyTargetRotationInfo(info);
8610 return WSError::WS_OK;
8611 }, __func__);
8612 return WSError::WS_OK;
8613 }
8614
SetSystemBarPropertyForRotation(const std::map<Rosen::WindowType,Rosen::SystemBarProperty> & properties)8615 void SceneSession::SetSystemBarPropertyForRotation(
8616 const std::map<Rosen::WindowType, Rosen::SystemBarProperty>& properties)
8617 {
8618 targetSystemBarProperty_ = properties;
8619 }
8620
GetSystemBarPropertyForRotation()8621 std::map<Rosen::WindowType, Rosen::SystemBarProperty>& SceneSession::GetSystemBarPropertyForRotation()
8622 {
8623 return targetSystemBarProperty_;
8624 }
8625
AddRSNodeModifier(bool isDark,const std::shared_ptr<RSBaseNode> & rsNode)8626 void SceneSession::AddRSNodeModifier(bool isDark, const std::shared_ptr<RSBaseNode>& rsNode)
8627 {
8628 if (!rsNode) {
8629 TLOGE(WmsLogTag::WMS_PC, "rsNode is nullptr");
8630 return;
8631 }
8632 TLOGI(WmsLogTag::WMS_PC, "isDark: %{public}d", isDark);
8633 if (isDark) {
8634 blurRadiusValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
8635 SIDEBAR_DEFAULT_RADIUS_DARK);
8636 blurSaturationValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
8637 SIDEBAR_DEFAULT_SATURATION_DARK);
8638 blurBrightnessValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
8639 SIDEBAR_DEFAULT_BRIGHTNESS_DARK);
8640 blurMaskColorValue_ = std::make_shared<RSAnimatableProperty<Rosen::RSColor>>(
8641 Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_DARK));
8642 } else {
8643 blurRadiusValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
8644 SIDEBAR_DEFAULT_RADIUS_LIGHT);
8645 blurSaturationValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
8646 SIDEBAR_DEFAULT_SATURATION_LIGHT);
8647 blurBrightnessValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
8648 SIDEBAR_DEFAULT_BRIGHTNESS_LIGHT);
8649 blurMaskColorValue_ = std::make_shared<RSAnimatableProperty<Rosen::RSColor>>(
8650 Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_LIGHT));
8651 }
8652
8653 auto modifier = std::make_shared<Rosen::ModifierNG::RSBehindWindowFilterModifier>();
8654 modifier->AttachProperty(ModifierNG::RSPropertyType::BEHIND_WINDOW_FILTER_RADIUS, blurRadiusValue_);
8655 modifier->AttachProperty(ModifierNG::RSPropertyType::BEHIND_WINDOW_FILTER_SATURATION, blurSaturationValue_);
8656 modifier->AttachProperty(ModifierNG::RSPropertyType::BEHIND_WINDOW_FILTER_BRIGHTNESS, blurBrightnessValue_);
8657 modifier->AttachProperty(ModifierNG::RSPropertyType::BEHIND_WINDOW_FILTER_MASK_COLOR, blurMaskColorValue_);
8658 rsNode->AddModifier(modifier);
8659 }
8660
SetSidebarBlur(bool isDefaultSidebarBlur,bool isNeedAnimation)8661 void SceneSession::SetSidebarBlur(bool isDefaultSidebarBlur, bool isNeedAnimation)
8662 {
8663 TLOGI(WmsLogTag::WMS_PC, "isDefaultSidebarBlur: %{public}d, isNeedAnimation: %{public}d",
8664 isDefaultSidebarBlur, isNeedAnimation);
8665 auto surfaceNode = GetSurfaceNode();
8666 if (!surfaceNode) {
8667 TLOGE(WmsLogTag::WMS_PC, "surfaceNode is null");
8668 return;
8669 }
8670 if (!blurRadiusValue_ || !blurSaturationValue_ || !blurBrightnessValue_ || !blurMaskColorValue_) {
8671 TLOGE(WmsLogTag::WMS_PC, "RSAnimatableProperty is null");
8672 return;
8673 }
8674
8675 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext =
8676 AbilityRuntime::Context::GetApplicationContext();
8677 if (appContext == nullptr) {
8678 TLOGE(WmsLogTag::WMS_PC, "app context is nullptr");
8679 return;
8680 }
8681 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
8682 if (config == nullptr) {
8683 TLOGE(WmsLogTag::WMS_PC, "app configuration is nullptr");
8684 return;
8685 }
8686 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
8687 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
8688 ModifyRSAnimatableProperty(isDefaultSidebarBlur, isDark, isNeedAnimation);
8689 }
8690
ModifyRSAnimatableProperty(bool isDefaultSidebarBlur,bool isDark,bool isNeedAnimation)8691 void SceneSession::ModifyRSAnimatableProperty(bool isDefaultSidebarBlur, bool isDark, bool isNeedAnimation)
8692 {
8693 TLOGI(WmsLogTag::WMS_PC, "isDefaultSidebarBlur: %{public}d, isDark: %{public}d, isNeedAnimation: %{public}d",
8694 isDefaultSidebarBlur, isDark, isNeedAnimation);
8695 // sidebar animation duration
8696 constexpr int32_t duration = 150;
8697 if (isDefaultSidebarBlur) {
8698 auto rsUIContext = GetRSUIContext();
8699 if (isNeedAnimation) {
8700 Rosen::RSAnimationTimingProtocol timingProtocol;
8701 timingProtocol.SetDuration(duration);
8702 timingProtocol.SetDirection(true);
8703 timingProtocol.SetFillMode(Rosen::FillMode::FORWARDS);
8704 timingProtocol.SetFinishCallbackType(Rosen::FinishCallbackType::LOGICALLY);
8705 RSNode::OpenImplicitAnimation(rsUIContext, timingProtocol, Rosen::RSAnimationTimingCurve::LINEAR, nullptr);
8706 }
8707 if (isDark) {
8708 blurRadiusValue_->Set(SIDEBAR_DEFAULT_RADIUS_DARK);
8709 blurSaturationValue_->Set(SIDEBAR_DEFAULT_SATURATION_DARK);
8710 blurBrightnessValue_->Set(SIDEBAR_DEFAULT_BRIGHTNESS_DARK);
8711 blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_DARK));
8712 } else {
8713 blurRadiusValue_->Set(SIDEBAR_DEFAULT_RADIUS_LIGHT);
8714 blurSaturationValue_->Set(SIDEBAR_DEFAULT_SATURATION_LIGHT);
8715 blurBrightnessValue_->Set(SIDEBAR_DEFAULT_BRIGHTNESS_LIGHT);
8716 blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_LIGHT));
8717 }
8718 if (isNeedAnimation) {
8719 RSNode::CloseImplicitAnimation(rsUIContext);
8720 }
8721 } else {
8722 blurRadiusValue_->Set(SIDEBAR_BLUR_NUMBER_ZERO);
8723 blurSaturationValue_->Set(SIDEBAR_BLUR_NUMBER_ZERO);
8724 blurBrightnessValue_->Set(SIDEBAR_BLUR_NUMBER_ZERO);
8725 if (isDark) {
8726 blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_SNAPSHOT_MASKCOLOR_DARK));
8727 } else {
8728 blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_SNAPSHOT_MASKCOLOR_LIGHT));
8729 }
8730 }
8731 }
8732
NotifyWindowAttachStateListenerRegistered(bool registered)8733 void SceneSession::NotifyWindowAttachStateListenerRegistered(bool registered)
8734 {
8735 needNotifyAttachState_.store(registered);
8736 }
8737
NotifyKeyboardAnimationCompleted(bool isShowAnimation,const WSRect & beginRect,const WSRect & endRect)8738 void SceneSession::NotifyKeyboardAnimationCompleted(bool isShowAnimation,
8739 const WSRect& beginRect, const WSRect& endRect)
8740 {
8741 PostTask([weakThis = wptr(this), isShowAnimation, beginRect, endRect, where = __func__] {
8742 auto session = weakThis.promote();
8743 if (!session) {
8744 TLOGNE(WmsLogTag::WMS_KEYBOARD, "%{public}s session is null", where);
8745 return;
8746 }
8747 if (session->sessionStage_ == nullptr) {
8748 TLOGND(WmsLogTag::WMS_KEYBOARD, "%{public}s sessionStage_ is null, id: %{public}d",
8749 where, session->GetPersistentId());
8750 return;
8751 }
8752 if (isShowAnimation && !session->GetSessionProperty()->EditSessionInfo().isKeyboardDidShowRegistered_) {
8753 TLOGND(WmsLogTag::WMS_KEYBOARD, "keyboard did show listener is not registered");
8754 return;
8755 }
8756 if (!isShowAnimation && !session->GetSessionProperty()->EditSessionInfo().isKeyboardDidHideRegistered_) {
8757 TLOGND(WmsLogTag::WMS_KEYBOARD, "keyboard did hide listener is not registered");
8758 return;
8759 }
8760
8761 KeyboardPanelInfo keyboardPanelInfo;
8762 keyboardPanelInfo.beginRect_ = SessionHelper::TransferToRect(beginRect);
8763 keyboardPanelInfo.endRect_ = SessionHelper::TransferToRect(endRect);
8764 keyboardPanelInfo.isShowing_ = isShowAnimation;
8765 session->sessionStage_->NotifyKeyboardAnimationCompleted(keyboardPanelInfo);
8766 }, __func__);
8767 }
8768
NotifyKeyboardAnimationWillBegin(bool isKeyboardShow,const WSRect & beginRect,const WSRect & endRect,bool withAnimation,const std::shared_ptr<RSTransaction> & rsTransaction)8769 void SceneSession::NotifyKeyboardAnimationWillBegin(bool isKeyboardShow, const WSRect& beginRect, const WSRect& endRect,
8770 bool withAnimation, const std::shared_ptr<RSTransaction>& rsTransaction)
8771 {
8772 PostTask([weakThis = wptr(this), isKeyboardShow, beginRect, endRect, withAnimation,
8773 rsTransaction, where = __func__] {
8774 auto session = weakThis.promote();
8775 if (!session) {
8776 TLOGNE(WmsLogTag::WMS_KEYBOARD, "%{public}s session is null", where);
8777 return;
8778 }
8779 if (session->sessionStage_ == nullptr) {
8780 TLOGND(WmsLogTag::WMS_KEYBOARD, "%{public}s sessionStage_ is null, id: %{public}d",
8781 where, session->GetPersistentId());
8782 return;
8783 }
8784 if (isKeyboardShow && !session->GetSessionProperty()->EditSessionInfo().isKeyboardWillShowRegistered_) {
8785 TLOGNI(WmsLogTag::WMS_KEYBOARD, "keyboard will show listener is not registered");
8786 return;
8787 }
8788 if (!isKeyboardShow && !session->GetSessionProperty()->EditSessionInfo().isKeyboardWillHideRegistered_) {
8789 TLOGNI(WmsLogTag::WMS_KEYBOARD, "keyboard will hide listener is not registered");
8790 return;
8791 }
8792 KeyboardAnimationInfo keyboardAnimationInfo;
8793 keyboardAnimationInfo.beginRect = SessionHelper::TransferToRect(beginRect);
8794 keyboardAnimationInfo.endRect = SessionHelper::TransferToRect(endRect);
8795 keyboardAnimationInfo.isShow = isKeyboardShow;
8796 keyboardAnimationInfo.withAnimation = withAnimation;
8797 session->sessionStage_->NotifyKeyboardAnimationWillBegin(keyboardAnimationInfo, rsTransaction);
8798 }, __func__);
8799 }
8800
NotifyKeyboardWillShowRegistered(bool registered)8801 void SceneSession::NotifyKeyboardWillShowRegistered(bool registered)
8802 {
8803 GetSessionProperty()->EditSessionInfo().isKeyboardWillShowRegistered_ = registered;
8804 }
8805
NotifyKeyboardWillHideRegistered(bool registered)8806 void SceneSession::NotifyKeyboardWillHideRegistered(bool registered)
8807 {
8808 GetSessionProperty()->EditSessionInfo().isKeyboardWillHideRegistered_ = registered;
8809 }
8810
NotifyKeyboardDidShowRegistered(bool registered)8811 void SceneSession::NotifyKeyboardDidShowRegistered(bool registered)
8812 {
8813 GetSessionProperty()->EditSessionInfo().isKeyboardDidShowRegistered_ = registered;
8814 }
8815
NotifyKeyboardDidHideRegistered(bool registered)8816 void SceneSession::NotifyKeyboardDidHideRegistered(bool registered)
8817 {
8818 GetSessionProperty()->EditSessionInfo().isKeyboardDidHideRegistered_ = registered;
8819 }
8820
SaveLastDensity()8821 void SceneSession::SaveLastDensity()
8822 {
8823 auto property = GetSessionProperty();
8824 DisplayId displayId = property->GetDisplayId();
8825 if (auto display = DisplayManager::GetInstance().GetDisplayById(displayId)) {
8826 property->SetLastLimitsVpr(display->GetVirtualPixelRatio());
8827 }
8828 }
8829
NotifyUpdateFlagCallback(NotifyUpdateFlagFunc && func)8830 void SceneSession::NotifyUpdateFlagCallback(NotifyUpdateFlagFunc&& func)
8831 {
8832 const char* const where = __func__;
8833 PostTask([weakThis = wptr(this), where, func = std::move(func)] {
8834 auto session = weakThis.promote();
8835 if (!session || !func) {
8836 TLOGNE(WmsLogTag::WMS_MAIN, "session or func is null");
8837 return;
8838 }
8839 session->onUpdateFlagFunc_ = std::move(func);
8840 session->onUpdateFlagFunc_(session->sessionInfo_.specifiedFlag_);
8841 TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d specifiedFlag: %{public}s", where,
8842 session->GetPersistentId(), session->sessionInfo_.specifiedFlag_.c_str());
8843 }, __func__);
8844 }
8845
UpdateRotationChangeRegistered(int32_t persistentId,bool isRegister)8846 WSError SceneSession::UpdateRotationChangeRegistered(int32_t persistentId, bool isRegister)
8847 {
8848 PostTask(
8849 [weakThis = wptr(this), persistentId, isRegister, where = __func__] {
8850 auto session = weakThis.promote();
8851 if (!session) {
8852 TLOGNE(WmsLogTag::WMS_ROTATION, "%{public}s session is null", where);
8853 return;
8854 }
8855 TLOGI(
8856 WmsLogTag::WMS_ROTATION, "persistentId: %{public}d, isRegister: %{public}d", persistentId, isRegister);
8857 if (isRegister) {
8858 session->isRotationChangeCallbackRegistered = true;
8859 } else {
8860 session->isRotationChangeCallbackRegistered = false;
8861 }
8862 }, __func__);
8863
8864 return WSError::WS_OK;
8865 }
8866
NotifyRotationChange(const RotationChangeInfo & rotationChangeInfo,bool isRestrictNotify)8867 RotationChangeResult SceneSession::NotifyRotationChange(const RotationChangeInfo& rotationChangeInfo,
8868 bool isRestrictNotify)
8869 {
8870 WindowType type = Session::GetWindowType();
8871 bool isSystemCalling = GetSessionProperty()->GetSystemCalling();
8872 return PostSyncTask(
8873 [weakThis = wptr(this), rotationChangeInfo, isRestrictNotify, type, isSystemCalling,
8874 where = __func__]() -> RotationChangeResult {
8875 auto session = weakThis.promote();
8876 if (!session) {
8877 TLOGNE(WmsLogTag::WMS_ROTATION, "%{public}s session is null", where);
8878 return { RectType::RELATIVE_TO_SCREEN, { 0, 0, 0, 0 } };
8879 }
8880 if (!session->sessionStage_ || !session->isRotationChangeCallbackRegistered) {
8881 TLOGE(WmsLogTag::WMS_ROTATION, "sessionStage_ is null or isRotationChangeCallbackRegistered is false");
8882 return { RectType::RELATIVE_TO_SCREEN, { 0, 0, 0, 0 } };
8883 }
8884 if (isRestrictNotify && (!WindowHelper::IsSystemWindow(type) || !isSystemCalling)) {
8885 TLOGE(WmsLogTag::WMS_ROTATION,
8886 "restrict NotifyRotationChange when not system window or not system calling");
8887 return { RectType::RELATIVE_TO_SCREEN, { 0, 0, 0, 0 } };
8888 }
8889 return session->sessionStage_->NotifyRotationChange(rotationChangeInfo);
8890 }, __func__);
8891 }
8892
SetCurrentRotation(int32_t currentRotation)8893 WSError SceneSession::SetCurrentRotation(int32_t currentRotation)
8894 {
8895 TLOGI(WmsLogTag::WMS_ROTATION, "currentRotation: %{public}d", currentRotation);
8896 PostTask([weakThis = wptr(this), currentRotation, where = __func__] {
8897 auto session = weakThis.promote();
8898 if (!session) {
8899 TLOGNE(WmsLogTag::WMS_ROTATION, "%{public}s session is null", where);
8900 return;
8901 }
8902 session->currentRotation_ = currentRotation;
8903 if (!session->sessionStage_) {
8904 TLOGNE(WmsLogTag::WMS_ROTATION, "%{public}s sessionStage is null", where);
8905 return;
8906 }
8907 session->sessionStage_->SetCurrentRotation(currentRotation);
8908 }, __func__);
8909 return WSError::WS_OK;
8910 }
8911
UpdateScreenshotAppEventRegistered(int32_t persistentId,bool isRegister)8912 WMError SceneSession::UpdateScreenshotAppEventRegistered(int32_t persistentId, bool isRegister)
8913 {
8914 PostTask([weakThis = wptr(this), persistentId, isRegister, where = __func__] {
8915 auto session = weakThis.promote();
8916 if (!session) {
8917 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win %{public}d session is null", where, persistentId);
8918 return;
8919 }
8920 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win %{public}d isRegister %{public}uu",
8921 where, persistentId, isRegister);
8922 if (session->updateScreenshotAppEventRegisteredFunc_) {
8923 session->updateScreenshotAppEventRegisteredFunc_(persistentId, isRegister);
8924 }
8925 }, __func__);
8926
8927 return WMError::WM_OK;
8928 }
8929
UpdateAcrossDisplaysChangeRegistered(bool isRegister)8930 WMError SceneSession::UpdateAcrossDisplaysChangeRegistered(bool isRegister)
8931 {
8932 if (!SessionPermission::IsSystemCalling()) {
8933 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d permission denied!", GetPersistentId());
8934 return WMError::WM_ERROR_NOT_SYSTEM_APP;
8935 }
8936 if (!WindowHelper::IsAppWindow(GetWindowType())) {
8937 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid window: %{public}d type %{public}u",
8938 GetPersistentId(), GetWindowType());
8939 return WMError::WM_ERROR_INVALID_CALLING;
8940 }
8941 PostTask([weakThis = wptr(this), isRegister, where = __func__] {
8942 auto session = weakThis.promote();
8943 if (!session) {
8944 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s session is null", where);
8945 return;
8946 }
8947 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s winId: %{public}d, isRegister: %{public}d",
8948 where, session->GetPersistentId(), isRegister);
8949 session->isRegisterAcrossDisplaysChanged_.store(isRegister);
8950 }, __func__);
8951
8952 return WMError::WM_OK;
8953 }
8954
NotifyDisableDelegatorChange()8955 WMError SceneSession::NotifyDisableDelegatorChange()
8956 {
8957 PostTask([weakThis = wptr(this), where = __func__] {
8958 auto session = weakThis.promote();
8959 if (!session) {
8960 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
8961 return;
8962 }
8963 TLOGNI(WmsLogTag::WMS_LIFE, "set session id %{public}d disableDelegator true", session->persistentId_);
8964 session->sessionInfo_.disableDelegator = true;
8965 }, __func__);
8966 return WMError::WM_OK;
8967 }
8968
HookSceneSessionActivation(NotifyHookSceneSessionActivationFunc && func)8969 void SceneSession::HookSceneSessionActivation(NotifyHookSceneSessionActivationFunc&& func)
8970 {
8971 const char* const where = __func__;
8972 PostTask([weakThis = wptr(this), where, func = std::move(func)] {
8973 auto session = weakThis.promote();
8974 if (!session) {
8975 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
8976 return;
8977 }
8978 session->hookSceneSessionActivationFunc_ = std::move(func);
8979 }, where);
8980 }
8981
SetSidebarBlurMaximize(bool isMaximize)8982 void SceneSession::SetSidebarBlurMaximize(bool isMaximize)
8983 {
8984 TLOGI(WmsLogTag::WMS_PC, "isMaximize: %{public}d", isMaximize);
8985 auto surfaceNode = GetSurfaceNode();
8986 if (!surfaceNode) {
8987 TLOGE(WmsLogTag::WMS_PC, "surfaceNode is null");
8988 return;
8989 }
8990 if (!blurRadiusValue_ || !blurSaturationValue_ || !blurBrightnessValue_ || !blurMaskColorValue_) {
8991 TLOGE(WmsLogTag::WMS_PC, "RSAnimatableProperty is null");
8992 return;
8993 }
8994
8995 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext =
8996 AbilityRuntime::Context::GetApplicationContext();
8997 if (appContext == nullptr) {
8998 TLOGE(WmsLogTag::WMS_PC, "app context is nullptr");
8999 return;
9000 }
9001 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
9002 if (config == nullptr) {
9003 TLOGE(WmsLogTag::WMS_PC, "app configuration is nullptr");
9004 return;
9005 }
9006 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
9007 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
9008 ModifyRSAnimatablePropertyMaximize(isMaximize, isDark);
9009 }
9010
ModifyRSAnimatablePropertyMaximize(bool isMaximize,bool isDark)9011 void SceneSession::ModifyRSAnimatablePropertyMaximize(bool isMaximize, bool isDark)
9012 {
9013 TLOGI(WmsLogTag::WMS_PC, "isMaximize: %{public}d, isDark: %{public}d", isMaximize, isDark);
9014 // sidebar maximize animation duration
9015 constexpr int32_t duration = 150;
9016 Rosen::RSAnimationTimingProtocol timingProtocol;
9017 timingProtocol.SetDuration(duration);
9018 timingProtocol.SetDirection(true);
9019 timingProtocol.SetFillMode(Rosen::FillMode::FORWARDS);
9020 timingProtocol.SetFinishCallbackType(Rosen::FinishCallbackType::LOGICALLY);
9021 auto rsUIContext = GetRSUIContext();
9022 RSNode::OpenImplicitAnimation(rsUIContext, timingProtocol, Rosen::RSAnimationTimingCurve::LINEAR, nullptr);
9023 if (isMaximize) {
9024 if (isDark) {
9025 blurRadiusValue_->Set(SIDEBAR_MAXIMIZE_RADIUS_DARK);
9026 blurSaturationValue_->Set(SIDEBAR_MAXIMIZE_SATURATION_DARK);
9027 blurBrightnessValue_->Set(SIDEBAR_MAXIMIZE_BRIGHTNESS_DARK);
9028 blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_MAXIMIZE_MASKCOLOR_DARK));
9029 } else {
9030 blurRadiusValue_->Set(SIDEBAR_MAXIMIZE_RADIUS_LIGHT);
9031 blurSaturationValue_->Set(SIDEBAR_MAXIMIZE_SATURATION_LIGHT);
9032 blurBrightnessValue_->Set(SIDEBAR_MAXIMIZE_BRIGHTNESS_LIGHT);
9033 blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_MAXIMIZE_MASKCOLOR_LIGHT));
9034 }
9035 } else {
9036 if (isDark) {
9037 blurRadiusValue_->Set(SIDEBAR_DEFAULT_RADIUS_DARK);
9038 blurSaturationValue_->Set(SIDEBAR_DEFAULT_SATURATION_DARK);
9039 blurBrightnessValue_->Set(SIDEBAR_DEFAULT_BRIGHTNESS_DARK);
9040 blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_DARK));
9041 } else {
9042 blurRadiusValue_->Set(SIDEBAR_DEFAULT_RADIUS_LIGHT);
9043 blurSaturationValue_->Set(SIDEBAR_DEFAULT_SATURATION_LIGHT);
9044 blurBrightnessValue_->Set(SIDEBAR_DEFAULT_BRIGHTNESS_LIGHT);
9045 blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_LIGHT));
9046 }
9047 }
9048 RSNode::CloseImplicitAnimation(rsUIContext);
9049 }
9050
SetSceneSessionDestructNotificationFunc(NotifySceneSessionDestructFunc && func)9051 void SceneSession::SetSceneSessionDestructNotificationFunc(NotifySceneSessionDestructFunc&& func)
9052 {
9053 notifySceneSessionDestructFunc_ = std::move(func);
9054 }
9055
SetIsUserRequestedExit(bool isUserRequestedExit)9056 void SceneSession::SetIsUserRequestedExit(bool isUserRequestedExit)
9057 {
9058 isUserRequestedExit_ = isUserRequestedExit;
9059 }
9060
SetIsAncoForFloatingWindow(bool isAncoForFloatingWindow)9061 void SceneSession::SetIsAncoForFloatingWindow(bool isAncoForFloatingWindow)
9062 {
9063 isAncoForFloatingWindow_ = isAncoForFloatingWindow;
9064 }
9065
GetIsAncoForFloatingWindow() const9066 bool SceneSession::GetIsAncoForFloatingWindow() const
9067 {
9068 return isAncoForFloatingWindow_;
9069 }
9070
UseImplicitAnimation(bool useImplicit)9071 WSError SceneSession::UseImplicitAnimation(bool useImplicit)
9072 {
9073 return PostSyncTask([weakThis = wptr(this), useImplicit, where = __func__] {
9074 auto session = weakThis.promote();
9075 if (!session) {
9076 TLOGNE(WmsLogTag::WMS_PC, "%{public}s session is null", where);
9077 return WSError::WS_ERROR_DESTROYED_OBJECT;
9078 }
9079 if (session->useImplicitAnimationChangeFunc_) {
9080 session->useImplicitAnimationChangeFunc_(useImplicit);
9081 }
9082 return WSError::WS_OK;
9083 }, __func__);
9084 }
9085
RegisterUseImplicitAnimationChangeCallback(NotifyUseImplicitAnimationChangeFunc && func)9086 void SceneSession::RegisterUseImplicitAnimationChangeCallback(NotifyUseImplicitAnimationChangeFunc&& func)
9087 {
9088 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
9089 auto session = weakThis.promote();
9090 if (!session || !func) {
9091 TLOGNE(WmsLogTag::WMS_PC, "%{public}s session or func is null", where);
9092 return;
9093 }
9094 session->useImplicitAnimationChangeFunc_ = std::move(func);
9095 TLOGND(WmsLogTag::WMS_PC, "%{public}s id: %{public}d", where, session->GetPersistentId());
9096 }, __func__);
9097 }
9098
SetSubWindowOutlineEnabled(bool subWindowOutlineEnabled)9099 void SceneSession::SetSubWindowOutlineEnabled(bool subWindowOutlineEnabled)
9100 {
9101 subWindowOutlineEnabled_ = subWindowOutlineEnabled;
9102 }
9103
IsSubWindowOutlineEnabled() const9104 bool SceneSession::IsSubWindowOutlineEnabled() const
9105 {
9106 if (auto sessionProperty = GetSessionProperty()) {
9107 return sessionProperty->IsSubWindowOutlineEnabled();
9108 }
9109 return false;
9110 }
9111
9112 /**
9113 * Window Transition Animation For PC and FreeMultiWindow device
9114 */
SetWindowTransitionAnimation(WindowTransitionType transitionType,const TransitionAnimation & animation)9115 WSError SceneSession::SetWindowTransitionAnimation(WindowTransitionType transitionType,
9116 const TransitionAnimation& animation)
9117 {
9118 if (!(IsPcWindow() || IsFreeMultiWindowMode())) {
9119 TLOGE(WmsLogTag::WMS_ANIMATION, "Not pc or pad device");
9120 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
9121 }
9122
9123 if (!WindowHelper::IsMainWindow(GetWindowType())) {
9124 TLOGE(WmsLogTag::WMS_ANIMATION, "Scene session is not main window");
9125 return WSError::WS_ERROR_INVALID_CALLING;
9126 }
9127
9128 if (updateTransitionAnimationFunc_) {
9129 updateTransitionAnimationFunc_(transitionType, animation);
9130 }
9131 return WSError::WS_OK;
9132 }
9133
SetSubWindowSourceFunc(NotifySetSubWindowSourceFunc && func)9134 void SceneSession::SetSubWindowSourceFunc(NotifySetSubWindowSourceFunc&& func)
9135 {
9136 if (!func) {
9137 TLOGW(WmsLogTag::WMS_SUB, "func is null");
9138 return;
9139 }
9140 PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
9141 auto session = weakThis.promote();
9142 if (!session) {
9143 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is null", where);
9144 return;
9145 }
9146 func(session->subWindowSource_);
9147 session->subWindowSourceFunc_ = std::move(func);
9148 }, __func__);
9149 }
9150
SetSubWindowSource(SubWindowSource source)9151 WSError SceneSession::SetSubWindowSource(SubWindowSource source)
9152 {
9153 auto property = GetSessionProperty();
9154 if (!WindowHelper::IsSubWindow(property->GetWindowType()) &&
9155 !WindowHelper::IsDialogWindow(property->GetWindowType())) {
9156 TLOGE(WmsLogTag::WMS_SUB, "only sub window and dialog is valid");
9157 return WSError::WS_ERROR_INVALID_WINDOW;
9158 }
9159 PostTask([weakThis = wptr(this), source = source, where = __func__] {
9160 auto session = weakThis.promote();
9161 if (!session) {
9162 TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is null", where);
9163 return;
9164 }
9165 TLOGI(WmsLogTag::WMS_SUB, "SetSubWindowSource source: %{public}d", source);
9166 session->subWindowSource_ = source;
9167 if (session->subWindowSourceFunc_) {
9168 session->subWindowSourceFunc_(source);
9169 } else {
9170 TLOGNE(WmsLogTag::WMS_SUB, "func is null");
9171 }
9172 }, __func__);
9173 return WSError::WS_OK;
9174 }
9175
CloseSpecificScene()9176 WSError SceneSession::CloseSpecificScene()
9177 {
9178 TLOGI(WmsLogTag::WMS_EVENT, "close specific scene");
9179 if (!sessionStage_) {
9180 TLOGE(WmsLogTag::WMS_EVENT, "sessionStage is null");
9181 return WSError::WS_ERROR_NULLPTR;
9182 }
9183 return sessionStage_->CloseSpecificScene();
9184 }
9185
RegisterAnimateToCallback(NotifyAnimateToFunc && callback)9186 void SceneSession::RegisterAnimateToCallback(NotifyAnimateToFunc&& callback)
9187 {
9188 PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
9189 auto session = weakThis.promote();
9190 if (!session) {
9191 TLOGNE(WmsLogTag::WMS_ANIMATION, "%{public}s: Session is null", where);
9192 return;
9193 }
9194 session->onAnimateTo_ = std::move(callback);
9195 }, __func__);
9196 }
9197
AnimateTo(const WindowAnimationProperty & animationProperty,const WindowAnimationOption & animationOption)9198 WMError SceneSession::AnimateTo(const WindowAnimationProperty& animationProperty,
9199 const WindowAnimationOption& animationOption)
9200 {
9201 PostTask([weakThis = wptr(this), where = __func__, animationProperty, animationOption] {
9202 auto session = weakThis.promote();
9203 if (!session) {
9204 TLOGNE(WmsLogTag::WMS_ANIMATION, "%{public}s: Session is null", where);
9205 return;
9206 }
9207 if (session->onAnimateTo_) {
9208 session->onAnimateTo_(animationProperty, animationOption);
9209 return;
9210 }
9211 TLOGNE(WmsLogTag::WMS_ANIMATION, "%{public}s: onAnimateTo_ is nullptr", where);
9212 }, __func__);
9213 TLOGI(WmsLogTag::WMS_ANIMATION, "Post AnimateTo task success. windowId: %{public}d, targetScale: %{public}f, \
9214 animationOption: %{public}s", GetWindowId(), animationProperty.targetScale, \
9215 animationOption.ToString().c_str());
9216 return WMError::WM_OK;
9217 }
9218
SetGetAllAppUseControlMapFunc(GetAllAppUseControlMapFunc && func)9219 void SceneSession::SetGetAllAppUseControlMapFunc(GetAllAppUseControlMapFunc&& func)
9220 {
9221 onGetAllAppUseControlMapFunc_ = std::move(func);
9222 }
9223
SetFrameRectForPartialZoomIn(const Rect & frameRect)9224 WSError SceneSession::SetFrameRectForPartialZoomIn(const Rect& frameRect)
9225 {
9226 if (!SessionPermission::IsSACalling()) {
9227 TLOGE(WmsLogTag::WMS_ANIMATION, "permission denied.");
9228 return WSError::WS_ERROR_INVALID_PERMISSION;
9229 }
9230 PostTask([weakThis = wptr(this), frameRect] {
9231 auto session = weakThis.promote();
9232 if (!session) {
9233 TLOGE(WmsLogTag::WMS_ANIMATION, "session is null");
9234 return WSError::WS_ERROR_DESTROYED_OBJECT;
9235 }
9236 return session->SetFrameRectForPartialZoomInInner(frameRect);
9237 }, __func__);
9238 return WSError::WS_OK;
9239 }
9240
SetFrameRectForPartialZoomInInner(const Rect & frameRect)9241 WSError SceneSession::SetFrameRectForPartialZoomInInner(const Rect& frameRect)
9242 {
9243 auto surfaceNode = GetSurfaceNode();
9244 if (surfaceNode == nullptr) {
9245 TLOGE(WmsLogTag::WMS_ANIMATION, "surface node is null");
9246 return WSError::WS_ERROR_INVALID_WINDOW;
9247 }
9248 AutoRSTransaction trans(GetRSUIContext(), true);
9249 surfaceNode->SetRegionToBeMagnified({ frameRect.posX_, frameRect.posY_, frameRect.width_, frameRect.height_ });
9250 TLOGI(WmsLogTag::WMS_ANIMATION, "frameRect: %{public}s", frameRect.ToString().c_str());
9251 return WSError::WS_OK;
9252 }
9253 } // namespace OHOS::Rosen
9254