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