• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <hitrace_meter.h>
23 #include <type_traits>
24 #ifdef IMF_ENABLE
25 #include <input_method_controller.h>
26 #endif // IMF_ENABLE
27 #include <ipc_skeleton.h>
28 #include <pointer_event.h>
29 #include <transaction/rs_sync_transaction_controller.h>
30 #include <transaction/rs_transaction.h>
31 #include <ui/rs_surface_node.h>
32 
33 #include "proxy/include/window_info.h"
34 
35 #include "application_context.h"
36 #include "common/include/session_permission.h"
37 #ifdef DEVICE_STATUS_ENABLE
38 #include "interaction_manager.h"
39 #endif // DEVICE_STATUS_ENABLE
40 #include "interfaces/include/ws_common.h"
41 #include "pixel_map.h"
42 #include "session/screen/include/screen_session.h"
43 #include "screen_session_manager_client/include/screen_session_manager_client.h"
44 #include "session/host/include/scene_persistent_storage.h"
45 #include "session/host/include/session_utils.h"
46 #include "display_manager.h"
47 #include "session_helper.h"
48 #include "window_helper.h"
49 #include "window_manager_hilog.h"
50 #include "wm_math.h"
51 #include <running_lock.h>
52 #include "screen_manager.h"
53 #include "screen.h"
54 #include "fold_screen_state_internel.h"
55 #include "fold_screen_common.h"
56 #include "session/host/include/ability_info_manager.h"
57 #include "session/host/include/multi_instance_manager.h"
58 #include "session/host/include/pc_fold_screen_controller.h"
59 
60 #ifdef POWER_MANAGER_ENABLE
61 #include <power_mgr_client.h>
62 #endif
63 
64 namespace OHOS::Rosen {
65 namespace {
66 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSession" };
67 const std::string DLP_INDEX = "ohos.dlp.params.index";
68 const std::string ERROR_REASON_LOW_MEMORY_KILL = "LowMemoryKill";
69 constexpr const char* APP_CLONE_INDEX = "ohos.extra.param.key.appCloneIndex";
70 constexpr float MINI_FLOAT_SCALE = 0.3f;
71 constexpr float MOVE_DRAG_POSITION_Z = 100.5f;
72 constexpr DisplayId VIRTUAL_DISPLAY_ID = 999;
73 constexpr WSRectF VELOCITY_RELOCATION_TO_TOP = {0.0f, -10.0f, 0.0f, 0.0f};
74 constexpr WSRectF VELOCITY_RELOCATION_TO_BOTTOM = {0.0f, 10.0f, 0.0f, 0.0f};
75 constexpr int32_t API_VERSION_18 = 18;
76 constexpr int32_t HOOK_SYSTEM_BAR_HEIGHT = 40;
77 constexpr int32_t HOOK_AI_BAR_HEIGHT = 28;
78 constexpr int32_t MULTI_WINDOW_TITLE_BAR_DEFAULT_HEIGHT_VP = 32;
79 
CheckIfRectElementIsTooLarge(const WSRect & rect)80 bool CheckIfRectElementIsTooLarge(const WSRect& rect)
81 {
82     int32_t largeNumber = static_cast<int32_t>(SHRT_MAX);
83     if (rect.posX_ >= largeNumber || rect.posY_ >= largeNumber ||
84         rect.width_ >= largeNumber || rect.height_ >= largeNumber) {
85         return true;
86     }
87     return false;
88 }
89 } // namespace
90 
91 MaximizeMode SceneSession::maximizeMode_ = MaximizeMode::MODE_RECOVER;
92 std::shared_mutex SceneSession::windowDragHotAreaMutex_;
93 std::map<uint64_t, std::map<uint32_t, WSRect>> SceneSession::windowDragHotAreaMap_;
94 static bool g_enableForceUIFirst = system::GetParameter("window.forceUIFirst.enabled", "1") == "1";
95 GetConstrainedModalExtWindowInfoFunc SceneSession::onGetConstrainedModalExtWindowInfoFunc_;
96 
SceneSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)97 SceneSession::SceneSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
98     : Session(info)
99 {
100     GeneratePersistentId(false, info.persistentId_);
101     specificCallback_ = specificCallback;
102     SetCollaboratorType(info.collaboratorType_);
103     TLOGI(WmsLogTag::WMS_LIFE, "Create session, id: %{public}d", GetPersistentId());
104 }
105 
~SceneSession()106 SceneSession::~SceneSession()
107 {
108     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
109 }
110 
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)111 WSError SceneSession::ConnectInner(const sptr<ISessionStage>& sessionStage,
112     const sptr<IWindowEventChannel>& eventChannel,
113     const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
114     sptr<WindowSessionProperty> property, sptr<IRemoteObject> token, int32_t pid, int32_t uid,
115     const std::string& identityToken)
116 {
117     return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, &systemConfig,
118         property, token, pid, uid, identityToken, where = __func__] {
119         auto session = weakThis.promote();
120         if (!session) {
121             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
122             return WSError::WS_ERROR_DESTROYED_OBJECT;
123         }
124         if (SessionHelper::IsMainWindow(session->GetWindowType())) {
125             if (!session->CheckIdentityTokenIfMatched(identityToken)) {
126                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s check failed", where);
127                 return WSError::WS_OK;
128             }
129         }
130         if (property) {
131             property->SetCollaboratorType(session->GetCollaboratorType());
132             property->SetAppInstanceKey(session->GetAppInstanceKey());
133         }
134         session->RetrieveStatusBarDefaultVisibility();
135         auto ret = LOCK_GUARD_EXPR(SCENE_GUARD, session->Session::ConnectInner(
136             sessionStage, eventChannel, surfaceNode, systemConfig, property, token, pid, uid));
137         if (ret != WSError::WS_OK) {
138             return ret;
139         }
140         session->NotifySingleHandTransformChange(session->GetSingleHandTransform());
141         session->NotifyPropertyWhenConnect();
142         if (session->pcFoldScreenController_) {
143             session->pcFoldScreenController_->OnConnect();
144         }
145         session->SaveLastDensity();
146         return ret;
147     }, __func__);
148 }
149 
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)150 WSError SceneSession::Connect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
151     const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
152     sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
153     const std::string& identityToken)
154 {
155     // Get pid and uid before posting task.
156     int32_t pid = IPCSkeleton::GetCallingRealPid();
157     int32_t uid = IPCSkeleton::GetCallingUid();
158     return ConnectInner(sessionStage, eventChannel, surfaceNode, systemConfig,
159         property, token, pid, uid, identityToken);
160 }
161 
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)162 WSError SceneSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
163     const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
164     int32_t pid, int32_t uid)
165 {
166     return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel,
167         surfaceNode, property, token, pid, uid, where = __func__] {
168         auto session = weakThis.promote();
169         if (!session) {
170             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
171             return WSError::WS_ERROR_DESTROYED_OBJECT;
172         }
173         WSError ret = LOCK_GUARD_EXPR(SCENE_GUARD,
174             session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid));
175         if (ret != WSError::WS_OK) {
176             return ret;
177         }
178         return LOCK_GUARD_EXPR(SCENE_GUARD, session->ReconnectInner(property));
179     });
180 }
181 
ReconnectInner(sptr<WindowSessionProperty> property)182 WSError SceneSession::ReconnectInner(sptr<WindowSessionProperty> property)
183 {
184     if (property == nullptr) {
185         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
186         return WSError::WS_ERROR_NULLPTR;
187     }
188     WindowState windowState = property->GetWindowState();
189     TLOGI(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, windowState: %{public}d ", GetPersistentId(), windowState);
190     WSError ret = WSError::WS_OK;
191     switch (windowState) {
192         case WindowState::STATE_INITIAL: {
193             TLOGE(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, invalid window state: STATE_INITIAL",
194                 GetPersistentId());
195             ret = WSError::WS_ERROR_INVALID_PARAM;
196             break;
197         }
198         case WindowState::STATE_CREATED:
199             break;
200         case WindowState::STATE_SHOWN: {
201             UpdateSessionState(SessionState::STATE_FOREGROUND);
202             UpdateActiveStatus(true);
203             break;
204         }
205         case WindowState::STATE_HIDDEN: {
206             UpdateSessionState(SessionState::STATE_BACKGROUND);
207             break;
208         }
209         default:
210             TLOGE(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, invalid window state: %{public}u",
211                 GetPersistentId(), windowState);
212             ret = WSError::WS_ERROR_INVALID_PARAM;
213             break;
214     }
215     if (ret != WSError::WS_OK) {
216         Session::Disconnect(false);
217     }
218     return ret;
219 }
220 
IsShowOnLockScreen(uint32_t lockScreenZOrder)221 bool SceneSession::IsShowOnLockScreen(uint32_t lockScreenZOrder)
222 {
223     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: lockScreenZOrder: %{public}d, zOrder_: %{public}d", lockScreenZOrder,
224         zOrder_);
225 
226     // must be default screen
227     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
228     auto sessionProperty = GetSessionProperty();
229     if (sessionProperty != nullptr && defaultScreenId != sessionProperty->GetDisplayId()) {
230         TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not default display");
231         return false;
232     }
233 
234     // current window on lock screen jurded by zorder
235     if (zOrder_ >= lockScreenZOrder) {
236         TLOGI(WmsLogTag::WMS_UIEXT, "zOrder >= lockScreenZOrder");
237         return true;
238     }
239 
240     if (zOrder_ == 0) {
241         if (auto mainSession = GetMainSession()) {
242             TLOGI(WmsLogTag::WMS_UIEXT, "mainSession zOrder=%{public}d", mainSession->GetZOrder());
243             return mainSession->GetZOrder() >= lockScreenZOrder;
244         }
245     }
246     return false;
247 }
248 
AddExtensionTokenInfo(const UIExtensionTokenInfo & tokenInfo)249 void SceneSession::AddExtensionTokenInfo(const UIExtensionTokenInfo& tokenInfo)
250 {
251     extensionTokenInfos_.push_back(tokenInfo);
252     TLOGI(WmsLogTag::WMS_UIEXT, "can show:%{public}u, id: %{public}d",
253         tokenInfo.canShowOnLockScreen, GetPersistentId());
254 }
255 
RemoveExtensionTokenInfo(const sptr<IRemoteObject> & abilityToken)256 void SceneSession::RemoveExtensionTokenInfo(const sptr<IRemoteObject>& abilityToken)
257 {
258     auto persistentId = GetPersistentId();
259     auto itr = std::remove_if(
260         extensionTokenInfos_.begin(), extensionTokenInfos_.end(),
261         [&abilityToken, persistentId, where = __func__](const auto& tokenInfo) {
262             TLOGNI(WmsLogTag::WMS_UIEXT,
263                 "%{public}s UIExtOnLock: need remove, token: %{public}u, persistentId: %{public}d",
264                 where, tokenInfo.callingTokenId, persistentId);
265             return tokenInfo.abilityToken == abilityToken;
266         });
267     extensionTokenInfos_.erase(itr, extensionTokenInfos_.end());
268 }
269 
OnNotifyAboveLockScreen()270 void SceneSession::OnNotifyAboveLockScreen()
271 {
272     CheckExtensionOnLockScreenToClose();
273 }
274 
CheckExtensionOnLockScreenToClose()275 void SceneSession::CheckExtensionOnLockScreenToClose()
276 {
277     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: %{public}d", GetPersistentId());
278 
279     // 1. check sub session
280     for (auto& session : GetSubSession()) {
281         if (!session) {
282             TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: session is null");
283             continue;
284         }
285         session->CheckExtensionOnLockScreenToClose();
286     }
287 
288     // 2. check self permission
289     std::vector<UIExtensionTokenInfo> tokenInfosToClose;
290     for (auto& tokenInfo : extensionTokenInfos_) {
291         if (tokenInfo.canShowOnLockScreen) {
292             continue;
293         }
294         tokenInfosToClose.push_back(tokenInfo);
295     }
296 
297     // 3. close ui extension without lock screen permisson
298     std::for_each(tokenInfosToClose.rbegin(), tokenInfosToClose.rend(),
299         [this](const UIExtensionTokenInfo& tokenInfo) { CloseExtensionSync(tokenInfo); });
300 }
301 
CloseExtensionSync(const UIExtensionTokenInfo & tokenInfo)302 void SceneSession::CloseExtensionSync(const UIExtensionTokenInfo& tokenInfo)
303 {
304     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock");
305 
306     // hide sub window
307     auto subSceneSessions = GetSubSession();
308     for (auto& session : subSceneSessions) {
309         if (!session) {
310             TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: session is null");
311             continue;
312         }
313         // hide sub window of ui extension
314         if (session->GetAbilityToken() == tokenInfo.abilityToken) {
315             TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: hide sub window %{public}u", session->GetWindowId());
316             session->HideSync();
317         }
318     }
319 
320     TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: close ui extension, callerToken: %{public}u, persistent id %{public}d",
321         tokenInfo.callingTokenId, GetPersistentId());
322 
323     // kill ui extension ability
324     AAFwk::AbilityManagerClient::GetInstance()->CloseUIExtensionAbilityBySCB(tokenInfo.abilityToken);
325 }
326 
Foreground(sptr<WindowSessionProperty> property,bool isFromClient,const std::string & identityToken)327 WSError SceneSession::Foreground(
328     sptr<WindowSessionProperty> property, bool isFromClient, const std::string& identityToken)
329 {
330     if (!CheckPermissionWithPropertyAnimation(property)) {
331         return WSError::WS_ERROR_NOT_SYSTEM_APP;
332     }
333 
334     // return when screen is locked and show without ShowWhenLocked flag
335     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
336     auto sessionProperty = GetSessionProperty();
337     if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
338         IsActivatedAfterScreenLocked() &&
339         GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED) &&
340         (sessionProperty != nullptr && defaultScreenId == sessionProperty->GetDisplayId()) &&
341         !IsShowWhenLocked()) {
342         if (SessionPermission::VerifyCallingPermission("ohos.permission.CALLED_BELOW_LOCK_SCREEN")) {
343             TLOGW(WmsLogTag::WMS_LIFE, "screen is locked, session %{public}d %{public}s permission verified",
344                 GetPersistentId(), sessionInfo_.bundleName_.c_str());
345         } else {
346             TLOGW(WmsLogTag::WMS_LIFE,
347                 "failed: screen is locked, session %{public}d %{public}s show without ShowWhenLocked flag",
348                 GetPersistentId(), sessionInfo_.bundleName_.c_str());
349             return WSError::WS_ERROR_INVALID_SESSION;
350         }
351     }
352 
353     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
354         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
355             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
356             return WSError::WS_OK;
357         }
358     }
359     return ForegroundTask(property);
360 }
361 
SetRequestNextVsyncFunc(RequestVsyncFunc && func)362 void SceneSession::SetRequestNextVsyncFunc(RequestVsyncFunc&& func)
363 {
364     if (func == nullptr) {
365         TLOGI(WmsLogTag::DEFAULT, "func is nullptr");
366         return;
367     }
368     requestNextVsyncFunc_ = std::move(func);
369 }
370 
ForegroundTask(const sptr<WindowSessionProperty> & property)371 WSError SceneSession::ForegroundTask(const sptr<WindowSessionProperty>& property)
372 {
373     PostTask([weakThis = wptr(this), property, where = __func__] {
374         auto session = weakThis.promote();
375         if (!session) {
376             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
377             return WSError::WS_ERROR_DESTROYED_OBJECT;
378         }
379         auto sessionProperty = session->GetSessionProperty();
380         if (property && sessionProperty) {
381             sessionProperty->SetWindowMode(property->GetWindowMode());
382             sessionProperty->SetDecorEnable(property->IsDecorEnable());
383             session->SetFocusableOnShow(property->GetFocusableOnShow());
384         }
385         int32_t persistentId = session->GetPersistentId();
386         auto ret = session->Session::Foreground(property);
387         if (ret != WSError::WS_OK) {
388             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session foreground failed, ret=%{public}d persistentId=%{public}d",
389                 where, ret, persistentId);
390             return ret;
391         }
392         session->NotifySingleHandTransformChange(session->GetSingleHandTransform());
393         auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
394         if (leashWinSurfaceNode && sessionProperty) {
395             bool lastPrivacyMode = sessionProperty->GetPrivacyMode() || sessionProperty->GetSystemPrivacyMode();
396             leashWinSurfaceNode->SetSecurityLayer(lastPrivacyMode);
397         }
398         if (session->specificCallback_ != nullptr) {
399             if (Session::IsScbCoreEnabled()) {
400                 session->MarkAvoidAreaAsDirty();
401             } else {
402                 session->specificCallback_->onUpdateAvoidArea_(persistentId);
403             }
404             session->specificCallback_->onWindowInfoUpdate_(
405                 persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
406             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
407             session->UpdateGestureBackEnabled();
408         } else {
409             TLOGNI(WmsLogTag::WMS_LIFE,
410                 "%{public}s foreground specific callback does not take effect, callback function null", where);
411         }
412         return WSError::WS_OK;
413     }, __func__);
414     return WSError::WS_OK;
415 }
416 
CheckAndMoveDisplayIdRecursively(uint64_t displayId)417 void SceneSession::CheckAndMoveDisplayIdRecursively(uint64_t displayId)
418 {
419     if (GetSessionProperty()->GetDisplayId() == displayId || !shouldFollowParentWhenShow_) {
420         return;
421     }
422     TLOGI(WmsLogTag::WMS_LAYOUT, "session id: %{public}d, Move display to %{public}" PRIu64,
423         GetPersistentId(), displayId);
424     SetScreenId(displayId); // notify client to update display id
425     GetSessionProperty()->SetDisplayId(displayId); // set session property
426     NotifySessionDisplayIdChange(displayId);
427     for (const auto& session : subSession_) {
428         if (session) {
429             session->CheckAndMoveDisplayIdRecursively(displayId);
430         }
431     }
432 }
433 
Background(bool isFromClient,const std::string & identityToken)434 WSError SceneSession::Background(bool isFromClient, const std::string& identityToken)
435 {
436     if (!CheckPermissionWithPropertyAnimation(GetSessionProperty())) {
437         return WSError::WS_ERROR_NOT_SYSTEM_APP;
438     }
439 
440     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
441         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
442             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
443             return WSError::WS_OK;
444         }
445     }
446     return BackgroundTask(true);
447 }
448 
NotifyFrameLayoutFinishFromApp(bool notifyListener,const WSRect & rect)449 WSError SceneSession::NotifyFrameLayoutFinishFromApp(bool notifyListener, const WSRect& rect)
450 {
451     TLOGI(WmsLogTag::WMS_PATTERN, "%{public}d, %{public}s", notifyListener, rect.ToString().c_str());
452     PostTask([weakThis = wptr(this), notifyListener, rect, where = __func__] {
453         auto session = weakThis.promote();
454         if (!session) {
455             TLOGNE(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s session is null", where);
456             return WSError::WS_ERROR_DESTROYED_OBJECT;
457         }
458         session->layoutRect_ = rect;
459         session->NotifyLayoutFinished();
460         if (notifyListener && session->frameLayoutFinishFunc_) {
461             TLOGND(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s id: %{public}d", where, session->GetPersistentId());
462             session->frameLayoutFinishFunc_();
463         }
464         return WSError::WS_OK;
465     }, __func__);
466     return WSError::WS_OK;
467 }
468 
BackgroundTask(const bool isSaveSnapshot)469 WSError SceneSession::BackgroundTask(const bool isSaveSnapshot)
470 {
471     PostTask([weakThis = wptr(this), isSaveSnapshot, where = __func__] {
472         auto session = weakThis.promote();
473         if (!session) {
474             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
475             return WSError::WS_ERROR_DESTROYED_OBJECT;
476         }
477         auto state = session->GetSessionState();
478         if (state == SessionState::STATE_BACKGROUND) {
479             return WSError::WS_OK;
480         }
481         auto ret = session->Session::Background();
482         if (ret != WSError::WS_OK) {
483             return ret;
484         }
485         if (WindowHelper::IsMainWindow(session->GetWindowType()) && isSaveSnapshot) {
486             session->SaveSnapshot(true);
487         }
488         if (session->specificCallback_ != nullptr) {
489             if (Session::IsScbCoreEnabled()) {
490                 session->MarkAvoidAreaAsDirty();
491             } else {
492                 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
493             }
494             session->specificCallback_->onWindowInfoUpdate_(
495                 session->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
496             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
497             session->UpdateGestureBackEnabled();
498         }
499         return WSError::WS_OK;
500     }, __func__);
501     return WSError::WS_OK;
502 }
503 
ClearSpecificSessionCbMap()504 void SceneSession::ClearSpecificSessionCbMap()
505 {
506     PostTask([weakThis = wptr(this), where = __func__] {
507         auto session = weakThis.promote();
508         if (!session) {
509             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s: session is null", where);
510             return;
511         }
512         session->ClearJsSceneSessionCbMap(true);
513     }, __func__);
514 }
515 
ClearJsSceneSessionCbMap(bool needRemove)516 void SceneSession::ClearJsSceneSessionCbMap(bool needRemove)
517 {
518     if (clearCallbackMapFunc_) {
519         TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, needRemove: %{public}d", GetPersistentId(), needRemove);
520         clearCallbackMapFunc_(needRemove);
521     } else {
522         TLOGE(WmsLogTag::WMS_LIFE, "get callback failed, id: %{public}d", GetPersistentId());
523     }
524 }
525 
RegisterShowWhenLockedCallback(NotifyShowWhenLockedFunc && callback)526 void SceneSession::RegisterShowWhenLockedCallback(NotifyShowWhenLockedFunc&& callback)
527 {
528     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
529         auto session = weakThis.promote();
530         if (!session) {
531             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
532             return;
533         }
534         session->onShowWhenLockedFunc_ = std::move(callback);
535         session->onShowWhenLockedFunc_(session->GetShowWhenLockedFlagValue());
536     }, __func__);
537 }
538 
RegisterForceHideChangeCallback(NotifyForceHideChangeFunc && callback)539 void SceneSession::RegisterForceHideChangeCallback(NotifyForceHideChangeFunc&& callback)
540 {
541     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
542         auto session = weakThis.promote();
543         if (!session) {
544             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
545             return;
546         }
547         session->onForceHideChangeFunc_ = std::move(callback);
548     }, __func__);
549 }
550 
RegisterClearCallbackMapCallback(ClearCallbackMapFunc && callback)551 void SceneSession::RegisterClearCallbackMapCallback(ClearCallbackMapFunc&& callback)
552 {
553     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
554         auto session = weakThis.promote();
555         if (!session) {
556             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
557             return;
558         }
559         session->clearCallbackMapFunc_ = std::move(callback);
560     }, __func__);
561 }
562 
Disconnect(bool isFromClient,const std::string & identityToken)563 WSError SceneSession::Disconnect(bool isFromClient, const std::string& identityToken)
564 {
565     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
566         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
567             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
568             return WSError::WS_OK;
569         }
570     }
571     return DisconnectTask(isFromClient, true);
572 }
573 
DisconnectTask(bool isFromClient,bool isSaveSnapshot)574 WSError SceneSession::DisconnectTask(bool isFromClient, bool isSaveSnapshot)
575 {
576     PostTask([weakThis = wptr(this), isFromClient, isSaveSnapshot, where = __func__]()
577         THREAD_SAFETY_GUARD(SCENE_GUARD) {
578         auto session = weakThis.promote();
579         if (!session) {
580             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
581             return WSError::WS_ERROR_DESTROYED_OBJECT;
582         }
583         if (isFromClient) {
584             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s Client need notify destroy session, id: %{public}d",
585                 where, session->GetPersistentId());
586             session->SetSessionState(SessionState::STATE_DISCONNECT);
587             return WSError::WS_OK;
588         }
589         auto state = session->GetSessionState();
590         auto isMainWindow = SessionHelper::IsMainWindow(session->GetWindowType());
591         if ((session->needSnapshot_ || (state == SessionState::STATE_ACTIVE && isMainWindow)) && isSaveSnapshot) {
592             session->SaveSnapshot(false);
593         }
594         session->Session::Disconnect(isFromClient);
595         session->isTerminating_ = false;
596         if (session->specificCallback_ != nullptr) {
597             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
598             session->isEnableGestureBack_ = true;
599             session->UpdateGestureBackEnabled();
600             session->isEnableGestureBackHadSet_ = false;
601         }
602         return WSError::WS_OK;
603     }, __func__);
604     return WSError::WS_OK;
605 }
606 
UpdateActiveStatus(bool isActive)607 WSError SceneSession::UpdateActiveStatus(bool isActive)
608 {
609     PostTask([weakThis = wptr(this), isActive, where = __func__] {
610         auto session = weakThis.promote();
611         if (!session) {
612             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
613             return WSError::WS_ERROR_DESTROYED_OBJECT;
614         }
615         if (!session->IsSessionValid()) {
616             TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Session is invalid, id: %{public}d state: %{public}u",
617                 where, session->GetPersistentId(), session->GetSessionState());
618             return WSError::WS_ERROR_INVALID_SESSION;
619         }
620         if (isActive == session->isActive_) {
621             TLOGND(WmsLogTag::WMS_LIFE, "%{public}s Session active do not change: %{public}d",
622                 where, isActive);
623             return WSError::WS_DO_NOTHING;
624         }
625 
626         WSError ret = WSError::WS_DO_NOTHING;
627         if (isActive && session->GetSessionState() == SessionState::STATE_FOREGROUND) {
628             session->UpdateSessionState(SessionState::STATE_ACTIVE);
629             session->isActive_ = isActive;
630             ret = WSError::WS_OK;
631         }
632         if (!isActive && session->GetSessionState() == SessionState::STATE_ACTIVE) {
633             session->UpdateSessionState(SessionState::STATE_INACTIVE);
634             session->isActive_ = isActive;
635             ret = WSError::WS_OK;
636         }
637         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s isActive: %{public}d, state: %{public}u",
638             where, session->isActive_, session->GetSessionState());
639         return ret;
640     }, std::string(__func__) + ":" + std::to_string(isActive));
641     return WSError::WS_OK;
642 }
643 
CalcRectForStatusBar()644 DMRect SceneSession::CalcRectForStatusBar()
645 {
646     DMRect statusBarRect = {0, 0, 0, 0};
647     if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_ == nullptr) {
648         TLOGE(WmsLogTag::WMS_KEYBOARD, "specificCallback is null");
649         return statusBarRect;
650     }
651     const auto& statusBarVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
652         WindowType::WINDOW_TYPE_STATUS_BAR, GetSessionProperty()->GetDisplayId());
653     for (auto& statusBar : statusBarVector) {
654         if (statusBar == nullptr) {
655             continue;
656         }
657         if (statusBar->IsVisible() &&
658             static_cast<uint32_t>(statusBar->GetSessionRect().height_) > statusBarRect.height_) {
659             statusBarRect.height_ = static_cast<uint32_t>(statusBar->GetSessionRect().height_);
660         }
661         if (static_cast<uint32_t>(statusBar->GetSessionRect().width_) > statusBarRect.width_) {
662             statusBarRect.width_ = static_cast<uint32_t>(statusBar->GetSessionRect().width_);
663         }
664     }
665     TLOGD(
666         WmsLogTag::WMS_KEYBOARD, "width: %{public}d, height: %{public}d", statusBarRect.width_, statusBarRect.height_);
667     return statusBarRect;
668 }
669 
SetMoveAvailableArea(DisplayId displayId)670 WSError SceneSession::SetMoveAvailableArea(DisplayId displayId)
671 {
672     sptr<Display> display = DisplayManager::GetInstance().GetDisplayById(displayId);
673     if (display == nullptr) {
674         TLOGE(WmsLogTag::WMS_KEYBOARD, "fail to get display");
675         return WSError::WS_ERROR_INVALID_DISPLAY;
676     }
677 
678     DMRect availableArea;
679     DMError ret = display->GetAvailableArea(availableArea);
680     if (ret != DMError::DM_OK) {
681         TLOGE(WmsLogTag::WMS_KEYBOARD, "Failed to get available area, ret: %{public}d", ret);
682         return WSError::WS_ERROR_INVALID_DISPLAY;
683     }
684 
685     DMRect statusBarRect = CalcRectForStatusBar();
686     if (systemConfig_.IsPadWindow() || systemConfig_.IsPhoneWindow()) {
687         uint32_t statusBarHeight = statusBarRect.height_;
688         if (statusBarHeight > availableArea.posY_) {
689             availableArea.posY_ = statusBarHeight;
690         }
691 
692         sptr<ScreenSession> currentScreenSession =
693             ScreenSessionManagerClient::GetInstance().GetScreenSessionById(GetSessionProperty()->GetDisplayId());
694         if (currentScreenSession == nullptr) {
695             TLOGW(WmsLogTag::WMS_KEYBOARD, "Screen session is null");
696             return WSError::WS_ERROR_INVALID_DISPLAY;
697         }
698         uint32_t currentScreenHeight = currentScreenSession->GetScreenProperty().GetBounds().rect_.height_;
699         availableArea.height_ = currentScreenHeight - static_cast<uint32_t>(availableArea.posY_);
700     }
701 
702     bool isFoldable = ScreenSessionManagerClient::GetInstance().IsFoldable();
703     if (systemConfig_.IsPhoneWindow() && isFoldable && statusBarRect.width_) {
704         availableArea.width_ = statusBarRect.width_;
705     }
706     TLOGD(WmsLogTag::WMS_KEYBOARD,
707           "the available area x is: %{public}d, y is: %{public}d, width is: %{public}d, height is: %{public}d",
708           availableArea.posX_, availableArea.posY_, availableArea.width_, availableArea.height_);
709     moveDragController_->SetMoveAvailableArea(availableArea);
710     return WSError::WS_OK;
711 }
712 
InitializeMoveInputBar()713 WSError SceneSession::InitializeMoveInputBar()
714 {
715     auto property = GetSessionProperty();
716     WindowType windowType = property->GetWindowType();
717     if (WindowHelper::IsInputWindow(windowType)) {
718         TLOGD(WmsLogTag::WMS_KEYBOARD, "Start init move input bar param");
719         DisplayId displayId = property->GetDisplayId();
720 
721         WSError ret = SetMoveAvailableArea(displayId);
722         if (ret != WSError::WS_OK) {
723             TLOGD(WmsLogTag::WMS_KEYBOARD, "set move availableArea error");
724             return WSError::WS_ERROR_INVALID_OPERATION;
725         }
726         moveDragController_->SetMoveInputBarStartDisplayId(displayId);
727     }
728     return WSError::WS_OK;
729 }
730 
OnSessionEvent(SessionEvent event)731 WSError SceneSession::OnSessionEvent(SessionEvent event)
732 {
733     PostTask([weakThis = wptr(this), event, where = __func__] {
734         auto session = weakThis.promote();
735         if (!session) {
736             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
737             return WSError::WS_ERROR_DESTROYED_OBJECT;
738         }
739         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s event: %{public}d", where, static_cast<int32_t>(event));
740         session->UpdateWaterfallMode(event);
741         if (event == SessionEvent::EVENT_START_MOVE) {
742             if (!session->IsMovable()) {
743                 return WSError::WS_OK;
744             }
745             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::StartMove");
746             WSError ret = session->InitializeMoveInputBar();
747             if (ret != WSError::WS_OK) {
748                 return ret;
749             }
750             session->InitializeCrossMoveDrag();
751             session->moveDragController_->InitMoveDragProperty();
752             if (session->pcFoldScreenController_) {
753                 session->pcFoldScreenController_->RecordStartMoveRect(session->GetSessionRect(),
754                     session->IsFullScreenMovable());
755             }
756             WSRect rect = session->winRect_;
757             if (session->IsFullScreenMovable()) {
758                 session->UpdateFullScreenWaterfallMode(false);
759                 rect = session->moveDragController_->GetFullScreenToFloatingRect(session->winRect_,
760                     session->GetSessionRequestRect());
761                 session->Session::UpdateRect(rect, SizeChangeReason::RECOVER, where, nullptr);
762                 session->moveDragController_->SetStartMoveFlag(true);
763                 session->moveDragController_->CalcFirstMoveTargetRect(rect, true);
764             } else {
765                 session->moveDragController_->SetStartMoveFlag(true);
766                 session->moveDragController_->CalcFirstMoveTargetRect(rect, false);
767             }
768             session->SetSessionEventParam({session->moveDragController_->GetOriginalPointerPosX(),
769                 session->moveDragController_->GetOriginalPointerPosY(), rect.width_, rect.height_});
770         }
771         session->HandleSessionDragEvent(event);
772         if (session->onSessionEvent_) {
773             session->onSessionEvent_(static_cast<uint32_t>(event), session->sessionEventParam_);
774         }
775         return WSError::WS_OK;
776     }, std::string(__func__) + ":" + std::to_string(static_cast<uint32_t>(event)));
777     return WSError::WS_OK;
778 }
779 
HandleSessionDragEvent(SessionEvent event)780 void SceneSession::HandleSessionDragEvent(SessionEvent event)
781 {
782     if (moveDragController_ &&
783         (event == SessionEvent::EVENT_DRAG || event == SessionEvent::EVENT_DRAG_START)) {
784         WSRect rect = moveDragController_->GetTargetRect(
785             MoveDragController::TargetRectCoordinate::RELATED_TO_START_DISPLAY);
786         DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
787         if (event == SessionEvent::EVENT_DRAG_START) {
788             dragResizeType = GetAppDragResizeType();
789             SetDragResizeTypeDuringDrag(dragResizeType);
790         }
791         SetSessionEventParam({rect.posX_, rect.posY_, rect.width_, rect.height_,
792             static_cast<uint32_t>(dragResizeType)});
793     }
794 }
795 
UpdateWaterfallMode(SessionEvent event)796 void SceneSession::UpdateWaterfallMode(SessionEvent event)
797 {
798     if (pcFoldScreenController_ == nullptr) {
799         return;
800     }
801     switch (event) {
802         case SessionEvent::EVENT_MAXIMIZE_WATERFALL:
803             UpdateFullScreenWaterfallMode(pcFoldScreenController_->IsHalfFolded(GetScreenId()));
804             break;
805         case SessionEvent::EVENT_WATERFALL_TO_MAXIMIZE:
806         case SessionEvent::EVENT_RECOVER:
807         case SessionEvent::EVENT_SPLIT_PRIMARY:
808         case SessionEvent::EVENT_SPLIT_SECONDARY:
809             UpdateFullScreenWaterfallMode(false);
810             break;
811         default:
812             break;
813     }
814 }
815 
SyncSessionEvent(SessionEvent event)816 WSError SceneSession::SyncSessionEvent(SessionEvent event)
817 {
818     TLOGD(WmsLogTag::WMS_LAYOUT, "the sync session event is: %{public}d", event);
819     if (event != SessionEvent::EVENT_START_MOVE && event != SessionEvent::EVENT_END_MOVE) {
820         TLOGE(WmsLogTag::WMS_LAYOUT, "This is not start move event or end move event, "
821             "eventId=%{public}u windowId=%{public}d", event, GetPersistentId());
822         return WSError::WS_ERROR_NULLPTR;
823     }
824     return PostSyncTask([weakThis = wptr(this), event, where = __func__] {
825         auto session = weakThis.promote();
826         if (!session || !session->moveDragController_) {
827             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s: session or moveDragController is null", where);
828             return WSError::WS_ERROR_NULLPTR;
829         }
830         if (event == SessionEvent::EVENT_END_MOVE) {
831             if (!session->moveDragController_->GetStartMoveFlag()) {
832                 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s Repeat operation, window is not moving", where);
833                 return WSError::WS_OK;
834             }
835             session->moveDragController_->StopMoving();
836             return WSError::WS_OK;
837         }
838         if (session->moveDragController_->GetStartMoveFlag()) {
839             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s: Repeat operation, system window is moving", where);
840             return WSError::WS_ERROR_REPEAT_OPERATION;
841         }
842         session->OnSessionEvent(event);
843         return WSError::WS_OK;
844     }, __func__);
845 }
846 
StartMovingWithCoordinate(int32_t offsetX,int32_t offsetY,int32_t pointerPosX,int32_t pointerPosY)847 WSError SceneSession::StartMovingWithCoordinate(int32_t offsetX, int32_t offsetY,
848     int32_t pointerPosX, int32_t pointerPosY)
849 {
850     return PostSyncTask([weakThis = wptr(this), offsetX, offsetY, pointerPosX, pointerPosY, where = __func__] {
851         auto session = weakThis.promote();
852         if (!session || !session->moveDragController_) {
853             TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s: session or moveDragController is null", where);
854             return WSError::WS_ERROR_NULLPTR;
855         }
856         if (session->moveDragController_->GetStartMoveFlag()) {
857             TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s: Repeat operation, window is moving", where);
858             return WSError::WS_ERROR_REPEAT_OPERATION;
859         }
860         TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s: offsetX:%{public}d offsetY:%{public}d pointerPosX:%{public}d"
861             " pointerPosY:%{public}d", where, offsetX, offsetY, pointerPosX, pointerPosY);
862         WSRect winRect = {
863             pointerPosX - offsetX,
864             pointerPosY - offsetY,
865             session->winRect_.width_,
866             session->winRect_.height_
867         };
868         session->moveDragController_->HandleStartMovingWithCoordinate(offsetX,
869             offsetY, pointerPosX, pointerPosY, winRect);
870         session->OnSessionEvent(SessionEvent::EVENT_START_MOVE);
871         return WSError::WS_OK;
872     }, __func__);
873 }
874 
GetWindowDragHotAreaType(DisplayId displayId,uint32_t type,int32_t pointerX,int32_t pointerY)875 uint32_t SceneSession::GetWindowDragHotAreaType(DisplayId displayId, uint32_t type, int32_t pointerX, int32_t pointerY)
876 {
877     std::shared_lock<std::shared_mutex> lock(windowDragHotAreaMutex_);
878     if (windowDragHotAreaMap_.find(displayId) == windowDragHotAreaMap_.end()) {
879         TLOGW(WmsLogTag::WMS_LAYOUT, "Display is invalid.");
880         return type;
881     }
882     for (const auto& [key, rect] : windowDragHotAreaMap_[displayId]) {
883         if (rect.IsInRegion(pointerX, pointerY)) {
884             type |= key;
885         }
886     }
887     return type;
888 }
889 
AddOrUpdateWindowDragHotArea(DisplayId displayId,uint32_t type,const WSRect & area)890 void SceneSession::AddOrUpdateWindowDragHotArea(DisplayId displayId, uint32_t type, const WSRect& area)
891 {
892     std::unique_lock<std::shared_mutex> lock(windowDragHotAreaMutex_);
893     windowDragHotAreaMap_[displayId].insert_or_assign(type, area);
894 }
895 
NotifySubModalTypeChange(SubWindowModalType subWindowModalType)896 WSError SceneSession::NotifySubModalTypeChange(SubWindowModalType subWindowModalType)
897 {
898     PostTask([weakThis = wptr(this), subWindowModalType, where = __func__] {
899         auto session = weakThis.promote();
900         if (!session) {
901             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
902             return;
903         }
904         TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s subWindowModalType: %{public}u",
905             where, static_cast<uint32_t>(subWindowModalType));
906         if (session->onSubModalTypeChange_) {
907             session->onSubModalTypeChange_(subWindowModalType);
908         }
909     }, __func__);
910     return WSError::WS_OK;
911 }
912 
RegisterSubModalTypeChangeCallback(NotifySubModalTypeChangeFunc && func)913 void SceneSession::RegisterSubModalTypeChangeCallback(NotifySubModalTypeChangeFunc&& func)
914 {
915     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
916         auto session = weakThis.promote();
917         if (!session || !func) {
918             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session or SessionModalTypeChangeFunc is null", where);
919             return;
920         }
921         session->onSubModalTypeChange_ = std::move(func);
922         TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s id: %{public}d",
923             where, session->GetPersistentId());
924     }, __func__);
925 }
926 
RegisterMainModalTypeChangeCallback(NotifyMainModalTypeChangeFunc && func)927 void SceneSession::RegisterMainModalTypeChangeCallback(NotifyMainModalTypeChangeFunc&& func)
928 {
929     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
930         auto session = weakThis.promote();
931         if (!session || !func) {
932             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session or func is null", where);
933             return;
934         }
935         session->onMainModalTypeChange_ = std::move(func);
936         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, session->GetPersistentId());
937     }, __func__);
938 }
939 
IsDialogWindow() const940 bool SceneSession::IsDialogWindow() const
941 {
942     return WindowHelper::IsDialogWindow(GetSessionProperty()->GetWindowType());
943 }
944 
GetSubWindowModalType() const945 SubWindowModalType SceneSession::GetSubWindowModalType() const
946 {
947     SubWindowModalType modalType = SubWindowModalType::TYPE_UNDEFINED;
948     auto property = GetSessionProperty();
949     if (property == nullptr) {
950         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
951         return modalType;
952     }
953     auto windowType = property->GetWindowType();
954     if (WindowHelper::IsToastSubWindow(windowType, property->GetWindowFlags())) {
955         return SubWindowModalType::TYPE_TOAST;
956     }
957     if (WindowHelper::IsTextMenuSubWindow(windowType, property->GetWindowFlags())) {
958         return SubWindowModalType::TYPE_TEXT_MENU;
959     }
960     if (WindowHelper::IsDialogWindow(windowType)) {
961         modalType = SubWindowModalType::TYPE_DIALOG;
962     } else if (WindowHelper::IsModalSubWindow(windowType, property->GetWindowFlags())) {
963         if (WindowHelper::IsApplicationModalSubWindow(windowType, property->GetWindowFlags())) {
964             modalType = SubWindowModalType::TYPE_APPLICATION_MODALITY;
965         } else {
966             modalType = SubWindowModalType::TYPE_WINDOW_MODALITY;
967         }
968     } else if (WindowHelper::IsSubWindow(windowType)) {
969         modalType = SubWindowModalType::TYPE_NORMAL;
970     }
971     return modalType;
972 }
973 
SetSessionEventParam(SessionEventParam param)974 void SceneSession::SetSessionEventParam(SessionEventParam param)
975 {
976     sessionEventParam_ = param;
977 }
978 
RegisterSessionEventCallback(NotifySessionEventFunc && callback)979 void SceneSession::RegisterSessionEventCallback(NotifySessionEventFunc&& callback)
980 {
981     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
982         auto session = weakThis.promote();
983         if (!session) {
984             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
985             return;
986         }
987         session->onSessionEvent_ = std::move(callback);
988     }, __func__);
989 }
990 
RegisterUpdateAppUseControlCallback(UpdateAppUseControlFunc && callback)991 void SceneSession::RegisterUpdateAppUseControlCallback(UpdateAppUseControlFunc&& callback)
992 {
993     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
994         auto session = weakThis.promote();
995         if (!session) {
996             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
997             return;
998         }
999         session->onUpdateAppUseControlFunc_ = std::move(callback);
1000         for (const auto& [type, info] : session->appUseControlMap_) {
1001             session->onUpdateAppUseControlFunc_(type, info.isNeedControl, info.isControlRecentOnly);
1002         }
1003     }, __func__);
1004 }
1005 
NotifyUpdateAppUseControl(ControlAppType type,const ControlInfo & controlInfo)1006 void SceneSession::NotifyUpdateAppUseControl(ControlAppType type, const ControlInfo& controlInfo)
1007 {
1008     PostTask([weakThis = wptr(this), type, controlInfo, where = __func__] {
1009         auto session = weakThis.promote();
1010         if (!session) {
1011             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1012             return;
1013         }
1014         session->appUseControlMap_[type] = controlInfo;
1015         if (session->onUpdateAppUseControlFunc_) {
1016             session->onUpdateAppUseControlFunc_(type, controlInfo.isNeedControl, controlInfo.isControlRecentOnly);
1017         }
1018     }, __func__);
1019 }
1020 
RegisterDefaultAnimationFlagChangeCallback(NotifyWindowAnimationFlagChangeFunc && callback)1021 void SceneSession::RegisterDefaultAnimationFlagChangeCallback(NotifyWindowAnimationFlagChangeFunc&& callback)
1022 {
1023     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1024         auto session = weakThis.promote();
1025         if (!session) {
1026             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1027             return;
1028         }
1029         session->onWindowAnimationFlagChange_ = std::move(callback);
1030         session->onWindowAnimationFlagChange_(session->IsNeedDefaultAnimation());
1031     }, __func__);
1032 }
1033 
RegisterDefaultDensityEnabledCallback(NotifyDefaultDensityEnabledFunc && callback)1034 void SceneSession::RegisterDefaultDensityEnabledCallback(NotifyDefaultDensityEnabledFunc&& callback)
1035 {
1036     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1037         auto session = weakThis.promote();
1038         if (!session) {
1039             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1040             return;
1041         }
1042         session->onDefaultDensityEnabledFunc_ = std::move(callback);
1043     }, __func__);
1044 }
1045 
RegisterNeedAvoidCallback(NotifyNeedAvoidFunc && callback)1046 void SceneSession::RegisterNeedAvoidCallback(NotifyNeedAvoidFunc&& callback)
1047 {
1048     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1049         auto session = weakThis.promote();
1050         if (!session) {
1051             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
1052             return;
1053         }
1054         session->onNeedAvoid_ = std::move(callback);
1055     }, __func__);
1056 }
1057 
RegisterSystemBarPropertyChangeCallback(NotifySystemBarPropertyChangeFunc && callback)1058 void SceneSession::RegisterSystemBarPropertyChangeCallback(NotifySystemBarPropertyChangeFunc&& callback)
1059 {
1060     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1061         auto session = weakThis.promote();
1062         if (!session) {
1063             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1064             return;
1065         }
1066         session->onSystemBarPropertyChange_ = std::move(callback);
1067     }, __func__);
1068 }
1069 
RegisterTouchOutsideCallback(NotifyTouchOutsideFunc && callback)1070 void SceneSession::RegisterTouchOutsideCallback(NotifyTouchOutsideFunc&& callback)
1071 {
1072     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1073         auto session = weakThis.promote();
1074         if (!session) {
1075             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1076             return;
1077         }
1078         session->onTouchOutside_ = std::move(callback);
1079     }, __func__);
1080 }
1081 
SetGlobalMaximizeMode(MaximizeMode mode)1082 WSError SceneSession::SetGlobalMaximizeMode(MaximizeMode mode)
1083 {
1084     return PostSyncTask([weakThis = wptr(this), mode, where = __func__] {
1085         auto session = weakThis.promote();
1086         if (!session) {
1087             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1088             return WSError::WS_ERROR_DESTROYED_OBJECT;
1089         }
1090         TLOGND(WmsLogTag::WMS_PC, "%{public}s mode: %{public}u", where, static_cast<uint32_t>(mode));
1091         session->maximizeMode_ = mode;
1092         ScenePersistentStorage::Insert("maximize_state", static_cast<int32_t>(session->maximizeMode_),
1093             ScenePersistentStorageType::MAXIMIZE_STATE);
1094         return WSError::WS_OK;
1095     }, __func__);
1096 }
1097 
GetGlobalMaximizeMode(MaximizeMode & mode)1098 WSError SceneSession::GetGlobalMaximizeMode(MaximizeMode& mode)
1099 {
1100     return PostSyncTask([weakThis = wptr(this), &mode, where = __func__] {
1101         auto session = weakThis.promote();
1102         if (!session) {
1103             TLOGNE(WmsLogTag::WMS_PC, "%{public}s session is null", where);
1104             return WSError::WS_ERROR_DESTROYED_OBJECT;
1105         }
1106         mode = maximizeMode_;
1107         TLOGND(WmsLogTag::WMS_PC, "%{public}s mode: %{public}u", where, static_cast<uint32_t>(mode));
1108         return WSError::WS_OK;
1109     }, __func__);
1110 }
1111 
CheckAspectRatioValid(const sptr<SceneSession> & session,float ratio,float vpr)1112 static WSError CheckAspectRatioValid(const sptr<SceneSession>& session, float ratio, float vpr)
1113 {
1114     if (MathHelper::NearZero(ratio)) {
1115         return WSError::WS_OK;
1116     }
1117     if (!session) {
1118         return WSError::WS_ERROR_INVALID_PARAM;
1119     }
1120     auto sessionProperty = session->GetSessionProperty();
1121     if (!sessionProperty) {
1122         return WSError::WS_ERROR_INVALID_PARAM;
1123     }
1124     auto limits = sessionProperty->GetWindowLimits();
1125     if (session->IsDecorEnable()) {
1126         if (limits.minWidth_ && limits.maxHeight_ &&
1127             MathHelper::LessNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.minWidth_, vpr) /
1128             SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr))) {
1129             WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
1130             return WSError::WS_ERROR_INVALID_PARAM;
1131         } else if (limits.minHeight_ && limits.maxWidth_ &&
1132             MathHelper::GreatNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr) /
1133             SessionUtils::ToLayoutHeight(limits.minHeight_, vpr))) {
1134             WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
1135             return WSError::WS_ERROR_INVALID_PARAM;
1136         }
1137     } else {
1138         if (limits.minWidth_ && limits.maxHeight_ && MathHelper::LessNotEqual(ratio,
1139             static_cast<float>(limits.minWidth_) / limits.maxHeight_)) {
1140             WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
1141             return WSError::WS_ERROR_INVALID_PARAM;
1142         } else if (limits.minHeight_ && limits.maxWidth_ && MathHelper::GreatNotEqual(ratio,
1143             static_cast<float>(limits.maxWidth_) / limits.minHeight_)) {
1144             WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
1145             return WSError::WS_ERROR_INVALID_PARAM;
1146         }
1147     }
1148     return WSError::WS_OK;
1149 }
1150 
1151 /** @note @window.layout */
SetAspectRatio(float ratio)1152 WSError SceneSession::SetAspectRatio(float ratio)
1153 {
1154     return PostSyncTask([weakThis = wptr(this), ratio, where = __func__] {
1155         auto session = weakThis.promote();
1156         if (!session) {
1157             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
1158             return WSError::WS_ERROR_DESTROYED_OBJECT;
1159         }
1160         float vpr = 1.5f; // 1.5f: default virtual pixel ratio
1161         auto display = DisplayManager::GetInstance().GetDefaultDisplay();
1162         if (display) {
1163             vpr = display->GetVirtualPixelRatio();
1164             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s vpr=%{public}f", where, vpr);
1165         }
1166         WSError ret = CheckAspectRatioValid(session, ratio, vpr);
1167         if (ret != WSError::WS_OK) {
1168             return ret;
1169         }
1170         session->aspectRatio_ = ratio;
1171         if (session->moveDragController_) {
1172             session->moveDragController_->SetAspectRatio(ratio);
1173         }
1174         session->SaveAspectRatio(session->aspectRatio_);
1175         WSRect adjustedRect = session->winRect_;
1176         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s Before adjusting, the id:%{public}d, the current rect:%{public}s, "
1177             "ratio:%{public}f", where, session->GetPersistentId(), adjustedRect.ToString().c_str(), ratio);
1178         if (session->AdjustRectByAspectRatio(adjustedRect)) {
1179             TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s After adjusting, the id:%{public}d, the adjusted rect:%{public}s",
1180                 where, session->GetPersistentId(), adjustedRect.ToString().c_str());
1181             session->NotifySessionRectChange(adjustedRect, SizeChangeReason::RESIZE);
1182         }
1183         return WSError::WS_OK;
1184     }, __func__);
1185 }
1186 
1187 /** @note @window.layout */
UpdateRect(const WSRect & rect,SizeChangeReason reason,const std::string & updateReason,const std::shared_ptr<RSTransaction> & rsTransaction)1188 WSError SceneSession::UpdateRect(const WSRect& rect, SizeChangeReason reason,
1189     const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction)
1190 {
1191     PostTask([weakThis = wptr(this), rect, reason, rsTransaction, updateReason, where = __func__] {
1192         auto session = weakThis.promote();
1193         if (!session) {
1194             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
1195             return;
1196         }
1197         if (session->reason_ == SizeChangeReason::DRAG) {
1198             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: skip drag reason update id:%{public}d rect:%{public}s",
1199                 where, session->GetPersistentId(), rect.ToString().c_str());
1200             return;
1201         }
1202         if (session->winRect_ == rect && session->reason_ != SizeChangeReason::DRAG_END &&
1203             (session->GetWindowType() != WindowType::WINDOW_TYPE_KEYBOARD_PANEL &&
1204              session->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT)) {
1205             if (!session->sessionStage_) {
1206                 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: skip same rect update id:%{public}d rect:%{public}s",
1207                     where, session->GetPersistentId(), rect.ToString().c_str());
1208                 return;
1209             } else if (session->GetClientRect() == rect) {
1210                 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: skip same rect update id:%{public}d rect:%{public}s "
1211                     "clientRect:%{public}s", where, session->GetPersistentId(), rect.ToString().c_str(),
1212                     session->GetClientRect().ToString().c_str());
1213                 return;
1214             }
1215         }
1216         if (rect.IsInvalid()) {
1217             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d rect:%{public}s is invalid",
1218                 where, session->GetPersistentId(), rect.ToString().c_str());
1219             return;
1220         }
1221         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::UpdateRect %d [%d, %d, %u, %u]",
1222             session->GetPersistentId(), rect.posX_, rect.posY_, rect.width_, rect.height_);
1223         // position change no need to notify client, since frame layout finish will notify
1224         if (NearEqual(rect.width_, session->winRect_.width_) && NearEqual(rect.height_, session->winRect_.height_) &&
1225             (session->reason_ != SizeChangeReason::DRAG_MOVE || !session->rectChangeListenerRegistered_)) {
1226             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: position change no need notify client id:%{public}d, "
1227                 "rect:%{public}s, preRect:%{public}s", where,
1228                 session->GetPersistentId(), rect.ToString().c_str(), session->winRect_.ToString().c_str());
1229             session->SetWinRectWhenUpdateRect(rect);
1230         } else {
1231             session->SetWinRectWhenUpdateRect(rect);
1232             session->NotifyClientToUpdateRect(updateReason, rsTransaction);
1233         }
1234         session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
1235         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, reason:%{public}d %{public}s, "
1236             "rect:%{public}s, clientRect:%{public}s",
1237             where, session->GetPersistentId(), session->reason_, updateReason.c_str(),
1238             rect.ToString().c_str(), session->GetClientRect().ToString().c_str());
1239     }, __func__ + GetRectInfo(rect));
1240     return WSError::WS_OK;
1241 }
1242 
1243 /** @note @window.layout */
SetWinRectWhenUpdateRect(const WSRect & rect)1244 void SceneSession::SetWinRectWhenUpdateRect(const WSRect& rect)
1245 {
1246     if (GetIsMidScene() && rect.posX_ == 0 && rect.posY_ == 0) {
1247         winRect_.width_ = rect.width_;
1248         winRect_.height_ = rect.height_;
1249     } else {
1250         winRect_ = rect;
1251     }
1252 }
1253 
NotifyClientToUpdateRectTask(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)1254 WSError SceneSession::NotifyClientToUpdateRectTask(const std::string& updateReason,
1255     std::shared_ptr<RSTransaction> rsTransaction)
1256 {
1257     TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, reason:%{public}d, rect:%{public}s",
1258         GetPersistentId(), reason_, winRect_.ToString().c_str());
1259     bool isMoveOrDrag = moveDragController_ &&
1260         (moveDragController_->GetStartDragFlag() || moveDragController_->GetStartMoveFlag());
1261     if (isMoveOrDrag && reason_ == SizeChangeReason::UNDEFINED) {
1262         TLOGD(WmsLogTag::WMS_LAYOUT, "skip redundant rect update!");
1263         return WSError::WS_ERROR_REPEAT_OPERATION;
1264     }
1265     WSError ret = WSError::WS_OK;
1266     if (reason_ != SizeChangeReason::DRAG_MOVE) {
1267         UpdateCrossAxisOfLayout(winRect_);
1268     }
1269     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
1270         "SceneSession::NotifyClientToUpdateRect%d [%d, %d, %u, %u] reason:%u",
1271         GetPersistentId(), winRect_.posX_, winRect_.posY_, winRect_.width_, winRect_.height_, reason_);
1272 
1273     std::map<AvoidAreaType, AvoidArea> avoidAreas;
1274     if (GetForegroundInteractiveStatus()) {
1275         GetAllAvoidAreas(avoidAreas);
1276     } else {
1277         TLOGD(WmsLogTag::WMS_IMMS, "win [%{public}d] avoid area update rejected by recent", GetPersistentId());
1278     }
1279     // once reason is undefined, not use rsTransaction
1280     // when rotation, sync cnt++ in marshalling. Although reason is undefined caused by resize
1281     if (reason_ == SizeChangeReason::UNDEFINED || reason_ == SizeChangeReason::RESIZE || IsMoveToOrDragMove(reason_)) {
1282         ret = Session::UpdateRectWithLayoutInfo(winRect_, reason_, updateReason, nullptr, avoidAreas);
1283     } else {
1284         ret = Session::UpdateRectWithLayoutInfo(winRect_, reason_, updateReason, rsTransaction, avoidAreas);
1285 #ifdef DEVICE_STATUS_ENABLE
1286         // When the drag is in progress, the drag window needs to be notified to rotate.
1287         if (rsTransaction != nullptr) {
1288             RotateDragWindow(rsTransaction);
1289         }
1290 #endif // DEVICE_STATUS_ENABLE
1291     }
1292 
1293     return ret;
1294 }
1295 
NotifyClientToUpdateRect(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)1296 WSError SceneSession::NotifyClientToUpdateRect(const std::string& updateReason,
1297     std::shared_ptr<RSTransaction> rsTransaction)
1298 {
1299     PostTask([weakThis = wptr(this), rsTransaction, updateReason, where = __func__] {
1300         auto session = weakThis.promote();
1301         if (!session) {
1302             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
1303             return WSError::WS_ERROR_DESTROYED_OBJECT;
1304         }
1305         WSError ret = session->NotifyClientToUpdateRectTask(updateReason, rsTransaction);
1306         if (ret != WSError::WS_OK) {
1307             return ret;
1308         }
1309         if (session->specificCallback_ && session->specificCallback_->onUpdateOccupiedAreaIfNeed_) {
1310             session->specificCallback_->onUpdateOccupiedAreaIfNeed_(session->GetPersistentId());
1311         }
1312         return ret;
1313     }, __func__);
1314     return WSError::WS_OK;
1315 }
1316 
GetScreenWidthAndHeightFromServer(const sptr<WindowSessionProperty> & sessionProperty,uint32_t & screenWidth,uint32_t & screenHeight)1317 bool SceneSession::GetScreenWidthAndHeightFromServer(const sptr<WindowSessionProperty>& sessionProperty,
1318     uint32_t& screenWidth, uint32_t& screenHeight)
1319 {
1320     const auto& screenSession = sessionProperty == nullptr ? nullptr :
1321         ScreenSessionManagerClient::GetInstance().GetScreenSession(sessionProperty->GetDisplayId());
1322     if (screenSession != nullptr) {
1323         screenWidth = screenSession->GetScreenProperty().GetBounds().rect_.width_;
1324         screenHeight = screenSession->GetScreenProperty().GetBounds().rect_.height_;
1325     } else {
1326         TLOGI(WmsLogTag::WMS_KEYBOARD, "sessionProperty or screenSession is nullptr, use defaultDisplayInfo");
1327         auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
1328         if (defaultDisplayInfo != nullptr) {
1329             screenWidth = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
1330             screenHeight = static_cast<uint32_t>(defaultDisplayInfo->GetHeight());
1331         } else {
1332             TLOGE(WmsLogTag::WMS_KEYBOARD, "defaultDisplayInfo is null, get screenWidthAndHeight failed");
1333             return false;
1334         }
1335     }
1336     if (IsSystemKeyboard() && PcFoldScreenManager::GetInstance().IsHalfFolded(GetScreenId())) {
1337         const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
1338             PcFoldScreenManager::GetInstance().GetDisplayRects();
1339         screenHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
1340         TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d, virtual display posY: %{public}d, height: %{public}d",
1341             GetPersistentId(), virtualDisplayRect.posY_, virtualDisplayRect.height_);
1342     }
1343     TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
1344     return true;
1345 }
1346 
GetScreenWidthAndHeightFromClient(const sptr<WindowSessionProperty> & sessionProperty,uint32_t & screenWidth,uint32_t & screenHeight)1347 bool SceneSession::GetScreenWidthAndHeightFromClient(const sptr<WindowSessionProperty>& sessionProperty,
1348     uint32_t& screenWidth, uint32_t& screenHeight)
1349 {
1350     auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
1351     if (defaultDisplayInfo != nullptr) {
1352         screenWidth = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
1353         screenHeight = static_cast<uint32_t>(defaultDisplayInfo->GetHeight());
1354     } else {
1355         TLOGE(WmsLogTag::WMS_KEYBOARD, "defaultDisplayInfo is null, get screenWidthAndHeight failed");
1356         return false;
1357     }
1358     if (IsSystemKeyboard() && PcFoldScreenManager::GetInstance().IsHalfFolded(GetScreenId())) {
1359         const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
1360             PcFoldScreenManager::GetInstance().GetDisplayRects();
1361         screenHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
1362         TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d, virtual display posY: %{public}d, height: %{public}d",
1363             GetPersistentId(), virtualDisplayRect.posY_, virtualDisplayRect.height_);
1364     }
1365     TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
1366     return true;
1367 }
1368 
SetSessionRectChangeCallback(const NotifySessionRectChangeFunc & func)1369 void SceneSession::SetSessionRectChangeCallback(const NotifySessionRectChangeFunc& func)
1370 {
1371     PostTask([weakThis = wptr(this), func, where = __func__] {
1372         auto session = weakThis.promote();
1373         if (!session) {
1374             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1375             return WSError::WS_ERROR_DESTROYED_OBJECT;
1376         }
1377         session->sessionRectChangeFunc_ = func;
1378         if (session->sessionRectChangeFunc_ && session->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1379             auto reason = SizeChangeReason::UNDEFINED;
1380             auto rect = session->GetSessionRequestRect();
1381             if (rect.width_ == 0 && rect.height_ == 0) {
1382                 reason = SizeChangeReason::MOVE;
1383             }
1384             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s, winName:%{public}s, reason:%{public}d, rect:%{public}s",
1385                 where, session->GetWindowName().c_str(), reason, rect.ToString().c_str());
1386             auto rectAnimationConfig = session->GetRequestRectAnimationConfig();
1387             session->sessionRectChangeFunc_(rect, reason, DISPLAY_ID_INVALID, rectAnimationConfig);
1388         }
1389         return WSError::WS_OK;
1390     }, __func__);
1391 }
1392 
SetSessionDisplayIdChangeCallback(NotifySessionDisplayIdChangeFunc && func)1393 void SceneSession::SetSessionDisplayIdChangeCallback(NotifySessionDisplayIdChangeFunc&& func)
1394 {
1395     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1396         auto session = weakThis.promote();
1397         if (!session || !func) {
1398             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session or display id is null", where);
1399             return;
1400         }
1401         session->sessionDisplayIdChangeFunc_ = std::move(func);
1402     }, __func__);
1403 }
1404 
SetMainWindowTopmostChangeCallback(NotifyMainWindowTopmostChangeFunc && func)1405 void SceneSession::SetMainWindowTopmostChangeCallback(NotifyMainWindowTopmostChangeFunc&& func)
1406 {
1407     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1408         auto session = weakThis.promote();
1409         if (!session || !func) {
1410             TLOGNE(WmsLogTag::WMS_HIERARCHY, "%{public}s session or func is null", where);
1411             return;
1412         }
1413         session->mainWindowTopmostChangeFunc_ = std::move(func);
1414     }, __func__);
1415 }
1416 
SetTitleAndDockHoverShowChangeCallback(NotifyTitleAndDockHoverShowChangeFunc && func)1417 void SceneSession::SetTitleAndDockHoverShowChangeCallback(NotifyTitleAndDockHoverShowChangeFunc&& func)
1418 {
1419     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1420         auto session = weakThis.promote();
1421         if (!session || !func) {
1422             TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session or TitleAndDockHoverShowChangeFunc is null", where);
1423             return;
1424         }
1425         session->onTitleAndDockHoverShowChangeFunc_ = std::move(func);
1426         TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s id: %{public}d",
1427             where, session->GetPersistentId());
1428     }, __func__);
1429 }
1430 
SetRestoreMainWindowCallback(NotifyRestoreMainWindowFunc && func)1431 void SceneSession::SetRestoreMainWindowCallback(NotifyRestoreMainWindowFunc&& func)
1432 {
1433     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
1434         auto session = weakThis.promote();
1435         if (!session || !func) {
1436             TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session or RestoreMainWindowFunc is null", where);
1437             return;
1438         }
1439         session->onRestoreMainWindowFunc_ = std::move(func);
1440         TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s id: %{public}d",
1441             where, session->GetPersistentId());
1442     }, __func__);
1443 }
1444 
SetAdjustKeyboardLayoutCallback(const NotifyKeyboardLayoutAdjustFunc & func)1445 void SceneSession::SetAdjustKeyboardLayoutCallback(const NotifyKeyboardLayoutAdjustFunc& func)
1446 {
1447     PostTask([weakThis = wptr(this), func, where = __func__] {
1448         auto session = weakThis.promote();
1449         if (!session || !func) {
1450             TLOGNE(WmsLogTag::WMS_KEYBOARD, "%{public}s session or keyboardLayoutFunc is null", where);
1451             return WSError::WS_ERROR_DESTROYED_OBJECT;
1452         }
1453         session->adjustKeyboardLayoutFunc_ = func;
1454         auto property = session->GetSessionProperty();
1455         if (property == nullptr) {
1456             TLOGNE(WmsLogTag::WMS_KEYBOARD, "%{public}s property is null", where);
1457             return WSError::WS_ERROR_DESTROYED_OBJECT;
1458         }
1459         KeyboardLayoutParams params = property->GetKeyboardLayoutParams();
1460         session->adjustKeyboardLayoutFunc_(params);
1461         TLOGNI(WmsLogTag::WMS_KEYBOARD,
1462             "%{public}s Notify adjust keyboard layout when register, keyboardId: %{public}d, "
1463             "gravity: %{public}u, landscapeAvoidHeight: %{public}d, PortraitAvoidHeight: %{public}d, "
1464             "LandscapeKeyboardRect: %{public}s, PortraitKeyboardRect: %{public}s, "
1465             "LandscapePanelRect: %{public}s, PortraitPanelRect: %{public}s", where, session->GetPersistentId(),
1466             static_cast<uint32_t>(params.gravity_), params.landscapeAvoidHeight_, params.portraitAvoidHeight_,
1467             params.LandscapeKeyboardRect_.ToString().c_str(), params.PortraitKeyboardRect_.ToString().c_str(),
1468             params.LandscapePanelRect_.ToString().c_str(), params.PortraitPanelRect_.ToString().c_str());
1469         return WSError::WS_OK;
1470     }, __func__);
1471 }
1472 
SetSessionPiPControlStatusChangeCallback(const NotifySessionPiPControlStatusChangeFunc & func)1473 void SceneSession::SetSessionPiPControlStatusChangeCallback(const NotifySessionPiPControlStatusChangeFunc& func)
1474 {
1475     PostTask([weakThis = wptr(this), func, where = __func__] {
1476         auto session = weakThis.promote();
1477         if (!session) {
1478             TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
1479             return WSError::WS_ERROR_DESTROYED_OBJECT;
1480         }
1481         session->sessionPiPControlStatusChangeFunc_ = func;
1482         return WSError::WS_OK;
1483     }, __func__);
1484 }
1485 
SetAutoStartPiPStatusChangeCallback(const NotifyAutoStartPiPStatusChangeFunc & func)1486 void SceneSession::SetAutoStartPiPStatusChangeCallback(const NotifyAutoStartPiPStatusChangeFunc& func)
1487 {
1488     PostTask([weakThis = wptr(this), func, where = __func__] {
1489         auto session = weakThis.promote();
1490         if (!session) {
1491             TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
1492             return;
1493         }
1494         session->autoStartPiPStatusChangeFunc_ = func;
1495     }, __func__);
1496 }
1497 
1498 /** @note @window.layout */
UpdateSessionRectInner(const WSRect & rect,SizeChangeReason reason,const MoveConfiguration & moveConfiguration,const RectAnimationConfig & rectAnimationConfig)1499 void SceneSession::UpdateSessionRectInner(const WSRect& rect, SizeChangeReason reason,
1500     const MoveConfiguration& moveConfiguration, const RectAnimationConfig& rectAnimationConfig)
1501 {
1502     auto newWinRect = winRect_;
1503     auto newRequestRect = GetSessionRequestRect();
1504     SizeChangeReason newReason = reason;
1505     if (reason == SizeChangeReason::MOVE || reason == SizeChangeReason::MOVE_WITH_ANIMATION) {
1506         newWinRect.posX_ = rect.posX_;
1507         newWinRect.posY_ = rect.posY_;
1508         newRequestRect.posX_ = rect.posX_;
1509         newRequestRect.posY_ = rect.posY_;
1510         if (!Session::IsScbCoreEnabled() && !WindowHelper::IsMainWindow(GetWindowType())) {
1511             SetSessionRect(newWinRect);
1512         }
1513         SetSessionRequestRect(newRequestRect);
1514         SetRequestRectAnimationConfig(moveConfiguration.rectAnimationConfig);
1515         NotifySessionRectChange(newRequestRect, reason, moveConfiguration.displayId,
1516             moveConfiguration.rectAnimationConfig);
1517     } else if (reason == SizeChangeReason::RESIZE || reason == SizeChangeReason::RESIZE_WITH_ANIMATION) {
1518         if (rect.width_ > 0 && rect.height_ > 0) {
1519             newWinRect.width_ = rect.width_;
1520             newWinRect.height_ = rect.height_;
1521             newRequestRect.width_ = rect.width_;
1522             newRequestRect.height_ = rect.height_;
1523         }
1524         if (!Session::IsScbCoreEnabled() && GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1525             SetSessionRect(newWinRect);
1526         }
1527         SetRequestRectAnimationConfig(rectAnimationConfig);
1528         DisplayId displayId = GetSessionProperty() != nullptr ? GetSessionProperty()->GetDisplayId() :
1529             DISPLAY_ID_INVALID;
1530         TLOGI(WmsLogTag::WMS_LAYOUT, "Get displayId: %{public}" PRIu64, displayId);
1531         auto notifyRect = newRequestRect;
1532         if (PcFoldScreenManager::GetInstance().IsHalfFolded(GetScreenId())) {
1533             newReason = SizeChangeReason::UNDEFINED;
1534             notifyRect = rect;
1535         }
1536         SetSessionRequestRect(notifyRect);
1537         NotifySessionRectChange(notifyRect, newReason, displayId, rectAnimationConfig);
1538     } else {
1539         if (!Session::IsScbCoreEnabled()) {
1540             SetSessionRect(rect);
1541         }
1542         NotifySessionRectChange(rect, reason);
1543     }
1544     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d reason:%{public}d newReason:%{public}d moveConfiguration:%{public}s "
1545         "rect:%{public}s newRequestRect:%{public}s newWinRect:%{public}s", GetPersistentId(), reason, newReason,
1546         moveConfiguration.ToString().c_str(), rect.ToString().c_str(), newRequestRect.ToString().c_str(),
1547         newWinRect.ToString().c_str());
1548 }
1549 
UpdateSessionRectPosYFromClient(SizeChangeReason reason,DisplayId & configDisplayId,WSRect & rect)1550 void SceneSession::UpdateSessionRectPosYFromClient(SizeChangeReason reason, DisplayId& configDisplayId, WSRect& rect)
1551 {
1552     if (!PcFoldScreenManager::GetInstance().IsHalfFolded(GetScreenId())) {
1553         TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, displayId: %{public}" PRIu64,
1554             GetPersistentId(), GetScreenId());
1555         return;
1556     }
1557     TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, reason: %{public}u, lastRect: %{public}s, currRect: %{public}s",
1558         GetPersistentId(), reason, winRect_.ToString().c_str(), rect.ToString().c_str());
1559     if (reason != SizeChangeReason::RESIZE) {
1560         configDisplayId_ = configDisplayId;
1561     }
1562     if (configDisplayId_ != DISPLAY_ID_INVALID &&
1563         !PcFoldScreenManager::GetInstance().IsPcFoldScreen(configDisplayId_)) {
1564         TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, configDisplayId: %{public}" PRIu64,
1565             GetPersistentId(), configDisplayId_);
1566         return;
1567     }
1568     auto clientDisplayId = clientDisplayId_;
1569     TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, input: %{public}s, screenId: %{public}" PRIu64
1570         ", clientDisplayId: %{public}" PRIu64 ", configDisplayId: %{public}" PRIu64,
1571         GetPersistentId(), rect.ToString().c_str(), GetScreenId(), clientDisplayId, configDisplayId_);
1572     if (configDisplayId_ != VIRTUAL_DISPLAY_ID && clientDisplayId != VIRTUAL_DISPLAY_ID) {
1573         return;
1574     }
1575     const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
1576         PcFoldScreenManager::GetInstance().GetDisplayRects();
1577     rect.posY_ += defaultDisplayRect.height_ + foldCreaseRect.height_;
1578     configDisplayId = DEFAULT_DISPLAY_ID;
1579     TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}d, output: %{public}s", GetPersistentId(), rect.ToString().c_str());
1580 }
1581 
1582 /** @note @window.layout */
UpdateSessionRect(const WSRect & rect,SizeChangeReason reason,bool isGlobal,bool isFromMoveToGlobal,const MoveConfiguration & moveConfiguration,const RectAnimationConfig & rectAnimationConfig)1583 WSError SceneSession::UpdateSessionRect(
1584     const WSRect& rect, SizeChangeReason reason, bool isGlobal, bool isFromMoveToGlobal,
1585     const MoveConfiguration& moveConfiguration, const RectAnimationConfig& rectAnimationConfig)
1586 {
1587     bool isMoveOrResize = reason == SizeChangeReason::MOVE || reason == SizeChangeReason::RESIZE ||
1588         reason == SizeChangeReason::MOVE_WITH_ANIMATION || reason == SizeChangeReason::RESIZE_WITH_ANIMATION;
1589     if (isMoveOrResize && GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1590         return WSError::WS_DO_NOTHING;
1591     }
1592     WSRect newRect = rect;
1593     MoveConfiguration newMoveConfiguration = moveConfiguration;
1594     UpdateSessionRectPosYFromClient(reason, newMoveConfiguration.displayId, newRect);
1595     if (isGlobal && WindowHelper::IsSubWindow(Session::GetWindowType()) &&
1596         (systemConfig_.IsPhoneWindow() ||
1597          (systemConfig_.IsPadWindow() && !IsFreeMultiWindowMode()))) {
1598         auto parentSession = GetParentSession();
1599         if (parentSession) {
1600             auto parentRect = parentSession->GetSessionRect();
1601             if (!CheckIfRectElementIsTooLarge(parentRect)) {
1602                 newRect.posX_ -= parentRect.posX_;
1603                 newRect.posY_ -= parentRect.posY_;
1604             }
1605         }
1606     }
1607     if (isFromMoveToGlobal && WindowHelper::IsSubWindow(Session::GetWindowType()) &&
1608         (systemConfig_.IsPhoneWindow() ||
1609          (systemConfig_.IsPadWindow() && !IsFreeMultiWindowMode()))) {
1610         auto parentSession = GetParentSession();
1611         if (parentSession && parentSession->GetFloatingScale() != 0) {
1612             Rect parentGlobalRect;
1613             WMError errorCode = parentSession->GetGlobalScaledRect(parentGlobalRect);
1614             newRect.posX_ = (newRect.posX_ - parentGlobalRect.posX_) / parentSession->GetFloatingScale();
1615             newRect.posY_ = (newRect.posY_ - parentGlobalRect.posY_) / parentSession->GetFloatingScale();
1616         }
1617     }
1618     Session::RectCheckProcess();
1619     PostTask([weakThis = wptr(this), newRect, reason, newMoveConfiguration, rectAnimationConfig, where = __func__] {
1620         auto session = weakThis.promote();
1621         if (!session) {
1622             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
1623             return WSError::WS_ERROR_DESTROYED_OBJECT;
1624         }
1625         session->UpdateSessionRectInner(newRect, reason, newMoveConfiguration, rectAnimationConfig);
1626         return WSError::WS_OK;
1627     }, __func__ + GetRectInfo(rect));
1628     return WSError::WS_OK;
1629 }
1630 
UpdateCrossAxisOfLayout(const WSRect & rect)1631 void SceneSession::UpdateCrossAxisOfLayout(const WSRect& rect)
1632 {
1633     const int FOLD_CREASE_TYPE = 2;
1634     isCrossAxisOfLayout_ = rect.IsOverlap(std::get<FOLD_CREASE_TYPE>(
1635         PcFoldScreenManager::GetInstance().GetDisplayRects()));
1636     UpdateCrossAxis();
1637 }
1638 
UpdateCrossAxis()1639 void SceneSession::UpdateCrossAxis()
1640 {
1641     CrossAxisState crossAxisState = CrossAxisState::STATE_INVALID;
1642     if (PcFoldScreenManager::GetInstance().GetDisplayId() == SCREEN_ID_INVALID ||
1643         PcFoldScreenManager::GetInstance().GetDisplayId() != GetSessionProperty()->GetDisplayId()) {
1644         return;
1645     }
1646     if (PcFoldScreenManager::GetInstance().GetScreenFoldStatus() != SuperFoldStatus::UNKNOWN) {
1647         if (PcFoldScreenManager::GetInstance().GetScreenFoldStatus() == SuperFoldStatus::HALF_FOLDED &&
1648             isCrossAxisOfLayout_) {
1649             crossAxisState = CrossAxisState::STATE_CROSS;
1650         } else {
1651             crossAxisState = CrossAxisState::STATE_NO_CROSS;
1652         }
1653     }
1654     if (crossAxisState_ != static_cast<uint32_t>(crossAxisState) && sessionStage_ != nullptr) {
1655         crossAxisState_ = static_cast<uint32_t>(crossAxisState);
1656         sessionStage_->NotifyWindowCrossAxisChange(crossAxisState);
1657     } else if (sessionStage_ == nullptr) {
1658         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sessionStage_ is nullptr, id: %{public}d", GetPersistentId());
1659     }
1660 }
1661 
GetCrossAxisState(CrossAxisState & state)1662 WSError SceneSession::GetCrossAxisState(CrossAxisState& state)
1663 {
1664     state = static_cast<CrossAxisState>(crossAxisState_.load());
1665     return WSError::WS_OK;
1666 }
1667 
1668 /** @note @window.layout */
UpdateClientRect(const WSRect & rect)1669 WSError SceneSession::UpdateClientRect(const WSRect& rect)
1670 {
1671     PostTask([weakThis = wptr(this), rect, funcName = __func__] {
1672         auto session = weakThis.promote();
1673         if (!session) {
1674             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", funcName);
1675             return;
1676         }
1677         if (rect.IsInvalid()) {
1678             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d rect:%{public}s is invalid",
1679                 funcName, session->GetPersistentId(), rect.ToString().c_str());
1680             return;
1681         }
1682         if (rect == session->GetClientRect()) {
1683             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d skip same rect",
1684                 funcName, session->GetPersistentId());
1685             return;
1686         }
1687         session->SetClientRect(rect);
1688     }, __func__ + GetRectInfo(rect));
1689     return WSError::WS_OK;
1690 }
1691 
NotifySingleHandTransformChange(const SingleHandTransform & singleHandTransform)1692 void SceneSession::NotifySingleHandTransformChange(const SingleHandTransform& singleHandTransform)
1693 {
1694     if (!IsSessionForeground() && !IsVisible()) {
1695         TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, session is not foreground and not visible!", GetPersistentId());
1696         return;
1697     }
1698     if (sessionStage_ != nullptr) {
1699         sessionStage_->NotifySingleHandTransformChange(singleHandTransform);
1700     }
1701 }
1702 
RegisterRaiseToTopCallback(NotifyRaiseToTopFunc && callback)1703 void SceneSession::RegisterRaiseToTopCallback(NotifyRaiseToTopFunc&& callback)
1704 {
1705     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1706         auto session = weakThis.promote();
1707         if (!session) {
1708             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1709             return;
1710         }
1711         session->onRaiseToTop_ = std::move(callback);
1712     }, __func__);
1713 }
1714 
RegisterRaiseAboveTargetCallback(NotifyRaiseAboveTargetFunc && callback)1715 void SceneSession::RegisterRaiseAboveTargetCallback(NotifyRaiseAboveTargetFunc&& callback)
1716 {
1717     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1718         auto session = weakThis.promote();
1719         if (!session) {
1720             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1721             return;
1722         }
1723         session->onRaiseAboveTarget_ = std::move(callback);
1724     }, __func__);
1725 }
1726 
RegisterSessionTopmostChangeCallback(NotifySessionTopmostChangeFunc && callback)1727 void SceneSession::RegisterSessionTopmostChangeCallback(NotifySessionTopmostChangeFunc&& callback)
1728 {
1729     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1730         auto session = weakThis.promote();
1731         if (!session) {
1732             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1733             return;
1734         }
1735         session->onSessionTopmostChange_ = std::move(callback);
1736         session->onSessionTopmostChange_(session->IsTopmost());
1737     }, __func__);
1738 }
1739 
1740 /** @note @window.hierarchy */
RegisterSubSessionZLevelChangeCallback(NotifySubSessionZLevelChangeFunc && callback)1741 void SceneSession::RegisterSubSessionZLevelChangeCallback(NotifySubSessionZLevelChangeFunc&& callback)
1742 {
1743     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
1744         auto session = weakThis.promote();
1745         if (!session) {
1746             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1747             return;
1748         }
1749         session->onSubSessionZLevelChange_ = std::move(callback);
1750         session->onSubSessionZLevelChange_(session->GetSubWindowZLevel());
1751     }, __func__);
1752 }
1753 
1754 /** @note @window.hierarchy */
RaiseToAppTop()1755 WSError SceneSession::RaiseToAppTop()
1756 {
1757     return PostSyncTask([weakThis = wptr(this), where = __func__] {
1758         auto session = weakThis.promote();
1759         if (!session) {
1760             TLOGNE(WmsLogTag::WMS_HIERARCHY, "%{public}s session is null", where);
1761             return WSError::WS_ERROR_DESTROYED_OBJECT;
1762         }
1763         if (session->onRaiseToTop_) {
1764             TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s id: %{public}d", where, session->GetPersistentId());
1765             session->onRaiseToTop_();
1766             session->SetMainSessionUIStateDirty(true);
1767         }
1768         return WSError::WS_OK;
1769     }, __func__);
1770 }
1771 
1772 /** @note @window.hierarchy */
RaiseAboveTarget(int32_t subWindowId)1773 WSError SceneSession::RaiseAboveTarget(int32_t subWindowId)
1774 {
1775     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1776         WLOGFE("RaiseAboveTarget permission denied!");
1777         return WSError::WS_ERROR_NOT_SYSTEM_APP;
1778     }
1779     auto subSession = std::find_if(subSession_.begin(), subSession_.end(), [subWindowId](sptr<SceneSession> session) {
1780         bool res = (session != nullptr && session->GetWindowId() == subWindowId) ? true : false;
1781         return res;
1782     });
1783     int32_t callingPid = IPCSkeleton::GetCallingPid();
1784     if (subSession != subSession_.end() && callingPid != (*subSession)->GetCallingPid()) {
1785         TLOGE(WmsLogTag::WMS_HIERARCHY, "permission denied! id: %{public}d", subWindowId);
1786         return WSError::WS_ERROR_INVALID_CALLING;
1787     }
1788     return PostSyncTask([weakThis = wptr(this), subWindowId, where = __func__] {
1789         auto session = weakThis.promote();
1790         if (!session) {
1791             TLOGNE(WmsLogTag::WMS_HIERARCHY, "%{public}s session is null", where);
1792             return WSError::WS_ERROR_DESTROYED_OBJECT;
1793         }
1794         if (session->onRaiseAboveTarget_) {
1795             session->onRaiseAboveTarget_(subWindowId);
1796         }
1797         return WSError::WS_OK;
1798     }, __func__);
1799 }
1800 
BindDialogSessionTarget(const sptr<SceneSession> & sceneSession)1801 WSError SceneSession::BindDialogSessionTarget(const sptr<SceneSession>& sceneSession)
1802 {
1803     if (sceneSession == nullptr) {
1804         TLOGE(WmsLogTag::WMS_DIALOG, "dialog session is null");
1805         return WSError::WS_ERROR_NULLPTR;
1806     }
1807     if (onBindDialogTarget_) {
1808         TLOGI(WmsLogTag::WMS_DIALOG, "id: %{public}d", sceneSession->GetPersistentId());
1809         onBindDialogTarget_(sceneSession);
1810     }
1811     return WSError::WS_OK;
1812 }
1813 
SetSystemBarProperty(WindowType type,SystemBarProperty systemBarProperty)1814 WSError SceneSession::SetSystemBarProperty(WindowType type, SystemBarProperty systemBarProperty)
1815 {
1816     TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u type %{public}u "
1817         "%{public}u %{public}x %{public}x %{public}u settingFlag %{public}u",
1818         GetPersistentId(), static_cast<uint32_t>(type),
1819         systemBarProperty.enable_, systemBarProperty.backgroundColor_, systemBarProperty.contentColor_,
1820         systemBarProperty.enableAnimation_, systemBarProperty.settingFlag_);
1821     auto property = GetSessionProperty();
1822     property->SetSystemBarProperty(type, systemBarProperty);
1823     if (type == WindowType::WINDOW_TYPE_STATUS_BAR && systemBarProperty.enable_) {
1824         SetIsDisplayStatusBarTemporarily(false);
1825     }
1826     if (onSystemBarPropertyChange_) {
1827         onSystemBarPropertyChange_(property->GetSystemBarProperty());
1828     }
1829     return WSError::WS_OK;
1830 }
1831 
SetIsStatusBarVisible(bool isVisible)1832 void SceneSession::SetIsStatusBarVisible(bool isVisible)
1833 {
1834     PostTask([weakThis = wptr(this), isVisible, where = __func__] {
1835         sptr<SceneSession> sceneSession = weakThis.promote();
1836         if (sceneSession == nullptr) {
1837             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
1838             return;
1839         }
1840         sceneSession->SetIsStatusBarVisibleInner(isVisible);
1841     }, __func__);
1842 }
1843 
SetIsStatusBarVisibleInner(bool isVisible)1844 WSError SceneSession::SetIsStatusBarVisibleInner(bool isVisible)
1845 {
1846     bool isNeedNotify = isStatusBarVisible_ != isVisible;
1847     TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}d, %{public}s] visible %{public}u need notify %{public}u",
1848         GetPersistentId(), GetWindowName().c_str(), isVisible, isNeedNotify);
1849     isStatusBarVisible_ = isVisible;
1850     if (!isNeedNotify) {
1851         return WSError::WS_OK;
1852     }
1853     if (isLastFrameLayoutFinishedFunc_ == nullptr) {
1854         TLOGE(WmsLogTag::WMS_IMMS, "isLastFrameLayoutFinishedFunc is null, win %{public}d", GetPersistentId());
1855         return WSError::WS_ERROR_NULLPTR;
1856     }
1857     bool isLayoutFinished = false;
1858     WSError ret = isLastFrameLayoutFinishedFunc_(isLayoutFinished);
1859     if (ret != WSError::WS_OK) {
1860         TLOGE(WmsLogTag::WMS_IMMS, "isLastFrameLayoutFinishedFunc failed, ret %{public}d", ret);
1861         return ret;
1862     }
1863     if (isLayoutFinished) {
1864         UpdateAvoidArea(new AvoidArea(GetAvoidAreaByType(AvoidAreaType::TYPE_SYSTEM)), AvoidAreaType::TYPE_SYSTEM);
1865     } else {
1866         MarkAvoidAreaAsDirty();
1867     }
1868     return WSError::WS_OK;
1869 }
1870 
NotifyPropertyWhenConnect()1871 void SceneSession::NotifyPropertyWhenConnect()
1872 {
1873     WLOGFI("Notify property when connect.");
1874     auto property = GetSessionProperty();
1875     if (property == nullptr) {
1876         WLOGFD("id: %{public}d property is nullptr", persistentId_);
1877         return;
1878     }
1879     NotifySessionFocusableChange(property->GetFocusable());
1880     NotifySessionTouchableChange(property->GetTouchable());
1881     OnShowWhenLocked(GetShowWhenLockedFlagValue());
1882 }
1883 
1884 /** @note @window.hierarchy */
RaiseAppMainWindowToTop()1885 WSError SceneSession::RaiseAppMainWindowToTop()
1886 {
1887     PostTask([weakThis = wptr(this), where = __func__] {
1888         auto session = weakThis.promote();
1889         if (!session) {
1890             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
1891             return WSError::WS_ERROR_DESTROYED_OBJECT;
1892         }
1893         if (session->IsFocusedOnShow()) {
1894             FocusChangeReason reason = FocusChangeReason::MOVE_UP;
1895             session->NotifyRequestFocusStatusNotifyManager(true, true, reason);
1896             session->NotifyClick(true, false);
1897         } else {
1898             session->SetFocusedOnShow(true);
1899         }
1900         return WSError::WS_OK;
1901     }, __func__);
1902     return WSError::WS_OK;
1903 }
1904 
OnNeedAvoid(bool status)1905 WSError SceneSession::OnNeedAvoid(bool status)
1906 {
1907     PostTask([weakThis = wptr(this), status, where = __func__] {
1908         auto session = weakThis.promote();
1909         if (!session) {
1910             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
1911             return WSError::WS_ERROR_DESTROYED_OBJECT;
1912         }
1913         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d status %{public}d",
1914             where, session->GetPersistentId(), static_cast<int32_t>(status));
1915         if (session->onNeedAvoid_) {
1916             session->onNeedAvoid_(status);
1917         }
1918         return WSError::WS_OK;
1919     }, __func__);
1920     return WSError::WS_OK;
1921 }
1922 
OnShowWhenLocked(bool showWhenLocked)1923 WSError SceneSession::OnShowWhenLocked(bool showWhenLocked)
1924 {
1925     WLOGFD("SceneSession ShowWhenLocked status:%{public}d", static_cast<int32_t>(showWhenLocked));
1926     if (onShowWhenLockedFunc_) {
1927         onShowWhenLockedFunc_(showWhenLocked);
1928     }
1929     return WSError::WS_OK;
1930 }
1931 
IsShowWhenLocked() const1932 bool SceneSession::IsShowWhenLocked() const
1933 {
1934     return (GetSessionProperty()->GetWindowFlags() &
1935         static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) || IsTemporarilyShowWhenLocked();
1936 }
1937 
GetShowWhenLockedFlagValue() const1938 bool SceneSession::GetShowWhenLockedFlagValue() const
1939 {
1940     return GetSessionProperty()->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
1941 }
1942 
CalculateAvoidAreaRect(const WSRect & rect,const WSRect & avoidRect,AvoidArea & avoidArea) const1943 void SceneSession::CalculateAvoidAreaRect(const WSRect& rect, const WSRect& avoidRect, AvoidArea& avoidArea) const
1944 {
1945     if (SessionHelper::IsEmptyRect(rect) || SessionHelper::IsEmptyRect(avoidRect)) {
1946         return;
1947     }
1948     Rect avoidAreaRect = SessionHelper::TransferToRect(
1949         SessionHelper::GetOverlap(rect, avoidRect, rect.posX_, rect.posY_));
1950     if (WindowHelper::IsEmptyRect(avoidAreaRect)) {
1951         return;
1952     }
1953 
1954     uint32_t avoidAreaCenterX = static_cast<uint32_t>(avoidAreaRect.posX_) + (avoidAreaRect.width_ >> 1);
1955     uint32_t avoidAreaCenterY = static_cast<uint32_t>(avoidAreaRect.posY_) + (avoidAreaRect.height_ >> 1);
1956     float res1 = float(avoidAreaCenterY) - float(rect.height_) / float(rect.width_) *
1957         float(avoidAreaCenterX);
1958     float res2 = float(avoidAreaCenterY) + float(rect.height_) / float(rect.width_) *
1959         float(avoidAreaCenterX) - float(rect.height_);
1960     if (res1 < 0) {
1961         if (res2 < 0) {
1962             avoidArea.topRect_ = avoidAreaRect;
1963         } else {
1964             avoidArea.rightRect_ = avoidAreaRect;
1965         }
1966     } else {
1967         if (res2 < 0) {
1968             avoidArea.leftRect_ = avoidAreaRect;
1969         } else {
1970             avoidArea.bottomRect_ = avoidAreaRect;
1971         }
1972     }
1973 }
1974 
GetSystemAvoidArea(WSRect & rect,AvoidArea & avoidArea)1975 void SceneSession::GetSystemAvoidArea(WSRect& rect, AvoidArea& avoidArea)
1976 {
1977     auto sessionProperty = GetSessionProperty();
1978     bool isNeedAvoid = sessionProperty->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID);
1979     if (isNeedAvoid && WindowHelper::IsAppWindow(GetWindowType())) {
1980         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d type %{public}u flag %{public}d",
1981             GetPersistentId(), static_cast<uint32_t>(GetWindowType()), sessionProperty->GetWindowFlags());
1982         return;
1983     }
1984     if (sessionProperty->GetCompatibleModeInPc()) {
1985         HookAvoidAreaInCompatibleMode(rect, avoidArea, AvoidAreaType::TYPE_SYSTEM);
1986         return;
1987     }
1988     WindowMode windowMode = Session::GetWindowMode();
1989     bool isWindowFloatingOrSplit = windowMode == WindowMode::WINDOW_MODE_FLOATING ||
1990                                    windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1991                                    windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY;
1992     WindowType windowType = Session::GetWindowType();
1993     bool isAvailableSystemWindow = WindowHelper::IsSystemWindow(windowType) &&
1994         (GetSessionProperty()->GetAvoidAreaOption() & static_cast<uint32_t>(AvoidAreaOption::ENABLE_SYSTEM_WINDOW));
1995     bool isAvailableAppSubWindow = WindowHelper::IsSubWindow(windowType) &&
1996         (GetSessionProperty()->GetAvoidAreaOption() & static_cast<uint32_t>(AvoidAreaOption::ENABLE_APP_SUB_WINDOW));
1997     bool isAvailableWindowType = WindowHelper::IsMainWindow(windowType) || isAvailableSystemWindow ||
1998                                  isAvailableAppSubWindow;
1999     bool isAvailableDevice = systemConfig_.IsPhoneWindow() ||
2000                              (systemConfig_.IsPadWindow() && !IsFreeMultiWindowMode());
2001     DisplayId displayId = sessionProperty->GetDisplayId();
2002     auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
2003     bool isAvailableScreen = !screenSession || (screenSession->GetName() != "HiCar");
2004     if (isWindowFloatingOrSplit && isAvailableWindowType && isAvailableDevice && isAvailableScreen) {
2005         // mini floating scene no need avoid
2006         if (LessOrEqual(Session::GetFloatingScale(), MINI_FLOAT_SCALE)) {
2007             return;
2008         }
2009         float vpr = 3.5f; // 3.5f: default pixel ratio
2010         auto display = DisplayManager::GetInstance().GetDefaultDisplay();
2011         if (display == nullptr) {
2012             WLOGFE("display is null");
2013             return;
2014         }
2015         vpr = display->GetVirtualPixelRatio();
2016         bool isFloat = windowMode == WindowMode::WINDOW_MODE_FLOATING && !GetIsMidScene();
2017         int32_t height = isFloat ? GetStatusBarHeight() : vpr * MULTI_WINDOW_TITLE_BAR_DEFAULT_HEIGHT_VP;
2018         avoidArea.topRect_.height_ = static_cast<uint32_t>(height);
2019         avoidArea.topRect_.width_ = static_cast<uint32_t>(display->GetWidth());
2020         return;
2021     }
2022     std::vector<sptr<SceneSession>> statusBarVector;
2023     if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_) {
2024         statusBarVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
2025             WindowType::WINDOW_TYPE_STATUS_BAR, sessionProperty->GetDisplayId());
2026     }
2027     for (auto& statusBar : statusBarVector) {
2028         if (statusBar == nullptr) {
2029             continue;
2030         }
2031         bool isVisible = statusBar->isVisible_;
2032         if (onGetStatusBarConstantlyShowFunc_) {
2033             onGetStatusBarConstantlyShowFunc_(displayId, isVisible);
2034             TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d displayId %{public}" PRIu64 " constantly isVisible %{public}d",
2035                 GetPersistentId(), displayId, isVisible);
2036         }
2037         bool isStatusBarVisible = WindowHelper::IsMainWindow(Session::GetWindowType()) ?
2038             isStatusBarVisible_ : isVisible;
2039         if (!isStatusBarVisible) {
2040             TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d status bar not visible", GetPersistentId());
2041             continue;
2042         }
2043         WSRect statusBarRect = statusBar->GetSessionRect();
2044         if (onGetStatusBarAvoidHeightFunc_) {
2045             onGetStatusBarAvoidHeightFunc_(statusBarRect);
2046             TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d status bar height %{public}d",
2047                 GetPersistentId(), statusBarRect.height_);
2048         }
2049         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d rect %{public}s status bar %{public}s",
2050             GetPersistentId(), rect.ToString().c_str(), statusBarRect.ToString().c_str());
2051         CalculateAvoidAreaRect(rect, statusBarRect, avoidArea);
2052     }
2053     return;
2054 }
2055 
GetKeyboardAvoidArea(WSRect & rect,AvoidArea & avoidArea)2056 void SceneSession::GetKeyboardAvoidArea(WSRect& rect, AvoidArea& avoidArea)
2057 {
2058     if (!keyboardAvoidAreaActive_) {
2059         TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d, isSystemKeyboard: %{public}d, state: %{public}d, "
2060             "gravity: %{public}d", GetPersistentId(), IsSystemKeyboard(), GetSessionState(), GetKeyboardGravity());
2061         return;
2062     }
2063     if (Session::CheckEmptyKeyboardAvoidAreaIfNeeded()) {
2064         TLOGD(WmsLogTag::WMS_IMMS, "Keyboard avoid area needs to be empty in floating mode");
2065         return;
2066     }
2067     std::vector<sptr<SceneSession>> inputMethodVector;
2068     if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByType_) {
2069         inputMethodVector = specificCallback_->onGetSceneSessionVectorByType_(
2070             WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
2071     }
2072     for (auto& inputMethod : inputMethodVector) {
2073         if (inputMethod->GetSessionState() != SessionState::STATE_FOREGROUND &&
2074             inputMethod->GetSessionState() != SessionState::STATE_ACTIVE) {
2075             continue;
2076         }
2077         SessionGravity gravity = inputMethod->GetKeyboardGravity();
2078         if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT || !inputMethod->IsKeyboardAvoidAreaActive()) {
2079             continue;
2080         }
2081         if (isKeyboardPanelEnabled_) {
2082             WSRect keyboardRect = {0, 0, 0, 0};
2083             if (inputMethod && inputMethod->GetKeyboardPanelSession()) {
2084                 keyboardRect = inputMethod->GetKeyboardPanelSession()->GetSessionRect();
2085                 inputMethod->RecalculatePanelRectForAvoidArea(keyboardRect);
2086             }
2087             TLOGI(WmsLogTag::WMS_IMMS, "win %{public}s keyboard %{public}s",
2088                   rect.ToString().c_str(), keyboardRect.ToString().c_str());
2089             CalculateAvoidAreaRect(rect, keyboardRect, avoidArea);
2090         } else {
2091             WSRect inputMethodRect = inputMethod->GetSessionRect();
2092             TLOGI(WmsLogTag::WMS_IMMS, "win %{public}s input method %{public}s",
2093                   rect.ToString().c_str(), inputMethodRect.ToString().c_str());
2094             CalculateAvoidAreaRect(rect, inputMethodRect, avoidArea);
2095         }
2096     }
2097     return;
2098 }
2099 
GetCutoutAvoidArea(WSRect & rect,AvoidArea & avoidArea)2100 void SceneSession::GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea)
2101 {
2102     auto display = DisplayManager::GetInstance().GetDisplayById(GetSessionProperty()->GetDisplayId());
2103     if (display == nullptr) {
2104         TLOGE(WmsLogTag::WMS_IMMS, "Failed to get display");
2105         return;
2106     }
2107     sptr<CutoutInfo> cutoutInfo = display->GetCutoutInfo();
2108     if (cutoutInfo == nullptr) {
2109         TLOGI(WmsLogTag::WMS_IMMS, "There is no cutout info");
2110         return;
2111     }
2112     std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
2113     if (cutoutAreas.empty()) {
2114         TLOGI(WmsLogTag::WMS_IMMS, "There is no cutout area");
2115         return;
2116     }
2117     for (auto& cutoutArea : cutoutAreas) {
2118         WSRect cutoutAreaRect = {
2119             cutoutArea.posX_,
2120             cutoutArea.posY_,
2121             cutoutArea.width_,
2122             cutoutArea.height_
2123         };
2124         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}s cutout %{public}s",
2125               rect.ToString().c_str(), cutoutAreaRect.ToString().c_str());
2126         CalculateAvoidAreaRect(rect, cutoutAreaRect, avoidArea);
2127     }
2128 
2129     return;
2130 }
2131 
GetAINavigationBarArea(WSRect rect,AvoidArea & avoidArea) const2132 void SceneSession::GetAINavigationBarArea(WSRect rect, AvoidArea& avoidArea) const
2133 {
2134     if (isDisplayStatusBarTemporarily_.load()) {
2135         TLOGD(WmsLogTag::WMS_IMMS, "temporary show navigation bar, no need to avoid");
2136         return;
2137     }
2138     if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
2139         TLOGD(WmsLogTag::WMS_IMMS, "window mode pip return");
2140         return;
2141     }
2142     // compatibleMode app need to hook avoidArea in pc
2143     if (GetSessionProperty()->GetCompatibleModeInPc()) {
2144         HookAvoidAreaInCompatibleMode(rect, avoidArea, AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
2145         return;
2146     }
2147     WSRect barArea;
2148     if (specificCallback_ != nullptr && specificCallback_->onGetAINavigationBarArea_) {
2149         barArea = specificCallback_->onGetAINavigationBarArea_(GetSessionProperty()->GetDisplayId());
2150     }
2151     TLOGI(WmsLogTag::WMS_IMMS, "win %{public}s AI bar %{public}s",
2152           rect.ToString().c_str(), barArea.ToString().c_str());
2153     CalculateAvoidAreaRect(rect, barArea, avoidArea);
2154 }
2155 
HookAvoidAreaInCompatibleMode(WSRect & rect,AvoidArea & avoidArea,AvoidAreaType avoidAreaType) const2156 void SceneSession::HookAvoidAreaInCompatibleMode(WSRect& rect, AvoidArea& avoidArea, AvoidAreaType avoidAreaType) const
2157 {
2158     WindowMode mode = GetWindowMode();
2159     if (!GetSessionProperty()->GetCompatibleModeInPc() || mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2160         TLOGE(WmsLogTag::WMS_PC, "only support compatibleMode app in pc");
2161         return;
2162     }
2163 
2164     float vpr = 3.5f; // 3.5f: default pixel ratio
2165     DMHookInfo hookInfo;
2166     ScreenSessionManagerClient::GetInstance().GetDisplayHookInfo(GetCallingUid(), hookInfo);
2167     if (hookInfo.density_) {
2168         vpr = hookInfo.density_;
2169     }
2170     switch (avoidAreaType) {
2171         case AvoidAreaType::TYPE_SYSTEM: {
2172             avoidArea.topRect_.posX_ = rect.posX_;
2173             avoidArea.topRect_.posY_ = rect.posY_;
2174             avoidArea.topRect_.height_ = HOOK_SYSTEM_BAR_HEIGHT * vpr;
2175             avoidArea.topRect_.width_ = rect.width_;
2176             return;
2177         }
2178         case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
2179             avoidArea.bottomRect_.posX_ = rect.posX_;
2180             avoidArea.bottomRect_.posY_ = rect.posY_ + rect.height_ - HOOK_AI_BAR_HEIGHT * vpr;
2181             avoidArea.bottomRect_.width_ = rect.width_;
2182             avoidArea.bottomRect_.height_ = HOOK_AI_BAR_HEIGHT * vpr;
2183             return;
2184         }
2185         default: {
2186             TLOGE(WmsLogTag::WMS_IMMS, "cannot find win %{public}d type %{public}u", GetPersistentId(), avoidAreaType);
2187             return;
2188         }
2189     }
2190 }
2191 
CheckGetAvoidAreaAvailable(AvoidAreaType type)2192 bool SceneSession::CheckGetAvoidAreaAvailable(AvoidAreaType type)
2193 {
2194     if (type == AvoidAreaType::TYPE_KEYBOARD) {
2195         return true;
2196     }
2197     WindowMode mode = GetWindowMode();
2198     WindowType winType = GetWindowType();
2199     if (WindowHelper::IsSubWindow(winType)) {
2200         if (GetSessionProperty()->GetAvoidAreaOption() &
2201             static_cast<uint32_t>(AvoidAreaOption::ENABLE_APP_SUB_WINDOW)) {
2202             TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d option %{public}d",
2203                 GetPersistentId(), GetSessionProperty()->GetAvoidAreaOption());
2204             return true;
2205         }
2206         auto parentSession = GetParentSession();
2207         if (parentSession != nullptr && parentSession->GetSessionRect() == GetSessionRect()) {
2208             return parentSession->CheckGetAvoidAreaAvailable(type);
2209         } else if (parentSession == nullptr) {
2210             TLOGE(WmsLogTag::WMS_IMMS, "parentSession is nullptr");
2211         }
2212         TLOGE(WmsLogTag::WMS_IMMS, "session rect not equal to parent session rect");
2213     }
2214     if (WindowHelper::IsMainWindow(winType)) {
2215         // compatibleMode app in pc,need use avoid Area
2216         if (GetSessionProperty()->GetCompatibleModeInPc()) {
2217             return true;
2218         }
2219 
2220         if (mode == WindowMode::WINDOW_MODE_FLOATING && type != AvoidAreaType::TYPE_SYSTEM) {
2221             return false;
2222         }
2223 
2224         if (mode != WindowMode::WINDOW_MODE_FLOATING || systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) {
2225             return true;
2226         }
2227     }
2228     if (WindowHelper::IsSystemWindow(winType) &&
2229         (GetSessionProperty()->GetAvoidAreaOption() &
2230          static_cast<uint32_t>(AvoidAreaOption::ENABLE_SYSTEM_WINDOW))) {
2231         return systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
2232     }
2233     TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d type %{public}u "
2234         "avoidAreaType %{public}u windowMode %{public}u, return default avoid area.",
2235         GetPersistentId(), static_cast<uint32_t>(winType), static_cast<uint32_t>(type), static_cast<uint32_t>(mode));
2236     return false;
2237 }
2238 
AddNormalModalUIExtension(const ExtensionWindowEventInfo & extensionInfo)2239 void SceneSession::AddNormalModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)
2240 {
2241     TLOGD(WmsLogTag::WMS_UIEXT, "parentId=%{public}d, persistentId=%{public}d, pid=%{public}d", GetPersistentId(),
2242         extensionInfo.persistentId, extensionInfo.pid);
2243     {
2244         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
2245         modalUIExtensionInfoList_.push_back(extensionInfo);
2246     }
2247     NotifySessionInfoChange();
2248 }
2249 
UpdateNormalModalUIExtension(const ExtensionWindowEventInfo & extensionInfo)2250 void SceneSession::UpdateNormalModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)
2251 {
2252     TLOGD(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d,pid=%{public}d,"
2253         "Rect:[%{public}d %{public}d %{public}d %{public}d]",
2254         extensionInfo.persistentId, extensionInfo.pid, extensionInfo.windowRect.posX_,
2255         extensionInfo.windowRect.posY_, extensionInfo.windowRect.width_, extensionInfo.windowRect.height_);
2256     {
2257         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
2258         auto iter = std::find_if(modalUIExtensionInfoList_.begin(), modalUIExtensionInfoList_.end(),
2259             [extensionInfo](const ExtensionWindowEventInfo& eventInfo) {
2260             return extensionInfo.persistentId == eventInfo.persistentId && extensionInfo.pid == eventInfo.pid;
2261         });
2262         if (iter == modalUIExtensionInfoList_.end()) {
2263             return;
2264         }
2265         iter->windowRect = extensionInfo.windowRect;
2266         iter->uiExtRect = extensionInfo.uiExtRect;
2267         iter->hasUpdatedRect = extensionInfo.hasUpdatedRect;
2268     }
2269     NotifySessionInfoChange();
2270 }
2271 
RemoveNormalModalUIExtension(int32_t persistentId)2272 void SceneSession::RemoveNormalModalUIExtension(int32_t persistentId)
2273 {
2274     TLOGI(WmsLogTag::WMS_UIEXT, "parentId=%{public}d, persistentId=%{public}d", GetPersistentId(), persistentId);
2275     {
2276         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
2277         auto iter = std::find_if(modalUIExtensionInfoList_.begin(), modalUIExtensionInfoList_.end(),
2278             [persistentId](const ExtensionWindowEventInfo& extensionInfo) {
2279             return extensionInfo.persistentId == persistentId;
2280         });
2281         if (iter == modalUIExtensionInfoList_.end()) {
2282             return;
2283         }
2284         modalUIExtensionInfoList_.erase(iter);
2285     }
2286     NotifySessionInfoChange();
2287 }
2288 
RegisterGetConstrainedModalExtWindowInfo(GetConstrainedModalExtWindowInfoFunc && callback)2289 void SceneSession::RegisterGetConstrainedModalExtWindowInfo(GetConstrainedModalExtWindowInfoFunc&& callback)
2290 {
2291     onGetConstrainedModalExtWindowInfoFunc_ = std::move(callback);
2292 }
2293 
GetLastModalUIExtensionEventInfo()2294 std::optional<ExtensionWindowEventInfo> SceneSession::GetLastModalUIExtensionEventInfo()
2295 {
2296     // Priority query constrained modal UIExt, if unavailable, then query normal modal UIExt
2297     if (onGetConstrainedModalExtWindowInfoFunc_) {
2298         if (auto constrainedExtEventInfo = onGetConstrainedModalExtWindowInfoFunc_(this)) {
2299             TLOGD(WmsLogTag::WMS_UIEXT, "get constrained UIExt eventInfo, id: %{public}d",
2300                 constrainedExtEventInfo->persistentId);
2301             return constrainedExtEventInfo;
2302         }
2303     }
2304     std::shared_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
2305     return modalUIExtensionInfoList_.empty() ? std::nullopt :
2306         std::make_optional<ExtensionWindowEventInfo>(modalUIExtensionInfoList_.back());
2307 }
2308 
GetSessionGlobalPosition(bool useUIExtension)2309 Vector2f SceneSession::GetSessionGlobalPosition(bool useUIExtension)
2310 {
2311     WSRect windowRect = GetSessionGlobalRect();
2312     if (useUIExtension) {
2313         if (auto modalUIExtensionEventInfo = GetLastModalUIExtensionEventInfo()) {
2314             const auto& rect = modalUIExtensionEventInfo.value().windowRect;
2315             windowRect.posX_ = rect.posX_;
2316             windowRect.posY_ = rect.posY_;
2317         }
2318     }
2319     Vector2f position(windowRect.posX_, windowRect.posY_);
2320     return position;
2321 }
2322 
GetSessionGlobalRectWithSingleHandScale()2323 WSRect SceneSession::GetSessionGlobalRectWithSingleHandScale()
2324 {
2325     WSRect rectWithTransform = GetSessionGlobalRect();
2326     const SingleHandTransform& transform = GetSingleHandTransform();
2327     if (transform.posX == 0 && transform.posY == 0) {
2328         return rectWithTransform;
2329     }
2330     rectWithTransform.posX_ =
2331         static_cast<int32_t>(static_cast<float>(rectWithTransform.posX_) * transform.scaleX) + transform.posX;
2332     rectWithTransform.posY_ =
2333         static_cast<int32_t>(static_cast<float>(rectWithTransform.posY_) * transform.scaleY) + transform.posY;
2334     rectWithTransform.width_ =
2335         static_cast<int32_t>(static_cast<float>(rectWithTransform.width_) * transform.scaleX);
2336     rectWithTransform.height_ =
2337         static_cast<int32_t>(static_cast<float>(rectWithTransform.height_) * transform.scaleY);
2338     return rectWithTransform;
2339 }
2340 
AddUIExtSurfaceNodeId(uint64_t surfaceNodeId,int32_t persistentId)2341 void SceneSession::AddUIExtSurfaceNodeId(uint64_t surfaceNodeId, int32_t persistentId)
2342 {
2343     std::unique_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
2344     TLOGI(WmsLogTag::WMS_UIEXT, "Add uiExtension pair surfaceNodeId=%{public}" PRIu64 ", persistentId=%{public}d",
2345         surfaceNodeId, persistentId);
2346     uiExtNodeIdToPersistentIdMap_.insert(std::make_pair(surfaceNodeId, persistentId));
2347 }
2348 
RemoveUIExtSurfaceNodeId(int32_t persistentId)2349 void SceneSession::RemoveUIExtSurfaceNodeId(int32_t persistentId)
2350 {
2351     std::unique_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
2352     TLOGI(WmsLogTag::WMS_UIEXT, "Remove uiExtension by persistentId=%{public}d", persistentId);
2353     auto pairIter = std::find_if(uiExtNodeIdToPersistentIdMap_.begin(), uiExtNodeIdToPersistentIdMap_.end(),
2354         [persistentId](const auto& entry) { return entry.second == persistentId; });
2355     if (pairIter != uiExtNodeIdToPersistentIdMap_.end()) {
2356         TLOGI(WmsLogTag::WMS_UIEXT,
2357             "Successfully removed uiExtension pair surfaceNodeId=%{public}" PRIu64 ", persistentId=%{public}d",
2358             pairIter->first, persistentId);
2359         uiExtNodeIdToPersistentIdMap_.erase(pairIter);
2360         return;
2361     }
2362     TLOGE(WmsLogTag::WMS_UIEXT, "Failed to remove uiExtension by persistentId=%{public}d", persistentId);
2363 }
2364 
GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const2365 int32_t SceneSession::GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const
2366 {
2367     std::shared_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
2368     auto ret = uiExtNodeIdToPersistentIdMap_.find(surfaceNodeId);
2369     if (ret == uiExtNodeIdToPersistentIdMap_.end()) {
2370         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to find uiExtension by surfaceNodeId=%{public}" PRIu64 "", surfaceNodeId);
2371         return 0;
2372     }
2373     return ret->second;
2374 }
2375 
GetAvoidAreaByTypeInner(AvoidAreaType type,const WSRect & rect)2376 AvoidArea SceneSession::GetAvoidAreaByTypeInner(AvoidAreaType type, const WSRect& rect)
2377 {
2378     if (!CheckGetAvoidAreaAvailable(type)) {
2379         return {};
2380     }
2381 
2382     AvoidArea avoidArea;
2383     WSRect sessionRect = rect.IsEmpty() ? GetSessionRect() : rect;
2384     switch (type) {
2385         case AvoidAreaType::TYPE_SYSTEM: {
2386             GetSystemAvoidArea(sessionRect, avoidArea);
2387             return avoidArea;
2388         }
2389         case AvoidAreaType::TYPE_CUTOUT: {
2390             GetCutoutAvoidArea(sessionRect, avoidArea);
2391             return avoidArea;
2392         }
2393         case AvoidAreaType::TYPE_SYSTEM_GESTURE: {
2394             return avoidArea;
2395         }
2396         case AvoidAreaType::TYPE_KEYBOARD: {
2397             GetKeyboardAvoidArea(sessionRect, avoidArea);
2398             return avoidArea;
2399         }
2400         case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
2401             GetAINavigationBarArea(sessionRect, avoidArea);
2402             return avoidArea;
2403         }
2404         default: {
2405             TLOGE(WmsLogTag::WMS_IMMS, "cannot find win %{public}d type %{public}u",
2406                 GetPersistentId(), type);
2407             return avoidArea;
2408         }
2409     }
2410 }
2411 
GetAvoidAreaByType(AvoidAreaType type,const WSRect & rect,int32_t apiVersion)2412 AvoidArea SceneSession::GetAvoidAreaByType(AvoidAreaType type, const WSRect& rect, int32_t apiVersion)
2413 {
2414     return PostSyncTask([weakThis = wptr(this), type, rect, where = __func__]() -> AvoidArea {
2415         auto session = weakThis.promote();
2416         if (!session) {
2417             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
2418             return {};
2419         }
2420         return session->GetAvoidAreaByTypeInner(type, rect);
2421     }, __func__);
2422 }
2423 
GetAllAvoidAreas(std::map<AvoidAreaType,AvoidArea> & avoidAreas)2424 WSError SceneSession::GetAllAvoidAreas(std::map<AvoidAreaType, AvoidArea>& avoidAreas)
2425 {
2426     return PostSyncTask([weakThis = wptr(this), &avoidAreas, where = __func__] {
2427         auto session = weakThis.promote();
2428         if (!session) {
2429             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", where);
2430             return WSError::WS_ERROR_NULLPTR;
2431         }
2432 
2433         using T = std::underlying_type_t<AvoidAreaType>;
2434         for (T avoidType = static_cast<T>(AvoidAreaType::TYPE_START);
2435             avoidType < static_cast<T>(AvoidAreaType::TYPE_END); avoidType++) {
2436             auto type = static_cast<AvoidAreaType>(avoidType);
2437             auto area = session->GetAvoidAreaByTypeInner(type);
2438             // code below aims to check if ai bar avoid area reaches window rect's bottom
2439             // it should not be removed until unexpected window rect update issues were solved
2440             if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
2441                 if (session->isAINavigationBarAvoidAreaValid_ &&
2442                     !session->isAINavigationBarAvoidAreaValid_(area, session->GetSessionRect().height_)) {
2443                     continue;
2444                 }
2445             }
2446             avoidAreas[type] = area;
2447         }
2448         return WSError::WS_OK;
2449     }, __func__);
2450 }
2451 
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)2452 WSError SceneSession::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
2453 {
2454     if (!sessionStage_) {
2455         return WSError::WS_ERROR_NULLPTR;
2456     }
2457     if (!GetForegroundInteractiveStatus()) {
2458         TLOGD(WmsLogTag::WMS_IMMS, "win [%{public}d] avoid area update rejected by recent", GetPersistentId());
2459         return WSError::WS_DO_NOTHING;
2460     }
2461     return sessionStage_->UpdateAvoidArea(avoidArea, type);
2462 }
2463 
SetPipActionEvent(const std::string & action,int32_t status)2464 WSError SceneSession::SetPipActionEvent(const std::string& action, int32_t status)
2465 {
2466     TLOGI(WmsLogTag::WMS_PIP, "action: %{public}s, status: %{public}d", action.c_str(), status);
2467     if (!sessionStage_) {
2468         return WSError::WS_ERROR_NULLPTR;
2469     }
2470     return sessionStage_->SetPipActionEvent(action, status);
2471 }
2472 
SetPiPControlEvent(WsPiPControlType controlType,WsPiPControlStatus status)2473 WSError SceneSession::SetPiPControlEvent(WsPiPControlType controlType, WsPiPControlStatus status)
2474 {
2475     TLOGI(WmsLogTag::WMS_PIP, "controlType: %{public}u, status: %{public}u", controlType, status);
2476     if (GetWindowType() != WindowType::WINDOW_TYPE_PIP || GetWindowMode() != WindowMode::WINDOW_MODE_PIP) {
2477         return WSError::WS_ERROR_INVALID_TYPE;
2478     }
2479     if (!sessionStage_) {
2480         return WSError::WS_ERROR_NULLPTR;
2481     }
2482     return sessionStage_->SetPiPControlEvent(controlType, status);
2483 }
2484 
NotifyPipWindowSizeChange(double width,double height,double scale)2485 WSError SceneSession::NotifyPipWindowSizeChange(double width, double height, double scale)
2486 {
2487     TLOGI(WmsLogTag::WMS_PIP, "width: %{public}f, height: %{public}f scale: %{public}f", width, height, scale);
2488     if (!sessionStage_) {
2489         return WSError::WS_ERROR_NULLPTR;
2490     }
2491     return sessionStage_->NotifyPipWindowSizeChange(width, height, scale);
2492 }
2493 
RegisterProcessPrepareClosePiPCallback(NotifyPrepareClosePiPSessionFunc && callback)2494 void SceneSession::RegisterProcessPrepareClosePiPCallback(NotifyPrepareClosePiPSessionFunc&& callback)
2495 {
2496     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
2497         auto session = weakThis.promote();
2498         if (!session) {
2499             TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
2500             return;
2501         }
2502         session->onPrepareClosePiPSession_ = std::move(callback);
2503     }, __func__);
2504 }
2505 
ProcessPointDownSession(int32_t posX,int32_t posY)2506 WSError SceneSession::ProcessPointDownSession(int32_t posX, int32_t posY)
2507 {
2508     const auto& id = GetPersistentId();
2509     TLOGD(WmsLogTag::WMS_INPUT_KEY_FLOW, "id:%{public}d, type:%{public}d", id, GetWindowType());
2510 
2511     // notify touch outside
2512     if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ &&
2513         sessionInfo_.bundleName_.find("SCBGestureBack") == std::string::npos) {
2514         specificCallback_->onSessionTouchOutside_(id);
2515     }
2516 
2517     // notify outside down event
2518     if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
2519         specificCallback_->onOutsideDownEvent_(posX, posY);
2520     }
2521     return WSError::WS_OK;
2522 }
2523 
SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool isExecuteDelayRaise)2524 WSError SceneSession::SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2525     bool isExecuteDelayRaise)
2526 {
2527     NotifyOutsideDownEvent(pointerEvent);
2528     TransferPointerEvent(pointerEvent, false, isExecuteDelayRaise);
2529     return WSError::WS_OK;
2530 }
2531 
NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)2532 void SceneSession::NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
2533 {
2534     // notify touchOutside and touchDown event
2535     int32_t action = pointerEvent->GetPointerAction();
2536     if (action != MMI::PointerEvent::POINTER_ACTION_DOWN &&
2537         action != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
2538         return;
2539     }
2540 
2541     MMI::PointerEvent::PointerItem pointerItem;
2542     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
2543         return;
2544     }
2545 
2546     // notify touch outside
2547     if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ &&
2548         sessionInfo_.bundleName_.find("SCBGestureBack") == std::string::npos) {
2549         specificCallback_->onSessionTouchOutside_(GetPersistentId());
2550     }
2551 
2552     // notify outside down event
2553     if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
2554         specificCallback_->onOutsideDownEvent_(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
2555     }
2556 }
2557 
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool needNotifyClient,bool isExecuteDelayRaise)2558 WSError SceneSession::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2559     bool needNotifyClient, bool isExecuteDelayRaise)
2560 {
2561     PostTask([weakThis = wptr(this), pointerEvent, needNotifyClient, isExecuteDelayRaise, where = __func__] {
2562         auto session = weakThis.promote();
2563         if (!session) {
2564             TLOGNE(WmsLogTag::DEFAULT, "%{public}s session is null", where);
2565             return WSError::WS_ERROR_DESTROYED_OBJECT;
2566         }
2567         return session->TransferPointerEventInner(pointerEvent, needNotifyClient, isExecuteDelayRaise);
2568     }, __func__);
2569     return WSError::WS_OK;
2570 }
2571 
TransferPointerEventInner(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool needNotifyClient,bool isExecuteDelayRaise)2572 WSError SceneSession::TransferPointerEventInner(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2573     bool needNotifyClient, bool isExecuteDelayRaise)
2574 {
2575     WLOGFD("[WMSCom] TransferPointEvent, id: %{public}d, type: %{public}d, needNotifyClient: %{public}d",
2576         GetPersistentId(), GetWindowType(), needNotifyClient);
2577     if (pointerEvent == nullptr) {
2578         WLOGFE("pointerEvent is null");
2579         return WSError::WS_ERROR_NULLPTR;
2580     }
2581 
2582     int32_t action = pointerEvent->GetPointerAction();
2583 
2584     if (!CheckPointerEventDispatch(pointerEvent)) {
2585         WLOGFI("Do not dispatch this pointer event");
2586         return WSError::WS_DO_NOTHING;
2587     }
2588 
2589     bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
2590         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
2591 
2592     auto property = GetSessionProperty();
2593     if (property == nullptr) {
2594         return Session::TransferPointerEvent(pointerEvent, needNotifyClient, isExecuteDelayRaise);
2595     }
2596     auto windowType = property->GetWindowType();
2597     bool isMovableWindowType = IsMovableWindowType();
2598     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
2599     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
2600     bool isDialog = WindowHelper::IsDialogWindow(windowType);
2601     bool isMaxModeAvoidSysBar = property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR;
2602     bool isDragAccessibleSystemWindow = WindowHelper::IsSystemWindow(windowType) && IsDragAccessible() &&
2603         !isDialog;
2604     bool isMovableSystemWindow = WindowHelper::IsSystemWindow(windowType) && !isDialog;
2605     TLOGD(WmsLogTag::WMS_EVENT, "%{public}s: %{public}d && %{public}d", property->GetWindowName().c_str(),
2606         WindowHelper::IsSystemWindow(windowType), IsDragAccessible());
2607     if (isMovableWindowType && !isMaxModeAvoidSysBar &&
2608         (isMainWindow || isSubWindow || isDialog || isDragAccessibleSystemWindow || isMovableSystemWindow)) {
2609         if (CheckDialogOnForeground() && isPointDown) {
2610             HandlePointDownDialog();
2611             pointerEvent->MarkProcessed();
2612             TLOGI(WmsLogTag::WMS_DIALOG, "There is dialog window foreground");
2613             return WSError::WS_OK;
2614         }
2615         if (!moveDragController_) {
2616             TLOGD(WmsLogTag::WMS_LAYOUT, "moveDragController_ is null");
2617             return Session::TransferPointerEvent(pointerEvent, needNotifyClient, isExecuteDelayRaise);
2618         }
2619         if (isFollowParentLayout_) {
2620             return WSError::WS_OK;
2621         }
2622         if ((property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && IsDragAccessible()) ||
2623             isDragAccessibleSystemWindow) {
2624             if ((systemConfig_.IsPcWindow() || IsFreeMultiWindowMode() ||
2625                  (property->GetIsPcAppInPad() && !isMainWindow)) &&
2626                 moveDragController_->ConsumeDragEvent(pointerEvent, winRect_, property, systemConfig_)) {
2627                 auto surfaceNode = GetSurfaceNode();
2628                 moveDragController_->UpdateGravityWhenDrag(pointerEvent, surfaceNode);
2629                 PresentFoucusIfNeed(pointerEvent->GetPointerAction());
2630                 pointerEvent->MarkProcessed();
2631                 return WSError::WS_OK;
2632             }
2633         }
2634         if ((WindowHelper::IsMainWindow(windowType) ||
2635              WindowHelper::IsSubWindow(windowType) ||
2636              WindowHelper::IsSystemWindow(windowType)) &&
2637             moveDragController_->ConsumeMoveEvent(pointerEvent, winRect_)) {
2638             PresentFoucusIfNeed(pointerEvent->GetPointerAction());
2639             pointerEvent->MarkProcessed();
2640             Session::TransferPointerEvent(pointerEvent, needNotifyClient, isExecuteDelayRaise);
2641             ProcessWindowMoving(pointerEvent);
2642             return WSError::WS_OK;
2643         }
2644     }
2645 
2646     bool raiseEnabled = property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && property->GetRaiseEnabled() &&
2647         (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
2648     if (raiseEnabled) {
2649         RaiseToAppTopForPointDown();
2650     }
2651     // modify the window coordinates when move end
2652     MMI::PointerEvent::PointerItem pointerItem;
2653     if ((action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP || action == MMI::PointerEvent::POINTER_ACTION_MOVE) &&
2654         needNotifyClient && pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem) &&
2655         IsStartMoving()) {
2656         int32_t windowX = pointerItem.GetDisplayX() - winRect_.posX_;
2657         int32_t windowY = pointerItem.GetDisplayY() - winRect_.posY_;
2658         TLOGD(WmsLogTag::WMS_EVENT, "move end position: windowX:%{private}d windowY:%{private}d action:%{public}d",
2659             windowX, windowY, action);
2660         pointerItem.SetWindowX(windowX);
2661         pointerItem.SetWindowY(windowY);
2662         pointerEvent->AddPointerItem(pointerItem);
2663     }
2664     return Session::TransferPointerEvent(pointerEvent, needNotifyClient, isExecuteDelayRaise);
2665 }
2666 
NotifyUpdateGravity()2667 void SceneSession::NotifyUpdateGravity()
2668 {
2669     std::unordered_map<int32_t, NotifySurfaceBoundsChangeFunc> funcMap;
2670     {
2671         std::lock_guard lock(registerNotifySurfaceBoundsChangeMutex_);
2672         funcMap = notifySurfaceBoundsChangeFuncMap_;
2673     }
2674     for (const auto& [sessionId, _] : funcMap) {
2675         auto subSession = GetSceneSessionById(sessionId);
2676         if (!subSession || !subSession->GetIsFollowParentLayout()) {
2677             return;
2678         }
2679         auto surfaceNode = subSession->GetSurfaceNode();
2680         auto subController = subSession->GetMoveDragController();
2681         if (subController && surfaceNode) {
2682             subController->UpdateSubWindowGravityWhenFollow(moveDragController_, surfaceNode);
2683         }
2684     }
2685 }
2686 
ProcessWindowMoving(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)2687 void SceneSession::ProcessWindowMoving(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
2688 {
2689     if (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_MOVE) {
2690         return;
2691     }
2692     MMI::PointerEvent::PointerItem pointerItem;
2693     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
2694         return;
2695     }
2696     if (notifyWindowMovingFunc_) {
2697         notifyWindowMovingFunc_(static_cast<DisplayId>(pointerEvent->GetTargetDisplayId()),
2698             pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
2699     }
2700 }
2701 
SetWindowMovingCallback(NotifyWindowMovingFunc && func)2702 void SceneSession::SetWindowMovingCallback(NotifyWindowMovingFunc&& func)
2703 {
2704     PostTask([weakThis = wptr(this), where = __func__, func = std::move(func)] {
2705         auto session = weakThis.promote();
2706         if (!session || !func) {
2707             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session or func is null", where);
2708             return;
2709         }
2710         session->notifyWindowMovingFunc_ = std::move(func);
2711         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where,
2712             session->GetPersistentId());
2713     }, __func__);
2714 }
2715 
IsMovableWindowType()2716 bool SceneSession::IsMovableWindowType()
2717 {
2718     auto property = GetSessionProperty();
2719     if (property == nullptr) {
2720         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
2721         return false;
2722     }
2723 
2724     return property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ||
2725         property->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
2726         property->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
2727         IsFullScreenMovable();
2728 }
2729 
IsFullScreenMovable()2730 bool SceneSession::IsFullScreenMovable()
2731 {
2732     auto property = GetSessionProperty();
2733     if (property == nullptr) {
2734         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
2735         return false;
2736     }
2737     return property->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2738         WindowHelper::IsWindowModeSupported(property->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING);
2739 }
2740 
IsMovable()2741 bool SceneSession::IsMovable()
2742 {
2743     if (!moveDragController_) {
2744         TLOGW(WmsLogTag::WMS_LAYOUT, "moveDragController_ is null, id: %{public}d", GetPersistentId());
2745         return false;
2746     }
2747 
2748     bool windowIsMovable = !moveDragController_->GetStartDragFlag() && IsMovableWindowType() &&
2749                            moveDragController_->HasPointDown() && moveDragController_->GetMovable();
2750     auto property = GetSessionProperty();
2751     if (property->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR &&
2752         property->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2753         windowIsMovable = windowIsMovable && IsFocused();
2754     }
2755     if (!windowIsMovable) {
2756         TLOGW(WmsLogTag::WMS_LAYOUT, "Window is not movable, id: %{public}d, startDragFlag: %{public}d, "
2757             "isFocused: %{public}d, movableWindowType: %{public}d, hasPointDown: %{public}d, movable: %{public}d",
2758             GetPersistentId(), moveDragController_->GetStartDragFlag(), IsFocused(), IsMovableWindowType(),
2759             moveDragController_->HasPointDown(), moveDragController_->GetMovable());
2760         return false;
2761     }
2762     return true;
2763 }
2764 
RequestSessionBack(bool needMoveToBackground)2765 WSError SceneSession::RequestSessionBack(bool needMoveToBackground)
2766 {
2767     PostTask([weakThis = wptr(this), needMoveToBackground, where = __func__] {
2768         auto session = weakThis.promote();
2769         if (!session) {
2770             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
2771             return WSError::WS_ERROR_DESTROYED_OBJECT;
2772         }
2773         if (!session->backPressedFunc_) {
2774             TLOGNW(WmsLogTag::WMS_EVENT, "%{public}s Session didn't register back event consumer!", where);
2775             return WSError::WS_DO_NOTHING;
2776         }
2777         if (g_enableForceUIFirst) {
2778             auto rsTransaction = RSTransactionProxy::GetInstance();
2779             if (rsTransaction) {
2780                 rsTransaction->Begin();
2781             }
2782             auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
2783             if (leashWinSurfaceNode) {
2784                 leashWinSurfaceNode->SetForceUIFirst(true);
2785                 TLOGNI(WmsLogTag::WMS_EVENT, "%{public}s leashWinSurfaceNode_ SetForceUIFirst id:%{public}u!",
2786                     where, session->GetPersistentId());
2787             } else {
2788                 TLOGNI(WmsLogTag::WMS_EVENT, "%{public}s failed, leashWinSurfaceNode_ null id:%{public}u",
2789                     where, session->GetPersistentId());
2790             }
2791             if (rsTransaction) {
2792                 rsTransaction->Commit();
2793             }
2794         }
2795         session->backPressedFunc_(needMoveToBackground);
2796         return WSError::WS_OK;
2797     }, std::string(__func__) + ":" + std::to_string(needMoveToBackground));
2798     return WSError::WS_OK;
2799 }
2800 
2801 #ifdef DEVICE_STATUS_ENABLE
RotateDragWindow(std::shared_ptr<RSTransaction> rsTransaction)2802 void SceneSession::RotateDragWindow(std::shared_ptr<RSTransaction> rsTransaction)
2803 {
2804     Msdp::DeviceStatus::DragState state = Msdp::DeviceStatus::DragState::STOP;
2805     Msdp::DeviceStatus::InteractionManager::GetInstance()->GetDragState(state);
2806     if (state == Msdp::DeviceStatus::DragState::START) {
2807         Msdp::DeviceStatus::InteractionManager::GetInstance()->RotateDragWindowSync(rsTransaction);
2808     }
2809 }
2810 #endif // DEVICE_STATUS_ENABLE
2811 
2812 /** @note @window.layout */
NotifySessionRectChange(const WSRect & rect,SizeChangeReason reason,DisplayId displayId,const RectAnimationConfig & rectAnimationConfig)2813 void SceneSession::NotifySessionRectChange(const WSRect& rect,
2814     SizeChangeReason reason, DisplayId displayId, const RectAnimationConfig& rectAnimationConfig)
2815 {
2816     PostTask([weakThis = wptr(this), rect, reason, displayId, rectAnimationConfig, where = __func__] {
2817         auto session = weakThis.promote();
2818         if (!session) {
2819             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
2820             return;
2821         }
2822         if (session->sessionRectChangeFunc_) {
2823             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::NotifySessionRectChange");
2824             session->sessionRectChangeFunc_(rect, reason, displayId, rectAnimationConfig);
2825         }
2826     }, __func__ + GetRectInfo(rect));
2827 }
2828 
2829 /** @note @window.layout */
NotifySessionDisplayIdChange(uint64_t displayId)2830 void SceneSession::NotifySessionDisplayIdChange(uint64_t displayId)
2831 {
2832     PostTask([weakThis = wptr(this), displayId] {
2833         auto session = weakThis.promote();
2834         if (!session) {
2835             TLOGNE(WmsLogTag::WMS_LAYOUT, "session is null");
2836             return;
2837         }
2838         if (session->sessionDisplayIdChangeFunc_) {
2839             session->sessionDisplayIdChangeFunc_(displayId);
2840         }
2841     }, __func__);
2842 }
2843 
CheckSubSessionShouldFollowParent(uint64_t displayId)2844 void SceneSession::CheckSubSessionShouldFollowParent(uint64_t displayId)
2845 {
2846     for (const auto& session : subSession_) {
2847         if (session && session->IsSessionForeground() && session->GetSessionProperty()->GetDisplayId() != displayId) {
2848             session->SetShouldFollowParentWhenShow(false);
2849         }
2850     }
2851 }
2852 
IsDecorEnable() const2853 bool SceneSession::IsDecorEnable() const
2854 {
2855     auto property = GetSessionProperty();
2856     if (property == nullptr) {
2857         WLOGE("property is nullptr");
2858         return false;
2859     }
2860     auto windowType = property->GetWindowType();
2861     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
2862     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
2863     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
2864     bool isValidWindow = isMainWindow ||
2865         ((isSubWindow || isDialogWindow) && property->IsDecorEnable());
2866     bool isWindowModeSupported = WindowHelper::IsWindowModeSupported(
2867         systemConfig_.decorWindowModeSupportType_, property->GetWindowMode());
2868     bool enable = isValidWindow && systemConfig_.isSystemDecorEnable_ && isWindowModeSupported;
2869     return enable;
2870 }
2871 
GetRatioPreferenceKey()2872 std::string SceneSession::GetRatioPreferenceKey()
2873 {
2874     std::string key = sessionInfo_.bundleName_ + sessionInfo_.moduleName_ + sessionInfo_.abilityName_;
2875     if (key.length() > ScenePersistentStorage::MAX_KEY_LEN) {
2876         return key.substr(key.length() - ScenePersistentStorage::MAX_KEY_LEN);
2877     }
2878     return key;
2879 }
2880 
SaveAspectRatio(float ratio)2881 bool SceneSession::SaveAspectRatio(float ratio)
2882 {
2883     std::string key = GetRatioPreferenceKey();
2884     if (!key.empty()) {
2885         ScenePersistentStorage::Insert(key, ratio, ScenePersistentStorageType::ASPECT_RATIO);
2886         WLOGD("SceneSession save aspectRatio , key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
2887         return true;
2888     }
2889     return false;
2890 }
2891 
AdjustRectByLimits(WindowLimits limits,float ratio,bool isDecor,float vpr,WSRect & rect)2892 void SceneSession::AdjustRectByLimits(WindowLimits limits, float ratio, bool isDecor, float vpr, WSRect& rect)
2893 {
2894     if (isDecor) {
2895         rect.width_ = SessionUtils::ToLayoutWidth(rect.width_, vpr);
2896         rect.height_ = SessionUtils::ToLayoutHeight(rect.height_, vpr);
2897         limits.minWidth_ = SessionUtils::ToLayoutWidth(limits.minWidth_, vpr);
2898         limits.maxWidth_ = SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr);
2899         limits.minHeight_ = SessionUtils::ToLayoutHeight(limits.minHeight_, vpr);
2900         limits.maxHeight_ = SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr);
2901     }
2902     if (static_cast<uint32_t>(rect.height_) > limits.maxHeight_) {
2903         rect.height_ = static_cast<int32_t>(limits.maxHeight_);
2904         rect.width_ = floor(rect.height_ * ratio);
2905     } else if (static_cast<uint32_t>(rect.width_) > limits.maxWidth_) {
2906         rect.width_ = static_cast<int32_t>(limits.maxWidth_);
2907         rect.height_ = floor(rect.width_ / ratio);
2908     } else if (static_cast<uint32_t>(rect.width_) < limits.minWidth_) {
2909         rect.width_ = static_cast<int32_t>(limits.minWidth_);
2910         rect.height_ = ceil(rect.width_ / ratio);
2911     } else if (static_cast<uint32_t>(rect.height_) < limits.minHeight_) {
2912         rect.height_ = static_cast<int32_t>(limits.minHeight_);
2913         rect.width_ = ceil(rect.height_ * ratio);
2914     }
2915     if (isDecor) {
2916         rect.height_ = SessionUtils::ToWinHeight(rect.height_, vpr) ;
2917         rect.width_ = SessionUtils::ToWinWidth(rect.width_, vpr);
2918     }
2919 }
AdjustRectByAspectRatio(WSRect & rect)2920 bool SceneSession::AdjustRectByAspectRatio(WSRect& rect)
2921 {
2922     const int tolerancePx = 2; // 2: tolerance delta pixel value, unit: px
2923     WSRect originalRect = rect;
2924     auto property = GetSessionProperty();
2925     if (!property || property->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING ||
2926         !WindowHelper::IsMainWindow(GetWindowType())) {
2927         return false;
2928     }
2929 
2930     if (MathHelper::NearZero(aspectRatio_)) {
2931         return false;
2932     }
2933     float vpr = 1.5f; // 1.5f: default virtual pixel ratio
2934     auto display = DisplayManager::GetInstance().GetDefaultDisplay();
2935     if (display) {
2936         vpr = display->GetVirtualPixelRatio();
2937     }
2938     int32_t minW;
2939     int32_t maxW;
2940     int32_t minH;
2941     int32_t maxH;
2942     SessionUtils::CalcFloatWindowRectLimits(property->GetWindowLimits(), systemConfig_.maxFloatingWindowSize_, vpr,
2943         minW, maxW, minH, maxH);
2944     rect.width_ = std::max(minW, static_cast<int32_t>(rect.width_));
2945     rect.width_ = std::min(maxW, static_cast<int32_t>(rect.width_));
2946     rect.height_ = std::max(minH, static_cast<int32_t>(rect.height_));
2947     rect.height_ = std::min(maxH, static_cast<int32_t>(rect.height_));
2948     if (IsDecorEnable()) {
2949         if (SessionUtils::ToLayoutWidth(rect.width_, vpr) >
2950                 SessionUtils::ToLayoutHeight(rect.height_, vpr) * aspectRatio_) {
2951             rect.width_ = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(rect.height_, vpr)* aspectRatio_, vpr);
2952         } else {
2953             rect.height_ = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(rect.width_, vpr) / aspectRatio_, vpr);
2954         }
2955     } else {
2956         if (rect.width_ > rect.height_ * aspectRatio_) {
2957             rect.width_ = rect.height_ * aspectRatio_;
2958         } else {
2959             rect.height_ = rect.width_ / aspectRatio_;
2960         }
2961     }
2962     AdjustRectByLimits(property->GetWindowLimits(), aspectRatio_, IsDecorEnable(), vpr, rect);
2963     if (std::abs(static_cast<int32_t>(originalRect.width_) - static_cast<int32_t>(rect.width_)) <= tolerancePx &&
2964         std::abs(static_cast<int32_t>(originalRect.height_) - static_cast<int32_t>(rect.height_)) <= tolerancePx) {
2965         rect = originalRect;
2966         return false;
2967     }
2968     return true;
2969 }
2970 
HandleCompatibleModeMoveDrag(WSRect & rect,SizeChangeReason reason)2971 void SceneSession::HandleCompatibleModeMoveDrag(WSRect& rect, SizeChangeReason reason)
2972 {
2973     auto sessionProperty = GetSessionProperty();
2974     if (!sessionProperty) {
2975         TLOGE(WmsLogTag::WMS_SCB, "sessionProperty is null");
2976         return;
2977     }
2978     bool isSupportDragInPcCompatibleMode = sessionProperty->GetIsSupportDragInPcCompatibleMode();
2979     if (reason != SizeChangeReason::DRAG_MOVE) {
2980         if (reason == SizeChangeReason::DRAG_END && !moveDragController_->GetStartDragFlag()) {
2981             return;
2982         } else {
2983             HandleCompatibleModeDrag(rect, reason, isSupportDragInPcCompatibleMode);
2984         }
2985     }
2986 }
2987 
HandleCompatibleModeDrag(WSRect & rect,SizeChangeReason reason,bool isSupportDragInPcCompatibleMode)2988 void SceneSession::HandleCompatibleModeDrag(WSRect& rect, SizeChangeReason reason, bool isSupportDragInPcCompatibleMode)
2989 {
2990     auto sessionProperty = GetSessionProperty();
2991     if (!sessionProperty) {
2992         TLOGE(WmsLogTag::WMS_SCB, "sessionProperty is null");
2993         return;
2994     }
2995     WindowLimits windowLimits = sessionProperty->GetWindowLimits();
2996     const int32_t compatibleInPcPortraitWidth = sessionProperty->GetCompatibleInPcPortraitWidth();
2997     const int32_t compatibleInPcPortraitHeight = sessionProperty->GetCompatibleInPcPortraitHeight();
2998     const int32_t compatibleInPcLandscapeWidth = sessionProperty->GetCompatibleInPcLandscapeWidth();
2999     const int32_t compatibleInPcLandscapeHeight = sessionProperty->GetCompatibleInPcLandscapeHeight();
3000     const int32_t compatibleInPcDragLimit = compatibleInPcLandscapeWidth - compatibleInPcPortraitWidth;
3001     WSRect windowRect = moveDragController_->GetOriginalRect();
3002     auto windowWidth = windowRect.width_;
3003     auto windowHeight = windowRect.height_;
3004     if (isSupportDragInPcCompatibleMode && windowWidth > windowHeight &&
3005         (rect.width_ < compatibleInPcLandscapeWidth - compatibleInPcDragLimit ||
3006             rect.width_ == static_cast<int32_t>(windowLimits.minWidth_))) {
3007         rect.width_ = compatibleInPcPortraitWidth;
3008         rect.height_ = compatibleInPcPortraitHeight;
3009     } else if (isSupportDragInPcCompatibleMode && windowWidth < windowHeight &&
3010         rect.width_ > compatibleInPcPortraitWidth + compatibleInPcDragLimit) {
3011         rect.width_ = compatibleInPcLandscapeWidth;
3012         rect.height_ = compatibleInPcLandscapeHeight;
3013     } else if (isSupportDragInPcCompatibleMode) {
3014         rect.width_ = (windowWidth < windowHeight) ? compatibleInPcPortraitWidth : compatibleInPcLandscapeWidth;
3015         rect.height_ = (windowWidth < windowHeight) ? compatibleInPcPortraitHeight : compatibleInPcLandscapeHeight;
3016     }
3017 }
3018 
SetMoveDragCallback()3019 void SceneSession::SetMoveDragCallback()
3020 {
3021     if (moveDragController_) {
3022         MoveDragCallback callBack = [this](SizeChangeReason reason) {
3023             this->OnMoveDragCallback(reason);
3024         };
3025         moveDragController_->RegisterMoveDragCallback(callBack);
3026     }
3027 }
3028 
3029 /** @note @window.drag */
InitializeCrossMoveDrag()3030 void SceneSession::InitializeCrossMoveDrag()
3031 {
3032     auto movedSurfaceNode = GetSurfaceNodeForMoveDrag();
3033     if (!movedSurfaceNode) {
3034         return;
3035     }
3036     auto parentNode = movedSurfaceNode->GetParent();
3037     if (!parentNode) {
3038         return;
3039     }
3040     auto property = GetSessionProperty();
3041     if (!property) {
3042         return;
3043     }
3044     auto originalPositionZ = movedSurfaceNode->GetStagingProperties().GetPositionZ();
3045     moveDragController_->SetOriginalPositionZ(originalPositionZ);
3046     moveDragController_->InitCrossDisplayProperty(property->GetDisplayId(), parentNode->GetId());
3047 }
3048 
3049 /** @note @window.drag */
HandleMoveDragSurfaceBounds(WSRect & rect,WSRect & globalRect,SizeChangeReason reason)3050 void SceneSession::HandleMoveDragSurfaceBounds(WSRect& rect, WSRect& globalRect, SizeChangeReason reason)
3051 {
3052     bool isGlobal = (reason != SizeChangeReason::DRAG_END);
3053     bool needFlush = (reason != SizeChangeReason::DRAG_END);
3054     throwSlipToFullScreenAnimCount_.store(0);
3055     UpdateSizeChangeReason(reason);
3056     if (moveDragController_ && moveDragController_->GetPointerType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN &&
3057         pcFoldScreenController_ && pcFoldScreenController_->IsAllowThrowSlip(GetScreenId()) &&
3058         (reason == SizeChangeReason::DRAG_MOVE || reason == SizeChangeReason::DRAG_END)) {
3059         if (pcFoldScreenController_->NeedFollowHandAnimation()) {
3060             auto movingPair = std::make_pair(pcFoldScreenController_->GetMovingTimingProtocol(),
3061                 pcFoldScreenController_->GetMovingTimingCurve());
3062             SetSurfaceBoundsWithAnimation(movingPair, globalRect, nullptr, isGlobal);
3063         } else if (reason != SizeChangeReason::DRAG_START) {
3064             SetSurfaceBounds(globalRect, isGlobal, needFlush);
3065         }
3066         pcFoldScreenController_->RecordMoveRects(rect);
3067     } else {
3068         SetSurfaceBounds(globalRect, isGlobal, needFlush);
3069     }
3070     if (reason != SizeChangeReason::DRAG_MOVE) {
3071         UpdateRectForDrag(rect);
3072         std::shared_ptr<VsyncCallback> nextVsyncDragCallback = std::make_shared<VsyncCallback>();
3073         nextVsyncDragCallback->onCallback = [weakThis = wptr(this), where = __func__](int64_t, int64_t) {
3074             auto session = weakThis.promote();
3075             if (!session) {
3076                 TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
3077                 return;
3078             }
3079             session->OnNextVsyncReceivedWhenDrag();
3080         };
3081         if (requestNextVsyncFunc_) {
3082             requestNextVsyncFunc_(nextVsyncDragCallback);
3083         } else {
3084             TLOGNE(WmsLogTag::WMS_LAYOUT, "Func is null, could not request vsync");
3085         }
3086     }
3087 }
3088 
OnNextVsyncReceivedWhenDrag()3089 void SceneSession::OnNextVsyncReceivedWhenDrag()
3090 {
3091     PostTask([weakThis = wptr(this), where = __func__] {
3092         auto session = weakThis.promote();
3093         if (!session) {
3094             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
3095             return;
3096         }
3097         if (session->IsDirtyDragWindow()) {
3098             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}u, winRect:%{public}s",
3099                 where, session->GetPersistentId(), session->winRect_.ToString().c_str());
3100             session->NotifyClientToUpdateRect("OnMoveDragCallback", nullptr);
3101             session->ResetDirtyDragFlags();
3102         }
3103     });
3104 }
3105 
3106 /** @note @window.drag */
HandleMoveDragEnd(WSRect & rect,SizeChangeReason reason)3107 void SceneSession::HandleMoveDragEnd(WSRect& rect, SizeChangeReason reason)
3108 {
3109     if (GetOriPosYBeforeRaisedByKeyboard() != 0) {
3110         TLOGI(WmsLogTag::WMS_KEYBOARD, "Calling session is moved and reset oriPosYBeforeRaisedByKeyboard");
3111         SetOriPosYBeforeRaisedByKeyboard(0);
3112     }
3113     if (moveDragController_->GetPointerType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN &&
3114         MoveUnderInteriaAndNotifyRectChange(rect, reason)) {
3115         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "set full screen after throw slip");
3116     }
3117     if ((moveDragController_->GetMoveDragEndDisplayId() == moveDragController_->GetMoveDragStartDisplayId() ||
3118          WindowHelper::IsSystemWindow(GetWindowType())) && !WindowHelper::IsInputWindow(GetWindowType())) {
3119         NotifySessionRectChange(rect, reason);
3120     } else {
3121         displayChangedByMoveDrag_ = true;
3122         NotifySessionRectChange(rect, reason, moveDragController_->GetMoveDragEndDisplayId());
3123         CheckSubSessionShouldFollowParent(moveDragController_->GetMoveDragEndDisplayId());
3124     }
3125     moveDragController_->ResetCrossMoveDragProperty();
3126     OnSessionEvent(SessionEvent::EVENT_END_MOVE);
3127 }
3128 
3129 /**
3130  * move with init velocity
3131  * @return true: successfully throw slip
3132  */
MoveUnderInteriaAndNotifyRectChange(WSRect & rect,SizeChangeReason reason)3133 bool SceneSession::MoveUnderInteriaAndNotifyRectChange(WSRect& rect, SizeChangeReason reason)
3134 {
3135     if (pcFoldScreenController_ == nullptr) {
3136         return false;
3137     }
3138     bool ret = pcFoldScreenController_->ThrowSlip(GetScreenId(), rect, GetStatusBarHeight(), GetDockHeight());
3139     if (!ret) {
3140         TLOGD(WmsLogTag::WMS_LAYOUT_PC, "no throw slip");
3141         pcFoldScreenController_->ResetRecords();
3142         return false;
3143     }
3144 
3145     WSRect endRect = rect;
3146     std::function<void()> finishCallback = nullptr;
3147     bool needSetFullScreen = pcFoldScreenController_->IsStartFullScreen();
3148     if (needSetFullScreen) {
3149         // maximize end rect and notify last rect
3150         throwSlipToFullScreenAnimCount_.fetch_add(1);
3151         pcFoldScreenController_->ResizeToFullScreen(endRect, GetStatusBarHeight(), GetDockHeight());
3152         if (pcFoldScreenController_->IsThrowSlipDirectly()) {
3153             pcFoldScreenController_->ThrowSlipFloatingRectDirectly(
3154                 rect, GetSessionRequestRect(), GetStatusBarHeight(), GetDockHeight());
3155         }
3156         finishCallback = [weakThis = wptr(this), rect, where = __func__] {
3157             auto session = weakThis.promote();
3158             if (session == nullptr) {
3159                 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is nullptr", where);
3160                 return;
3161             }
3162             session->OnThrowSlipAnimationStateChange(false);
3163             session->NotifyFullScreenAfterThrowSlip(rect);
3164         };
3165     } else {
3166         finishCallback = [weakThis = wptr(this), rect, where = __func__] {
3167             auto session = weakThis.promote();
3168             if (session == nullptr) {
3169                 TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is nullptr", where);
3170                 return;
3171             }
3172             session->OnThrowSlipAnimationStateChange(false);
3173         };
3174     }
3175     auto throwSlipPair = std::make_pair(pcFoldScreenController_->GetThrowSlipTimingProtocol(),
3176         pcFoldScreenController_->GetThrowSlipTimingCurve());
3177     SetSurfaceBoundsWithAnimation(throwSlipPair, endRect, finishCallback);
3178     OnThrowSlipAnimationStateChange(true);
3179     rect = endRect;
3180     pcFoldScreenController_->ResetRecords();
3181     return true;
3182 }
3183 
OnThrowSlipAnimationStateChange(bool isAnimating)3184 void SceneSession::OnThrowSlipAnimationStateChange(bool isAnimating)
3185 {
3186     TLOGD(WmsLogTag::WMS_LAYOUT_PC, "status: %{public}d", isAnimating);
3187     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3188     if (leashWinSurfaceNode) {
3189         leashWinSurfaceNode->SetUIFirstSwitch(isAnimating ? RSUIFirstSwitch::FORCE_DISABLE : RSUIFirstSwitch::NONE);
3190     }
3191     if (onThrowSlipAnimationStateChangeFunc_) {
3192         onThrowSlipAnimationStateChangeFunc_(isAnimating);
3193     }
3194 }
3195 
NotifyFullScreenAfterThrowSlip(const WSRect & rect)3196 void SceneSession::NotifyFullScreenAfterThrowSlip(const WSRect& rect)
3197 {
3198     PostTask([weakThis = wptr(this), rect, where = __func__] {
3199         auto session = weakThis.promote();
3200         if (session == nullptr) {
3201             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s session is nullptr", where);
3202             return;
3203         }
3204         if (!session->IsVisibleForeground()) {
3205             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s session go background when throw", where);
3206             return;
3207         }
3208         if (session->throwSlipToFullScreenAnimCount_.load() == 0) {
3209             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s session moved when throw", where);
3210             return;
3211         }
3212         if (session->throwSlipToFullScreenAnimCount_.load() > 1) {
3213             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s throw-slip fullscreen animation count: %{public}u",
3214                 where, session->throwSlipToFullScreenAnimCount_.load());
3215             session->throwSlipToFullScreenAnimCount_.fetch_sub(1);
3216             return;
3217         }
3218         session->throwSlipToFullScreenAnimCount_.fetch_sub(1);
3219         if (!session->onSessionEvent_) {
3220             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s invalid callback", where);
3221             return;
3222         }
3223         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s rect: %{public}s", where, rect.ToString().c_str());
3224         session->onSessionEvent_(
3225             static_cast<uint32_t>(SessionEvent::EVENT_MAXIMIZE_WITHOUT_ANIMATION),
3226             SessionEventParam {rect.posX_, rect.posY_, rect.width_, rect.height_});
3227     }, __func__);
3228 }
3229 
ThrowSlipDirectly(const WSRectF & velocity)3230 void SceneSession::ThrowSlipDirectly(const WSRectF& velocity)
3231 {
3232     const char* const where = __func__;
3233     PostTask([weakThis = wptr(this), velocity, where] {
3234         auto session = weakThis.promote();
3235         if (session == nullptr) {
3236             TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is nullptr", where);
3237             return;
3238         }
3239         auto controller = session->pcFoldScreenController_;
3240         TLOGNI(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session: %{public}d, velocity: %{public}s",
3241             where, session->GetPersistentId(), velocity.ToString().c_str());
3242         if (!(controller && controller->IsAllowThrowSlip(session->GetScreenId()))) {
3243             TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s not allow throw slip", where);
3244             return;
3245         }
3246         if (!session->IsMovableWindowType()) {
3247             TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s not movable", where);
3248             return;
3249         }
3250         bool isFullScreen = session->IsFullScreenMovable();
3251         controller->RecordStartMoveRectDirectly(session->GetSessionRect(), velocity, isFullScreen);
3252         const WSRect& oriGlobalRect = session->GetSessionGlobalRect();
3253         WSRect globalRect = oriGlobalRect;
3254         if (!session->MoveUnderInteriaAndNotifyRectChange(globalRect, SizeChangeReason::UNDEFINED)) {
3255             TLOGNW(WmsLogTag::WMS_LAYOUT_PC, "%{public}s no throw", where);
3256             return;
3257         }
3258         if (isFullScreen) {
3259             session->UpdateFullScreenWaterfallMode(false);
3260         }
3261         WSRect rect = session->GetSessionRect();
3262         rect.posX_ += globalRect.posX_ - oriGlobalRect.posX_;
3263         rect.posY_ += globalRect.posY_ - oriGlobalRect.posY_;
3264         session->NotifySessionRectChange(globalRect, SizeChangeReason::UNDEFINED);
3265     }, __func__);
3266 }
3267 
3268 /** @note @window.drag */
OnMoveDragCallback(SizeChangeReason reason)3269 void SceneSession::OnMoveDragCallback(SizeChangeReason reason)
3270 {
3271     if (!moveDragController_) {
3272         WLOGE("moveDragController_ is null");
3273         return;
3274     }
3275     auto property = GetSessionProperty();
3276     if (property == nullptr) {
3277         TLOGE(WmsLogTag::WMS_SCB, "property is null");
3278         return;
3279     }
3280     if (reason == SizeChangeReason::DRAG_START) {
3281         InitializeCrossMoveDrag();
3282     }
3283     bool isCompatibleModeInPc = property->GetCompatibleModeInPc();
3284     bool isSupportDragInPcCompatibleMode = property->GetIsSupportDragInPcCompatibleMode();
3285     bool isMainWindow = WindowHelper::IsMainWindow(property->GetWindowType());
3286     WSRect rect = moveDragController_->GetTargetRect(
3287         MoveDragController::TargetRectCoordinate::RELATED_TO_START_DISPLAY);
3288     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
3289         "SceneSession::OnMoveDragCallback [%d, %d, %u, %u]", rect.posX_, rect.posY_, rect.width_, rect.height_);
3290     if (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_END) {
3291         UpdateWinRectForSystemBar(rect);
3292     }
3293     if (isCompatibleModeInPc && !IsFreeMultiWindowMode()) {
3294         HandleCompatibleModeMoveDrag(rect, reason);
3295     }
3296     if (IsDragResizeWhenEnd(reason)) {
3297         UpdateSizeChangeReason(reason);
3298         OnSessionEvent(SessionEvent::EVENT_DRAG);
3299         return;
3300     }
3301     moveDragController_->SetTargetRect(rect);
3302     TLOGD(WmsLogTag::WMS_LAYOUT, "Rect: [%{public}d, %{public}d, %{public}u, %{public}u], reason: %{public}d, "
3303         "isCompatibleMode: %{public}d",
3304         rect.posX_, rect.posY_, rect.width_, rect.height_, reason, isCompatibleModeInPc);
3305     WSRect relativeRect = moveDragController_->GetTargetRect(reason == SizeChangeReason::DRAG_END ?
3306         MoveDragController::TargetRectCoordinate::RELATED_TO_END_DISPLAY :
3307         MoveDragController::TargetRectCoordinate::RELATED_TO_START_DISPLAY);
3308     WSRect globalRect = moveDragController_->GetTargetRect(reason == SizeChangeReason::DRAG_END ?
3309         MoveDragController::TargetRectCoordinate::RELATED_TO_END_DISPLAY :
3310         MoveDragController::TargetRectCoordinate::GLOBAL);
3311     HandleMoveDragSurfaceNode(reason);
3312     HandleMoveDragSurfaceBounds(relativeRect, globalRect, reason);
3313     if (reason == SizeChangeReason::DRAG_END) {
3314         HandleMoveDragEnd(relativeRect, reason);
3315         SetUIFirstSwitch(RSUIFirstSwitch::NONE);
3316     } else if (reason == SizeChangeReason::DRAG_START) {
3317         OnSessionEvent(SessionEvent::EVENT_DRAG_START);
3318         NotifyUpdateGravity();
3319         SetUIFirstSwitch(RSUIFirstSwitch::FORCE_DISABLE);
3320     }
3321 }
3322 
IsDragResizeWhenEnd(SizeChangeReason reason)3323 bool SceneSession::IsDragResizeWhenEnd(SizeChangeReason reason)
3324 {
3325     auto property = GetSessionProperty();
3326     if (property == nullptr) {
3327         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
3328         return true;
3329     }
3330     bool isPcOrPcModeMainWindow = (systemConfig_.IsPcWindow() || IsFreeMultiWindowMode()) &&
3331         WindowHelper::IsMainWindow(property->GetWindowType());
3332     return reason == SizeChangeReason::DRAG && isPcOrPcModeMainWindow &&
3333         GetDragResizeTypeDuringDrag() == DragResizeType::RESIZE_WHEN_DRAG_END;
3334 }
3335 
3336 /** @note @window.drag */
HandleMoveDragSurfaceNode(SizeChangeReason reason)3337 void SceneSession::HandleMoveDragSurfaceNode(SizeChangeReason reason)
3338 {
3339     auto movedSurfaceNode = GetSurfaceNodeForMoveDrag();
3340     if (movedSurfaceNode == nullptr) {
3341         TLOGD(WmsLogTag::WMS_LAYOUT, "SurfaceNode is null");
3342         return;
3343     }
3344     if (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_MOVE) {
3345         auto rsTransaction = RSTransactionProxy::GetInstance();
3346         if (rsTransaction != nullptr) {
3347             rsTransaction->Begin();
3348         }
3349         for (const auto displayId : moveDragController_->GetNewAddedDisplayIdsDuringMoveDrag()) {
3350             if (displayId == moveDragController_->GetMoveDragStartDisplayId()) {
3351                 continue;
3352             }
3353             auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
3354             if (screenSession == nullptr) {
3355                 TLOGD(WmsLogTag::WMS_LAYOUT, "ScreenSession is null");
3356                 continue;
3357             }
3358             if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
3359                 TLOGD(WmsLogTag::WMS_LAYOUT, "virtual screen, no need to add cross parent child");
3360                 continue;
3361             }
3362             movedSurfaceNode->SetPositionZ(MOVE_DRAG_POSITION_Z);
3363             screenSession->GetDisplayNode()->AddCrossScreenChild(movedSurfaceNode, -1, true);
3364             movedSurfaceNode->SetIsCrossNode(true);
3365             TLOGD(WmsLogTag::WMS_LAYOUT, "Add window to display: %{public}" PRIu64, displayId);
3366         }
3367         if (rsTransaction != nullptr) {
3368             rsTransaction->Commit();
3369         }
3370     } else if (reason == SizeChangeReason::DRAG_END) {
3371         for (const auto displayId : moveDragController_->GetDisplayIdsDuringMoveDrag()) {
3372             if (displayId == moveDragController_->GetMoveDragStartDisplayId()) {
3373                 continue;
3374             }
3375             auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
3376             if (screenSession == nullptr) {
3377                 TLOGD(WmsLogTag::WMS_LAYOUT, "ScreenSession is null");
3378                 continue;
3379             }
3380             if (screenSession->GetScreenProperty().GetScreenType() == ScreenType::VIRTUAL) {
3381                 TLOGD(WmsLogTag::WMS_LAYOUT, "virtual screen, no need to remove cross parent child");
3382                 continue;
3383             }
3384             movedSurfaceNode->SetPositionZ(moveDragController_->GetOriginalPositionZ());
3385             screenSession->GetDisplayNode()->RemoveCrossScreenChild(movedSurfaceNode);
3386             movedSurfaceNode->SetIsCrossNode(false);
3387             TLOGD(WmsLogTag::WMS_LAYOUT, "Remove window from display: %{public}" PRIu64, displayId);
3388         }
3389     }
3390 }
3391 
3392 /** @note @window.drag */
UpdateRectForDrag(const WSRect & rect)3393 WSError SceneSession::UpdateRectForDrag(const WSRect& rect)
3394 {
3395     return PostSyncTask([weakThis = wptr(this), rect, where = __func__] {
3396         auto sceneSession = weakThis.promote();
3397         if (!sceneSession) {
3398             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
3399             return WSError::WS_ERROR_DESTROYED_OBJECT;
3400         }
3401         sceneSession->winRect_ = rect;
3402         sceneSession->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::DRAG_RECT);
3403         sceneSession->isDragging_ = true; // isDrag only reset by Vsync, not flushuiparam
3404         return WSError::WS_OK;
3405     }, __func__);
3406 }
3407 
3408 /** @note @window.drag */
UpdateWinRectForSystemBar(WSRect & rect)3409 void SceneSession::UpdateWinRectForSystemBar(WSRect& rect)
3410 {
3411     if (!specificCallback_) {
3412         WLOGFE("specificCallback_ is null!");
3413         return;
3414     }
3415     auto sessionProperty = GetSessionProperty();
3416     float tmpPosY = 0.0;
3417     std::vector<sptr<SceneSession>> statusBarVector;
3418     if (specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_) {
3419         statusBarVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
3420             WindowType::WINDOW_TYPE_STATUS_BAR, sessionProperty->GetDisplayId());
3421     }
3422     for (auto& statusBar : statusBarVector) {
3423         if (!(statusBar->isVisible_)) {
3424             continue;
3425         }
3426         WSRect statusBarRect = statusBar->GetSessionRect();
3427         if ((rect.posY_ < statusBarRect.posY_ + static_cast<int32_t>(statusBarRect.height_)) &&
3428             (rect.height_ != winRect_.height_ || rect.width_ != winRect_.width_)) {
3429             tmpPosY = rect.posY_ + rect.height_;
3430             rect.posY_ = statusBarRect.posY_ + statusBarRect.height_;
3431             rect.height_ = tmpPosY - rect.posY_;
3432         }
3433     }
3434     WLOGFD("after UpdateWinRectForSystemBar rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
3435         rect.posX_, rect.posY_, rect.width_, rect.height_);
3436 }
3437 
SetSurfaceBoundsWithAnimation(const std::pair<RSAnimationTimingProtocol,RSAnimationTimingCurve> & animationParam,const WSRect & rect,const std::function<void ()> & finishCallback,bool isGlobal)3438 void SceneSession::SetSurfaceBoundsWithAnimation(
3439     const std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve>& animationParam,
3440     const WSRect& rect, const std::function<void()>& finishCallback, bool isGlobal)
3441 {
3442     RSNode::Animate(animationParam.first, animationParam.second, [weakThis = wptr(this), rect,
3443         isGlobal, where = __func__] {
3444         auto session = weakThis.promote();
3445         if (session == nullptr) {
3446             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s session is nullptr", where);
3447             return;
3448         }
3449         session->SetSurfaceBounds(rect, isGlobal, false);
3450         RSTransaction::FlushImplicitTransaction();
3451     }, finishCallback);
3452 }
3453 
SetSurfaceBounds(const WSRect & rect,bool isGlobal,bool needFlush)3454 void SceneSession::SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush)
3455 {
3456     TLOGD(WmsLogTag::WMS_LAYOUT, "id: %{public}d, rect: %{public}s isGlobal: %{public}d needFlush: %{public}d",
3457         GetPersistentId(), rect.ToString().c_str(), isGlobal, needFlush);
3458     auto rsTransaction = RSTransactionProxy::GetInstance();
3459     if (rsTransaction != nullptr && needFlush) {
3460         rsTransaction->Begin();
3461     }
3462     auto surfaceNode = GetSurfaceNode();
3463     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3464     NotifySubAndDialogFollowRectChange(rect, isGlobal, needFlush);
3465     if (surfaceNode && leashWinSurfaceNode) {
3466         leashWinSurfaceNode->SetGlobalPositionEnabled(isGlobal);
3467         leashWinSurfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
3468         leashWinSurfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
3469         surfaceNode->SetBounds(0, 0, rect.width_, rect.height_);
3470         surfaceNode->SetFrame(0, 0, rect.width_, rect.height_);
3471     } else if (WindowHelper::IsPipWindow(GetWindowType()) && surfaceNode) {
3472         TLOGD(WmsLogTag::WMS_PIP, "PipWindow setSurfaceBounds");
3473         surfaceNode->SetGlobalPositionEnabled(isGlobal);
3474         surfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
3475         surfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
3476     } else if (WindowHelper::IsSubWindow(GetWindowType()) && surfaceNode) {
3477         WLOGFD("subwindow setSurfaceBounds");
3478         surfaceNode->SetGlobalPositionEnabled(isGlobal);
3479         surfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
3480         surfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
3481     } else if (WindowHelper::IsDialogWindow(GetWindowType()) && surfaceNode) {
3482         TLOGD(WmsLogTag::WMS_DIALOG, "dialogWindow setSurfaceBounds");
3483         surfaceNode->SetGlobalPositionEnabled(isGlobal);
3484         surfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
3485         surfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
3486     } else if (WindowHelper::IsSystemWindow(GetWindowType()) && surfaceNode) {
3487         TLOGD(WmsLogTag::WMS_SYSTEM, "system window setSurfaceBounds");
3488         surfaceNode->SetGlobalPositionEnabled(isGlobal);
3489         surfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
3490         surfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
3491     } else {
3492         WLOGE("SetSurfaceBounds surfaceNode is null!");
3493     }
3494     if (rsTransaction != nullptr && needFlush) {
3495         rsTransaction->Commit();
3496     }
3497 }
3498 
SetZOrder(uint32_t zOrder)3499 void SceneSession::SetZOrder(uint32_t zOrder)
3500 {
3501     PostTask([weakThis = wptr(this), zOrder, where = __func__] {
3502         auto session = weakThis.promote();
3503         if (session == nullptr) {
3504             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
3505             return;
3506         }
3507         if (session->zOrder_ != zOrder) {
3508             session->Session::SetZOrder(zOrder);
3509             if (session->specificCallback_ != nullptr) {
3510                 session->specificCallback_->onWindowInfoUpdate_(session->GetPersistentId(),
3511                     WindowUpdateType::WINDOW_UPDATE_PROPERTY);
3512             }
3513         }
3514     }, __func__);
3515 }
3516 
SetFloatingScale(float floatingScale)3517 void SceneSession::SetFloatingScale(float floatingScale)
3518 {
3519     if (floatingScale_ != floatingScale) {
3520         Session::SetFloatingScale(floatingScale);
3521         if (specificCallback_ != nullptr) {
3522             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
3523             if (Session::IsScbCoreEnabled()) {
3524                 MarkAvoidAreaAsDirty();
3525             } else {
3526                 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
3527             }
3528         }
3529     }
3530 }
3531 
SetParentPersistentId(int32_t parentId)3532 void SceneSession::SetParentPersistentId(int32_t parentId)
3533 {
3534     auto property = GetSessionProperty();
3535     if (property) {
3536         property->SetParentPersistentId(parentId);
3537     }
3538 }
3539 
GetParentPersistentId() const3540 int32_t SceneSession::GetParentPersistentId() const
3541 {
3542     auto property = GetSessionProperty();
3543     if (property) {
3544         return property->GetParentPersistentId();
3545     }
3546     return INVALID_SESSION_ID;
3547 }
3548 
GetMainSessionId()3549 int32_t SceneSession::GetMainSessionId()
3550 {
3551     const auto& mainSession = GetMainSession();
3552     if (mainSession) {
3553         return mainSession->GetPersistentId();
3554     }
3555     return INVALID_SESSION_ID;
3556 }
3557 
GetWindowNameAllType() const3558 std::string SceneSession::GetWindowNameAllType() const
3559 {
3560     if (GetSessionInfo().isSystem_) {
3561         return GetSessionInfo().abilityName_;
3562     } else {
3563         return GetWindowName();
3564     }
3565 }
3566 
SetTurnScreenOn(bool turnScreenOn)3567 WSError SceneSession::SetTurnScreenOn(bool turnScreenOn)
3568 {
3569     GetSessionProperty()->SetTurnScreenOn(turnScreenOn);
3570     return WSError::WS_OK;
3571 }
3572 
IsTurnScreenOn() const3573 bool SceneSession::IsTurnScreenOn() const
3574 {
3575     return GetSessionProperty()->IsTurnScreenOn();
3576 }
3577 
SetKeepScreenOn(bool keepScreenOn)3578 WSError SceneSession::SetKeepScreenOn(bool keepScreenOn)
3579 {
3580     GetSessionProperty()->SetKeepScreenOn(keepScreenOn);
3581     return WSError::WS_OK;
3582 }
3583 
IsKeepScreenOn() const3584 bool SceneSession::IsKeepScreenOn() const
3585 {
3586     return GetSessionProperty()->IsKeepScreenOn();
3587 }
3588 
SetViewKeepScreenOn(bool keepScreenOn)3589 WSError SceneSession::SetViewKeepScreenOn(bool keepScreenOn)
3590 {
3591     GetSessionProperty()->SetViewKeepScreenOn(keepScreenOn);
3592     return WSError::WS_OK;
3593 }
3594 
IsViewKeepScreenOn() const3595 bool SceneSession::IsViewKeepScreenOn() const
3596 {
3597     return GetSessionProperty()->IsViewKeepScreenOn();
3598 }
3599 
SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap> & icon)3600 void SceneSession::SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap>& icon)
3601 {
3602     WLOGFI("run SaveUpdatedIcon");
3603     if (scenePersistence_ != nullptr) {
3604         scenePersistence_->SaveUpdatedIcon(icon);
3605     }
3606 }
3607 
GetUpdatedIconPath() const3608 std::string SceneSession::GetUpdatedIconPath() const
3609 {
3610     WLOGFI("run GetUpdatedIconPath");
3611     if (scenePersistence_ != nullptr) {
3612         return scenePersistence_->GetUpdatedIconPath();
3613     }
3614     return "";
3615 }
3616 
UpdateNativeVisibility(bool visible)3617 void SceneSession::UpdateNativeVisibility(bool visible)
3618 {
3619     PostTask([weakThis = wptr(this), visible, where = __func__]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
3620         auto session = weakThis.promote();
3621         if (!session) {
3622             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
3623             return;
3624         }
3625         int32_t persistentId = session->GetPersistentId();
3626         TLOGNI(WmsLogTag::WMS_SCB, "%{public}s name: %{public}s, id: %{public}u, visible: %{public}u",
3627             where, session->sessionInfo_.bundleName_.c_str(), persistentId, visible);
3628         bool oldVisibleState = session->isVisible_;
3629         session->isVisible_ = visible;
3630         if (session->visibilityChangedDetectFunc_) {
3631             session->visibilityChangedDetectFunc_(session->GetCallingPid(), oldVisibleState, visible);
3632         }
3633         if (session->specificCallback_ == nullptr) {
3634             TLOGNW(WmsLogTag::WMS_SCB, "%{public}s specific callback is null.", where);
3635             return;
3636         }
3637         if (visible) {
3638             session->specificCallback_->onWindowInfoUpdate_(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
3639         } else {
3640             session->specificCallback_->onWindowInfoUpdate_(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
3641         }
3642         session->NotifyAccessibilityVisibilityChange();
3643         session->specificCallback_->onUpdateAvoidArea_(persistentId);
3644         // update private state
3645         if (!session->GetSessionProperty()) {
3646             TLOGNE(WmsLogTag::WMS_SCB, "%{public}s property is null", where);
3647             return;
3648         }
3649         if (session->updatePrivateStateAndNotifyFunc_ != nullptr) {
3650             session->updatePrivateStateAndNotifyFunc_(persistentId);
3651         }
3652     }, __func__);
3653 }
3654 
UpdateRotationAvoidArea()3655 void SceneSession::UpdateRotationAvoidArea()
3656 {
3657     if (specificCallback_) {
3658         if (Session::IsScbCoreEnabled()) {
3659             MarkAvoidAreaAsDirty();
3660         } else {
3661             specificCallback_->onUpdateAvoidArea_(GetPersistentId());
3662         }
3663     }
3664 }
3665 
SetPrivacyMode(bool isPrivacy)3666 void SceneSession::SetPrivacyMode(bool isPrivacy)
3667 {
3668     auto property = GetSessionProperty();
3669     if (!property) {
3670         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "property is null");
3671         return;
3672     }
3673     auto surfaceNode = GetSurfaceNode();
3674     if (!surfaceNode) {
3675         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode_ is null");
3676         return;
3677     }
3678     bool lastPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
3679     if (lastPrivacyMode == isPrivacy) {
3680         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "privacy mode does not change, isPrivacy:%{public}d", isPrivacy);
3681         return;
3682     }
3683     property->SetPrivacyMode(isPrivacy);
3684     property->SetSystemPrivacyMode(isPrivacy);
3685     auto rsTransaction = RSTransactionProxy::GetInstance();
3686     if (rsTransaction != nullptr) {
3687         rsTransaction->Begin();
3688     }
3689     surfaceNode->SetSecurityLayer(isPrivacy);
3690     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3691     if (leashWinSurfaceNode != nullptr) {
3692         leashWinSurfaceNode->SetSecurityLayer(isPrivacy);
3693     }
3694     if (rsTransaction != nullptr) {
3695         rsTransaction->Commit();
3696     }
3697     NotifyPrivacyModeChange();
3698 }
3699 
NotifyPrivacyModeChange()3700 void SceneSession::NotifyPrivacyModeChange()
3701 {
3702     bool isPrivacyMode = GetSessionProperty()->GetPrivacyMode();
3703     std::unique_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
3704     bool currExtPrivacyMode = combinedExtWindowFlags_.privacyModeFlag;
3705     TLOGD(WmsLogTag::WMS_SCB, "id:%{public}d, currExtPrivacyMode:%{public}d, session property privacyMode: %{public}d, "
3706         "last privacyMode:%{public}d",
3707         GetPersistentId(), currExtPrivacyMode, isPrivacyMode, isPrivacyMode_);
3708     bool mixedPrivacyMode = currExtPrivacyMode || isPrivacyMode;
3709     if (mixedPrivacyMode != isPrivacyMode_) {
3710         isPrivacyMode_ = mixedPrivacyMode;
3711         if (privacyModeChangeNotifyFunc_) {
3712             privacyModeChangeNotifyFunc_(isPrivacyMode_);
3713         }
3714     }
3715 }
3716 
SetSnapshotSkip(bool isSkip)3717 WMError SceneSession::SetSnapshotSkip(bool isSkip)
3718 {
3719     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3720         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, permission denied!", GetPersistentId());
3721         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3722     }
3723     auto property = GetSessionProperty();
3724     if (!property) {
3725         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "property is null");
3726         return WMError::WM_ERROR_DESTROYED_OBJECT;
3727     }
3728     auto surfaceNode = GetSurfaceNode();
3729     if (!surfaceNode) {
3730         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode_ is null");
3731         return WMError::WM_ERROR_DESTROYED_OBJECT;
3732     }
3733     bool lastSnapshotSkip = property->GetSnapshotSkip();
3734     if (lastSnapshotSkip == isSkip) {
3735         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "Snapshot skip does not change, do nothing, isSkip: %{public}d, "
3736             "id: %{public}d", isSkip, GetPersistentId());
3737         return WMError::WM_OK;
3738     }
3739     property->SetSnapshotSkip(isSkip);
3740     auto rsTransaction = RSTransactionProxy::GetInstance();
3741     if (rsTransaction != nullptr) {
3742         rsTransaction->Begin();
3743     }
3744     surfaceNode->SetSkipLayer(isSkip);
3745     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3746     if (leashWinSurfaceNode != nullptr) {
3747         leashWinSurfaceNode->SetSkipLayer(isSkip);
3748     }
3749     if (rsTransaction != nullptr) {
3750         rsTransaction->Commit();
3751     }
3752     return WMError::WM_OK;
3753 }
3754 
SetWatermarkEnabled(const std::string & watermarkName,bool isEnabled)3755 void SceneSession::SetWatermarkEnabled(const std::string& watermarkName, bool isEnabled)
3756 {
3757     auto surfaceNode = GetSurfaceNode();
3758     if (!surfaceNode) {
3759         TLOGE(WmsLogTag::DEFAULT, "surfaceNode is null");
3760         return;
3761     }
3762     TLOGI(WmsLogTag::DEFAULT, "watermarkName:%{public}s, isEnabled:%{public}d, wid:%{public}d",
3763         watermarkName.c_str(), isEnabled, GetPersistentId());
3764     auto rsTransaction = RSTransactionProxy::GetInstance();
3765     if (rsTransaction != nullptr) {
3766         rsTransaction->Begin();
3767     }
3768     surfaceNode->SetWatermarkEnabled(watermarkName, isEnabled);
3769     if (auto leashWinSurfaceNode = GetLeashWinSurfaceNode()) {
3770         leashWinSurfaceNode->SetWatermarkEnabled(watermarkName, isEnabled);
3771     }
3772     if (rsTransaction != nullptr) {
3773         rsTransaction->Commit();
3774     }
3775 }
3776 
SetPiPTemplateInfo(const PiPTemplateInfo & pipTemplateInfo)3777 void SceneSession::SetPiPTemplateInfo(const PiPTemplateInfo& pipTemplateInfo)
3778 {
3779     pipTemplateInfo_ = pipTemplateInfo;
3780 }
3781 
SetSystemSceneOcclusionAlpha(double alpha)3782 void SceneSession::SetSystemSceneOcclusionAlpha(double alpha)
3783 {
3784     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetAbilityBGAlpha");
3785     if (alpha < 0 || alpha > 1.0) {
3786         WLOGFE("OnSetSystemSceneOcclusionAlpha property is null");
3787         return;
3788     }
3789     auto surfaceNode = GetSurfaceNode();
3790     if (!surfaceNode) {
3791         WLOGFE("surfaceNode_ is null");
3792         return;
3793     }
3794     uint8_t alpha8bit = static_cast<uint8_t>(alpha * 255);
3795     WLOGFI("SetAbilityBGAlpha alpha8bit=%{public}u.", alpha8bit);
3796     auto rsTransaction = RSTransactionProxy::GetInstance();
3797     if (rsTransaction != nullptr) {
3798         rsTransaction->Begin();
3799     }
3800     surfaceNode->SetAbilityBGAlpha(alpha8bit);
3801     if (rsTransaction != nullptr) {
3802         rsTransaction->Commit();
3803     }
3804 }
3805 
ResetOcclusionAlpha()3806 void SceneSession::ResetOcclusionAlpha()
3807 {
3808     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::ResetAbilityBGAlpha");
3809     auto surfaceNode = GetSurfaceNode();
3810     if (!surfaceNode) {
3811         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode_ is null");
3812         return;
3813     }
3814     uint8_t alpha8bit = GetSessionProperty()->GetBackgroundAlpha();
3815     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "alpha8bit=%{public}u, windowId=%{public}d", alpha8bit, GetPersistentId());
3816     auto rsTransaction = RSTransactionProxy::GetInstance();
3817     if (rsTransaction != nullptr) {
3818         rsTransaction->Begin();
3819     }
3820     surfaceNode->SetAbilityBGAlpha(alpha8bit);
3821     if (rsTransaction != nullptr) {
3822         rsTransaction->Commit();
3823     }
3824 }
3825 
SetSystemSceneForceUIFirst(bool forceUIFirst)3826 void SceneSession::SetSystemSceneForceUIFirst(bool forceUIFirst)
3827 {
3828     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetForceUIFirst");
3829     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3830     auto surfaceNode = GetSurfaceNode();
3831     if (leashWinSurfaceNode == nullptr && surfaceNode == nullptr) {
3832         TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
3833         return;
3834     }
3835     auto rsTransaction = RSTransactionProxy::GetInstance();
3836     if (rsTransaction != nullptr) {
3837         rsTransaction->Begin();
3838     }
3839     if (leashWinSurfaceNode != nullptr) {
3840         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " forceUIFirst=%{public}d.",
3841             leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), forceUIFirst);
3842         leashWinSurfaceNode->SetForceUIFirst(forceUIFirst);
3843     } else if (surfaceNode != nullptr) {
3844         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " forceUIFirst=%{public}d.",
3845             surfaceNode->GetName().c_str(), surfaceNode->GetId(), forceUIFirst);
3846         surfaceNode->SetForceUIFirst(forceUIFirst);
3847     }
3848     if (rsTransaction != nullptr) {
3849         rsTransaction->Commit();
3850     }
3851 }
3852 
SetUIFirstSwitch(RSUIFirstSwitch uiFirstSwitch)3853 void SceneSession::SetUIFirstSwitch(RSUIFirstSwitch uiFirstSwitch)
3854 {
3855     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetUIFirstSwitch");
3856     auto rsTransaction = RSTransactionProxy::GetInstance();
3857     if (rsTransaction == nullptr) {
3858         TLOGE(WmsLogTag::DEFAULT, "rsTransaction is nullptr");
3859         return;
3860     }
3861     rsTransaction->Begin();
3862     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3863     auto surfaceNode = GetSurfaceNode();
3864     if (leashWinSurfaceNode != nullptr) {
3865         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " uiFirstSwitch=%{public}d",
3866             leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), uiFirstSwitch);
3867         leashWinSurfaceNode->SetUIFirstSwitch(uiFirstSwitch);
3868     } else if (surfaceNode != nullptr) {
3869         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " uiFirstSwitch=%{public}d",
3870             surfaceNode->GetName().c_str(), surfaceNode->GetId(), uiFirstSwitch);
3871         surfaceNode->SetUIFirstSwitch(uiFirstSwitch);
3872     } else {
3873         TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
3874     }
3875     rsTransaction->Commit();
3876 }
3877 
CloneWindow(NodeId surfaceNodeId)3878 void SceneSession::CloneWindow(NodeId surfaceNodeId)
3879 {
3880     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::CloneWindow");
3881     auto rsTransaction = RSTransactionProxy::GetInstance();
3882     if (rsTransaction != nullptr) {
3883         rsTransaction->Begin();
3884     }
3885     if (auto surfaceNode = GetSurfaceNode()) {
3886         TLOGI(WmsLogTag::WMS_PC, "%{public}s this: %{public}" PRIu64 " cloned: %{public}" PRIu64,
3887             surfaceNode->GetName().c_str(), surfaceNode->GetId(), surfaceNodeId);
3888         surfaceNode->SetClonedNodeId(surfaceNodeId);
3889     }
3890     if (rsTransaction != nullptr) {
3891         rsTransaction->Commit();
3892     }
3893 }
3894 
MarkSystemSceneUIFirst(bool isForced,bool isUIFirstEnabled)3895 void SceneSession::MarkSystemSceneUIFirst(bool isForced, bool isUIFirstEnabled)
3896 {
3897     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::MarkSystemSceneUIFirst");
3898     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3899     auto surfaceNode = GetSurfaceNode();
3900     if (leashWinSurfaceNode == nullptr && surfaceNode == nullptr) {
3901         TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
3902         return;
3903     }
3904     if (leashWinSurfaceNode != nullptr) {
3905         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " isForced=%{public}d. isUIFirstEnabled=%{public}d",
3906             leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), isForced, isUIFirstEnabled);
3907         leashWinSurfaceNode->MarkUifirstNode(isForced, isUIFirstEnabled);
3908     } else {
3909         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " isForced=%{public}d. isUIFirstEnabled=%{public}d",
3910             surfaceNode->GetName().c_str(), surfaceNode->GetId(), isForced, isUIFirstEnabled);
3911         surfaceNode->MarkUifirstNode(isForced, isUIFirstEnabled);
3912     }
3913 }
3914 
UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)3915 WSError SceneSession::UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)
3916 {
3917     return PostSyncTask([weakThis = wptr(this), needDefaultAnimationFlag, where = __func__] {
3918         auto session = weakThis.promote();
3919         if (!session) {
3920             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
3921             return WSError::WS_ERROR_DESTROYED_OBJECT;
3922         }
3923         session->needDefaultAnimationFlag_ = needDefaultAnimationFlag;
3924         if (session->onWindowAnimationFlagChange_) {
3925             session->onWindowAnimationFlagChange_(needDefaultAnimationFlag);
3926         }
3927         return WSError::WS_OK;
3928     }, __func__);
3929 }
3930 
SetWindowAnimationFlag(bool needDefaultAnimationFlag)3931 void SceneSession::SetWindowAnimationFlag(bool needDefaultAnimationFlag)
3932 {
3933     needDefaultAnimationFlag_ = needDefaultAnimationFlag;
3934     if (onWindowAnimationFlagChange_) {
3935         onWindowAnimationFlagChange_(needDefaultAnimationFlag);
3936     }
3937     return;
3938 }
3939 
IsNeedDefaultAnimation() const3940 bool SceneSession::IsNeedDefaultAnimation() const
3941 {
3942     return needDefaultAnimationFlag_;
3943 }
3944 
IsAppSession() const3945 bool SceneSession::IsAppSession() const
3946 {
3947     if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3948         return true;
3949     }
3950     if (GetMainSession()) {
3951         return true;
3952     }
3953     return false;
3954 }
3955 
3956 /** @note @window.focus */
IsAppOrLowerSystemSession() const3957 bool SceneSession::IsAppOrLowerSystemSession() const
3958 {
3959     WindowType windowType = GetWindowType();
3960     if (windowType == WindowType::WINDOW_TYPE_NEGATIVE_SCREEN ||
3961         windowType == WindowType::WINDOW_TYPE_GLOBAL_SEARCH ||
3962         windowType == WindowType::WINDOW_TYPE_DESKTOP) {
3963         return true;
3964     }
3965     return IsAppSession();
3966 }
3967 
3968 /** @note @window.focus */
IsSystemSessionAboveApp() const3969 bool SceneSession::IsSystemSessionAboveApp() const
3970 {
3971     WindowType windowType = GetWindowType();
3972     if (windowType == WindowType::WINDOW_TYPE_DIALOG || windowType == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
3973         return true;
3974     }
3975     if (windowType == WindowType::WINDOW_TYPE_PANEL &&
3976         sessionInfo_.bundleName_.find("SCBDropdownPanel") != std::string::npos) {
3977         return true;
3978     }
3979     if (windowType == WindowType::WINDOW_TYPE_FLOAT &&
3980         sessionInfo_.bundleName_.find("SCBGestureDock") != std::string::npos) {
3981         return true;
3982     }
3983     return false;
3984 }
3985 
3986 /** @note @window.focus */
IsSameMainSession(const sptr<SceneSession> & prevSession)3987 bool SceneSession::IsSameMainSession(const sptr<SceneSession>& prevSession)
3988 {
3989     if (prevSession == nullptr) {
3990         TLOGE(WmsLogTag::WMS_FOCUS, "prevSession is nullptr");
3991         return false;
3992     }
3993     int32_t currSessionId = GetMainSessionId();
3994     int32_t prevSessionId = prevSession->GetMainSessionId();
3995     return currSessionId == prevSessionId && prevSessionId != INVALID_SESSION_ID;
3996 }
3997 
NotifyIsCustomAnimationPlaying(bool isPlaying)3998 void SceneSession::NotifyIsCustomAnimationPlaying(bool isPlaying)
3999 {
4000     WLOGFI("id %{public}d %{public}u", GetPersistentId(), isPlaying);
4001     if (onIsCustomAnimationPlaying_) {
4002         onIsCustomAnimationPlaying_(isPlaying);
4003     }
4004 }
4005 
UpdateWindowSceneAfterCustomAnimation(bool isAdd)4006 WSError SceneSession::UpdateWindowSceneAfterCustomAnimation(bool isAdd)
4007 {
4008     if (!SessionPermission::IsSystemCalling()) {
4009         TLOGE(WmsLogTag::WMS_SYSTEM, "failed to update with id:%{public}u!", GetPersistentId());
4010         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4011     }
4012     PostTask([weakThis = wptr(this), isAdd, where = __func__] {
4013         auto session = weakThis.promote();
4014         if (!session) {
4015             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
4016             return WSError::WS_ERROR_DESTROYED_OBJECT;
4017         }
4018         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s id %{public}d, isAdd: %{public}d",
4019             where, session->GetPersistentId(), isAdd);
4020         if (isAdd) {
4021             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s SetOpacityFunc not register %{public}d",
4022                 where, session->GetPersistentId());
4023             return WSError::WS_ERROR_INVALID_OPERATION;
4024         } else {
4025             TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s background after custom animation id %{public}d",
4026                 where, session->GetPersistentId());
4027             // since background will remove surfaceNode
4028             session->Background();
4029             session->NotifyIsCustomAnimationPlaying(false);
4030         }
4031         return WSError::WS_OK;
4032     }, std::string(__func__) + ":" + std::to_string(isAdd));
4033     return WSError::WS_OK;
4034 }
4035 
IsFloatingWindowAppType() const4036 bool SceneSession::IsFloatingWindowAppType() const
4037 {
4038     auto property = GetSessionProperty();
4039     if (property == nullptr) {
4040         return false;
4041     }
4042     return property->IsFloatingWindowAppType();
4043 }
4044 
GetTouchHotAreas() const4045 std::vector<Rect> SceneSession::GetTouchHotAreas() const
4046 {
4047     std::vector<Rect> touchHotAreas;
4048     auto property = GetSessionProperty();
4049     if (property) {
4050         property->GetTouchHotAreas(touchHotAreas);
4051     }
4052     return touchHotAreas;
4053 }
4054 
GetPiPTemplateInfo() const4055 PiPTemplateInfo SceneSession::GetPiPTemplateInfo() const
4056 {
4057     return pipTemplateInfo_;
4058 }
4059 
DumpSessionElementInfo(const std::vector<std::string> & params)4060 void SceneSession::DumpSessionElementInfo(const std::vector<std::string>& params)
4061 {
4062     if (!sessionStage_) {
4063         return;
4064     }
4065     return sessionStage_->DumpSessionElementInfo(params);
4066 }
4067 
NotifyTouchOutside()4068 void SceneSession::NotifyTouchOutside()
4069 {
4070     WLOGFI("id: %{public}d, type: %{public}d", GetPersistentId(), GetWindowType());
4071     if (sessionStage_) {
4072         WLOGFD("Notify sessionStage TouchOutside");
4073         sessionStage_->NotifyTouchOutside();
4074     }
4075     if (onTouchOutside_) {
4076         WLOGFD("Notify sessionChangeCallback TouchOutside");
4077         onTouchOutside_();
4078     }
4079 }
4080 
NotifyWindowVisibility()4081 void SceneSession::NotifyWindowVisibility()
4082 {
4083     if (sessionStage_) {
4084         sessionStage_->NotifyWindowVisibility(GetRSVisible());
4085     } else {
4086         WLOGFE("Notify window(id:%{public}d) visibility failed, for this session stage is nullptr", GetPersistentId());
4087     }
4088 }
4089 
CheckTouchOutsideCallbackRegistered()4090 bool SceneSession::CheckTouchOutsideCallbackRegistered()
4091 {
4092     return onTouchOutside_ != nullptr;
4093 }
4094 
SetRequestedOrientation(Orientation orientation)4095 void SceneSession::SetRequestedOrientation(Orientation orientation)
4096 {
4097     WLOGFI("id: %{public}d orientation: %{public}u", GetPersistentId(), static_cast<uint32_t>(orientation));
4098     GetSessionProperty()->SetRequestedOrientation(orientation);
4099     if (onRequestedOrientationChange_) {
4100         onRequestedOrientationChange_(static_cast<uint32_t>(orientation));
4101     }
4102 }
4103 
SetDefaultRequestedOrientation(Orientation orientation)4104 WSError SceneSession::SetDefaultRequestedOrientation(Orientation orientation)
4105 {
4106     return PostSyncTask([weakThis = wptr(this), orientation, where = __func__]() -> WSError {
4107         auto session = weakThis.promote();
4108         if (!session) {
4109             TLOGNE(WmsLogTag::DEFAULT, "%{public}s session is null", where);
4110             return WSError::WS_ERROR_NULLPTR;
4111         }
4112         TLOGNI(WmsLogTag::DEFAULT, "%{public}s id: %{public}d defaultRequestedOrientation: %{public}u",
4113             where, session->GetPersistentId(), static_cast<uint32_t>(orientation));
4114         auto property = session->GetSessionProperty();
4115         property->SetRequestedOrientation(orientation);
4116         property->SetDefaultRequestedOrientation(orientation);
4117         return WSError::WS_OK;
4118     }, __func__);
4119 }
4120 
NotifyForceHideChange(bool hide)4121 void SceneSession::NotifyForceHideChange(bool hide)
4122 {
4123     WLOGFI("id: %{public}d forceHide: %{public}u", persistentId_, hide);
4124     auto property = GetSessionProperty();
4125     if (property == nullptr) {
4126         WLOGFD("id: %{public}d property is nullptr", persistentId_);
4127         return;
4128     }
4129     property->SetForceHide(hide);
4130     if (onForceHideChangeFunc_) {
4131         onForceHideChangeFunc_(hide);
4132     }
4133     SetForceTouchable(!hide);
4134     if (hide) {
4135         if (isFocused_) {
4136             FocusChangeReason reason = FocusChangeReason::DEFAULT;
4137             NotifyRequestFocusStatusNotifyManager(false, true, reason);
4138             SetForceHideState(ForceHideState::HIDDEN_WHEN_FOCUSED);
4139         } else if (forceHideState_ == ForceHideState::NOT_HIDDEN) {
4140             SetForceHideState(ForceHideState::HIDDEN_WHEN_UNFOCUSED);
4141         }
4142     } else {
4143         if (forceHideState_ == ForceHideState::HIDDEN_WHEN_FOCUSED) {
4144             SetForceHideState(ForceHideState::NOT_HIDDEN);
4145             FocusChangeReason reason = FocusChangeReason::DEFAULT;
4146             NotifyRequestFocusStatusNotifyManager(true, true, reason);
4147         } else {
4148             SetForceHideState(ForceHideState::NOT_HIDDEN);
4149         }
4150     }
4151 }
4152 
GetRequestedOrientation() const4153 Orientation SceneSession::GetRequestedOrientation() const
4154 {
4155     return GetSessionProperty()->GetRequestedOrientation();
4156 }
4157 
IsAnco() const4158 bool SceneSession::IsAnco() const
4159 {
4160     return collaboratorType_ == static_cast<int32_t>(CollaboratorType::RESERVE_TYPE);
4161 }
4162 
SetBlank(bool isAddBlank)4163 void SceneSession::SetBlank(bool isAddBlank)
4164 {
4165     isAddBlank_ = isAddBlank;
4166 }
4167 
GetBlank() const4168 bool SceneSession::GetBlank() const
4169 {
4170     return isAddBlank_;
4171 }
4172 
SetBufferAvailableCallbackEnable(bool enable)4173 void SceneSession::SetBufferAvailableCallbackEnable(bool enable)
4174 {
4175     bufferAvailableCallbackEnable_ = enable;
4176 }
4177 
GetBufferAvailableCallbackEnable() const4178 bool SceneSession::GetBufferAvailableCallbackEnable() const
4179 {
4180     return bufferAvailableCallbackEnable_;
4181 }
4182 
GetCollaboratorType() const4183 int32_t SceneSession::GetCollaboratorType() const
4184 {
4185     return collaboratorType_;
4186 }
4187 
SetCollaboratorType(int32_t collaboratorType)4188 void SceneSession::SetCollaboratorType(int32_t collaboratorType)
4189 {
4190     collaboratorType_ = collaboratorType;
4191     sessionInfo_.collaboratorType_ = collaboratorType;
4192 }
4193 
GetClientIdentityToken() const4194 std::string SceneSession::GetClientIdentityToken() const
4195 {
4196     return clientIdentityToken_;
4197 }
4198 
SetClientIdentityToken(const std::string & clientIdentityToken)4199 void SceneSession::SetClientIdentityToken(const std::string& clientIdentityToken)
4200 {
4201     clientIdentityToken_ = clientIdentityToken;
4202 }
4203 
DumpSessionInfo(std::vector<std::string> & info) const4204 void SceneSession::DumpSessionInfo(std::vector<std::string>& info) const
4205 {
4206     std::string dumpInfo = "      Session ID #" + std::to_string(persistentId_);
4207     info.push_back(dumpInfo);
4208     dumpInfo = "        session name [" + SessionUtils::ConvertSessionName(sessionInfo_.bundleName_,
4209         sessionInfo_.abilityName_, sessionInfo_.moduleName_, sessionInfo_.appIndex_) + "]";
4210     info.push_back(dumpInfo);
4211     dumpInfo = "        runningState [" + std::string(isActive_ ? "FOREGROUND" : "BACKGROUND") + "]";
4212     info.push_back(dumpInfo);
4213     dumpInfo = "        lockedState [" + std::to_string(sessionInfo_.lockedState) + "]";
4214     info.push_back(dumpInfo);
4215     auto abilityInfo = sessionInfo_.abilityInfo;
4216     dumpInfo = "        continuable [" + (abilityInfo ? std::to_string(abilityInfo->continuable) : " ") + "]";
4217     info.push_back(dumpInfo);
4218     dumpInfo = "        timeStamp [" + sessionInfo_.time + "]";
4219     info.push_back(dumpInfo);
4220     dumpInfo = "        label [" + (abilityInfo ? abilityInfo->label : " ") + "]";
4221     info.push_back(dumpInfo);
4222     dumpInfo = "        iconPath [" + (abilityInfo ? abilityInfo->iconPath : " ") + "]";
4223     info.push_back(dumpInfo);
4224     dumpInfo = "        want [" + (sessionInfo_.want ? sessionInfo_.want->ToUri() : " ") + "]";
4225     info.push_back(dumpInfo);
4226 }
4227 
GetAbilityInfo() const4228 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSession::GetAbilityInfo() const
4229 {
4230     return GetSessionInfo().abilityInfo;
4231 }
4232 
SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)4233 void SceneSession::SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
4234 {
4235     SetSessionInfoAbilityInfo(abilityInfo);
4236 }
4237 
SetSessionState(SessionState state)4238 void SceneSession::SetSessionState(SessionState state)
4239 {
4240     Session::SetSessionState(state);
4241     NotifyAccessibilityVisibilityChange();
4242 }
4243 
UpdateSessionState(SessionState state)4244 void SceneSession::UpdateSessionState(SessionState state)
4245 {
4246     Session::UpdateSessionState(state);
4247     NotifyAccessibilityVisibilityChange();
4248 }
4249 
IsVisibleForAccessibility() const4250 bool SceneSession::IsVisibleForAccessibility() const
4251 {
4252     if (Session::IsScbCoreEnabled()) {
4253         return GetSystemTouchable() && GetForegroundInteractiveStatus() && IsVisibleForeground();
4254     }
4255     return GetSystemTouchable() && GetForegroundInteractiveStatus() &&
4256         (IsVisible() || state_ == SessionState::STATE_ACTIVE || state_ == SessionState::STATE_FOREGROUND);
4257 }
4258 
SetForegroundInteractiveStatus(bool interactive)4259 void SceneSession::SetForegroundInteractiveStatus(bool interactive)
4260 {
4261     Session::SetForegroundInteractiveStatus(interactive);
4262     NotifyAccessibilityVisibilityChange();
4263     if (interactive) {
4264         return;
4265     }
4266     for (auto toastSession : toastSession_) {
4267         if (toastSession == nullptr) {
4268             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
4269             continue;
4270         }
4271         auto state = toastSession->GetSessionState();
4272         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
4273             continue;
4274         }
4275         toastSession->SetActive(false);
4276         toastSession->BackgroundTask();
4277     }
4278 }
4279 
NotifyAccessibilityVisibilityChange()4280 void SceneSession::NotifyAccessibilityVisibilityChange()
4281 {
4282     bool isVisibleForAccessibilityNew = IsVisibleForAccessibility();
4283     if (isVisibleForAccessibilityNew == isVisibleForAccessibility_.load()) {
4284         return;
4285     }
4286     WLOGFD("[WMSAccess] NotifyAccessibilityVisibilityChange id: %{public}d, access: %{public}d ",
4287         GetPersistentId(), isVisibleForAccessibilityNew);
4288     isVisibleForAccessibility_.store(isVisibleForAccessibilityNew);
4289     if (specificCallback_ && specificCallback_->onWindowInfoUpdate_) {
4290         if (isVisibleForAccessibilityNew) {
4291             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
4292         } else {
4293             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
4294         }
4295     } else {
4296         WLOGFD("specificCallback_->onWindowInfoUpdate_ not exist, persistent id: %{public}d", GetPersistentId());
4297     }
4298 }
4299 
SetSystemTouchable(bool touchable)4300 void SceneSession::SetSystemTouchable(bool touchable)
4301 {
4302     Session::SetSystemTouchable(touchable);
4303     NotifyAccessibilityVisibilityChange();
4304 }
4305 
ChangeSessionVisibilityWithStatusBar(const sptr<AAFwk::SessionInfo> abilitySessionInfo,bool visible)4306 WSError SceneSession::ChangeSessionVisibilityWithStatusBar(
4307     const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool visible)
4308 {
4309     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
4310         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
4311         return WSError::WS_ERROR_INVALID_PERMISSION;
4312     }
4313     PostTask([weakThis = wptr(this), abilitySessionInfo, visible, where = __func__] {
4314         auto session = weakThis.promote();
4315         if (!session) {
4316             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
4317             return WSError::WS_ERROR_DESTROYED_OBJECT;
4318         }
4319         if (abilitySessionInfo == nullptr) {
4320             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s abilitySessionInfo is null", where);
4321             return WSError::WS_ERROR_NULLPTR;
4322         }
4323 
4324         SessionInfo info;
4325         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
4326         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
4327         info.moduleName_ = abilitySessionInfo->want.GetModuleName();
4328         int32_t appCloneIndex = abilitySessionInfo->want.GetIntParam(APP_CLONE_INDEX, 0);
4329         info.appIndex_ = appCloneIndex == 0 ? abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0) : appCloneIndex;
4330         info.persistentId_ = abilitySessionInfo->persistentId;
4331         info.callerPersistentId_ = session->GetPersistentId();
4332         info.callerBundleName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_BUNDLE_NAME);
4333         info.callerAbilityName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_ABILITY_NAME);
4334         info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
4335         info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
4336         info.requestId = abilitySessionInfo->requestId;
4337         info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
4338         info.requestCode = abilitySessionInfo->requestCode;
4339         info.callerToken_ = abilitySessionInfo->callerToken;
4340         info.startSetting = abilitySessionInfo->startSetting;
4341         info.callingTokenId_ = abilitySessionInfo->callingTokenId;
4342         info.reuse = abilitySessionInfo->reuse;
4343         info.processOptions = abilitySessionInfo->processOptions;
4344 
4345         if (session->changeSessionVisibilityWithStatusBarFunc_) {
4346             session->changeSessionVisibilityWithStatusBarFunc_(info, visible);
4347         }
4348 
4349         return WSError::WS_OK;
4350     }, __func__);
4351     return WSError::WS_OK;
4352 }
4353 
MakeSessionInfoDuringPendingActivation(const sptr<AAFwk::SessionInfo> & abilitySessionInfo,const sptr<SceneSession> & session,bool isFoundationCall)4354 static SessionInfo MakeSessionInfoDuringPendingActivation(const sptr<AAFwk::SessionInfo>& abilitySessionInfo,
4355     const sptr<SceneSession>& session, bool isFoundationCall)
4356 {
4357     SessionInfo info;
4358     info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
4359     info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
4360     info.moduleName_ = abilitySessionInfo->want.GetModuleName();
4361     int32_t appCloneIndex = abilitySessionInfo->want.GetIntParam(APP_CLONE_INDEX, 0);
4362     info.appIndex_ = appCloneIndex == 0 ? abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0) : appCloneIndex;
4363     info.persistentId_ = abilitySessionInfo->persistentId;
4364     info.callerPersistentId_ = session->GetPersistentId();
4365     info.callerBundleName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_BUNDLE_NAME);
4366     info.callerAbilityName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_ABILITY_NAME);
4367     info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
4368     info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
4369     info.requestId = abilitySessionInfo->requestId;
4370     info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
4371     info.requestCode = abilitySessionInfo->requestCode;
4372     info.callerToken_ = abilitySessionInfo->callerToken;
4373     info.startSetting = abilitySessionInfo->startSetting;
4374     info.callingTokenId_ = abilitySessionInfo->callingTokenId;
4375     info.reuse = abilitySessionInfo->reuse;
4376     info.processOptions = abilitySessionInfo->processOptions;
4377     info.isAtomicService_ = abilitySessionInfo->isAtomicService;
4378     info.isBackTransition_ = abilitySessionInfo->isBackTransition;
4379     info.needClearInNotShowRecent_ = abilitySessionInfo->needClearInNotShowRecent;
4380     info.appInstanceKey_ = abilitySessionInfo->instanceKey;
4381     info.isFromIcon_ = abilitySessionInfo->isFromIcon;
4382     info.isPcOrPadEnableActivation_ = session->IsPcOrPadEnableActivation();
4383     info.canStartAbilityFromBackground_ = abilitySessionInfo->canStartAbilityFromBackground;
4384     info.isFoundationCall_ = isFoundationCall;
4385     info.specifiedFlag_ = abilitySessionInfo->specifiedFlag;
4386     if (session->IsPcOrPadEnableActivation()) {
4387         info.startWindowOption = abilitySessionInfo->startWindowOption;
4388         int32_t maxWindowWidth = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_RESV_MAX_WINDOW_WIDTH, 0);
4389         info.windowSizeLimits.maxWindowWidth = static_cast<std::uint32_t>(maxWindowWidth > 0 ? maxWindowWidth : 0);
4390         int32_t minWindowWidth = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_RESV_MIN_WINDOW_WIDTH, 0);
4391         info.windowSizeLimits.minWindowWidth = static_cast<std::uint32_t>(minWindowWidth > 0 ? minWindowWidth : 0);
4392         int32_t maxWindowHeight = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_RESV_MAX_WINDOW_HEIGHT, 0);
4393         info.windowSizeLimits.maxWindowHeight = static_cast<std::uint32_t>(maxWindowHeight > 0 ? maxWindowHeight : 0);
4394         int32_t minWindowHeight = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_RESV_MIN_WINDOW_HEIGHT, 0);
4395         info.windowSizeLimits.minWindowHeight = static_cast<std::uint32_t>(minWindowHeight > 0 ? minWindowHeight : 0);
4396         if (!abilitySessionInfo->supportWindowModes.empty()) {
4397             info.supportedWindowModes.assign(abilitySessionInfo->supportWindowModes.begin(),
4398                 abilitySessionInfo->supportWindowModes.end());
4399         }
4400     }
4401     if (info.want != nullptr) {
4402         info.windowMode = info.want->GetIntParam(AAFwk::Want::PARAM_RESV_WINDOW_MODE, 0);
4403         info.sessionAffinity = info.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
4404         info.screenId_ = static_cast<uint64_t>(info.want->GetIntParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, -1));
4405         TLOGI(WmsLogTag::WMS_LIFE, "want: screenId %{public}" PRIu64, info.screenId_);
4406     }
4407     if (info.windowMode == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN)) {
4408         info.fullScreenStart_ = true;
4409     }
4410     TLOGI(WmsLogTag::WMS_LIFE, "bundleName:%{public}s, moduleName:%{public}s, abilityName:%{public}s, "
4411         "appIndex:%{public}d, affinity:%{public}s. callState:%{public}d, want persistentId:%{public}d, "
4412         "uiAbilityId:%{public}" PRIu64 ", windowMode:%{public}d, callerId:%{public}d, "
4413         "needClearInNotShowRecent:%{public}u, appInstanceKey: %{public}s, isFromIcon:%{public}d, "
4414         "supportedWindowModes.size:%{public}zu, requestId:%{public}d, "
4415         "maxWindowWidth:%{public}d, minWindowWidth:%{public}d, maxWindowHeight:%{public}d, minWindowHeight:%{public}d",
4416         info.bundleName_.c_str(), info.moduleName_.c_str(), info.abilityName_.c_str(), info.appIndex_,
4417         info.sessionAffinity.c_str(), info.callState_, info.persistentId_, info.uiAbilityId_, info.windowMode,
4418         info.callerPersistentId_, info.needClearInNotShowRecent_, info.appInstanceKey_.c_str(), info.isFromIcon_,
4419         info.supportedWindowModes.size(), info.requestId,
4420         info.windowSizeLimits.maxWindowWidth, info.windowSizeLimits.minWindowWidth,
4421         info.windowSizeLimits.maxWindowHeight, info.windowSizeLimits.minWindowHeight);
4422     return info;
4423 }
4424 
PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)4425 WSError SceneSession::PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
4426 {
4427     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
4428         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
4429         return WSError::WS_ERROR_INVALID_PERMISSION;
4430     }
4431     bool isFoundationCall = SessionPermission::IsFoundationCall();
4432     PostTask([weakThis = wptr(this), abilitySessionInfo, isFoundationCall, where = __func__] {
4433         auto session = weakThis.promote();
4434         if (!session) {
4435             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
4436             return WSError::WS_ERROR_DESTROYED_OBJECT;
4437         }
4438         if (abilitySessionInfo == nullptr) {
4439             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s abilitySessionInfo is null", where);
4440             return WSError::WS_ERROR_NULLPTR;
4441         }
4442         bool isFromAncoAndToAnco = session->IsAnco() && AbilityInfoManager::GetInstance().IsAnco(
4443             abilitySessionInfo->want.GetElement().GetBundleName(),
4444             abilitySessionInfo->want.GetElement().GetAbilityName(), abilitySessionInfo->want.GetModuleName());
4445         if (session->DisallowActivationFromPendingBackground(session->IsPcOrPadEnableActivation(), isFoundationCall,
4446             abilitySessionInfo->canStartAbilityFromBackground, isFromAncoAndToAnco)) {
4447             return WSError::WS_ERROR_INVALID_OPERATION;
4448         }
4449         session->sessionInfo_.startMethod = StartMethod::START_CALL;
4450         SessionInfo info = MakeSessionInfoDuringPendingActivation(abilitySessionInfo, session, isFoundationCall);
4451         if (MultiInstanceManager::IsSupportMultiInstance(session->systemConfig_) &&
4452             MultiInstanceManager::GetInstance().IsMultiInstance(session->GetSessionInfo().bundleName_)) {
4453             if (!MultiInstanceManager::GetInstance().MultiInstancePendingSessionActivation(info)) {
4454                 TLOGNE(WmsLogTag::WMS_LIFE,
4455                     "%{public}s multi instance start fail, id:%{public}d instanceKey:%{public}s",
4456                     where, session->GetPersistentId(), info.appInstanceKey_.c_str());
4457                 return WSError::WS_ERROR_INVALID_PARAM;
4458             }
4459         }
4460         session->HandleCastScreenConnection(info, session);
4461         if (session->pendingSessionActivationFunc_) {
4462             session->pendingSessionActivationFunc_(info);
4463         }
4464         return WSError::WS_OK;
4465     }, __func__);
4466     return WSError::WS_OK;
4467 }
4468 
DisallowActivationFromPendingBackground(bool isPcOrPadEnableActivation,bool isFoundationCall,bool canStartAbilityFromBackground,bool isFromAncoAndToAnco)4469 bool SceneSession::DisallowActivationFromPendingBackground(bool isPcOrPadEnableActivation, bool isFoundationCall,
4470     bool canStartAbilityFromBackground, bool isFromAncoAndToAnco)
4471 {
4472     if (isPcOrPadEnableActivation || !WindowHelper::IsMainWindow(GetWindowType())) {
4473         return false;
4474     }
4475     bool isPendingToBackgroundState = GetIsPendingToBackgroundState();
4476     bool foregroundInteractiveStatus = GetForegroundInteractiveStatus();
4477     TLOGI(WmsLogTag::WMS_LIFE, "session state:%{public}d, isFoundationCall:%{public}u, "
4478         "canStartAbilityFromBackground:%{public}u, foregroundInteractiveStatus:%{public}u, "
4479         "isPendingToBackgroundState:%{public}u, isFromAncoAndToAnco:%{public}u",
4480         GetSessionState(), isFoundationCall, canStartAbilityFromBackground, foregroundInteractiveStatus,
4481         isPendingToBackgroundState, isFromAncoAndToAnco);
4482     bool isSessionForeground = GetSessionState() == SessionState::STATE_FOREGROUND ||
4483         GetSessionState() == SessionState::STATE_ACTIVE;
4484     if (isSessionForeground) {
4485         if (isPendingToBackgroundState) {
4486             if (!(isFoundationCall && canStartAbilityFromBackground) && !isFromAncoAndToAnco) {
4487                 TLOGW(WmsLogTag::WMS_LIFE, "no permission to start ability from PendingBackground, id:%{public}d",
4488                     GetPersistentId());
4489                 return true;
4490             }
4491         } else if (!foregroundInteractiveStatus) {
4492             TLOGW(WmsLogTag::WMS_LIFE, "start ability invalid, session in a non interactive state");
4493             return true;
4494         }
4495     } else if (!(isFoundationCall && canStartAbilityFromBackground) && !isFromAncoAndToAnco) {
4496         TLOGW(WmsLogTag::WMS_LIFE, "no permission to start ability from Background, id:%{public}d",
4497             GetPersistentId());
4498         return true;
4499     }
4500     return false;
4501 }
4502 
HandleCastScreenConnection(SessionInfo & info,sptr<SceneSession> session)4503 void SceneSession::HandleCastScreenConnection(SessionInfo& info, sptr<SceneSession> session)
4504 {
4505     ScreenId defScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
4506     if (defScreenId == info.screenId_) {
4507         return;
4508     }
4509     auto flag = Rosen::ScreenManager::GetInstance().GetVirtualScreenFlag(info.screenId_);
4510     if (flag != VirtualScreenFlag::CAST) {
4511         return;
4512     }
4513     TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state :%{public}d persistentId:%{public}d",
4514         session->GetSessionState(), info.callerPersistentId_);
4515     if (session->GetSessionState() != SessionState::STATE_FOREGROUND &&
4516         session->GetSessionState() != SessionState::STATE_ACTIVE) {
4517         TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state is not foreground");
4518         return;
4519     }
4520     info.isCastSession_ = true;
4521     std::vector<uint64_t> mirrorIds { info.screenId_ };
4522     Rosen::DMError ret = Rosen::ScreenManager::GetInstance().MakeUniqueScreen(mirrorIds);
4523     if (ret != Rosen::DMError::DM_OK) {
4524         TLOGE(WmsLogTag::WMS_LIFE, "MakeUniqueScreen failed,ret: %{public}d", ret);
4525         return;
4526     }
4527 }
4528 
IsNeedSystemPermissionByAction(WSPropertyChangeAction action,const sptr<WindowSessionProperty> & property,const sptr<WindowSessionProperty> & sessionProperty)4529 static bool IsNeedSystemPermissionByAction(WSPropertyChangeAction action,
4530     const sptr<WindowSessionProperty>& property, const sptr<WindowSessionProperty>& sessionProperty)
4531 {
4532     switch (action) {
4533         case WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON:
4534         case WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP:
4535         case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
4536         case WSPropertyChangeAction::ACTION_UPDATE_TOPMOST:
4537         case WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE:
4538         case WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO:
4539             return true;
4540         case WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG:
4541             return property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM);
4542         case WSPropertyChangeAction::ACTION_UPDATE_FLAGS: {
4543             uint32_t oldFlags = sessionProperty->GetWindowFlags();
4544             uint32_t flags = property->GetWindowFlags();
4545             if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) {
4546                 return true;
4547             }
4548             break;
4549         }
4550         default:
4551             break;
4552     }
4553     return false;
4554 }
4555 
UpdateSessionPropertyByAction(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4556 WMError SceneSession::UpdateSessionPropertyByAction(const sptr<WindowSessionProperty>& property,
4557     WSPropertyChangeAction action)
4558 {
4559     if (property == nullptr) {
4560         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
4561         return WMError::WM_ERROR_NULLPTR;
4562     }
4563     auto sessionProperty = GetSessionProperty();
4564     if (sessionProperty == nullptr) {
4565         TLOGE(WmsLogTag::DEFAULT, "get session property failed");
4566         return WMError::WM_ERROR_NULLPTR;
4567     }
4568     if (action == WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE) {
4569         if (!SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
4570             return WMError::WM_ERROR_INVALID_PERMISSION;
4571         }
4572     }
4573     if (action == WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST) {
4574         uint32_t accessTokenId = property->GetAccessTokenId();
4575         if (!SessionPermission::VerifyPermissionByCallerToken(accessTokenId,
4576             PermissionConstants::PERMISSION_MAIN_WINDOW_TOPMOST)) {
4577             TLOGE(WmsLogTag::WMS_HIERARCHY, "The caller has no permission granted.");
4578             return WMError::WM_ERROR_INVALID_PERMISSION;
4579         }
4580     }
4581 
4582     bool isSystemCalling = SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd();
4583     if (!isSystemCalling && IsNeedSystemPermissionByAction(action, property, sessionProperty)) {
4584         TLOGE(WmsLogTag::DEFAULT, "permission denied! action: %{public}" PRIu64, action);
4585         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4586     }
4587     property->SetSystemCalling(isSystemCalling);
4588     auto task = [weak = wptr(this), property, action, where = __func__]() -> WMError {
4589         auto sceneSession = weak.promote();
4590         if (sceneSession == nullptr) {
4591             TLOGNE(WmsLogTag::DEFAULT, "%{public}s the session is nullptr", where);
4592             return WMError::WM_DO_NOTHING;
4593         }
4594         TLOGND(WmsLogTag::DEFAULT, "%{public}s Id: %{public}d, action: %{public}" PRIu64,
4595             where, sceneSession->GetPersistentId(), action);
4596         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession:UpdateProperty");
4597         return sceneSession->HandleUpdatePropertyByAction(property, action);
4598     };
4599     if (AppExecFwk::EventRunner::IsAppMainThread()) {
4600         PostTask(std::move(task), __func__);
4601         return WMError::WM_OK;
4602     }
4603     return PostSyncTask(std::move(task), __func__);
4604 }
4605 
SetGestureBackEnabled(bool isEnabled)4606 WMError SceneSession::SetGestureBackEnabled(bool isEnabled)
4607 {
4608     PostTask([weakThis = wptr(this), isEnabled, where = __func__] {
4609         auto sceneSession = weakThis.promote();
4610         if (!sceneSession) {
4611             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is invalid", where);
4612             return;
4613         }
4614         if (sceneSession->isEnableGestureBack_ == isEnabled) {
4615             TLOGND(WmsLogTag::WMS_IMMS, "%{public}s isEnabled equals last", where);
4616             return;
4617         }
4618         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d isEnabled %{public}d",
4619             where, sceneSession->GetPersistentId(), isEnabled);
4620         sceneSession->isEnableGestureBack_ = isEnabled;
4621         sceneSession->isEnableGestureBackHadSet_ = true;
4622         sceneSession->UpdateGestureBackEnabled();
4623     }, __func__);
4624     return WMError::WM_OK;
4625 }
4626 
GetGestureBackEnabled()4627 bool SceneSession::GetGestureBackEnabled()
4628 {
4629     return isEnableGestureBack_;
4630 }
4631 
GetEnableGestureBackHadSet()4632 bool SceneSession::GetEnableGestureBackHadSet()
4633 {
4634     return isEnableGestureBackHadSet_;
4635 }
4636 
UpdateFullScreenWaterfallMode(bool isWaterfallMode)4637 void SceneSession::UpdateFullScreenWaterfallMode(bool isWaterfallMode)
4638 {
4639     PostTask([weakThis = wptr(this), isWaterfallMode, where = __func__] {
4640         auto session = weakThis.promote();
4641         if (session == nullptr) {
4642             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is nullptr", where);
4643             return;
4644         }
4645         if (session->pcFoldScreenController_ == nullptr) {
4646             return;
4647         }
4648         session->pcFoldScreenController_->UpdateFullScreenWaterfallMode(isWaterfallMode);
4649     }, __func__);
4650 }
4651 
IsFullScreenWaterfallMode()4652 bool SceneSession::IsFullScreenWaterfallMode()
4653 {
4654     if (pcFoldScreenController_ == nullptr) {
4655         return false;
4656     }
4657     return pcFoldScreenController_->IsFullScreenWaterfallMode();
4658 }
4659 
RegisterFullScreenWaterfallModeChangeCallback(std::function<void (bool isWaterfallMode)> && func)4660 void SceneSession::RegisterFullScreenWaterfallModeChangeCallback(std::function<void(bool isWaterfallMode)>&& func)
4661 {
4662     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__]() mutable {
4663         auto session = weakThis.promote();
4664         if (session == nullptr) {
4665             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is nullptr", where);
4666             return;
4667         }
4668         if (session->pcFoldScreenController_ == nullptr) {
4669             return;
4670         }
4671         session->pcFoldScreenController_->RegisterFullScreenWaterfallModeChangeCallback(std::move(func));
4672     }, __func__);
4673 }
4674 
RegisterThrowSlipAnimationStateChangeCallback(std::function<void (bool isAnimating)> && func)4675 void SceneSession::RegisterThrowSlipAnimationStateChangeCallback(std::function<void(bool isAnimating)>&& func)
4676 {
4677     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__]() mutable {
4678         auto session = weakThis.promote();
4679         if (session == nullptr) {
4680             TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is nullptr", where);
4681             return;
4682         }
4683         session->onThrowSlipAnimationStateChangeFunc_ = std::move(func);
4684     }, __func__);
4685 }
4686 
IsMissionHighlighted()4687 bool SceneSession::IsMissionHighlighted()
4688 {
4689     if (!SessionHelper::IsMainWindow(GetWindowType())) {
4690         return false;
4691     }
4692     if (IsFocused()) {
4693         return true;
4694     }
4695     return std::any_of(subSession_.begin(), subSession_.end(),
4696         [](const sptr<SceneSession>& sceneSession) {
4697             return sceneSession != nullptr && sceneSession->IsMissionHighlighted();
4698         });
4699 }
4700 
MaskSupportEnterWaterfallMode()4701 void SceneSession::MaskSupportEnterWaterfallMode()
4702 {
4703     if (pcFoldScreenController_ == nullptr) {
4704         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "pcFoldScreenController is null");
4705         return;
4706     }
4707     pcFoldScreenController_->MaskSupportEnterWaterfallMode();
4708 }
4709 
SetSupportEnterWaterfallMode(bool isSupportEnter)4710 void SceneSession::SetSupportEnterWaterfallMode(bool isSupportEnter)
4711 {
4712     if (!sessionStage_) {
4713         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sessionStage is nullptr");
4714         return;
4715     }
4716     sessionStage_->SetSupportEnterWaterfallMode(isSupportEnter);
4717 }
4718 
SetSessionChangeByActionNotifyManagerListener(const SessionChangeByActionNotifyManagerFunc & func)4719 void SceneSession::SetSessionChangeByActionNotifyManagerListener(const SessionChangeByActionNotifyManagerFunc& func)
4720 {
4721     TLOGD(WmsLogTag::DEFAULT, "setListener success");
4722     sessionChangeByActionNotifyManagerFunc_ = func;
4723 }
4724 
HandleUpdatePropertyByAction(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4725 WMError SceneSession::HandleUpdatePropertyByAction(const sptr<WindowSessionProperty>& property,
4726     WSPropertyChangeAction action)
4727 {
4728     if (property == nullptr) {
4729         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
4730         return WMError::WM_ERROR_NULLPTR;
4731     }
4732 
4733     return ProcessUpdatePropertyByAction(property, action);
4734 }
4735 
ProcessUpdatePropertyByAction(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4736 WMError SceneSession::ProcessUpdatePropertyByAction(const sptr<WindowSessionProperty>& property,
4737     WSPropertyChangeAction action)
4738 {
4739     switch (static_cast<uint64_t>(action)) {
4740         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON):
4741             return HandleActionUpdateTurnScreenOn(property, action);
4742         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON):
4743             return HandleActionUpdateKeepScreenOn(property, action);
4744         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_VIEW_KEEP_SCREEN_ON):
4745             return HandleActionUpdateViewKeepScreenOn(property, action);
4746         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE):
4747             return HandleActionUpdateFocusable(property, action);
4748         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE):
4749             return HandleActionUpdateTouchable(property, action);
4750         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS):
4751             return HandleActionUpdateSetBrightness(property, action);
4752         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_ORIENTATION):
4753             return HandleActionUpdateOrientation(property, action);
4754         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE):
4755             return HandleActionUpdatePrivacyMode(property, action);
4756         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE):
4757             return HandleActionUpdatePrivacyMode(property, action);
4758         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP):
4759             return HandleActionUpdateSnapshotSkip(property, action);
4760         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE):
4761             return HandleActionUpdateMaximizeState(property, action);
4762         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS):
4763             return HandleActionUpdateOtherProps(property, action);
4764         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS):
4765             return HandleActionUpdateStatusProps(property, action);
4766         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS):
4767             return HandleActionUpdateNavigationProps(property, action);
4768         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS):
4769             return HandleActionUpdateNavigationIndicatorProps(property, action);
4770         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_FLAGS):
4771             return HandleActionUpdateFlags(property, action);
4772         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_MODE):
4773             return HandleActionUpdateMode(property, action);
4774         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG):
4775             return HandleActionUpdateAnimationFlag(property, action);
4776         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA):
4777             return HandleActionUpdateTouchHotArea(property, action);
4778         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_KEYBOARD_TOUCH_HOT_AREA):
4779             return HandleActionUpdateKeyboardTouchHotArea(property, action);
4780         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE):
4781             return HandleActionUpdateDecorEnable(property, action);
4782         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS):
4783             return HandleActionUpdateWindowLimits(property, action);
4784         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED):
4785             return HandleActionUpdateDragenabled(property, action);
4786         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED):
4787             return HandleActionUpdateRaiseenabled(property, action);
4788         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS):
4789             return HandleActionUpdateHideNonSystemFloatingWindows(property, action);
4790         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO):
4791             return HandleActionUpdateTextfieldAvoidInfo(property, action);
4792         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK):
4793             return HandleActionUpdateWindowMask(property, action);
4794         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_TOPMOST):
4795             return HandleActionUpdateTopmost(property, action);
4796         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST):
4797             return HandleActionUpdateMainWindowTopmost(property, action);
4798         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_SUB_WINDOW_Z_LEVEL):
4799             return HandleActionUpdateSubWindowZLevel(property, action);
4800         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO):
4801             return HandleActionUpdateWindowModeSupportType(property, action);
4802         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_AVOID_AREA_OPTION):
4803             return HandleActionUpdateAvoidAreaOption(property, action);
4804         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_BACKGROUND_ALPHA):
4805             return HandleBackgroundAlpha(property, action);
4806         case static_cast<uint64_t>(WSPropertyChangeAction::ACTION_UPDATE_EXCLUSIVE_HIGHLIGHTED):
4807             return HandleActionUpdateExclusivelyHighlighted(property, action);
4808         default:
4809             TLOGE(WmsLogTag::DEFAULT, "Failed to find func handler!");
4810             return WMError::WM_DO_NOTHING;
4811     }
4812 }
4813 
HandleActionUpdateTurnScreenOn(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4814 WMError SceneSession::HandleActionUpdateTurnScreenOn(const sptr<WindowSessionProperty>& property,
4815     WSPropertyChangeAction action)
4816 {
4817     SetTurnScreenOn(property->IsTurnScreenOn());
4818 #ifdef POWER_MANAGER_ENABLE
4819     PostTask([weakThis = wptr(this), where = __func__] {
4820         auto sceneSession = weakThis.promote();
4821         if (!sceneSession) {
4822             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s session is invalid", where);
4823             return;
4824         }
4825         TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s Win: %{public}s, is turn on: %{public}d",
4826             where, sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
4827         std::string identity = IPCSkeleton::ResetCallingIdentity();
4828         if (sceneSession->IsTurnScreenOn()) {
4829             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s turn screen on", where);
4830             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
4831         }
4832         // set ipc identity to raw
4833         IPCSkeleton::SetCallingIdentity(identity);
4834     }, __func__);
4835 #else
4836     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
4837 #endif
4838     return WMError::WM_OK;
4839 }
4840 
HandleActionUpdateKeepScreenOn(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4841 WMError SceneSession::HandleActionUpdateKeepScreenOn(const sptr<WindowSessionProperty>& property,
4842     WSPropertyChangeAction action)
4843 {
4844     SetKeepScreenOn(property->IsKeepScreenOn());
4845     NotifySessionChangeByActionNotifyManager(property, action);
4846     return WMError::WM_OK;
4847 }
4848 
HandleActionUpdateViewKeepScreenOn(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4849 WMError SceneSession::HandleActionUpdateViewKeepScreenOn(const sptr<WindowSessionProperty>& property,
4850     WSPropertyChangeAction action)
4851 {
4852     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, enabled: %{public}u",
4853         GetPersistentId(), property->IsViewKeepScreenOn());
4854     SetViewKeepScreenOn(property->IsViewKeepScreenOn());
4855     NotifySessionChangeByActionNotifyManager(property, action);
4856     return WMError::WM_OK;
4857 }
4858 
HandleActionUpdateFocusable(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4859 WMError SceneSession::HandleActionUpdateFocusable(const sptr<WindowSessionProperty>& property,
4860     WSPropertyChangeAction action)
4861 {
4862     SetFocusable(property->GetFocusable());
4863     NotifySessionChangeByActionNotifyManager(property, action);
4864     return WMError::WM_OK;
4865 }
4866 
HandleActionUpdateTouchable(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4867 WMError SceneSession::HandleActionUpdateTouchable(const sptr<WindowSessionProperty>& property,
4868     WSPropertyChangeAction action)
4869 {
4870     SetTouchable(property->GetTouchable());
4871     NotifySessionChangeByActionNotifyManager(property, action);
4872     return WMError::WM_OK;
4873 }
4874 
HandleActionUpdateSetBrightness(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4875 WMError SceneSession::HandleActionUpdateSetBrightness(const sptr<WindowSessionProperty>& property,
4876     WSPropertyChangeAction action)
4877 {
4878     if (GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4879         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window can set brightness");
4880         return WMError::WM_OK;
4881     }
4882     if (!IsSessionValid()) {
4883         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
4884             GetPersistentId(), GetSessionState());
4885         return WMError::WM_ERROR_INVALID_SESSION;
4886     }
4887     float brightness = property->GetBrightness();
4888     if (std::abs(brightness - GetBrightness()) < std::numeric_limits<float>::epsilon()) {
4889         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Session brightness do not change: [%{public}f]", brightness);
4890         return WMError::WM_OK;
4891     }
4892     SetBrightness(brightness);
4893     NotifySessionChangeByActionNotifyManager(property, action);
4894     return WMError::WM_OK;
4895 }
4896 
HandleActionUpdateOrientation(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4897 WMError SceneSession::HandleActionUpdateOrientation(const sptr<WindowSessionProperty>& property,
4898     WSPropertyChangeAction action)
4899 {
4900     SetRequestedOrientation(property->GetRequestedOrientation());
4901     return WMError::WM_OK;
4902 }
4903 
HandleActionUpdatePrivacyMode(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4904 WMError SceneSession::HandleActionUpdatePrivacyMode(const sptr<WindowSessionProperty>& property,
4905     WSPropertyChangeAction action)
4906 {
4907     bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
4908     SetPrivacyMode(isPrivacyMode);
4909     NotifySessionChangeByActionNotifyManager(property, action);
4910     return WMError::WM_OK;
4911 }
4912 
HandleActionUpdateSnapshotSkip(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4913 WMError SceneSession::HandleActionUpdateSnapshotSkip(const sptr<WindowSessionProperty>& property,
4914     WSPropertyChangeAction action)
4915 {
4916     return SetSnapshotSkip(property->GetSnapshotSkip());
4917 }
4918 
HandleActionUpdateMaximizeState(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4919 WMError SceneSession::HandleActionUpdateMaximizeState(const sptr<WindowSessionProperty>& property,
4920     WSPropertyChangeAction action)
4921 {
4922     auto sessionProperty = GetSessionProperty();
4923     if (sessionProperty != nullptr) {
4924         sessionProperty->SetMaximizeMode(property->GetMaximizeMode());
4925         sessionProperty->SetIsLayoutFullScreen(property->IsLayoutFullScreen());
4926     }
4927     return WMError::WM_OK;
4928 }
4929 
HandleActionUpdateOtherProps(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4930 WMError SceneSession::HandleActionUpdateOtherProps(const sptr<WindowSessionProperty>& property,
4931     WSPropertyChangeAction action)
4932 {
4933     auto systemBarProperties = property->GetSystemBarProperty();
4934     for (auto iter : systemBarProperties) {
4935         SetSystemBarProperty(iter.first, iter.second);
4936     }
4937     NotifySessionChangeByActionNotifyManager(property, action);
4938     return WMError::WM_OK;
4939 }
4940 
HandleActionUpdateStatusProps(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4941 WMError SceneSession::HandleActionUpdateStatusProps(const sptr<WindowSessionProperty>& property,
4942     WSPropertyChangeAction action)
4943 {
4944     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, property);
4945     NotifySessionChangeByActionNotifyManager(property, action);
4946     return WMError::WM_OK;
4947 }
4948 
HandleActionUpdateNavigationProps(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4949 WMError SceneSession::HandleActionUpdateNavigationProps(const sptr<WindowSessionProperty>& property,
4950     WSPropertyChangeAction action)
4951 {
4952     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, property);
4953     NotifySessionChangeByActionNotifyManager(property, action);
4954     return WMError::WM_OK;
4955 }
4956 
HandleActionUpdateNavigationIndicatorProps(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4957 WMError SceneSession::HandleActionUpdateNavigationIndicatorProps(const sptr<WindowSessionProperty>& property,
4958     WSPropertyChangeAction action)
4959 {
4960     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, property);
4961     NotifySessionChangeByActionNotifyManager(property, action);
4962     return WMError::WM_OK;
4963 }
4964 
HandleActionUpdateFlags(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4965 WMError SceneSession::HandleActionUpdateFlags(const sptr<WindowSessionProperty>& property,
4966     WSPropertyChangeAction action)
4967 {
4968     SetWindowFlags(property);
4969     NotifySessionChangeByActionNotifyManager(property, action);
4970     return WMError::WM_OK;
4971 }
4972 
HandleActionUpdateMode(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4973 WMError SceneSession::HandleActionUpdateMode(const sptr<WindowSessionProperty>& property,
4974     WSPropertyChangeAction action)
4975 {
4976     auto sessionProperty = GetSessionProperty();
4977     if (sessionProperty != nullptr) {
4978         sessionProperty->SetWindowMode(property->GetWindowMode());
4979     }
4980     NotifySessionChangeByActionNotifyManager(property, action);
4981     return WMError::WM_OK;
4982 }
4983 
HandleActionUpdateAnimationFlag(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4984 WMError SceneSession::HandleActionUpdateAnimationFlag(const sptr<WindowSessionProperty>& property,
4985     WSPropertyChangeAction action)
4986 {
4987     auto sessionProperty = GetSessionProperty();
4988     if (sessionProperty != nullptr) {
4989         sessionProperty->SetAnimationFlag(property->GetAnimationFlag());
4990     }
4991     return WMError::WM_OK;
4992 }
4993 
HandleActionUpdateTouchHotArea(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4994 WMError SceneSession::HandleActionUpdateTouchHotArea(const sptr<WindowSessionProperty>& property,
4995     WSPropertyChangeAction action)
4996 {
4997     std::vector<Rect> touchHotAreas;
4998     property->GetTouchHotAreas(touchHotAreas);
4999     GetSessionProperty()->SetTouchHotAreas(touchHotAreas);
5000     return WMError::WM_OK;
5001 }
5002 
HandleActionUpdateKeyboardTouchHotArea(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5003 WMError SceneSession::HandleActionUpdateKeyboardTouchHotArea(const sptr<WindowSessionProperty>& property,
5004     WSPropertyChangeAction action)
5005 {
5006     if (GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
5007         return WMError::WM_ERROR_INVALID_TYPE;
5008     }
5009     GetSessionProperty()->SetKeyboardTouchHotAreas(property->GetKeyboardTouchHotAreas());
5010     return WMError::WM_OK;
5011 }
5012 
HandleActionUpdateDecorEnable(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5013 WMError SceneSession::HandleActionUpdateDecorEnable(const sptr<WindowSessionProperty>& property,
5014     WSPropertyChangeAction action)
5015 {
5016     if (property != nullptr && !property->GetSystemCalling()) {
5017         TLOGE(WmsLogTag::DEFAULT, "update decor enable permission denied!");
5018         return WMError::WM_ERROR_NOT_SYSTEM_APP;
5019     }
5020     auto sessionProperty = GetSessionProperty();
5021     if (sessionProperty != nullptr) {
5022         sessionProperty->SetDecorEnable(property->IsDecorEnable());
5023     }
5024     return WMError::WM_OK;
5025 }
5026 
HandleActionUpdateWindowLimits(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5027 WMError SceneSession::HandleActionUpdateWindowLimits(const sptr<WindowSessionProperty>& property,
5028     WSPropertyChangeAction action)
5029 {
5030     auto sessionProperty = GetSessionProperty();
5031     if (sessionProperty != nullptr) {
5032         sessionProperty->SetWindowLimits(property->GetWindowLimits());
5033         WindowLimits windowLimits = sessionProperty->GetWindowLimits();
5034         TLOGI(WmsLogTag::WMS_LAYOUT, "UpdateWindowLimits minWidth:%{public}u, minHeight:%{public}u, "
5035             "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", windowLimits.minWidth_,
5036             windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
5037     }
5038     return WMError::WM_OK;
5039 }
5040 
HandleActionUpdateDragenabled(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5041 WMError SceneSession::HandleActionUpdateDragenabled(const sptr<WindowSessionProperty>& property,
5042     WSPropertyChangeAction action)
5043 {
5044     auto sessionProperty = GetSessionProperty();
5045     if (sessionProperty != nullptr) {
5046         sessionProperty->SetDragEnabled(property->GetDragEnabled());
5047     }
5048     return WMError::WM_OK;
5049 }
5050 
HandleActionUpdateRaiseenabled(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5051 WMError SceneSession::HandleActionUpdateRaiseenabled(const sptr<WindowSessionProperty>& property,
5052     WSPropertyChangeAction action)
5053 {
5054     auto sessionProperty = GetSessionProperty();
5055     if (sessionProperty != nullptr) {
5056         TLOGI(WmsLogTag::WMS_HIERARCHY, "id: %{public}d, raise enabled: %{public}d", GetPersistentId(),
5057             property->GetRaiseEnabled());
5058         sessionProperty->SetRaiseEnabled(property->GetRaiseEnabled());
5059     }
5060     return WMError::WM_OK;
5061 }
5062 
HandleActionUpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5063 WMError SceneSession::HandleActionUpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
5064     WSPropertyChangeAction action)
5065 {
5066     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5067         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Update property hideNonSystemFloatingWindows permission denied!");
5068         return WMError::WM_OK;
5069     }
5070     auto currentProperty = GetSessionProperty();
5071     if (currentProperty != nullptr) {
5072         NotifySessionChangeByActionNotifyManager(property, action);
5073         currentProperty->SetHideNonSystemFloatingWindows(property->GetHideNonSystemFloatingWindows());
5074     }
5075     return WMError::WM_OK;
5076 }
5077 
HandleActionUpdateTextfieldAvoidInfo(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5078 WMError SceneSession::HandleActionUpdateTextfieldAvoidInfo(const sptr<WindowSessionProperty>& property,
5079     WSPropertyChangeAction action)
5080 {
5081     auto sessionProperty = GetSessionProperty();
5082     if (sessionProperty != nullptr) {
5083         sessionProperty->SetTextFieldPositionY(property->GetTextFieldPositionY());
5084         sessionProperty->SetTextFieldHeight(property->GetTextFieldHeight());
5085     }
5086     return WMError::WM_OK;
5087 }
5088 
HandleActionUpdateWindowMask(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5089 WMError SceneSession::HandleActionUpdateWindowMask(const sptr<WindowSessionProperty>& property,
5090     WSPropertyChangeAction action)
5091 {
5092     auto sessionProperty = GetSessionProperty();
5093     if (sessionProperty != nullptr) {
5094         sessionProperty->SetWindowMask(property->GetWindowMask());
5095         sessionProperty->SetIsShaped(property->GetIsShaped());
5096         NotifySessionChangeByActionNotifyManager(property, action);
5097     }
5098     return WMError::WM_OK;
5099 }
5100 
HandleActionUpdateTopmost(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5101 WMError SceneSession::HandleActionUpdateTopmost(const sptr<WindowSessionProperty>& property,
5102     WSPropertyChangeAction action)
5103 {
5104     if (!SessionPermission::IsSystemCalling()) {
5105         TLOGE(WmsLogTag::WMS_HIERARCHY, "UpdateTopmostProperty permission denied!");
5106         return WMError::WM_ERROR_NOT_SYSTEM_APP;
5107     }
5108 
5109     SetTopmost(property->IsTopmost());
5110     return WMError::WM_OK;
5111 }
5112 
HandleActionUpdateMainWindowTopmost(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5113 WMError SceneSession::HandleActionUpdateMainWindowTopmost(const sptr<WindowSessionProperty>& property,
5114     WSPropertyChangeAction action)
5115 {
5116     SetMainWindowTopmost(property->IsMainWindowTopmost());
5117     return WMError::WM_OK;
5118 }
5119 
HandleActionUpdateSubWindowZLevel(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5120 WMError SceneSession::HandleActionUpdateSubWindowZLevel(const sptr<WindowSessionProperty>& property,
5121     WSPropertyChangeAction action)
5122 {
5123     SetSubWindowZLevel(property->GetSubWindowZLevel());
5124     return WMError::WM_OK;
5125 }
5126 
HandleActionUpdateAvoidAreaOption(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5127 WMError SceneSession::HandleActionUpdateAvoidAreaOption(const sptr<WindowSessionProperty>& property,
5128     WSPropertyChangeAction action)
5129 {
5130     auto sessionProperty = GetSessionProperty();
5131     if (!SessionHelper::IsSubWindow(sessionProperty->GetWindowType()) &&
5132         !SessionHelper::IsSystemWindow(sessionProperty->GetWindowType())) {
5133         return WMError::WM_ERROR_INVALID_WINDOW;
5134     }
5135     sessionProperty->SetAvoidAreaOption(property->GetAvoidAreaOption());
5136     return WMError::WM_OK;
5137 }
5138 
HandleBackgroundAlpha(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5139 WMError SceneSession::HandleBackgroundAlpha(const sptr<WindowSessionProperty>& property,
5140     WSPropertyChangeAction action)
5141 {
5142     auto sessionProperty = GetSessionProperty();
5143     if (!sessionProperty) {
5144         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "property is null");
5145         return WMError::WM_ERROR_INVALID_PARAM;
5146     }
5147     sessionProperty->SetBackgroundAlpha(property->GetBackgroundAlpha());
5148     return WMError::WM_OK;
5149 }
5150 
HandleActionUpdateExclusivelyHighlighted(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5151 WMError SceneSession::HandleActionUpdateExclusivelyHighlighted(const sptr<WindowSessionProperty>& property,
5152     WSPropertyChangeAction action)
5153 {
5154     auto sessionProperty = GetSessionProperty();
5155     if (!sessionProperty) {
5156         TLOGE(WmsLogTag::WMS_FOCUS, "property is null");
5157         return WMError::WM_ERROR_INVALID_PARAM;
5158     }
5159     sessionProperty->SetExclusivelyHighlighted(property->GetExclusivelyHighlighted());
5160     return WMError::WM_OK;
5161 }
5162 
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property)5163 void SceneSession::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property)
5164 {
5165     auto systemBarProperties = property->GetSystemBarProperty();
5166     if (auto iter = systemBarProperties.find(type); iter != systemBarProperties.end()) {
5167         SetSystemBarProperty(iter->first, iter->second);
5168         TLOGD(WmsLogTag::WMS_IMMS, "type %{public}d enable %{public}d",
5169             static_cast<int32_t>(iter->first), iter->second.enable_);
5170     }
5171 }
5172 
SetWindowFlags(const sptr<WindowSessionProperty> & property)5173 void SceneSession::SetWindowFlags(const sptr<WindowSessionProperty>& property)
5174 {
5175     auto sessionProperty = GetSessionProperty();
5176     if (sessionProperty == nullptr) {
5177         TLOGE(WmsLogTag::DEFAULT, "get session property failed");
5178         return;
5179     }
5180     uint32_t flags = property->GetWindowFlags();
5181     uint32_t oldFlags = sessionProperty->GetWindowFlags();
5182     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
5183          (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
5184         !property->GetSystemCalling()) {
5185         TLOGE(WmsLogTag::DEFAULT, "Set window flags permission denied");
5186         return;
5187     }
5188     sessionProperty->SetWindowFlags(flags);
5189     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
5190         OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
5191     }
5192     TLOGI(WmsLogTag::DEFAULT, "flags: %{public}u", flags);
5193 }
5194 
NotifySessionChangeByActionNotifyManager(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)5195 void SceneSession::NotifySessionChangeByActionNotifyManager(const sptr<WindowSessionProperty>& property,
5196     WSPropertyChangeAction action)
5197 {
5198     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, action: %{public}" PRIu64, GetPersistentId(), action);
5199     if (sessionChangeByActionNotifyManagerFunc_ == nullptr) {
5200         TLOGW(WmsLogTag::DEFAULT, "func is null");
5201         return;
5202     }
5203     sessionChangeByActionNotifyManagerFunc_(this, property, action);
5204 }
5205 
TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)5206 WSError SceneSession::TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
5207 {
5208     PostLifeCycleTask([weakThis = wptr(this), abilitySessionInfo, where = __func__] {
5209         auto session = weakThis.promote();
5210         if (!session) {
5211             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
5212             return WSError::WS_ERROR_DESTROYED_OBJECT;
5213         }
5214         if (abilitySessionInfo == nullptr) {
5215             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s abilitySessionInfo is null", where);
5216             session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
5217             return WSError::WS_ERROR_NULLPTR;
5218         }
5219         if (session->isTerminating_) {
5220             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s is terminating, return!", where);
5221             session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
5222             return WSError::WS_ERROR_INVALID_OPERATION;
5223         }
5224         session->isTerminating_ = true;
5225         SessionInfo info;
5226         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
5227         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
5228         info.callerToken_ = abilitySessionInfo->callerToken;
5229         info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
5230         {
5231             std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
5232             session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
5233             session->sessionInfo_.resultCode = abilitySessionInfo->resultCode;
5234         }
5235         if (session->terminateSessionFunc_) {
5236             session->terminateSessionFunc_(info);
5237         }
5238         return WSError::WS_OK;
5239     }, __func__, LifeCycleTaskType::STOP);
5240     return WSError::WS_OK;
5241 }
5242 
NotifySessionExceptionInner(const sptr<AAFwk::SessionInfo> abilitySessionInfo,const ExceptionInfo & exceptionInfo,bool isFromClient,bool startFail)5243 WSError SceneSession::NotifySessionExceptionInner(const sptr<AAFwk::SessionInfo> abilitySessionInfo,
5244     const ExceptionInfo& exceptionInfo, bool isFromClient, bool startFail)
5245 {
5246     PostLifeCycleTask([weakThis = wptr(this), abilitySessionInfo, exceptionInfo,
5247         isFromClient, startFail, where = __func__] {
5248         auto session = weakThis.promote();
5249         if (!session) {
5250             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
5251             return WSError::WS_ERROR_DESTROYED_OBJECT;
5252         }
5253         if (abilitySessionInfo == nullptr) {
5254             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s abilitySessionInfo is null", where);
5255             session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
5256             return WSError::WS_ERROR_NULLPTR;
5257         }
5258         if (SessionHelper::IsMainWindow(session->GetWindowType()) && !session->clientIdentityToken_.empty() &&
5259             isFromClient && (abilitySessionInfo->errorReason != ERROR_REASON_LOW_MEMORY_KILL &&
5260             session->clientIdentityToken_ != abilitySessionInfo->identityToken)) {
5261             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s client exception not matched: %{public}s, %{public}s",
5262                 where, session->clientIdentityToken_.c_str(), abilitySessionInfo->identityToken.c_str());
5263             session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
5264             return WSError::WS_ERROR_INVALID_PARAM;
5265         }
5266         if (session->isTerminating_) {
5267             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s is terminating, return!", where);
5268             session->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
5269             return WSError::WS_ERROR_INVALID_OPERATION;
5270         }
5271         session->isTerminating_ = true;
5272         SessionInfo info;
5273         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
5274         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
5275         info.callerToken_ = abilitySessionInfo->callerToken;
5276         info.errorCode = abilitySessionInfo->errorCode;
5277         info.errorReason = abilitySessionInfo->errorReason;
5278         info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
5279         {
5280             std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
5281             session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
5282             session->sessionInfo_.errorCode = abilitySessionInfo->errorCode;
5283             session->sessionInfo_.errorReason = abilitySessionInfo->errorReason;
5284         }
5285         if (session->sessionExceptionFunc_) {
5286             session->sessionExceptionFunc_(info, exceptionInfo, false);
5287         }
5288         if (session->jsSceneSessionExceptionFunc_) {
5289             session->jsSceneSessionExceptionFunc_(info, exceptionInfo, startFail);
5290         }
5291         return WSError::WS_OK;
5292     }, __func__, LifeCycleTaskType::STOP);
5293     return WSError::WS_OK;
5294 }
5295 
NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo,const ExceptionInfo & exceptionInfo)5296 WSError SceneSession::NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo,
5297     const ExceptionInfo& exceptionInfo)
5298 {
5299     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
5300         TLOGE(WmsLogTag::WMS_LIFE, "permission failed.");
5301         return WSError::WS_ERROR_INVALID_PERMISSION;
5302     }
5303     return NotifySessionExceptionInner(abilitySessionInfo, exceptionInfo, true);
5304 }
5305 
GetLastSafeRect() const5306 WSRect SceneSession::GetLastSafeRect() const
5307 {
5308     return lastSafeRect;
5309 }
5310 
SetLastSafeRect(WSRect rect)5311 void SceneSession::SetLastSafeRect(WSRect rect)
5312 {
5313     lastSafeRect.posX_ = rect.posX_;
5314     lastSafeRect.posY_ = rect.posY_;
5315     lastSafeRect.width_ = rect.width_;
5316     lastSafeRect.height_ = rect.height_;
5317     return;
5318 }
5319 
SetMovable(bool movable)5320 void SceneSession::SetMovable(bool movable)
5321 {
5322     PostTask([weakThis = wptr(this), movable, where = __func__] {
5323         auto session = weakThis.promote();
5324         if (!session) {
5325             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
5326             return;
5327         }
5328         if (session->moveDragController_) {
5329             TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s id: %{public}d, isMovable: %{public}d",
5330                 where, session->GetPersistentId(), movable);
5331             session->moveDragController_->SetMovable(movable);
5332         }
5333     }, __func__);
5334 }
5335 
SetSplitButtonVisible(bool isVisible)5336 WSError SceneSession::SetSplitButtonVisible(bool isVisible)
5337 {
5338     TLOGI(WmsLogTag::WMS_LAYOUT, "isVisible: %{public}d", isVisible);
5339     if (!sessionStage_) {
5340         TLOGE(WmsLogTag::WMS_LAYOUT, "sessionStage is null");
5341         return WSError::WS_ERROR_NULLPTR;
5342     }
5343     return sessionStage_->SetSplitButtonVisible(isVisible);
5344 }
5345 
SendContainerModalEvent(const std::string & eventName,const std::string & eventValue)5346 WSError SceneSession::SendContainerModalEvent(const std::string& eventName, const std::string& eventValue)
5347 {
5348     TLOGI(WmsLogTag::WMS_EVENT, "name: %{public}s, value: %{public}s", eventName.c_str(), eventValue.c_str());
5349     if (!sessionStage_) {
5350         TLOGE(WmsLogTag::WMS_EVENT, "sessionStage is null");
5351         return WSError::WS_ERROR_NULLPTR;
5352     }
5353     return sessionStage_->SendContainerModalEvent(eventName, eventValue);
5354 }
5355 
OnContainerModalEvent(const std::string & eventName,const std::string & eventValue)5356 WSError SceneSession::OnContainerModalEvent(const std::string& eventName, const std::string& eventValue)
5357 {
5358     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "name: %{public}s, value: %{public}s", eventName.c_str(), eventValue.c_str());
5359     if (eventName == WINDOW_RELOCATION_EVENT) {
5360         if (eventValue == "true") {
5361             ThrowSlipDirectly(VELOCITY_RELOCATION_TO_TOP);
5362         } else {
5363             ThrowSlipDirectly(VELOCITY_RELOCATION_TO_BOTTOM);
5364         }
5365     }
5366     return WSError::WS_OK;
5367 }
5368 
RegisterSetLandscapeMultiWindowFunc(NotifyLandscapeMultiWindowSessionFunc && callback)5369 void SceneSession::RegisterSetLandscapeMultiWindowFunc(NotifyLandscapeMultiWindowSessionFunc&& callback)
5370 {
5371     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
5372         auto session = weakThis.promote();
5373         if (!session) {
5374             TLOGNE(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s session is null", where);
5375             return;
5376         }
5377         session->onSetLandscapeMultiWindowFunc_ = std::move(callback);
5378     }, __func__);
5379 }
5380 
GetOriPosYBeforeRaisedByKeyboard() const5381 int32_t SceneSession::GetOriPosYBeforeRaisedByKeyboard() const
5382 {
5383     return oriPosYBeforeRaisedByKeyboard_;
5384 }
5385 
SetOriPosYBeforeRaisedByKeyboard(int32_t posY)5386 void SceneSession::SetOriPosYBeforeRaisedByKeyboard(int32_t posY)
5387 {
5388     oriPosYBeforeRaisedByKeyboard_ = posY;
5389 }
5390 
AddSubSession(const sptr<SceneSession> & subSession)5391 bool SceneSession::AddSubSession(const sptr<SceneSession>& subSession)
5392 {
5393     if (subSession == nullptr) {
5394         TLOGE(WmsLogTag::WMS_SUB, "subSession is nullptr");
5395         return false;
5396     }
5397     const auto& persistentId = subSession->GetPersistentId();
5398     auto iter = std::find_if(subSession_.begin(), subSession_.end(),
5399         [persistentId](sptr<SceneSession> session) {
5400             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
5401             return res;
5402         });
5403     if (iter != subSession_.end()) {
5404         TLOGE(WmsLogTag::WMS_SUB, "Sub ession is already exists, id: %{public}d, parentId: %{public}d",
5405             subSession->GetPersistentId(), GetPersistentId());
5406         return false;
5407     }
5408     TLOGD(WmsLogTag::WMS_SUB, "Success, id: %{public}d, parentId: %{public}d",
5409         subSession->GetPersistentId(), GetPersistentId());
5410     subSession_.push_back(subSession);
5411     return true;
5412 }
5413 
RemoveSubSession(int32_t persistentId)5414 bool SceneSession::RemoveSubSession(int32_t persistentId)
5415 {
5416     auto iter = std::find_if(subSession_.begin(), subSession_.end(),
5417         [persistentId](sptr<SceneSession> session) {
5418             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
5419             return res;
5420         });
5421     if (iter == subSession_.end()) {
5422         TLOGE(WmsLogTag::WMS_SUB, "Could not find subsession, id: %{public}d, parentId: %{public}d",
5423             persistentId, GetPersistentId());
5424         return false;
5425     }
5426     TLOGD(WmsLogTag::WMS_SUB, "Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
5427     subSession_.erase(iter);
5428     return true;
5429 }
5430 
AddToastSession(const sptr<SceneSession> & toastSession)5431 bool SceneSession::AddToastSession(const sptr<SceneSession>& toastSession)
5432 {
5433     if (toastSession == nullptr) {
5434         TLOGE(WmsLogTag::WMS_TOAST, "toastSession is nullptr");
5435         return false;
5436     }
5437     const auto& persistentId = toastSession->GetPersistentId();
5438     auto iter = std::find_if(toastSession_.begin(), toastSession_.end(),
5439         [persistentId](sptr<SceneSession> session) {
5440             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
5441             return res;
5442         });
5443     if (iter != toastSession_.end()) {
5444         TLOGE(WmsLogTag::WMS_TOAST, "Toast ession is already exists, id: %{public}d, parentId: %{public}d",
5445             toastSession->GetPersistentId(), GetPersistentId());
5446         return false;
5447     }
5448     TLOGD(WmsLogTag::WMS_TOAST, "Success, id: %{public}d, parentId: %{public}d",
5449         toastSession->GetPersistentId(), GetPersistentId());
5450     toastSession_.push_back(toastSession);
5451     return true;
5452 }
5453 
RemoveToastSession(int32_t persistentId)5454 bool SceneSession::RemoveToastSession(int32_t persistentId)
5455 {
5456     auto iter = std::find_if(toastSession_.begin(), toastSession_.end(),
5457         [persistentId](sptr<SceneSession> session) {
5458             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
5459             return res;
5460         });
5461     if (iter == toastSession_.end()) {
5462         TLOGE(WmsLogTag::WMS_TOAST, "Could not find toastSession, id: %{public}d, parentId: %{public}d",
5463             persistentId, GetPersistentId());
5464         return false;
5465     }
5466     TLOGD(WmsLogTag::WMS_TOAST, "Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
5467     toastSession_.erase(iter);
5468     return true;
5469 }
5470 
NotifyPiPWindowPrepareClose()5471 void SceneSession::NotifyPiPWindowPrepareClose()
5472 {
5473     TLOGD(WmsLogTag::WMS_PIP, "in");
5474     int32_t callingPid = IPCSkeleton::GetCallingPid();
5475     PostTask([weakThis = wptr(this), callingPid, where = __func__] {
5476         auto session = weakThis.promote();
5477         if (!session) {
5478             TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null", where);
5479             return;
5480         }
5481         if (callingPid != session->GetCallingPid()) {
5482             TLOGNW(WmsLogTag::WMS_PIP, "%{public}s permission denied, not call by the same process", where);
5483             return;
5484         }
5485         if (session->onPrepareClosePiPSession_) {
5486             session->onPrepareClosePiPSession_();
5487         }
5488         TLOGND(WmsLogTag::WMS_PIP, "%{public}s id: %{public}d", where, session->GetPersistentId());
5489     }, __func__);
5490 }
5491 
SetLandscapeMultiWindow(bool isLandscapeMultiWindow)5492 WSError SceneSession::SetLandscapeMultiWindow(bool isLandscapeMultiWindow)
5493 {
5494     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
5495     int32_t callingPid = IPCSkeleton::GetCallingPid();
5496     PostTask([weakThis = wptr(this), isLandscapeMultiWindow, callingPid, where = __func__] {
5497         auto session = weakThis.promote();
5498         if (!session) {
5499             TLOGNE(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s session is null", where);
5500             return WSError::WS_ERROR_DESTROYED_OBJECT;
5501         }
5502         if (callingPid != session->GetCallingPid()) {
5503             TLOGNE(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s premission denied, not call by the same process", where);
5504             return WSError::WS_ERROR_INVALID_PERMISSION;
5505         }
5506         if (session->onSetLandscapeMultiWindowFunc_) {
5507             session->onSetLandscapeMultiWindowFunc_(isLandscapeMultiWindow);
5508         }
5509         TLOGND(WmsLogTag::WMS_MULTI_WINDOW, "%{public}s id: %{public}d, isLandscapeMultiWindow: %{public}u",
5510             where, session->GetPersistentId(), isLandscapeMultiWindow);
5511         return WSError::WS_OK;
5512     }, __func__);
5513     return WSError::WS_OK;
5514 }
5515 
GetSubSession() const5516 std::vector<sptr<SceneSession>> SceneSession::GetSubSession() const
5517 {
5518     return subSession_;
5519 }
5520 
GetToastSession() const5521 std::vector<sptr<SceneSession>> SceneSession::GetToastSession() const
5522 {
5523     return toastSession_;
5524 }
5525 
GetSessionTargetRectByDisplayId(DisplayId displayId) const5526 WSRect SceneSession::GetSessionTargetRectByDisplayId(DisplayId displayId) const
5527 {
5528     WSRect rect;
5529     if (moveDragController_) {
5530         rect = moveDragController_->GetTargetRectByDisplayId(displayId);
5531     } else {
5532         WLOGFI("moveDragController_ is null");
5533     }
5534     return rect;
5535 }
5536 
SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc & func)5537 void SceneSession::SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc& func)
5538 {
5539     if (moveDragController_) {
5540         moveDragController_->SetWindowDragHotAreaFunc(func);
5541     }
5542 }
5543 
NotifySessionForeground(uint32_t reason,bool withAnimation)5544 void SceneSession::NotifySessionForeground(uint32_t reason, bool withAnimation)
5545 {
5546     if (!sessionStage_) {
5547         return;
5548     }
5549     return sessionStage_->NotifySessionForeground(reason, withAnimation);
5550 }
5551 
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)5552 void SceneSession::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
5553 {
5554     if (!sessionStage_) {
5555         return;
5556     }
5557     return sessionStage_->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
5558 }
5559 
NotifySessionFullScreen(bool fullScreen)5560 void SceneSession::NotifySessionFullScreen(bool fullScreen)
5561 {
5562     if (!sessionStage_) {
5563         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sessionStage is null");
5564         return;
5565     }
5566     sessionStage_->NotifySessionFullScreen(fullScreen);
5567 }
5568 
UpdatePiPRect(const Rect & rect,SizeChangeReason reason)5569 WSError SceneSession::UpdatePiPRect(const Rect& rect, SizeChangeReason reason)
5570 {
5571     if (!WindowHelper::IsPipWindow(GetWindowType())) {
5572         return WSError::WS_DO_NOTHING;
5573     }
5574     int32_t callingPid = IPCSkeleton::GetCallingPid();
5575     auto task = [weakThis = wptr(this), rect, reason, callingPid, where = __func__] {
5576         auto session = weakThis.promote();
5577         if (!session || session->isTerminating_) {
5578             TLOGNE(WmsLogTag::WMS_PIP,
5579                 "%{public}s session is null or is terminating", where);
5580             return WSError::WS_ERROR_INVALID_OPERATION;
5581         }
5582         if (callingPid != session->GetCallingPid()) {
5583             TLOGNW(WmsLogTag::WMS_PIP, "%{public}s permission denied, not call by the same process", where);
5584             return WSError::WS_ERROR_INVALID_PERMISSION;
5585         }
5586         WSRect wsRect = SessionHelper::TransferToWSRect(rect);
5587         if (reason == SizeChangeReason::PIP_START) {
5588             session->SetSessionRequestRect(wsRect);
5589         }
5590         TLOGNI(WmsLogTag::WMS_PIP, "%{public}s rect:%{public}s, reason:%{public}u", where, wsRect.ToString().c_str(),
5591             static_cast<uint32_t>(reason));
5592         session->NotifySessionRectChange(wsRect, reason);
5593         return WSError::WS_OK;
5594     };
5595     if (mainHandler_ != nullptr) {
5596         mainHandler_->PostTask(std::move(task), __func__, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
5597     } else {
5598         PostTask(std::move(task), __func__);
5599     }
5600     return WSError::WS_OK;
5601 }
5602 
UpdatePiPControlStatus(WsPiPControlType controlType,WsPiPControlStatus status)5603 WSError SceneSession::UpdatePiPControlStatus(WsPiPControlType controlType, WsPiPControlStatus status)
5604 {
5605     TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, status:%{public}d", controlType, status);
5606     if (!WindowHelper::IsPipWindow(GetWindowType())) {
5607         return WSError::WS_DO_NOTHING;
5608     }
5609     int32_t callingPid = IPCSkeleton::GetCallingPid();
5610     PostTask([weakThis = wptr(this), controlType, status, callingPid, where = __func__] {
5611         auto session = weakThis.promote();
5612         if (!session || session->isTerminating_) {
5613             TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null or is terminating", where);
5614             return WSError::WS_ERROR_INVALID_OPERATION;
5615         }
5616         if (callingPid != session->GetCallingPid()) {
5617             TLOGNW(WmsLogTag::WMS_PIP, "%{public}s permission denied, not call by the same process", where);
5618             return WSError::WS_ERROR_INVALID_PERMISSION;
5619         }
5620         if (session->sessionPiPControlStatusChangeFunc_) {
5621             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::UpdatePiPControlStatus");
5622             session->sessionPiPControlStatusChangeFunc_(controlType, status);
5623         }
5624         return WSError::WS_OK;
5625     }, __func__);
5626     return WSError::WS_OK;
5627 }
5628 
SetAutoStartPiP(bool isAutoStart,uint32_t priority,uint32_t width,uint32_t height)5629 WSError SceneSession::SetAutoStartPiP(bool isAutoStart, uint32_t priority, uint32_t width, uint32_t height)
5630 {
5631     TLOGI(WmsLogTag::WMS_PIP, "isAutoStart:%{public}u priority:%{public}u width:%{public}u height:%{public}u",
5632         isAutoStart, priority, width, height);
5633     PostTask([weakThis = wptr(this), isAutoStart, priority, width, height, where = __func__] {
5634         auto session = weakThis.promote();
5635         if (!session || session->isTerminating_) {
5636             TLOGNE(WmsLogTag::WMS_PIP, "%{public}s session is null or is terminating", where);
5637             return;
5638         }
5639         if (session->autoStartPiPStatusChangeFunc_) {
5640             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetAutoStartPiP");
5641             session->autoStartPiPStatusChangeFunc_(isAutoStart, priority, width, height);
5642         }
5643     }, __func__);
5644     return WSError::WS_OK;
5645 }
5646 
SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)5647 void SceneSession::SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)
5648 {
5649     NotifySystemSessionPointerEventFunc systemSessionPointerEventFunc = nullptr;
5650     {
5651         std::lock_guard<std::mutex> lock(pointerEventMutex_);
5652         systemSessionPointerEventFunc = systemSessionPointerEventFunc_;
5653     }
5654     if (systemSessionPointerEventFunc != nullptr) {
5655         systemSessionPointerEventFunc(pointerEvent);
5656     } else {
5657         TLOGE(WmsLogTag::WMS_EVENT, "PointerEventFunc_ nullptr, id:%{public}d", pointerEvent->GetId());
5658         pointerEvent->MarkProcessed();
5659     }
5660 }
5661 
SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent,bool isPreImeEvent)5662 bool SceneSession::SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent, bool isPreImeEvent)
5663 {
5664     NotifySystemSessionKeyEventFunc systemSessionKeyEventFunc = nullptr;
5665     {
5666         std::shared_lock<std::shared_mutex> lock(keyEventMutex_);
5667         systemSessionKeyEventFunc = systemSessionKeyEventFunc_;
5668     }
5669     if (systemSessionKeyEventFunc != nullptr) {
5670         return systemSessionKeyEventFunc(keyEvent, isPreImeEvent);
5671     }
5672     return false;
5673 }
5674 
UpdateSizeChangeReason(SizeChangeReason reason)5675 WSError SceneSession::UpdateSizeChangeReason(SizeChangeReason reason)
5676 {
5677     PostTask([weakThis = wptr(this), reason, where = __func__] {
5678         auto session = weakThis.promote();
5679         if (!session) {
5680             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
5681             return WSError::WS_ERROR_DESTROYED_OBJECT;
5682         }
5683         session->reason_ = reason;
5684         if (reason != SizeChangeReason::UNDEFINED) {
5685             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
5686                 "SceneSession::UpdateSizeChangeReason%d reason:%d",
5687                 session->GetPersistentId(), static_cast<uint32_t>(reason));
5688             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s Id: %{public}d, reason: %{public}d",
5689                 where, session->GetPersistentId(), reason);
5690         }
5691         return WSError::WS_OK;
5692     }, __func__);
5693     return WSError::WS_OK;
5694 }
5695 
ResetSizeChangeReasonIfDirty()5696 void SceneSession::ResetSizeChangeReasonIfDirty()
5697 {
5698     auto reason = GetSizeChangeReason();
5699     if (IsDirtyWindow() &&
5700         reason != SizeChangeReason::DRAG &&
5701         reason != SizeChangeReason::DRAG_END &&
5702         reason != SizeChangeReason::DRAG_START &&
5703         reason != SizeChangeReason::DRAG_MOVE) {
5704         UpdateSizeChangeReason(SizeChangeReason::UNDEFINED);
5705     }
5706 }
5707 
IsDirtyWindow()5708 bool SceneSession::IsDirtyWindow()
5709 {
5710     return dirtyFlags_ & static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
5711 }
5712 
IsDirtyDragWindow()5713 bool SceneSession::IsDirtyDragWindow()
5714 {
5715     return dirtyFlags_ & static_cast<uint32_t>(SessionUIDirtyFlag::DRAG_RECT) || isDragging_;
5716 }
5717 
ResetDirtyDragFlags()5718 void SceneSession::ResetDirtyDragFlags()
5719 {
5720     dirtyFlags_ &= ~static_cast<uint32_t>(SessionUIDirtyFlag::DRAG_RECT);
5721     isDragging_ = false;
5722 }
5723 
NotifyUILostFocus()5724 void SceneSession::NotifyUILostFocus()
5725 {
5726     if (moveDragController_) {
5727         moveDragController_->OnLostFocus();
5728     }
5729     Session::NotifyUILostFocus();
5730 }
5731 
SetScale(float scaleX,float scaleY,float pivotX,float pivotY)5732 void SceneSession::SetScale(float scaleX, float scaleY, float pivotX, float pivotY)
5733 {
5734     if (scaleX_ != scaleX || scaleY_ != scaleY || pivotX_ != pivotX || pivotY_ != pivotY) {
5735         Session::SetScale(scaleX, scaleY, pivotX, pivotY);
5736         if (specificCallback_ != nullptr) {
5737             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5738         }
5739         if (sessionStage_ != nullptr) {
5740             Transform transform;
5741             transform.scaleX_ = scaleX;
5742             transform.scaleY_ = scaleY;
5743             transform.pivotX_ = pivotX;
5744             transform.pivotY_ = pivotY;
5745             sessionStage_->NotifyTransformChange(transform);
5746         } else {
5747             WLOGFE("sessionStage_ is nullptr");
5748         }
5749     }
5750 }
5751 
RequestHideKeyboard(bool isAppColdStart)5752 void SceneSession::RequestHideKeyboard(bool isAppColdStart)
5753 {
5754 #ifdef IMF_ENABLE
5755     PostExportTask([weakThis = wptr(this), isAppColdStart, where = __func__] {
5756         auto session = weakThis.promote();
5757         if (!session) {
5758             TLOGNE(WmsLogTag::WMS_KEYBOARD,
5759                 "%{public}s Session is null, notify inputMethod framework hide keyboard failed!", where);
5760             return;
5761         }
5762         TLOGNI(WmsLogTag::WMS_KEYBOARD, "%{public}s Notify inputMethod framework hide keyboard start, id: %{public}d,"
5763             "isAppColdStart: %{public}d", where, session->GetPersistentId(), isAppColdStart);
5764         if (MiscServices::InputMethodController::GetInstance()) {
5765             MiscServices::InputMethodController::GetInstance()->RequestHideInput();
5766             TLOGNI(WmsLogTag::WMS_KEYBOARD, "%{public}s Notify InputMethod framework hide keyboard end. id: %{public}d",
5767                 where, session->GetPersistentId());
5768         }
5769     }, __func__);
5770 #endif
5771 }
5772 
IsStartMoving()5773 bool SceneSession::IsStartMoving()
5774 {
5775     return isStartMoving_.load();
5776 }
5777 
SetIsStartMoving(bool startMoving)5778 void SceneSession::SetIsStartMoving(bool startMoving)
5779 {
5780     isStartMoving_.store(startMoving);
5781 }
5782 
SetShouldHideNonSecureWindows(bool shouldHide)5783 void SceneSession::SetShouldHideNonSecureWindows(bool shouldHide)
5784 {
5785     shouldHideNonSecureWindows_.store(shouldHide);
5786 }
5787 
CalculateCombinedExtWindowFlags()5788 void SceneSession::CalculateCombinedExtWindowFlags()
5789 {
5790     {
5791         // Only correct when each flag is true when active, and once a uiextension is active, the host is active
5792         std::unique_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
5793         combinedExtWindowFlags_.bitData = 0;
5794         for (const auto& iter: extWindowFlagsMap_) {
5795             combinedExtWindowFlags_.bitData |= iter.second.bitData;
5796         }
5797     }
5798     NotifyPrivacyModeChange();
5799 }
5800 
UpdateExtWindowFlags(int32_t extPersistentId,const ExtensionWindowFlags & extWindowFlags,const ExtensionWindowFlags & extWindowActions)5801 void SceneSession::UpdateExtWindowFlags(int32_t extPersistentId, const ExtensionWindowFlags& extWindowFlags,
5802     const ExtensionWindowFlags& extWindowActions)
5803 {
5804     auto iter = extWindowFlagsMap_.find(extPersistentId);
5805     // Each flag is false when inactive, 0 means all flags are inactive
5806     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
5807     ExtensionWindowFlags newFlags((extWindowFlags.bitData & extWindowActions.bitData) |
5808         (oldFlags.bitData & ~extWindowActions.bitData));
5809     if (newFlags.bitData == 0) {
5810         extWindowFlagsMap_.erase(extPersistentId);
5811     } else {
5812         extWindowFlagsMap_[extPersistentId] = newFlags;
5813     }
5814     CalculateCombinedExtWindowFlags();
5815 }
5816 
GetCombinedExtWindowFlags()5817 ExtensionWindowFlags SceneSession::GetCombinedExtWindowFlags()
5818 {
5819     std::shared_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
5820     auto combinedExtWindowFlags = combinedExtWindowFlags_;
5821     combinedExtWindowFlags.hideNonSecureWindowsFlag = IsSessionForeground() &&
5822         (combinedExtWindowFlags.hideNonSecureWindowsFlag || shouldHideNonSecureWindows_.load());
5823     return combinedExtWindowFlags;
5824 }
5825 
NotifyDisplayMove(DisplayId from,DisplayId to)5826 void SceneSession::NotifyDisplayMove(DisplayId from, DisplayId to)
5827 {
5828     if (sessionStage_) {
5829         sessionStage_->NotifyDisplayMove(from, to);
5830     } else {
5831         WLOGFE("Notify display move failed, sessionStage is null");
5832     }
5833 }
5834 
RemoveExtWindowFlags(int32_t extPersistentId)5835 void SceneSession::RemoveExtWindowFlags(int32_t extPersistentId)
5836 {
5837     extWindowFlagsMap_.erase(extPersistentId);
5838     CalculateCombinedExtWindowFlags();
5839 }
5840 
ClearExtWindowFlags()5841 void SceneSession::ClearExtWindowFlags()
5842 {
5843     std::unique_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
5844     extWindowFlagsMap_.clear();
5845     combinedExtWindowFlags_.bitData = 0;
5846 }
5847 
UpdateRectChangeListenerRegistered(bool isRegister)5848 WSError SceneSession::UpdateRectChangeListenerRegistered(bool isRegister)
5849 {
5850     PostTask([weakThis = wptr(this), isRegister, where = __func__] {
5851         auto session = weakThis.promote();
5852         if (!session) {
5853             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
5854             return WSError::WS_ERROR_DESTROYED_OBJECT;
5855         }
5856         session->rectChangeListenerRegistered_ = isRegister;
5857         return WSError::WS_OK;
5858     }, __func__);
5859     return WSError::WS_OK;
5860 }
5861 
SetIsLayoutFullScreen(bool isLayoutFullScreen)5862 void SceneSession::SetIsLayoutFullScreen(bool isLayoutFullScreen)
5863 {
5864     isLayoutFullScreen_ = isLayoutFullScreen;
5865 }
5866 
IsLayoutFullScreen() const5867 bool SceneSession::IsLayoutFullScreen() const
5868 {
5869     return isLayoutFullScreen_;
5870 }
5871 
OnLayoutFullScreenChange(bool isLayoutFullScreen)5872 WSError SceneSession::OnLayoutFullScreenChange(bool isLayoutFullScreen)
5873 {
5874     PostTask([weakThis = wptr(this), isLayoutFullScreen, where = __func__] {
5875         auto session = weakThis.promote();
5876         if (!session) {
5877             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
5878             return WSError::WS_ERROR_DESTROYED_OBJECT;
5879         }
5880         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s isLayoutFullScreen: %{public}d", where, isLayoutFullScreen);
5881         if (session->onLayoutFullScreenChangeFunc_) {
5882             session->SetIsLayoutFullScreen(isLayoutFullScreen);
5883             session->onLayoutFullScreenChangeFunc_(isLayoutFullScreen);
5884         }
5885         return WSError::WS_OK;
5886     }, __func__);
5887     return WSError::WS_OK;
5888 }
5889 
OnDefaultDensityEnabled(bool isDefaultDensityEnabled)5890 WSError SceneSession::OnDefaultDensityEnabled(bool isDefaultDensityEnabled)
5891 {
5892     PostTask([weakThis = wptr(this), isDefaultDensityEnabled, where = __func__] {
5893         auto session = weakThis.promote();
5894         if (!session) {
5895             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
5896             return;
5897         }
5898         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s isDefaultDensityEnabled: %{public}d",
5899             where, isDefaultDensityEnabled);
5900         if (session->onDefaultDensityEnabledFunc_) {
5901             session->onDefaultDensityEnabledFunc_(isDefaultDensityEnabled);
5902         }
5903     }, __func__);
5904     return WSError::WS_OK;
5905 }
5906 
SetForceHideState(ForceHideState forceHideState)5907 void SceneSession::SetForceHideState(ForceHideState forceHideState)
5908 {
5909     forceHideState_ = forceHideState;
5910 }
5911 
GetForceHideState() const5912 ForceHideState SceneSession::GetForceHideState() const
5913 {
5914     return forceHideState_;
5915 }
5916 
SetIsDisplayStatusBarTemporarily(bool isTemporary)5917 void SceneSession::SetIsDisplayStatusBarTemporarily(bool isTemporary)
5918 {
5919     isDisplayStatusBarTemporarily_.store(isTemporary);
5920 }
5921 
GetIsDisplayStatusBarTemporarily() const5922 bool SceneSession::GetIsDisplayStatusBarTemporarily() const
5923 {
5924     return isDisplayStatusBarTemporarily_.load();
5925 }
5926 
RetrieveStatusBarDefaultVisibility()5927 void SceneSession::RetrieveStatusBarDefaultVisibility()
5928 {
5929     if (specificCallback_ && specificCallback_->onGetStatusBarDefaultVisibilityByDisplayId_) {
5930         isStatusBarVisible_ = specificCallback_->onGetStatusBarDefaultVisibilityByDisplayId_(
5931             GetSessionProperty()->GetDisplayId());
5932     }
5933 }
5934 
SetIsLastFrameLayoutFinishedFunc(IsLastFrameLayoutFinishedFunc && func)5935 void SceneSession::SetIsLastFrameLayoutFinishedFunc(IsLastFrameLayoutFinishedFunc&& func)
5936 {
5937     isLastFrameLayoutFinishedFunc_ = std::move(func);
5938 }
5939 
SetIsAINavigationBarAvoidAreaValidFunc(IsAINavigationBarAvoidAreaValidFunc && func)5940 void SceneSession::SetIsAINavigationBarAvoidAreaValidFunc(IsAINavigationBarAvoidAreaValidFunc&& func)
5941 {
5942     isAINavigationBarAvoidAreaValid_ = std::move(func);
5943 }
5944 
SetStartingWindowExitAnimationFlag(bool enable)5945 void SceneSession::SetStartingWindowExitAnimationFlag(bool enable)
5946 {
5947     TLOGI(WmsLogTag::WMS_PATTERN, "SetStartingWindowExitAnimationFlag %{public}d", enable);
5948     needStartingWindowExitAnimation_.store(enable);
5949 }
5950 
NeedStartingWindowExitAnimation() const5951 bool SceneSession::NeedStartingWindowExitAnimation() const
5952 {
5953     return needStartingWindowExitAnimation_.load();
5954 }
5955 
IsSystemSpecificSession() const5956 bool SceneSession::IsSystemSpecificSession() const
5957 {
5958     return isSystemSpecificSession_;
5959 }
5960 
SetIsSystemSpecificSession(bool isSystemSpecificSession)5961 void SceneSession::SetIsSystemSpecificSession(bool isSystemSpecificSession)
5962 {
5963     isSystemSpecificSession_ = isSystemSpecificSession;
5964 }
5965 
SetTemporarilyShowWhenLocked(bool isTemporarilyShowWhenLocked)5966 void SceneSession::SetTemporarilyShowWhenLocked(bool isTemporarilyShowWhenLocked)
5967 {
5968     if (isTemporarilyShowWhenLocked_.load() == isTemporarilyShowWhenLocked) {
5969         return;
5970     }
5971     isTemporarilyShowWhenLocked_.store(isTemporarilyShowWhenLocked);
5972     TLOGI(WmsLogTag::WMS_SCB, "SetTemporarilyShowWhenLocked successfully, target:%{public}u",
5973         isTemporarilyShowWhenLocked);
5974 }
5975 
IsTemporarilyShowWhenLocked() const5976 bool SceneSession::IsTemporarilyShowWhenLocked() const
5977 {
5978     return isTemporarilyShowWhenLocked_.load();
5979 }
5980 
SetSkipDraw(bool skip)5981 void SceneSession::SetSkipDraw(bool skip)
5982 {
5983     auto surfaceNode = GetSurfaceNode();
5984     if (!surfaceNode) {
5985         WLOGFE("surfaceNode_ is null");
5986         return;
5987     }
5988     auto rsTransaction = RSTransactionProxy::GetInstance();
5989     if (rsTransaction != nullptr) {
5990         rsTransaction->Begin();
5991     }
5992     surfaceNode->SetSkipDraw(skip);
5993     if (auto leashWinSurfaceNode = GetLeashWinSurfaceNode()) {
5994         leashWinSurfaceNode->SetSkipDraw(skip);
5995     }
5996     if (rsTransaction != nullptr) {
5997         rsTransaction->Commit();
5998     }
5999 }
6000 
SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)6001 void SceneSession::SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)
6002 {
6003     TLOGW(WmsLogTag::WMS_SCB, "in sceneSession, do nothing");
6004     return;
6005 }
6006 
SetUniqueDensityDpi(bool useUnique,float dpi)6007 WMError SceneSession::SetUniqueDensityDpi(bool useUnique, float dpi)
6008 {
6009     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "SceneSession set unique dpi: id=%{public}d, dpi=%{public}f",
6010         GetPersistentId(), dpi);
6011     if (useUnique && (dpi > DOT_PER_INCH_MAXIMUM_VALUE || dpi < DOT_PER_INCH_MINIMUM_VALUE)) {
6012         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Invalid input dpi value, valid input range: %{public}u ~ %{public}u",
6013             DOT_PER_INCH_MINIMUM_VALUE, DOT_PER_INCH_MAXIMUM_VALUE);
6014         return WMError::WM_ERROR_INVALID_PARAM;
6015     }
6016     float density = static_cast<float>(dpi) / 160; // 160 is the coefficient between density and dpi;
6017     if (!IsSessionValid()) {
6018         return WMError::WM_ERROR_INVALID_SESSION;
6019     }
6020     if (!sessionStage_) {
6021         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionStage_ is nullptr");
6022         return WMError::WM_ERROR_NULLPTR;
6023     }
6024     sessionStage_->SetUniqueVirtualPixelRatio(useUnique, density);
6025     return WMError::WM_OK;
6026 }
6027 
SetSystemWindowEnableDrag(bool enableDrag)6028 WMError SceneSession::SetSystemWindowEnableDrag(bool enableDrag)
6029 {
6030     if (!SessionPermission::IsSystemCalling()) {
6031         TLOGE(WmsLogTag::WMS_LAYOUT, "id:%{public}d, permission denied!", GetPersistentId());
6032         return WMError::WM_ERROR_NOT_SYSTEM_APP;
6033     }
6034 
6035     if (!WindowHelper::IsSystemWindow(GetWindowType())) {
6036         TLOGE(WmsLogTag::WMS_LAYOUT, "id:%{public}d, this is not system window", GetPersistentId());
6037         return WMError::WM_ERROR_INVALID_CALLING;
6038     }
6039 
6040     PostTask([weakThis = wptr(this), enableDrag, where = __func__] {
6041         auto session = weakThis.promote();
6042         if (!session) {
6043             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", where);
6044             return;
6045         }
6046         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, enableDrag:%{public}d",
6047             where, session->GetPersistentId(), enableDrag);
6048         session->GetSessionProperty()->SetDragEnabled(enableDrag);
6049         session->NotifySessionInfoChange();
6050     }, __func__);
6051     return WMError::WM_OK;
6052 }
6053 
SetWindowEnableDragBySystem(bool enableDrag)6054 WMError SceneSession::SetWindowEnableDragBySystem(bool enableDrag)
6055 {
6056     TLOGI(WmsLogTag::WMS_LAYOUT, "enableDrag: %{public}d", enableDrag);
6057     PostTask([weakThis = wptr(this), enableDrag, where = __func__] {
6058         auto session = weakThis.promote();
6059         if (!session) {
6060             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
6061             return;
6062         }
6063         session->SetClientDragEnable(enableDrag);
6064         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s id: %{public}d, enableDrag: %{public}d",
6065             where, session->GetPersistentId(), enableDrag);
6066         session->GetSessionProperty()->SetDragEnabled(enableDrag);
6067         if (session->sessionStage_) {
6068             session->sessionStage_->SetEnableDragBySystem(enableDrag);
6069         }
6070     }, __func__);
6071     return WMError::WM_OK;
6072 }
6073 
ActivateDragBySystem(bool activateDrag)6074 WMError SceneSession::ActivateDragBySystem(bool activateDrag)
6075 {
6076     PostTask([weakThis = wptr(this), activateDrag, where = __func__] {
6077         auto session = weakThis.promote();
6078         if (!session) {
6079             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
6080             return;
6081         }
6082         session->SetDragActivated(activateDrag);
6083         session->NotifySessionInfoChange();
6084         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s id: %{public}d, activate drag: %{public}d",
6085             where, session->GetPersistentId(), activateDrag);
6086         if (session->sessionStage_) {
6087             session->sessionStage_->SetDragActivated(activateDrag);
6088         }
6089     }, __func__);
6090     return WMError::WM_OK;
6091 }
6092 
HandleActionUpdateWindowModeSupportType(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)6093 WMError SceneSession::HandleActionUpdateWindowModeSupportType(const sptr<WindowSessionProperty>& property,
6094     WSPropertyChangeAction action)
6095 {
6096     if (!property->GetSystemCalling()) {
6097         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
6098         return WMError::WM_ERROR_NOT_SYSTEM_APP;
6099     }
6100 
6101     auto sessionProperty = GetSessionProperty();
6102     if (sessionProperty != nullptr) {
6103         sessionProperty->SetWindowModeSupportType(property->GetWindowModeSupportType());
6104     }
6105     return WMError::WM_OK;
6106 }
6107 
RegisterForceSplitListener(const NotifyForceSplitFunc & func)6108 void SceneSession::RegisterForceSplitListener(const NotifyForceSplitFunc& func)
6109 {
6110     forceSplitFunc_ = func;
6111 }
6112 
RegisterRequestedOrientationChangeCallback(NotifyReqOrientationChangeFunc && callback)6113 void SceneSession::RegisterRequestedOrientationChangeCallback(NotifyReqOrientationChangeFunc&& callback)
6114 {
6115     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
6116         auto session = weakThis.promote();
6117         if (!session) {
6118             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
6119             return;
6120         }
6121         session->onRequestedOrientationChange_ = std::move(callback);
6122     }, __func__);
6123 }
6124 
RegisterBindDialogSessionCallback(const NotifyBindDialogSessionFunc & callback)6125 void SceneSession::RegisterBindDialogSessionCallback(const NotifyBindDialogSessionFunc& callback)
6126 {
6127     onBindDialogTarget_ = callback;
6128 }
6129 
RegisterIsCustomAnimationPlayingCallback(NotifyIsCustomAnimationPlayingCallback && callback)6130 void SceneSession::RegisterIsCustomAnimationPlayingCallback(NotifyIsCustomAnimationPlayingCallback&& callback)
6131 {
6132     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
6133         auto session = weakThis.promote();
6134         if (!session) {
6135             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
6136             return;
6137         }
6138         session->onIsCustomAnimationPlaying_ = std::move(callback);
6139     }, __func__);
6140 }
6141 
RegisterLayoutFullScreenChangeCallback(NotifyLayoutFullScreenChangeFunc && callback)6142 void SceneSession::RegisterLayoutFullScreenChangeCallback(NotifyLayoutFullScreenChangeFunc&& callback)
6143 {
6144     PostTask([weakThis = wptr(this), callback = std::move(callback), where = __func__] {
6145         auto session = weakThis.promote();
6146         if (!session) {
6147             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
6148             return;
6149         }
6150         session->onLayoutFullScreenChangeFunc_ = std::move(callback);
6151     }, __func__);
6152 }
6153 
RegisterGetStatusBarAvoidHeightFunc(GetStatusBarAvoidHeightFunc && callback)6154 void SceneSession::RegisterGetStatusBarAvoidHeightFunc(GetStatusBarAvoidHeightFunc&& callback)
6155 {
6156     onGetStatusBarAvoidHeightFunc_ = std::move(callback);
6157 }
6158 
RegisterGetStatusBarConstantlyShowFunc(GetStatusBarConstantlyShowFunc && callback)6159 void SceneSession::RegisterGetStatusBarConstantlyShowFunc(GetStatusBarConstantlyShowFunc&& callback)
6160 {
6161     onGetStatusBarConstantlyShowFunc_ = std::move(callback);
6162 }
6163 
GetAppForceLandscapeConfig(AppForceLandscapeConfig & config)6164 WMError SceneSession::GetAppForceLandscapeConfig(AppForceLandscapeConfig& config)
6165 {
6166     if (forceSplitFunc_ == nullptr) {
6167         return WMError::WM_ERROR_NULLPTR;
6168     }
6169     config = forceSplitFunc_(sessionInfo_.bundleName_);
6170     return WMError::WM_OK;
6171 }
6172 
SetUpdatePrivateStateAndNotifyFunc(const UpdatePrivateStateAndNotifyFunc & func)6173 void SceneSession::SetUpdatePrivateStateAndNotifyFunc(const UpdatePrivateStateAndNotifyFunc& func)
6174 {
6175     updatePrivateStateAndNotifyFunc_ = func;
6176 }
6177 
SetNotifyVisibleChangeFunc(const NotifyVisibleChangeFunc & func)6178 void SceneSession::SetNotifyVisibleChangeFunc(const NotifyVisibleChangeFunc& func)
6179 {
6180     notifyVisibleChangeFunc_ = func;
6181 }
6182 
SetPrivacyModeChangeNotifyFunc(NotifyPrivacyModeChangeFunc && func)6183 void SceneSession::SetPrivacyModeChangeNotifyFunc(NotifyPrivacyModeChangeFunc&& func)
6184 {
6185     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
6186         auto session = weakThis.promote();
6187         if (!session) {
6188             TLOGNE(WmsLogTag::WMS_SCB, "%{public}s session is null", where);
6189             return;
6190         }
6191         session->privacyModeChangeNotifyFunc_ = std::move(func);
6192     }, __func__);
6193 }
6194 
SetHighlightChangeNotifyFunc(const NotifyHighlightChangeFunc & func)6195 void SceneSession::SetHighlightChangeNotifyFunc(const NotifyHighlightChangeFunc& func)
6196 {
6197     std::lock_guard lock(highlightChangeFuncMutex_);
6198     highlightChangeFunc_ = func;
6199 }
6200 
RegisterNotifySurfaceBoundsChangeFunc(int32_t sessionId,NotifySurfaceBoundsChangeFunc && func)6201 void SceneSession::RegisterNotifySurfaceBoundsChangeFunc(int32_t sessionId, NotifySurfaceBoundsChangeFunc&& func)
6202 {
6203     if (!func) {
6204         TLOGE(WmsLogTag::WMS_SUB, "func is null");
6205         return;
6206     }
6207     std::lock_guard lock(registerNotifySurfaceBoundsChangeMutex_);
6208     notifySurfaceBoundsChangeFuncMap_[sessionId] = func;
6209 }
6210 
UnregisterNotifySurfaceBoundsChangeFunc(int32_t sessionId)6211 void SceneSession::UnregisterNotifySurfaceBoundsChangeFunc(int32_t sessionId)
6212 {
6213     std::lock_guard lock(registerNotifySurfaceBoundsChangeMutex_);
6214     notifySurfaceBoundsChangeFuncMap_.erase(sessionId);
6215 }
6216 
GetSceneSessionById(int32_t sessionId) const6217 sptr<SceneSession> SceneSession::GetSceneSessionById(int32_t sessionId) const
6218 {
6219     if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionByIdCallback_ == nullptr) {
6220         TLOGE(WmsLogTag::WMS_LAYOUT, "specificCallback or onGetSceneSessionByIdCallback is null");
6221         return nullptr;
6222     }
6223     return specificCallback_->onGetSceneSessionByIdCallback_(sessionId);
6224 }
6225 
SetFollowParentRectFunc(NotifyFollowParentRectFunc && func)6226 void SceneSession::SetFollowParentRectFunc(NotifyFollowParentRectFunc&& func)
6227 {
6228     if (!func) {
6229         TLOGW(WmsLogTag::WMS_SUB, "func is null");
6230         return;
6231     }
6232     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
6233         auto session = weakThis.promote();
6234         if (!session) {
6235             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is null", where);
6236             return;
6237         }
6238         func(session->isFollowParentLayout_);
6239         session->followParentRectFunc_ = std::move(func);
6240     });
6241 }
6242 
SetFollowParentWindowLayoutEnabled(bool isFollow)6243 WSError SceneSession::SetFollowParentWindowLayoutEnabled(bool isFollow)
6244 {
6245     auto property = GetSessionProperty();
6246     if (!property || property->GetSubWindowLevel() > 1) {
6247         TLOGE(WmsLogTag::WMS_SUB, "property is null or not surppot more than 1 level window");
6248         return WSError::WS_ERROR_INVALID_OPERATION;
6249     }
6250     if (!WindowHelper::IsSubWindow(property->GetWindowType()) &&
6251         !WindowHelper::IsDialogWindow(property->GetWindowType())) {
6252         TLOGE(WmsLogTag::WMS_SUB, "only sub window and dialog is valid");
6253         return WSError::WS_ERROR_INVALID_OPERATION;
6254     }
6255     if (!systemConfig_.supportFollowParentWindowLayout_) {
6256         TLOGI(WmsLogTag::WMS_SUB, "not support device");
6257         return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
6258     }
6259     PostTask([weakThis = wptr(this), isFollow = isFollow,  where = __func__] {
6260         auto session = weakThis.promote();
6261         if (!session) {
6262             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is null", where);
6263             return;
6264         }
6265         session->isFollowParentLayout_ = isFollow;
6266         if (session->followParentRectFunc_) {
6267             session->followParentRectFunc_(isFollow);
6268         } else {
6269             TLOGI(WmsLogTag::WMS_SUB, "func is null");
6270         }
6271         // if parent is null, don't need follow move drag
6272         if (!session->parentSession_) {
6273             TLOGW(WmsLogTag::WMS_SUB, "parent is null");
6274             return;
6275         }
6276         if (!isFollow) {
6277             session->parentSession_->UnregisterNotifySurfaceBoundsChangeFunc(session->GetPersistentId());
6278             return;
6279         }
6280         auto task = [weak = weakThis](const WSRect& rect, bool isGlobal, bool needFlush) {
6281             auto session = weak.promote();
6282             if (!session) {
6283                 TLOGNE(WmsLogTag::WMS_SUB, "session has been destroy");
6284                 return;
6285             }
6286             session->SetSurfaceBounds(rect, isGlobal, needFlush);
6287         };
6288         session->parentSession_->RegisterNotifySurfaceBoundsChangeFunc(session->GetPersistentId(), std::move(task));
6289     });
6290     return WSError::WS_OK;
6291 }
6292 
GetStatusBarHeight()6293 int32_t SceneSession::GetStatusBarHeight()
6294 {
6295     int32_t height = 0;
6296     if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_ == nullptr ||
6297         GetSessionProperty() == nullptr) {
6298         TLOGE(WmsLogTag::WMS_IMMS, "specificCallback_ or session property is null");
6299         return height;
6300     }
6301     const auto& statusBarVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
6302         WindowType::WINDOW_TYPE_STATUS_BAR, GetSessionProperty()->GetDisplayId());
6303     for (auto& statusBar : statusBarVector) {
6304         if (statusBar == nullptr) {
6305             continue;
6306         }
6307         WSRect statusBarRect = statusBar->GetSessionRect();
6308         if (onGetStatusBarAvoidHeightFunc_) {
6309             onGetStatusBarAvoidHeightFunc_(statusBarRect);
6310             TLOGD(WmsLogTag::WMS_IMMS, "win %{public}d status bar height %{public}d",
6311                 GetPersistentId(), statusBarRect.height_);
6312         }
6313         height = statusBarRect.height_;
6314     }
6315     TLOGI(WmsLogTag::WMS_IMMS, "win %{public}d height %{public}d", GetPersistentId(), height);
6316     return height;
6317 }
6318 
GetDockHeight()6319 int32_t SceneSession::GetDockHeight()
6320 {
6321     int32_t height = 0;
6322     if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_ == nullptr ||
6323         GetSessionProperty() == nullptr) {
6324         TLOGE(WmsLogTag::WMS_DECOR, "specificCallback_ or session property is null");
6325         return height;
6326     }
6327     const auto& dockVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
6328         WindowType::WINDOW_TYPE_LAUNCHER_DOCK, GetSessionProperty()->GetDisplayId());
6329     for (auto& dock : dockVector) {
6330         if (dock != nullptr && dock->IsVisible() && dock->GetWindowName().find("SCBSmartDock") != std::string::npos) {
6331             int32_t dockHeight = dock->GetSessionRect().height_;
6332             if (dockHeight > height) {
6333                 height = dockHeight;
6334             }
6335         }
6336     }
6337     return height;
6338 }
6339 
CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty> & property) const6340 bool SceneSession::CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty>& property) const
6341 {
6342     if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
6343         if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6344             TLOGE(WmsLogTag::WMS_LIFE, "Not system app, no permission");
6345             return false;
6346         }
6347     }
6348     return true;
6349 }
6350 
UpdatePCZOrderAndMarkDirty(const uint32_t zOrder)6351 void SceneSession::UpdatePCZOrderAndMarkDirty(const uint32_t zOrder)
6352 {
6353     dirtyFlags_ |= UpdateZOrderInner(zOrder) ? static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER) : 0;
6354 }
6355 
UpdateUIParam(const SessionUIParam & uiParam)6356 uint32_t SceneSession::UpdateUIParam(const SessionUIParam& uiParam)
6357 {
6358     bool lastVisible = IsVisible();
6359     dirtyFlags_ |= UpdateInteractiveInner(uiParam.interactive_) ?
6360         static_cast<uint32_t>(SessionUIDirtyFlag::INTERACTIVE) : 0;
6361     if (!uiParam.interactive_) {
6362         // keep ui state in recent
6363         return dirtyFlags_;
6364     }
6365     dirtyFlags_ |= UpdateVisibilityInner(true) ? static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE) : 0;
6366     dirtyFlags_ |= UpdateRectInner(uiParam, reason_) ?
6367         static_cast<uint32_t>(SessionUIDirtyFlag::RECT) : 0;
6368     dirtyFlags_ |= UpdateScaleInner(uiParam.scaleX_, uiParam.scaleY_, uiParam.pivotX_, uiParam.pivotY_) ?
6369         static_cast<uint32_t>(SessionUIDirtyFlag::SCALE) : 0;
6370     if (!isPcScenePanel_) {
6371         dirtyFlags_ |= UpdateZOrderInner(uiParam.zOrder_) ? static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER) : 0;
6372     }
6373     if (!lastVisible && IsVisible() && !isFocused_ && !postProcessFocusState_.enabled_ &&
6374         GetForegroundInteractiveStatus()) {
6375         postProcessFocusState_.enabled_ = true;
6376         postProcessFocusState_.isFocused_ = true;
6377         postProcessFocusState_.reason_ = isStarting_ ?
6378             FocusChangeReason::SCB_START_APP : FocusChangeReason::FOREGROUND;
6379     }
6380     return dirtyFlags_;
6381 }
6382 
UpdateUIParam()6383 uint32_t SceneSession::UpdateUIParam()
6384 {
6385     bool lastVisible = IsVisible();
6386     dirtyFlags_ |= UpdateVisibilityInner(false) ? static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE) : 0;
6387     if (lastVisible && !IsVisible() && isFocused_) {
6388         postProcessFocusState_.enabled_ = true;
6389         postProcessFocusState_.isFocused_ = false;
6390         postProcessFocusState_.reason_ = FocusChangeReason::BACKGROUND;
6391     }
6392     return dirtyFlags_;
6393 }
6394 
UpdateVisibilityInner(bool visibility)6395 bool SceneSession::UpdateVisibilityInner(bool visibility)
6396 {
6397     if (isVisible_ == visibility) {
6398         return false;
6399     }
6400     TLOGI(WmsLogTag::WMS_PIPELINE, "id: %{public}d, visibility: %{public}u -> %{public}u",
6401         GetPersistentId(), isVisible_, visibility);
6402     if (visibilityChangedDetectFunc_) {
6403         visibilityChangedDetectFunc_(GetCallingPid(), isVisible_, visibility);
6404     }
6405     isVisible_ = visibility;
6406     if (updatePrivateStateAndNotifyFunc_ != nullptr) {
6407         updatePrivateStateAndNotifyFunc_(GetPersistentId());
6408     }
6409     if (notifyVisibleChangeFunc_ != nullptr) {
6410         notifyVisibleChangeFunc_(GetPersistentId());
6411     }
6412     return true;
6413 }
6414 
UpdateInteractiveInner(bool interactive)6415 bool SceneSession::UpdateInteractiveInner(bool interactive)
6416 {
6417     if (GetForegroundInteractiveStatus() == interactive) {
6418         return false;
6419     }
6420     SetForegroundInteractiveStatus(interactive);
6421     NotifyClientToUpdateInteractive(interactive);
6422     return true;
6423 }
6424 
PipelineNeedNotifyClientToUpdateRect() const6425 bool SceneSession::PipelineNeedNotifyClientToUpdateRect() const
6426 {
6427     return IsVisibleForeground() && GetForegroundInteractiveStatus();
6428 }
6429 
UpdateRectInner(const SessionUIParam & uiParam,SizeChangeReason reason)6430 bool SceneSession::UpdateRectInner(const SessionUIParam& uiParam, SizeChangeReason reason)
6431 {
6432     if (!((NotifyServerToUpdateRect(uiParam, reason) || IsDirtyWindow()) && PipelineNeedNotifyClientToUpdateRect())) {
6433         return false;
6434     }
6435     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
6436     auto transactionController = RSSyncTransactionController::GetInstance();
6437     if (transactionController) {
6438         rsTransaction = transactionController->GetRSTransaction();
6439     }
6440     NotifyClientToUpdateRect("WMSPipeline", rsTransaction);
6441     return true;
6442 }
6443 
NotifyServerToUpdateRect(const SessionUIParam & uiParam,SizeChangeReason reason)6444 bool SceneSession::NotifyServerToUpdateRect(const SessionUIParam& uiParam, SizeChangeReason reason)
6445 {
6446     if (!GetForegroundInteractiveStatus()) {
6447         TLOGD(WmsLogTag::WMS_PIPELINE, "skip recent, id:%{public}d", GetPersistentId());
6448         return false;
6449     }
6450     if (uiParam.rect_.IsInvalid()) {
6451         TLOGW(WmsLogTag::WMS_PIPELINE, "id:%{public}d rect:%{public}s is invalid",
6452             GetPersistentId(), uiParam.rect_.ToString().c_str());
6453         return false;
6454     }
6455     auto globalRect = GetSessionGlobalRect();
6456     if (globalRect != uiParam.rect_) {
6457         UpdateAllModalUIExtensions(uiParam.rect_);
6458     }
6459     SetSessionGlobalRect(uiParam.rect_);
6460     if (!uiParam.needSync_ || !isNeedSyncSessionRect_) {
6461         TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, scenePanelNeedSync:%{public}u needSyncSessionRect:%{public}u "
6462             "rectAfter:%{public}s preRect:%{public}s preGlobalRect:%{public}s", GetPersistentId(), uiParam.needSync_,
6463             isNeedSyncSessionRect_, uiParam.rect_.ToString().c_str(), winRect_.ToString().c_str(),
6464             globalRect.ToString().c_str());
6465         return false;
6466     }
6467     WSRect rect = { uiParam.rect_.posX_ - uiParam.transX_, uiParam.rect_.posY_ - uiParam.transY_,
6468         uiParam.rect_.width_, uiParam.rect_.height_ };
6469     if (winRect_ == rect && (!sessionStage_ || clientRect_ == rect)) {
6470         TLOGD(WmsLogTag::WMS_PIPELINE, "skip same rect update id:%{public}d rect:%{public}s preGlobalRect:%{public}s!",
6471             GetPersistentId(), rect.ToString().c_str(), globalRect.ToString().c_str());
6472         return false;
6473     }
6474     if (rect.IsInvalid()) {
6475         TLOGE(WmsLogTag::WMS_PIPELINE, "id:%{public}d rect:%{public}s is invalid, preGlobalRect:%{public}s",
6476             GetPersistentId(), rect.ToString().c_str(), globalRect.ToString().c_str());
6477         return false;
6478     }
6479     TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, updateRect rectAfter:%{public}s preRect:%{public}s "
6480         "preGlobalRect:%{public}s clientRect:%{public}s", GetPersistentId(), rect.ToString().c_str(),
6481         winRect_.ToString().c_str(), globalRect.ToString().c_str(), clientRect_.ToString().c_str());
6482     winRect_ = rect;
6483     RectCheckProcess();
6484     return true;
6485 }
6486 
PostProcessNotifyAvoidArea()6487 void SceneSession::PostProcessNotifyAvoidArea()
6488 {
6489     if (PipelineNeedNotifyClientToUpdateAvoidArea(dirtyFlags_)) {
6490         NotifyClientToUpdateAvoidArea();
6491     }
6492 }
6493 
PipelineNeedNotifyClientToUpdateAvoidArea(uint32_t dirty) const6494 bool SceneSession::PipelineNeedNotifyClientToUpdateAvoidArea(uint32_t dirty) const
6495 {
6496     return ((dirty & static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE)) && IsImmersiveType()) ||
6497         ((dirty & static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) && isVisible_);
6498 }
6499 
NotifyClientToUpdateAvoidArea()6500 void SceneSession::NotifyClientToUpdateAvoidArea()
6501 {
6502     if (specificCallback_ == nullptr) {
6503         return;
6504     }
6505     // flush avoid areas on (avoid area dirty && (normal session rect NOT dirty || avoid session))
6506     if ((IsImmersiveType() || !IsDirtyWindow()) && specificCallback_->onUpdateAvoidArea_) {
6507         specificCallback_->onUpdateAvoidArea_(GetPersistentId());
6508     }
6509     if (specificCallback_->onUpdateOccupiedAreaIfNeed_) {
6510         specificCallback_->onUpdateOccupiedAreaIfNeed_(GetPersistentId());
6511     }
6512 }
6513 
IsTransformNeedChange(float scaleX,float scaleY,float pivotX,float pivotY)6514 bool SceneSession::IsTransformNeedChange(float scaleX, float scaleY, float pivotX, float pivotY)
6515 {
6516     bool nearEqual = NearEqual(scaleX_, scaleX) && NearEqual(scaleY_, scaleY) &&
6517         NearEqual(pivotX_, pivotX) && NearEqual(pivotY_, pivotY) &&
6518         NearEqual(clientScaleX_, scaleX) && NearEqual(clientScaleY_, scaleY) &&
6519         NearEqual(clientPivotX_, pivotX) && NearEqual(clientPivotY_, pivotY);
6520     return !nearEqual;
6521 }
6522 
UpdateScaleInner(float scaleX,float scaleY,float pivotX,float pivotY)6523 bool SceneSession::UpdateScaleInner(float scaleX, float scaleY, float pivotX, float pivotY)
6524 {
6525     if (!IsTransformNeedChange(scaleX, scaleY, pivotX, pivotY)) {
6526         return false;
6527     }
6528     Session::SetScale(scaleX, scaleY, pivotX, pivotY);
6529     if (!IsSessionForeground()) {
6530         TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, session is not foreground!", GetPersistentId());
6531         return false;
6532     }
6533     if (sessionStage_ != nullptr) {
6534         Transform transform;
6535         transform.scaleX_ = scaleX;
6536         transform.scaleY_ = scaleY;
6537         transform.pivotX_ = pivotX;
6538         transform.pivotY_ = pivotY;
6539         sessionStage_->NotifyTransformChange(transform);
6540         Session::SetClientScale(scaleX, scaleY, pivotX, pivotY);
6541     } else {
6542         WLOGFE("sessionStage is nullptr");
6543     }
6544     return true;
6545 }
6546 
UpdateZOrderInner(uint32_t zOrder)6547 bool SceneSession::UpdateZOrderInner(uint32_t zOrder)
6548 {
6549     if (zOrder_ == zOrder) {
6550         return false;
6551     }
6552     TLOGI(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}u -> %{public}u, lastZOrder: %{public}u",
6553           GetPersistentId(), zOrder_, zOrder, lastZOrder_);
6554     lastZOrder_ = zOrder_;
6555     zOrder_ = zOrder;
6556     return true;
6557 }
6558 
SetPostProcessFocusState(PostProcessFocusState state)6559 void SceneSession::SetPostProcessFocusState(PostProcessFocusState state)
6560 {
6561     postProcessFocusState_ = state;
6562 }
6563 
GetPostProcessFocusState() const6564 PostProcessFocusState SceneSession::GetPostProcessFocusState() const
6565 {
6566     return postProcessFocusState_;
6567 }
6568 
ResetPostProcessFocusState()6569 void SceneSession::ResetPostProcessFocusState()
6570 {
6571     postProcessFocusState_.Reset();
6572 }
6573 
SetPostProcessProperty(bool state)6574 void SceneSession::SetPostProcessProperty(bool state)
6575 {
6576     postProcessProperty_ = state;
6577 }
6578 
GetPostProcessProperty() const6579 bool SceneSession::GetPostProcessProperty() const
6580 {
6581     return postProcessProperty_;
6582 }
6583 
IsImmersiveType() const6584 bool SceneSession::IsImmersiveType() const
6585 {
6586     WindowType type = GetWindowType();
6587     return type == WindowType::WINDOW_TYPE_STATUS_BAR ||
6588         type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
6589         type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
6590 }
6591 
IsPcOrPadEnableActivation() const6592 bool SceneSession::IsPcOrPadEnableActivation() const
6593 {
6594     auto property = GetSessionProperty();
6595     bool isPcAppInPad = false;
6596     if (property != nullptr) {
6597         isPcAppInPad = property->GetIsPcAppInPad();
6598     }
6599     return systemConfig_.IsPcWindow() || IsFreeMultiWindowMode() || isPcAppInPad;
6600 }
6601 
SetMinimizedFlagByUserSwitch(bool isMinimized)6602 void SceneSession::SetMinimizedFlagByUserSwitch(bool isMinimized)
6603 {
6604     TLOGI(WmsLogTag::WMS_MULTI_USER, "winId: %{public}d, isMinimized: %{public}d", GetPersistentId(), isMinimized);
6605     isMinimizedByUserSwitch_ = isMinimized;
6606 }
6607 
IsMinimizedByUserSwitch() const6608 bool SceneSession::IsMinimizedByUserSwitch() const
6609 {
6610     return isMinimizedByUserSwitch_;
6611 }
6612 
UnregisterSessionChangeListeners()6613 void SceneSession::UnregisterSessionChangeListeners()
6614 {
6615     PostTask([weakThis = wptr(this), where = __func__] {
6616         auto session = weakThis.promote();
6617         if (session == nullptr) {
6618             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
6619             return;
6620         }
6621         session->Session::UnregisterSessionChangeListeners();
6622     }, __func__);
6623 }
6624 
SetVisibilityChangedDetectFunc(VisibilityChangedDetectFunc && func)6625 void SceneSession::SetVisibilityChangedDetectFunc(VisibilityChangedDetectFunc&& func)
6626 {
6627     LOCK_GUARD_EXPR(SCENE_GUARD, visibilityChangedDetectFunc_ = std::move(func));
6628 }
6629 
SetDefaultDisplayIdIfNeed()6630 void SceneSession::SetDefaultDisplayIdIfNeed()
6631 {
6632     if (sessionInfo_.screenId_ == SCREEN_ID_INVALID) {
6633         auto defaultDisplayId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
6634         sessionInfo_.screenId_ = defaultDisplayId;
6635         TLOGI(WmsLogTag::WMS_LIFE, "winId: %{public}d, update screen id %{public}" PRIu64,
6636             GetPersistentId(), defaultDisplayId);
6637         auto sessionProperty = GetSessionProperty();
6638         if (sessionProperty) {
6639             sessionProperty->SetDisplayId(defaultDisplayId);
6640         }
6641     }
6642 }
6643 
GetCustomDecorHeight() const6644 int32_t SceneSession::GetCustomDecorHeight() const
6645 {
6646     std::lock_guard lock(customDecorHeightMutex_);
6647     return customDecorHeight_;
6648 }
6649 
SetCustomDecorHeight(int32_t height)6650 void SceneSession::SetCustomDecorHeight(int32_t height)
6651 {
6652     constexpr int32_t MIN_DECOR_HEIGHT = 37;
6653     constexpr int32_t MAX_DECOR_HEIGHT = 112;
6654     if (height < MIN_DECOR_HEIGHT || height > MAX_DECOR_HEIGHT) {
6655         return;
6656     }
6657     std::lock_guard lock(customDecorHeightMutex_);
6658     customDecorHeight_ = height;
6659 }
6660 
UpdateGestureBackEnabled()6661 void SceneSession::UpdateGestureBackEnabled()
6662 {
6663     if (specificCallback_ != nullptr &&
6664         specificCallback_->onUpdateGestureBackEnabled_ != nullptr) {
6665         specificCallback_->onUpdateGestureBackEnabled_(GetPersistentId());
6666     }
6667 }
6668 
CheckIdentityTokenIfMatched(const std::string & identityToken)6669 bool SceneSession::CheckIdentityTokenIfMatched(const std::string& identityToken)
6670 {
6671     if (!identityToken.empty() && !clientIdentityToken_.empty() && identityToken != clientIdentityToken_) {
6672         TLOGW(WmsLogTag::WMS_LIFE,
6673             "failed, clientIdentityToken: %{public}s, identityToken: %{public}s, bundleName: %{public}s",
6674             clientIdentityToken_.c_str(), identityToken.c_str(), GetSessionInfo().bundleName_.c_str());
6675         return false;
6676     }
6677     return true;
6678 }
6679 
CheckPidIfMatched()6680 bool SceneSession::CheckPidIfMatched()
6681 {
6682     int32_t callingPid = IPCSkeleton::GetCallingPid();
6683     if (callingPid != -1 && callingPid != GetCallingPid()) {
6684         TLOGW(WmsLogTag::WMS_LIFE,
6685             "failed, callingPid_: %{public}d, callingPid: %{public}d, bundleName: %{public}s",
6686             GetCallingPid(), callingPid, GetSessionInfo().bundleName_.c_str());
6687         return false;
6688     }
6689     return true;
6690 }
6691 
SetNeedSyncSessionRect(bool needSync)6692 void SceneSession::SetNeedSyncSessionRect(bool needSync)
6693 {
6694     PostTask([weakThis = wptr(this), needSync, where = __func__] {
6695         auto session = weakThis.promote();
6696         if (session == nullptr) {
6697             TLOGNE(WmsLogTag::WMS_PIPELINE, "%{public}s session is null", where);
6698             return;
6699         }
6700         TLOGNI(WmsLogTag::WMS_PIPELINE,
6701             "%{public}s: change isNeedSync from %{public}d to %{public}d, id:%{public}d",
6702             where, session->isNeedSyncSessionRect_, needSync, session->GetPersistentId());
6703         session->isNeedSyncSessionRect_ = needSync;
6704     }, __func__);
6705 }
6706 
SetFrameGravity(Gravity gravity)6707 bool SceneSession::SetFrameGravity(Gravity gravity)
6708 {
6709     auto surfaceNode = GetSurfaceNode();
6710     if (surfaceNode == nullptr) {
6711         TLOGW(WmsLogTag::WMS_LAYOUT, "fail id:%{public}d gravity:%{public}d", GetPersistentId(), gravity);
6712         return false;
6713     }
6714     TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d gravity:%{public}d", GetPersistentId(), gravity);
6715     surfaceNode->SetFrameGravity(gravity);
6716     return true;
6717 }
6718 
SetWindowRectAutoSaveCallback(NotifySetWindowRectAutoSaveFunc && func)6719 void SceneSession::SetWindowRectAutoSaveCallback(NotifySetWindowRectAutoSaveFunc&& func)
6720 {
6721     PostTask([weakThis = wptr(this), where = __func__, func = std::move(func)] {
6722         auto session = weakThis.promote();
6723         if (!session || !func) {
6724             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session or onSetWindowRectAutoSaveFunc is null", where);
6725             return;
6726         }
6727         session->onSetWindowRectAutoSaveFunc_ = std::move(func);
6728         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where,
6729             session->GetPersistentId());
6730     }, __func__);
6731 }
6732 
SetIsSystemKeyboard(bool isSystemKeyboard)6733 void SceneSession::SetIsSystemKeyboard(bool isSystemKeyboard)
6734 {
6735     auto sessionProperty = GetSessionProperty();
6736     if (sessionProperty == nullptr) {
6737         TLOGE(WmsLogTag::WMS_KEYBOARD, "property is nullptr");
6738         return;
6739     }
6740     sessionProperty->SetIsSystemKeyboard(isSystemKeyboard);
6741 }
6742 
IsSystemKeyboard() const6743 bool SceneSession::IsSystemKeyboard() const
6744 {
6745     auto sessionProperty = GetSessionProperty();
6746     if (sessionProperty == nullptr) {
6747         TLOGE(WmsLogTag::WMS_KEYBOARD, "property is nullptr");
6748         return false;
6749     }
6750     return sessionProperty->IsSystemKeyboard();
6751 }
6752 
RegisterSupportWindowModesCallback(NotifySetSupportedWindowModesFunc && func)6753 void SceneSession::RegisterSupportWindowModesCallback(NotifySetSupportedWindowModesFunc&& func)
6754 {
6755     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
6756         auto session = weakThis.promote();
6757         if (!session || !func) {
6758             TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session or func is null", where);
6759             return;
6760         }
6761         session->onSetSupportedWindowModesFunc_ = std::move(func);
6762         TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s id: %{public}d", where, session->GetPersistentId());
6763     }, __func__);
6764 }
6765 
ActivateKeyboardAvoidArea(bool active,bool recalculateAvoid)6766 void SceneSession::ActivateKeyboardAvoidArea(bool active, bool recalculateAvoid)
6767 {
6768     if (recalculateAvoid && !active) {
6769         RestoreCallingSession();
6770     }
6771     keyboardAvoidAreaActive_ = active;
6772     if (recalculateAvoid && active) {
6773         EnableCallingSessionAvoidArea();
6774     }
6775 }
6776 
IsKeyboardAvoidAreaActive() const6777 bool SceneSession::IsKeyboardAvoidAreaActive() const
6778 {
6779     return keyboardAvoidAreaActive_;
6780 }
6781 
MarkAvoidAreaAsDirty()6782 void SceneSession::MarkAvoidAreaAsDirty()
6783 {
6784     dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
6785 }
6786 
SetMousePointerDownEventStatus(bool mousePointerDownEventStatus)6787 void SceneSession::SetMousePointerDownEventStatus(bool mousePointerDownEventStatus)
6788 {
6789     isMousePointerDownEventStatus_ = mousePointerDownEventStatus;
6790 }
6791 
GetMousePointerDownEventStatus() const6792 bool SceneSession::GetMousePointerDownEventStatus() const
6793 {
6794     return isMousePointerDownEventStatus_;
6795 }
6796 
SetFingerPointerDownStatus(int32_t fingerId)6797 void SceneSession::SetFingerPointerDownStatus(int32_t fingerId)
6798 {
6799     if (fingerPointerDownStatusList_.find(fingerId) != fingerPointerDownStatusList_.end()) {
6800         TLOGE(WmsLogTag::WMS_EVENT, "wid:%{public}d fingerId:%{public}d receive twice down event",
6801               GetPersistentId(), fingerId);
6802     } else {
6803         fingerPointerDownStatusList_.insert(fingerId);
6804     }
6805 }
6806 
RemoveFingerPointerDownStatus(int32_t fingerId)6807 void SceneSession::RemoveFingerPointerDownStatus(int32_t fingerId)
6808 {
6809     if (fingerPointerDownStatusList_.find(fingerId) == fingerPointerDownStatusList_.end()) {
6810         TLOGE(WmsLogTag::WMS_EVENT, "wid:%{public}d fingerId:%{public}d receive up without down event",
6811               GetPersistentId(), fingerId);
6812     } else {
6813         fingerPointerDownStatusList_.erase(fingerId);
6814     }
6815 }
6816 
GetFingerPointerDownStatusList() const6817 std::unordered_set<int32_t> SceneSession::GetFingerPointerDownStatusList() const
6818 {
6819     return fingerPointerDownStatusList_;
6820 }
6821 
SetBehindWindowFilterEnabled(bool enabled)6822 void SceneSession::SetBehindWindowFilterEnabled(bool enabled)
6823 {
6824     TLOGD(WmsLogTag::WMS_LAYOUT, "id: %{public}d, enabled: %{public}d", GetPersistentId(), enabled);
6825     auto surfaceNode = GetSurfaceNode();
6826     if (surfaceNode == nullptr) {
6827         TLOGW(WmsLogTag::WMS_LAYOUT, "fail to get surfaceNode");
6828         return;
6829     }
6830     auto rsTransaction = RSTransactionProxy::GetInstance();
6831     if (rsTransaction != nullptr) {
6832         TLOGD(WmsLogTag::WMS_LAYOUT, "begin rsTransaction");
6833         rsTransaction->Begin();
6834     }
6835 
6836     if (behindWindowFilterEnabledModifier_ == nullptr) {
6837         auto behindWindowFilterEnabledProperty = std::make_shared<RSProperty<bool>>(enabled);
6838         behindWindowFilterEnabledModifier_ = std::make_shared<RSBehindWindowFilterEnabledModifier>(
6839             behindWindowFilterEnabledProperty);
6840         surfaceNode->AddModifier(behindWindowFilterEnabledModifier_);
6841     } else {
6842         auto behindWindowFilterEnabledProperty = std::static_pointer_cast<RSProperty<bool>>(
6843             behindWindowFilterEnabledModifier_->GetProperty());
6844         if (!behindWindowFilterEnabledProperty) {
6845             TLOGE(WmsLogTag::WMS_LAYOUT, "fail to get property");
6846             return;
6847         }
6848         behindWindowFilterEnabledProperty->Set(enabled);
6849     }
6850 
6851     if (rsTransaction != nullptr) {
6852         TLOGD(WmsLogTag::WMS_LAYOUT, "commit rsTransaction");
6853         rsTransaction->Commit();
6854     }
6855 }
6856 
UpdateAllModalUIExtensions(const WSRect & globalRect)6857 void SceneSession::UpdateAllModalUIExtensions(const WSRect& globalRect)
6858 {
6859     if (modalUIExtensionInfoList_.empty()) {
6860         return;
6861     }
6862     PostTask([weakThis = wptr(this), where = __func__, globalRect] {
6863         auto session = weakThis.promote();
6864         if (!session) {
6865             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is null", where);
6866             return;
6867         }
6868         auto parentTransX = globalRect.posX_ - session->GetClientRect().posX_;
6869         auto parentTransY = globalRect.posY_ - session->GetClientRect().posY_;
6870         {
6871             std::unique_lock<std::shared_mutex> lock(session->modalUIExtensionInfoListMutex_);
6872             for (auto& extensionInfo : session->modalUIExtensionInfoList_) {
6873                 if (!extensionInfo.hasUpdatedRect) {
6874                     continue;
6875                 }
6876                 extensionInfo.windowRect = extensionInfo.uiExtRect;
6877                 extensionInfo.windowRect.posX_ += parentTransX;
6878                 extensionInfo.windowRect.posY_ += parentTransY;
6879             }
6880         }
6881         session->NotifySessionInfoChange();
6882         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: id: %{public}d, globalRect: %{public}s, parentTransX: %{public}d, "
6883             "parentTransY: %{public}d", where, session->GetPersistentId(), globalRect.ToString().c_str(),
6884             parentTransX, parentTransY);
6885     }, __func__);
6886 }
6887 
SetWindowCornerRadiusCallback(NotifySetWindowCornerRadiusFunc && func)6888 void SceneSession::SetWindowCornerRadiusCallback(NotifySetWindowCornerRadiusFunc&& func)
6889 {
6890     const char* const where = __func__;
6891     PostTask([weakThis = wptr(this), where, func = std::move(func)] {
6892         auto session = weakThis.promote();
6893         if (!session || !func) {
6894             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session or onSetWindowCornerRadiusFunc is null");
6895             return;
6896         }
6897         session->onSetWindowCornerRadiusFunc_ = std::move(func);
6898         auto property = session->GetSessionProperty();
6899         session->onSetWindowCornerRadiusFunc_(property->GetWindowCornerRadius());
6900         TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s id: %{public}d", where,
6901             session->GetPersistentId());
6902     }, __func__);
6903 }
6904 
SetWindowCornerRadius(float cornerRadius)6905 WSError SceneSession::SetWindowCornerRadius(float cornerRadius)
6906 {
6907     const char* const where = __func__;
6908     PostTask([weakThis = wptr(this), cornerRadius, where] {
6909         auto session = weakThis.promote();
6910         if (!session) {
6911             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is null");
6912             return;
6913         }
6914         if (session->onSetWindowCornerRadiusFunc_) {
6915             TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s id %{public}d radius: %{public}f",
6916                 where, session->GetPersistentId(), cornerRadius);
6917             session->onSetWindowCornerRadiusFunc_(cornerRadius);
6918             session->GetSessionProperty()->SetWindowCornerRadius(cornerRadius);
6919         }
6920     }, __func__);
6921     return WSError::WS_OK;
6922 }
6923 
UpdateSubWindowLevel(uint32_t subWindowLevel)6924 void SceneSession::UpdateSubWindowLevel(uint32_t subWindowLevel)
6925 {
6926     GetSessionProperty()->SetSubWindowLevel(subWindowLevel);
6927     for (const auto& session : GetSubSession()) {
6928         if (session != nullptr) {
6929             session->UpdateSubWindowLevel(subWindowLevel + 1);
6930         }
6931     }
6932 }
6933 
GetMaxSubWindowLevel() const6934 int SceneSession::GetMaxSubWindowLevel() const
6935 {
6936     int maxSubWindowLevel = 1;
6937     for (const auto& session : GetSubSession()) {
6938         if (session != nullptr) {
6939             maxSubWindowLevel = std::max(maxSubWindowLevel, session->GetMaxSubWindowLevel() + 1);
6940         }
6941     }
6942     return maxSubWindowLevel;
6943 }
6944 
SetColorSpace(ColorSpace colorSpace)6945 void SceneSession::SetColorSpace(ColorSpace colorSpace)
6946 {
6947     auto surfaceNode = GetSurfaceNode();
6948     if (!surfaceNode) {
6949         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode is invalid");
6950         return;
6951     }
6952     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "SetColorSpace value=%{public}u", colorSpace);
6953     auto colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
6954     if (colorSpace == ColorSpace::COLOR_SPACE_WIDE_GAMUT) {
6955         colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3;
6956     }
6957     auto rsTransaction = RSTransactionProxy::GetInstance();
6958     if (rsTransaction != nullptr) {
6959         rsTransaction->Begin();
6960         surfaceNode->SetColorSpace(colorGamut);
6961     }
6962     if (rsTransaction != nullptr) {
6963         rsTransaction->Commit();
6964     }
6965 }
6966 
AddSidebarBlur()6967 void SceneSession::AddSidebarBlur()
6968 {
6969     auto surfaceNode = GetSurfaceNode();
6970     if (!surfaceNode) {
6971         TLOGE(WmsLogTag::WMS_PC, "surfaceNode is null");
6972         return;
6973     }
6974     auto rsNodeTemp = Rosen::RSNodeMap::Instance().GetNode(surfaceNode->GetId());
6975     if (rsNodeTemp) {
6976         std::shared_ptr<AbilityRuntime::ApplicationContext> appContext =
6977         AbilityRuntime::Context::GetApplicationContext();
6978         if (appContext == nullptr) {
6979             TLOGE(WmsLogTag::WMS_PC, "app context is nullptr");
6980             return;
6981         }
6982         std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
6983         if (config == nullptr) {
6984             TLOGE(WmsLogTag::WMS_PC, "app configuration is nullptr");
6985             return;
6986         }
6987         std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
6988         bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
6989         AddRSNodeModifier(isDark, rsNodeTemp);
6990     }
6991 }
6992 
AddRSNodeModifier(bool isDark,const std::shared_ptr<RSBaseNode> & rsNode)6993 void SceneSession::AddRSNodeModifier(bool isDark, const std::shared_ptr<RSBaseNode>& rsNode)
6994 {
6995     if (!rsNode) {
6996         TLOGE(WmsLogTag::WMS_PC, "rsNode is nullptr");
6997         return;
6998     }
6999     TLOGI(WmsLogTag::WMS_PC, "isDark: %{public}d", isDark);
7000     if (isDark) {
7001         blurRadiusValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
7002             SIDEBAR_DEFAULT_RADIUS_DARK);
7003         blurSaturationValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
7004             SIDEBAR_DEFAULT_SATURATION_DARK);
7005         blurBrightnessValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
7006             SIDEBAR_DEFAULT_BRIGHTNESS_DARK);
7007         blurMaskColorValue_ = std::make_shared<RSAnimatableProperty<Rosen::RSColor>>(
7008             Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_DARK));
7009     } else {
7010         blurRadiusValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
7011             SIDEBAR_DEFAULT_RADIUS_LIGHT);
7012         blurSaturationValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
7013             SIDEBAR_DEFAULT_SATURATION_LIGHT);
7014         blurBrightnessValue_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(
7015             SIDEBAR_DEFAULT_BRIGHTNESS_LIGHT);
7016         blurMaskColorValue_ = std::make_shared<RSAnimatableProperty<Rosen::RSColor>>(
7017             Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_LIGHT));
7018     }
7019 
7020     std::shared_ptr<Rosen::RSBehindWindowFilterRadiusModifier> radius =
7021         std::make_shared<Rosen::RSBehindWindowFilterRadiusModifier>(blurRadiusValue_);
7022     rsNode->AddModifier(radius);
7023     std::shared_ptr<Rosen::RSBehindWindowFilterSaturationModifier> saturation =
7024         std::make_shared<Rosen::RSBehindWindowFilterSaturationModifier>(blurSaturationValue_);
7025     rsNode->AddModifier(saturation);
7026     std::shared_ptr<Rosen::RSBehindWindowFilterBrightnessModifier> brightness =
7027         std::make_shared<Rosen::RSBehindWindowFilterBrightnessModifier>(blurBrightnessValue_);
7028     rsNode->AddModifier(brightness);
7029     std::shared_ptr<Rosen::RSBehindWindowFilterMaskColorModifier> modifier =
7030         std::make_shared<Rosen::RSBehindWindowFilterMaskColorModifier>(blurMaskColorValue_);
7031     rsNode->AddModifier(modifier);
7032 }
7033 
SetSidebarBlur(bool isDefaultSidebarBlur)7034 void SceneSession::SetSidebarBlur(bool isDefaultSidebarBlur)
7035 {
7036     TLOGI(WmsLogTag::WMS_PC, "isDefaultSidebarBlur: %{public}d", isDefaultSidebarBlur);
7037     auto surfaceNode = GetSurfaceNode();
7038     if (!surfaceNode) {
7039         TLOGE(WmsLogTag::WMS_PC, "surfaceNode is null");
7040         return;
7041     }
7042     if (!blurRadiusValue_ || !blurSaturationValue_ || !blurBrightnessValue_ || !blurMaskColorValue_) {
7043         TLOGE(WmsLogTag::WMS_PC, "RSAnimatableProperty is null");
7044         return;
7045     }
7046 
7047     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext =
7048         AbilityRuntime::Context::GetApplicationContext();
7049     if (appContext == nullptr) {
7050         TLOGE(WmsLogTag::WMS_PC, "app context is nullptr");
7051         return;
7052     }
7053     std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
7054     if (config == nullptr) {
7055         TLOGE(WmsLogTag::WMS_PC, "app configuration is nullptr");
7056         return;
7057     }
7058     std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
7059     bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
7060     ModifyRSAnimatableProperty(isDefaultSidebarBlur, isDark);
7061 }
7062 
ModifyRSAnimatableProperty(bool isDefaultSidebarBlur,bool isDark)7063 void SceneSession::ModifyRSAnimatableProperty(bool isDefaultSidebarBlur, bool isDark)
7064 {
7065     TLOGI(WmsLogTag::WMS_PC, "isDefaultSidebarBlur: %{public}d, isDark: %{public}d",
7066         isDefaultSidebarBlur, isDark);
7067     // sidebar animation duration
7068     constexpr int32_t duration = 150;
7069     if (isDefaultSidebarBlur) {
7070         Rosen::RSAnimationTimingProtocol timingProtocol;
7071         timingProtocol.SetDuration(duration);
7072         timingProtocol.SetDirection(true);
7073         timingProtocol.SetFillMode(Rosen::FillMode::FORWARDS);
7074         timingProtocol.SetFinishCallbackType(Rosen::FinishCallbackType::LOGICALLY);
7075 
7076         Rosen::RSNode::OpenImplicitAnimation(timingProtocol, Rosen::RSAnimationTimingCurve::LINEAR, nullptr);
7077         if (isDark) {
7078             blurRadiusValue_->Set(SIDEBAR_DEFAULT_RADIUS_DARK);
7079             blurSaturationValue_->Set(SIDEBAR_DEFAULT_SATURATION_DARK);
7080             blurBrightnessValue_->Set(SIDEBAR_DEFAULT_BRIGHTNESS_DARK);
7081             blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_DARK));
7082         } else {
7083             blurRadiusValue_->Set(SIDEBAR_DEFAULT_RADIUS_LIGHT);
7084             blurSaturationValue_->Set(SIDEBAR_DEFAULT_SATURATION_LIGHT);
7085             blurBrightnessValue_->Set(SIDEBAR_DEFAULT_BRIGHTNESS_LIGHT);
7086             blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_DEFAULT_MASKCOLOR_LIGHT));
7087         }
7088         Rosen::RSNode::CloseImplicitAnimation();
7089     } else {
7090         blurRadiusValue_->Set(SIDEBAR_BLUR_NUMBER_ZERO);
7091         blurSaturationValue_->Set(SIDEBAR_BLUR_NUMBER_ZERO);
7092         blurBrightnessValue_->Set(SIDEBAR_BLUR_NUMBER_ZERO);
7093         if (isDark) {
7094             blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_SNAPSHOT_MASKCOLOR_DARK));
7095         } else {
7096             blurMaskColorValue_->Set(Rosen::RSColor::FromArgbInt(SIDEBAR_SNAPSHOT_MASKCOLOR_LIGHT));
7097         }
7098     }
7099 }
7100 
NotifyWindowAttachStateListenerRegistered(bool registered)7101 void SceneSession::NotifyWindowAttachStateListenerRegistered(bool registered)
7102 {
7103     SetNeedNotifyAttachState(registered);
7104 }
7105 
NotifyKeyboardAnimationCompleted(bool isShowAnimation,const WSRect & beginRect,const WSRect & endRect)7106 void SceneSession::NotifyKeyboardAnimationCompleted(bool isShowAnimation,
7107     const WSRect& beginRect, const WSRect& endRect)
7108 {
7109     PostTask([weakThis = wptr(this), isShowAnimation, beginRect, endRect, where = __func__] {
7110         auto session = weakThis.promote();
7111         if (!session) {
7112             TLOGNE(WmsLogTag::WMS_KEYBOARD, "%{public}s session is null", where);
7113             return;
7114         }
7115         if (session->sessionStage_ == nullptr) {
7116             TLOGNI(WmsLogTag::WMS_KEYBOARD, "%{public}s sessionStage_ is null, id: %{public}d",
7117                 where, session->GetPersistentId());
7118             return;
7119         }
7120         if (isShowAnimation && !session->isKeyboardDidShowRegistered_.load()) {
7121             TLOGND(WmsLogTag::WMS_KEYBOARD, "keyboard did show listener is not registered");
7122             return;
7123         }
7124         if (!isShowAnimation && !session->isKeyboardDidHideRegistered_.load()) {
7125             TLOGND(WmsLogTag::WMS_KEYBOARD, "keyboard did hide listener is not registered");
7126             return;
7127         }
7128 
7129         KeyboardPanelInfo keyboardPanelInfo;
7130         keyboardPanelInfo.beginRect_ = SessionHelper::TransferToRect(beginRect);
7131         keyboardPanelInfo.endRect_ = SessionHelper::TransferToRect(endRect);
7132         keyboardPanelInfo.isShowing_ = isShowAnimation;
7133         session->sessionStage_->NotifyKeyboardAnimationCompleted(keyboardPanelInfo);
7134     }, __func__);
7135 }
7136 
NotifyKeyboardDidShowRegistered(bool registered)7137 void SceneSession::NotifyKeyboardDidShowRegistered(bool registered)
7138 {
7139     isKeyboardDidShowRegistered_.store(registered);
7140 }
7141 
NotifyKeyboardDidHideRegistered(bool registered)7142 void SceneSession::NotifyKeyboardDidHideRegistered(bool registered)
7143 {
7144     isKeyboardDidHideRegistered_.store(registered);
7145 }
7146 
UpdateDensity()7147 WSError SceneSession::UpdateDensity()
7148 {
7149     if (systemConfig_.IsPcWindow() && WindowHelper::IsAppWindow(GetWindowType()) &&
7150         Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
7151         UpdateNewSizeForPCWindow();
7152     }
7153     SaveLastDensity();
7154     return Session::UpdateDensity();
7155 }
7156 
UpdateNewSizeForPCWindow()7157 void SceneSession::UpdateNewSizeForPCWindow()
7158 {
7159     if (moveDragController_ && moveDragController_->IsMoveDragHotAreaCrossDisplay()) {
7160         TLOGW(WmsLogTag::WMS_LAYOUT_PC, "is move drag to hot area, do nothing.");
7161         moveDragController_->SetMoveDragHotAreaCrossDisplay(false);
7162         return;
7163     }
7164 
7165     if (auto property = GetSessionProperty()) {
7166         DisplayId displayId = property->GetDisplayId();
7167         auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
7168         if (display == nullptr) {
7169             TLOGE(WmsLogTag::WMS_LAYOUT_PC, "get available area failed!");
7170             return;
7171         }
7172 
7173         DMRect availableArea = { 0, 0, 0, 0 };
7174         DMError ret = display->GetAvailableArea(availableArea);
7175         if (ret != DMError::DM_OK || availableArea.IsUninitializedRect()) {
7176             TLOGE(WmsLogTag::WMS_LAYOUT_PC, "get available area failed!");
7177             return;
7178         }
7179 
7180         float newVpr = display->GetVirtualPixelRatio();
7181         if (CalcNewWindowRectIfNeed(availableArea, newVpr)) {
7182             NotifySessionRectChange(winRect_, SizeChangeReason::UPDATE_DPI_SYNC);
7183             sessionStage_->UpdateRect(winRect_, SizeChangeReason::UPDATE_DPI_SYNC);
7184             TLOGI(WmsLogTag::WMS_LAYOUT_PC, "left: %{public}d, top: %{public}d, width: %{public}u, "
7185                 "height: %{public}u, Id: %{public}u", winRect_.posX_, winRect_.posY_, winRect_.width_,
7186                 winRect_.height_, GetPersistentId());
7187         }
7188     }
7189     displayChangedByMoveDrag_ = false;
7190 }
7191 
CalcNewWindowRectIfNeed(DMRect & availableArea,float newVpr)7192 bool SceneSession::CalcNewWindowRectIfNeed(DMRect& availableArea, float newVpr)
7193 {
7194     float currVpr = 0.0f;
7195     if (auto property = GetSessionProperty()) {
7196         currVpr = property->GetLastLimitsVpr();
7197         TLOGD(WmsLogTag::WMS_LAYOUT_PC, "currVpr: %{public}f Id: %{public}u", currVpr, GetPersistentId());
7198     }
7199     if (MathHelper::NearZero(currVpr - newVpr) || MathHelper::NearZero(currVpr)) {
7200         TLOGW(WmsLogTag::WMS_LAYOUT_PC, "need not update new rect, currVpr: %{public}f newVpr: %{public}f "
7201             "Id: %{public}u", currVpr, newVpr, GetPersistentId());
7202         return false;
7203     }
7204     int32_t left = winRect_.posX_;
7205     int32_t top = winRect_.posY_;
7206     uint32_t width = static_cast<uint32_t>(winRect_.width_ * newVpr / currVpr);
7207     uint32_t height = static_cast<uint32_t>(winRect_.height_ * newVpr / currVpr);
7208     int32_t statusBarHeight = 0;
7209     if (isStatusBarVisible_ && IsPrimaryDisplay()) {
7210         statusBarHeight = GetStatusBarHeight();
7211     }
7212     width = MathHelper::Min(width, availableArea.width_);
7213     height = MathHelper::Min(height, availableArea.height_);
7214     bool needMove = top < statusBarHeight || left < 0 ||
7215         top > static_cast<int32_t>(availableArea.height_ - height) ||
7216         left > static_cast<int32_t>(availableArea.width_ - width) || displayChangedByMoveDrag_;
7217     if (displayChangedByMoveDrag_ && moveDragController_) {
7218         int32_t pointerPosX = moveDragController_->GetLastMovePointerPosX();
7219         left = pointerPosX - static_cast<int32_t>((pointerPosX -left) * newVpr / currVpr);
7220     } else {
7221         top = MathHelper::Min(top, static_cast<int32_t>(availableArea.height_ - height));
7222         top = MathHelper::Max(top, statusBarHeight);
7223         left = MathHelper::Min(left, static_cast<int32_t>(availableArea.width_ - width));
7224         left = MathHelper::Max(left, 0);
7225     }
7226     winRect_.width_ = width;
7227     winRect_.height_ = height;
7228     if (needMove) {
7229         winRect_.posX_ = left;
7230         winRect_.posY_ = top;
7231     }
7232     return true;
7233 }
7234 
IsPrimaryDisplay() const7235 bool SceneSession::IsPrimaryDisplay() const
7236 {
7237     if (auto property = GetSessionProperty()) {
7238         auto display = DisplayManager::GetInstance().GetPrimaryDisplaySync();
7239         if (display == nullptr) {
7240             TLOGE(WmsLogTag::WMS_LAYOUT_PC, "display is null.");
7241             return false;
7242         }
7243         if (auto displayInfo = display->GetDisplayInfo()) {
7244             return property->GetDisplayId() == displayInfo->GetDisplayId();
7245         }
7246     }
7247     return false;
7248 }
7249 
SaveLastDensity()7250 void SceneSession::SaveLastDensity()
7251 {
7252     if (auto property = GetSessionProperty()) {
7253         DisplayId displayId = property->GetDisplayId();
7254         if (auto display = DisplayManager::GetInstance().GetDisplayById(displayId)) {
7255             property->SetLastLimitsVpr(display->GetVirtualPixelRatio());
7256         }
7257     }
7258 }
7259 
NotifyUpdateFlagCallback(NotifyUpdateFlagFunc && func)7260 void SceneSession::NotifyUpdateFlagCallback(NotifyUpdateFlagFunc&& func)
7261 {
7262     const char* const where = __func__;
7263     PostTask([weakThis = wptr(this), where, func = std::move(func)] {
7264         auto session = weakThis.promote();
7265         if (!session || !func) {
7266             TLOGNE(WmsLogTag::WMS_MAIN, "session or func is null");
7267             return;
7268         }
7269         session->onUpdateFlagFunc_ = std::move(func);
7270         session->onUpdateFlagFunc_(session->sessionInfo_.specifiedFlag_);
7271         TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d specifiedFlag: %{public}s", where,
7272             session->GetPersistentId(), session->sessionInfo_.specifiedFlag_.c_str());
7273     }, __func__);
7274 }
7275 
SetIsAncoForFloatingWindow(bool isAncoForFloatingWindow)7276 void SceneSession::SetIsAncoForFloatingWindow(bool isAncoForFloatingWindow)
7277 {
7278     isAncoForFloatingWindow_ = isAncoForFloatingWindow;
7279 }
7280 
GetIsAncoForFloatingWindow() const7281 bool SceneSession::GetIsAncoForFloatingWindow() const
7282 {
7283     return isAncoForFloatingWindow_;
7284 }
7285 } // namespace OHOS::Rosen
7286