1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "session/host/include/scene_session.h"
17 #include <parameters.h>
18 
19 #include <ability_manager_client.h>
20 #include <algorithm>
21 #include <climits>
22 #include <hitrace_meter.h>
23 #include <type_traits>
24 #ifdef IMF_ENABLE
25 #include <input_method_controller.h>
26 #endif // IMF_ENABLE
27 #include <ipc_skeleton.h>
28 #include <pointer_event.h>
29 #include <transaction/rs_sync_transaction_controller.h>
30 #include <transaction/rs_transaction.h>
31 #include <ui/rs_surface_node.h>
32 
33 #include "proxy/include/window_info.h"
34 
35 #include "common/include/session_permission.h"
36 #ifdef DEVICE_STATUS_ENABLE
37 #include "interaction_manager.h"
38 #endif // DEVICE_STATUS_ENABLE
39 #include "interfaces/include/ws_common.h"
40 #include "pixel_map.h"
41 #include "session/screen/include/screen_session.h"
42 #include "screen_session_manager/include/screen_session_manager_client.h"
43 #include "session/host/include/scene_persistent_storage.h"
44 #include "session/host/include/session_utils.h"
45 #include "display_manager.h"
46 #include "session_helper.h"
47 #include "window_helper.h"
48 #include "window_manager_hilog.h"
49 #include "wm_math.h"
50 #include <running_lock.h>
51 #include "screen_manager.h"
52 #include "screen.h"
53 #include "singleton_container.h"
54 #include "screen_session_manager/include/screen_session_manager_client.h"
55 #include "fold_screen_state_internel.h"
56 #include "session/host/include/ability_info_manager.h"
57 
58 #ifdef POWER_MANAGER_ENABLE
59 #include <power_mgr_client.h>
60 #endif
61 
62 namespace OHOS::Rosen {
63 namespace {
64 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSession" };
65 const std::string DLP_INDEX = "ohos.dlp.params.index";
66 constexpr const char* APP_CLONE_INDEX = "ohos.extra.param.key.appCloneIndex";
67 
CheckIfRectElementIsTooLarge(const WSRect & rect)68 bool CheckIfRectElementIsTooLarge(const WSRect& rect)
69 {
70     int32_t largeNumber = static_cast<int32_t>(SHRT_MAX);
71     if (rect.posX_ >= largeNumber || rect.posY_ >= largeNumber ||
72         rect.width_ >= largeNumber || rect.height_ >= largeNumber) {
73         return true;
74     }
75     return false;
76 }
77 } // namespace
78 
79 MaximizeMode SceneSession::maximizeMode_ = MaximizeMode::MODE_RECOVER;
80 wptr<SceneSession> SceneSession::enterSession_ = nullptr;
81 std::mutex SceneSession::enterSessionMutex_;
82 std::shared_mutex SceneSession::windowDragHotAreaMutex_;
83 std::map<uint32_t, WSRect> SceneSession::windowDragHotAreaMap_;
84 static bool g_enableForceUIFirst = system::GetParameter("window.forceUIFirst.enabled", "1") == "1";
85 
SceneSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)86 SceneSession::SceneSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
87     : Session(info)
88 {
89     GeneratePersistentId(false, info.persistentId_);
90     specificCallback_ = specificCallback;
91     SetCollaboratorType(info.collaboratorType_);
92     TLOGI(WmsLogTag::WMS_LIFE, "Create session, id: %{public}d", GetPersistentId());
93 }
94 
~SceneSession()95 SceneSession::~SceneSession()
96 {
97     TLOGI(WmsLogTag::WMS_LIFE, "~SceneSession, id: %{public}d", GetPersistentId());
98 }
99 
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)100 WSError SceneSession::ConnectInner(const sptr<ISessionStage>& sessionStage,
101     const sptr<IWindowEventChannel>& eventChannel,
102     const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
103     sptr<WindowSessionProperty> property, sptr<IRemoteObject> token, int32_t pid, int32_t uid,
104     const std::string& identityToken)
105 {
106     auto task = [weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, &systemConfig, property, token, pid,
107         uid, identityToken]() {
108         auto session = weakThis.promote();
109         if (!session) {
110             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
111             return WSError::WS_ERROR_DESTROYED_OBJECT;
112         }
113 
114         if (SessionHelper::IsMainWindow(session->GetWindowType())) {
115             if (!session->CheckIdentityTokenIfMatched(identityToken)) {
116                 TLOGNW(WmsLogTag::WMS_LIFE, "check failed");
117                 return WSError::WS_OK;
118             }
119         }
120         if (property) {
121             property->SetCollaboratorType(session->GetCollaboratorType());
122         }
123         session->RetrieveStatusBarDefaultVisibility();
124         auto ret = session->Session::ConnectInner(
125             sessionStage, eventChannel, surfaceNode, systemConfig, property, token, pid, uid);
126         if (ret != WSError::WS_OK) {
127             return ret;
128         }
129         session->NotifyPropertyWhenConnect();
130         return ret;
131     };
132     return PostSyncTask(task, "ConnectInner");
133 }
134 
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)135 WSError SceneSession::Connect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
136     const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
137     sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
138     const std::string& identityToken)
139 {
140     // Get pid and uid before posting task.
141     int32_t pid = IPCSkeleton::GetCallingRealPid();
142     int32_t uid = IPCSkeleton::GetCallingUid();
143     return ConnectInner(sessionStage, eventChannel, surfaceNode, systemConfig,
144         property, token, pid, uid, identityToken);
145 }
146 
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)147 WSError SceneSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
148     const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
149     int32_t pid, int32_t uid)
150 {
151     return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, property, token, pid, uid]() {
152         auto session = weakThis.promote();
153         if (!session) {
154             WLOGFE("session is null");
155             return WSError::WS_ERROR_DESTROYED_OBJECT;
156         }
157         WSError ret = session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
158         if (ret != WSError::WS_OK) {
159             return ret;
160         }
161         return session->ReconnectInner(property);
162     });
163 }
164 
ReconnectInner(sptr<WindowSessionProperty> property)165 WSError SceneSession::ReconnectInner(sptr<WindowSessionProperty> property)
166 {
167     if (property == nullptr) {
168         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
169         return WSError::WS_ERROR_NULLPTR;
170     }
171     WindowState windowState = property->GetWindowState();
172     TLOGI(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, windowState: %{public}d ", GetPersistentId(), windowState);
173     WSError ret = WSError::WS_OK;
174     switch (windowState) {
175         case WindowState::STATE_INITIAL: {
176             TLOGE(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, invalid window state: STATE_INITIAL",
177                 GetPersistentId());
178             ret = WSError::WS_ERROR_INVALID_PARAM;
179             break;
180         }
181         case WindowState::STATE_CREATED:
182             break;
183         case WindowState::STATE_SHOWN: {
184             UpdateSessionState(SessionState::STATE_FOREGROUND);
185             UpdateActiveStatus(true);
186             break;
187         }
188         case WindowState::STATE_HIDDEN: {
189             UpdateSessionState(SessionState::STATE_BACKGROUND);
190             break;
191         }
192         default:
193             TLOGE(WmsLogTag::WMS_RECOVER, "persistentId: %{public}d, invalid window state: %{public}u",
194                 GetPersistentId(), windowState);
195             ret = WSError::WS_ERROR_INVALID_PARAM;
196             break;
197     }
198     if (ret != WSError::WS_OK) {
199         Session::Disconnect(false);
200     }
201     return ret;
202 }
203 
IsShowOnLockScreen(uint32_t lockScreenZOrder)204 bool SceneSession::IsShowOnLockScreen(uint32_t lockScreenZOrder)
205 {
206     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: lockScreenZOrder: %{public}d, zOrder_: %{public}d", lockScreenZOrder,
207         zOrder_);
208     // must be default screen
209     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
210     auto sessionProperty = GetSessionProperty();
211     if (sessionProperty != nullptr && defaultScreenId != sessionProperty->GetDisplayId()) {
212         TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not default display");
213         return false;
214     }
215     // current window on lock screen jurded by zorder
216     if (zOrder_ >= lockScreenZOrder) {
217         TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: zOrder_ is no more than lockScreenZOrder");
218         return true;
219     }
220     return false;
221 }
222 
AddExtensionTokenInfo(const UIExtensionTokenInfo & tokenInfo)223 void SceneSession::AddExtensionTokenInfo(const UIExtensionTokenInfo& tokenInfo)
224 {
225     extensionTokenInfos_.push_back(tokenInfo);
226     TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: canShowOnLockScreen: %{public}u, persistentId: %{public}d",
227         tokenInfo.canShowOnLockScreen, GetPersistentId());
228 }
229 
RemoveExtensionTokenInfo(const sptr<IRemoteObject> & abilityToken)230 void SceneSession::RemoveExtensionTokenInfo(const sptr<IRemoteObject>& abilityToken)
231 {
232     auto persistentId = GetPersistentId();
233     auto itr = std::remove_if(
234         extensionTokenInfos_.begin(), extensionTokenInfos_.end(), [&abilityToken, persistentId](const auto& tokenInfo) {
235             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: need remove, token: %{public}u, persistentId: %{public}d",
236                 tokenInfo.callingTokenId, persistentId);
237             return tokenInfo.abilityToken == abilityToken;
238         });
239     extensionTokenInfos_.erase(itr, extensionTokenInfos_.end());
240 }
241 
OnNotifyAboveLockScreen()242 void SceneSession::OnNotifyAboveLockScreen()
243 {
244     CheckExtensionOnLockScreenToClose();
245 }
246 
CheckExtensionOnLockScreenToClose()247 void SceneSession::CheckExtensionOnLockScreenToClose()
248 {
249     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: %{public}d", GetPersistentId());
250     // 1. check sub session
251     for (auto& session : GetSubSession()) {
252         if (!session) {
253             TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: session is null");
254             continue;
255         }
256         session->CheckExtensionOnLockScreenToClose();
257     }
258     // 2. check self permission
259     std::vector<UIExtensionTokenInfo> tokenInfosToClose;
260     for (auto& tokenInfo : extensionTokenInfos_) {
261         if (tokenInfo.canShowOnLockScreen) {
262             continue;
263         }
264         tokenInfosToClose.push_back(tokenInfo);
265     }
266     // 3. close ui extension without lock screen permisson
267     std::for_each(tokenInfosToClose.rbegin(), tokenInfosToClose.rend(),
268         [this](const UIExtensionTokenInfo& tokenInfo) { CloseExtensionSync(tokenInfo); });
269 }
270 
CloseExtensionSync(const UIExtensionTokenInfo & tokenInfo)271 void SceneSession::CloseExtensionSync(const UIExtensionTokenInfo& tokenInfo)
272 {
273     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock");
274     // hide sub window
275     auto subSceneSessions = GetSubSession();
276     for (auto& session : subSceneSessions) {
277         if (!session) {
278             TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: session is null");
279             continue;
280         }
281         // hide sub window of ui extension
282         if (session->GetAbilityToken() == tokenInfo.abilityToken) {
283             TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: hide sub window %{public}u", session->GetWindowId());
284             session->HideSync();
285         }
286     }
287     TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: close ui extension, callerToken: %{public}u, persistent id %{public}d",
288         tokenInfo.callingTokenId, GetPersistentId());
289     // kill ui extension ability
290     AAFwk::AbilityManagerClient::GetInstance()->CloseUIExtensionAbilityBySCB(tokenInfo.abilityToken);
291 }
292 
Foreground(sptr<WindowSessionProperty> property,bool isFromClient,const std::string & identityToken)293 WSError SceneSession::Foreground(
294     sptr<WindowSessionProperty> property, bool isFromClient, const std::string& identityToken)
295 {
296     if (!CheckPermissionWithPropertyAnimation(property)) {
297         return WSError::WS_ERROR_NOT_SYSTEM_APP;
298     }
299     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
300         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
301             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
302             return WSError::WS_OK;
303         }
304     }
305     return ForegroundTask(property);
306 }
307 
ForegroundTask(const sptr<WindowSessionProperty> & property)308 WSError SceneSession::ForegroundTask(const sptr<WindowSessionProperty>& property)
309 {
310     auto task = [weakThis = wptr(this), property]() {
311         auto session = weakThis.promote();
312         if (!session) {
313             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
314             return WSError::WS_ERROR_DESTROYED_OBJECT;
315         }
316         auto sessionProperty = session->GetSessionProperty();
317         if (property && sessionProperty) {
318             sessionProperty->SetWindowMode(property->GetWindowMode());
319             sessionProperty->SetDecorEnable(property->IsDecorEnable());
320             session->SetFocusableOnShow(property->GetFocusableOnShow());
321         }
322         int32_t persistentId = session->GetPersistentId();
323         auto ret = session->Session::Foreground(property);
324         if (ret != WSError::WS_OK) {
325             TLOGE(WmsLogTag::WMS_LIFE, "session foreground failed, ret=%{public}d persistentId=%{public}d",
326                 ret, persistentId);
327             return ret;
328         }
329         auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
330         if (leashWinSurfaceNode && sessionProperty) {
331             bool lastPrivacyMode = sessionProperty->GetPrivacyMode() || sessionProperty->GetSystemPrivacyMode();
332             leashWinSurfaceNode->SetSecurityLayer(lastPrivacyMode);
333         }
334         if (session->specificCallback_ != nullptr) {
335             if (Session::IsScbCoreEnabled()) {
336                 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
337             } else {
338                 session->specificCallback_->onUpdateAvoidArea_(persistentId);
339             }
340             session->specificCallback_->onWindowInfoUpdate_(
341                 persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
342             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
343             session->UpdateGestureBackEnabled();
344         } else {
345             TLOGI(WmsLogTag::WMS_LIFE, "foreground specific callback does not take effect, callback function null");
346         }
347         return WSError::WS_OK;
348     };
349     PostTask(task, "Foreground");
350     return WSError::WS_OK;
351 }
352 
Background(bool isFromClient,const std::string & identityToken)353 WSError SceneSession::Background(bool isFromClient, const std::string& identityToken)
354 {
355     if (!CheckPermissionWithPropertyAnimation(GetSessionProperty())) {
356         return WSError::WS_ERROR_NOT_SYSTEM_APP;
357     }
358 
359     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
360         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
361             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
362             return WSError::WS_OK;
363         }
364     }
365 
366     return BackgroundTask(true);
367 }
368 
NotifyFrameLayoutFinishFromApp(bool notifyListener,const WSRect & rect)369 WSError SceneSession::NotifyFrameLayoutFinishFromApp(bool notifyListener, const WSRect& rect)
370 {
371     TLOGI(WmsLogTag::WMS_LAYOUT, "%{public}d, %{public}s", notifyListener, rect.ToString().c_str());
372     auto task = [weakThis = wptr(this), notifyListener, rect]() {
373         auto session = weakThis.promote();
374         if (!session) {
375             TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "session is null");
376             return WSError::WS_ERROR_DESTROYED_OBJECT;
377         }
378         session->layoutRect_ = rect;
379         session->NotifyLayoutFinished();
380         if (notifyListener && session->frameLayoutFinishFunc_) {
381             TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d", session->GetPersistentId());
382             session->frameLayoutFinishFunc_();
383         }
384         return WSError::WS_OK;
385     };
386     PostTask(task, "NotifyFrameLayoutFinishFromApp");
387     return WSError::WS_OK;
388 }
389 
BackgroundTask(const bool isSaveSnapshot)390 WSError SceneSession::BackgroundTask(const bool isSaveSnapshot)
391 {
392     auto task = [weakThis = wptr(this), isSaveSnapshot]() {
393         auto session = weakThis.promote();
394         if (!session) {
395             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
396             return WSError::WS_ERROR_DESTROYED_OBJECT;
397         }
398         auto state = session->GetSessionState();
399         if (state == SessionState::STATE_BACKGROUND) {
400             return WSError::WS_OK;
401         }
402         auto ret = session->Session::Background();
403         if (ret != WSError::WS_OK) {
404             return ret;
405         }
406         if (WindowHelper::IsMainWindow(session->GetWindowType()) && isSaveSnapshot) {
407             session->SaveSnapshot(true);
408         }
409         if (session->specificCallback_ != nullptr) {
410             if (Session::IsScbCoreEnabled()) {
411                 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
412             } else {
413                 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
414             }
415             session->specificCallback_->onWindowInfoUpdate_(
416                 session->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
417             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
418             session->UpdateGestureBackEnabled();
419         }
420         return WSError::WS_OK;
421     };
422     PostTask(task, "Background");
423     return WSError::WS_OK;
424 }
425 
ClearSpecificSessionCbMap()426 void SceneSession::ClearSpecificSessionCbMap()
427 {
428     auto task = [weakThis = wptr(this)]() {
429         auto session = weakThis.promote();
430         if (!session) {
431             TLOGE(WmsLogTag::WMS_SYSTEM, "session is null");
432             return;
433         }
434         if (session->clearCallbackMapFunc_) {
435             session->clearCallbackMapFunc_(true, session->GetPersistentId());
436             TLOGD(WmsLogTag::WMS_SYSTEM, "ClearCallbackMap, id: %{public}d", session->GetPersistentId());
437         } else {
438             TLOGE(WmsLogTag::WMS_SYSTEM, "get callback failed, id: %{public}d", session->GetPersistentId());
439         }
440     };
441     PostTask(task, "ClearSpecificSessionCbMap");
442 }
443 
RegisterShowWhenLockedCallback(NotifyShowWhenLockedFunc && callback)444 void SceneSession::RegisterShowWhenLockedCallback(NotifyShowWhenLockedFunc&& callback)
445 {
446     const char* const where = __func__;
447     auto task = [weakThis = wptr(this), callback = std::move(callback), where] {
448         auto session = weakThis.promote();
449         if (!session) {
450             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
451             return;
452         }
453         session->onShowWhenLockedFunc_ = std::move(callback);
454         session->onShowWhenLockedFunc_(session->GetShowWhenLockedFlagValue());
455     };
456     PostTask(task, where);
457 }
458 
RegisterForceHideChangeCallback(NotifyForceHideChangeFunc && callback)459 void SceneSession::RegisterForceHideChangeCallback(NotifyForceHideChangeFunc&& callback)
460 {
461     const char* const where = __func__;
462     auto task = [weakThis = wptr(this), callback = std::move(callback), where] {
463         auto session = weakThis.promote();
464         if (!session) {
465             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
466             return;
467         }
468         session->onForceHideChangeFunc_ = std::move(callback);
469     };
470     PostTask(task, where);
471 }
472 
RegisterClearCallbackMapCallback(ClearCallbackMapFunc && callback)473 void SceneSession::RegisterClearCallbackMapCallback(ClearCallbackMapFunc&& callback)
474 {
475     const char* const where = __func__;
476     auto task = [weakThis = wptr(this), callback = std::move(callback), where] {
477         auto session = weakThis.promote();
478         if (!session) {
479             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is nullptr", where);
480             return;
481         }
482         session->clearCallbackMapFunc_ = std::move(callback);
483     };
484     PostTask(task, where);
485 }
486 
Disconnect(bool isFromClient,const std::string & identityToken)487 WSError SceneSession::Disconnect(bool isFromClient, const std::string& identityToken)
488 {
489     if (isFromClient && SessionHelper::IsMainWindow(GetWindowType())) {
490         if (!CheckPidIfMatched() || !CheckIdentityTokenIfMatched(identityToken)) {
491             TLOGW(WmsLogTag::WMS_LIFE, "check failed");
492             return WSError::WS_OK;
493         }
494     }
495 
496     return DisconnectTask(isFromClient, true);
497 }
498 
DisconnectTask(bool isFromClient,bool isSaveSnapshot)499 WSError SceneSession::DisconnectTask(bool isFromClient, bool isSaveSnapshot)
500 {
501     PostTask([weakThis = wptr(this), isFromClient, isSaveSnapshot]() {
502         auto session = weakThis.promote();
503         if (!session) {
504             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
505             return WSError::WS_ERROR_DESTROYED_OBJECT;
506         }
507         if (isFromClient) {
508             TLOGI(WmsLogTag::WMS_LIFE, "Client need notify destroy session, id: %{public}d",
509                 session->GetPersistentId());
510             session->SetSessionState(SessionState::STATE_DISCONNECT);
511             return WSError::WS_OK;
512         }
513         auto state = session->GetSessionState();
514         auto isMainWindow = SessionHelper::IsMainWindow(session->GetWindowType());
515         if ((session->needSnapshot_ || (state == SessionState::STATE_ACTIVE && isMainWindow)) && isSaveSnapshot) {
516             session->SaveSnapshot(false);
517         }
518         session->Session::Disconnect(isFromClient);
519         session->isTerminating_ = false;
520         if (session->specificCallback_ != nullptr) {
521             session->specificCallback_->onHandleSecureSessionShouldHide_(session);
522             session->isEnableGestureBack_ = true;
523             session->UpdateGestureBackEnabled();
524             session->isEnableGestureBackHadSet_ = false;
525         }
526         return WSError::WS_OK;
527     },
528         "Disconnect");
529     return WSError::WS_OK;
530 }
531 
UpdateActiveStatus(bool isActive)532 WSError SceneSession::UpdateActiveStatus(bool isActive)
533 {
534     auto task = [weakThis = wptr(this), isActive]() {
535         auto session = weakThis.promote();
536         if (!session) {
537             WLOGFE("[WMSCom] session is null");
538             return WSError::WS_ERROR_DESTROYED_OBJECT;
539         }
540         if (!session->IsSessionValid()) {
541             TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
542                 session->GetPersistentId(), session->GetSessionState());
543             return WSError::WS_ERROR_INVALID_SESSION;
544         }
545         if (isActive == session->isActive_) {
546             WLOGFD("[WMSCom] Session active do not change: %{public}d", isActive);
547             return WSError::WS_DO_NOTHING;
548         }
549 
550         WSError ret = WSError::WS_DO_NOTHING;
551         if (isActive && session->GetSessionState() == SessionState::STATE_FOREGROUND) {
552             session->UpdateSessionState(SessionState::STATE_ACTIVE);
553             session->isActive_ = isActive;
554             ret = WSError::WS_OK;
555         }
556         if (!isActive && session->GetSessionState() == SessionState::STATE_ACTIVE) {
557             session->UpdateSessionState(SessionState::STATE_INACTIVE);
558             session->isActive_ = isActive;
559             ret = WSError::WS_OK;
560         }
561         WLOGFI("[WMSCom] UpdateActiveStatus, isActive: %{public}d, state: %{public}u",
562             session->isActive_, session->GetSessionState());
563         return ret;
564     };
565     PostTask(task, "UpdateActiveStatus:" + std::to_string(isActive));
566     return WSError::WS_OK;
567 }
568 
OnSessionEvent(SessionEvent event)569 WSError SceneSession::OnSessionEvent(SessionEvent event)
570 {
571     auto task = [weakThis = wptr(this), event]() {
572         auto session = weakThis.promote();
573         if (!session) {
574             WLOGFE("[WMSCom] session is null");
575             return WSError::WS_ERROR_DESTROYED_OBJECT;
576         }
577         WLOGFI("[WMSCom] SceneSession OnSessionEvent event: %{public}d", static_cast<int32_t>(event));
578         if (event == SessionEvent::EVENT_START_MOVE) {
579             if (!(session->moveDragController_ && !session->moveDragController_->GetStartDragFlag() &&
580                 session->IsFocused() && session->IsMovableWindowType() &&
581                 session->moveDragController_->HasPointDown())) {
582                 TLOGW(WmsLogTag::WMS_LAYOUT, "Window is not movable, id: %{public}d", session->GetPersistentId());
583                 return WSError::WS_OK;
584             }
585             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::StartMove");
586             session->moveDragController_->InitMoveDragProperty();
587             if (session->IsFullScreenMovable()) {
588                 WSRect rect = session->moveDragController_->GetFullScreenToFloatingRect(session->winRect_,
589                     session->GetSessionRequestRect());
590                 session->Session::UpdateRect(rect, SizeChangeReason::RECOVER, "OnSessionEvent", nullptr);
591                 session->moveDragController_->SetStartMoveFlag(true);
592                 session->moveDragController_->CalcFirstMoveTargetRect(rect, true);
593             } else {
594                 session->moveDragController_->SetStartMoveFlag(true);
595                 session->moveDragController_->CalcFirstMoveTargetRect(session->winRect_, false);
596             }
597             session->SetSessionEventParam({session->moveDragController_->GetOriginalPointerPosX(),
598                 session->moveDragController_->GetOriginalPointerPosY()});
599         }
600         session->HandleSessionDragEvent(event);
601         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->OnSessionEvent_) {
602             session->sessionChangeCallback_->OnSessionEvent_(static_cast<uint32_t>(event),
603                 session->sessionEventParam_);
604         }
605         return WSError::WS_OK;
606     };
607     PostTask(task, "OnSessionEvent:" + std::to_string(static_cast<int>(event)));
608     return WSError::WS_OK;
609 }
610 
HandleSessionDragEvent(SessionEvent event)611 void SceneSession::HandleSessionDragEvent(SessionEvent event)
612 {
613     if (moveDragController_ &&
614         (event == SessionEvent::EVENT_DRAG || event == SessionEvent::EVENT_DRAG_START)) {
615         WSRect rect = moveDragController_->GetTargetRect();
616         DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
617         if (event == SessionEvent::EVENT_DRAG_START) {
618             dragResizeType = GetAppDragResizeType();
619             SetDragResizeTypeDuringDrag(dragResizeType);
620         }
621         SetSessionEventParam({rect.posX_, rect.posY_, rect.width_, rect.height_,
622             static_cast<uint32_t>(dragResizeType)});
623     }
624 }
625 
SyncSessionEvent(SessionEvent event)626 WSError SceneSession::SyncSessionEvent(SessionEvent event)
627 {
628     if (event != SessionEvent::EVENT_START_MOVE) {
629         TLOGE(WmsLogTag::WMS_LAYOUT, "This is not start move event, eventId=%{public}d", event);
630         return WSError::WS_ERROR_NULLPTR;
631     }
632     const char* const funcName = __func__;
633     return PostSyncTask([weakThis = wptr(this), event, funcName] {
634         auto session = weakThis.promote();
635         if (!session || !session->moveDragController_) {
636             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s: session or moveDragController is null", funcName);
637             return WSError::WS_ERROR_NULLPTR;
638         }
639         if (session->moveDragController_->GetStartMoveFlag()) {
640             TLOGNW(WmsLogTag::WMS_LAYOUT, "%{public}s: Repeat operation, system window is moving", funcName);
641             return WSError::WS_ERROR_REPEAT_OPERATION;
642         }
643         session->OnSessionEvent(event);
644         return WSError::WS_OK;
645     }, funcName);
646 }
647 
GetWindowDragHotAreaType(uint32_t type,int32_t pointerX,int32_t pointerY)648 uint32_t SceneSession::GetWindowDragHotAreaType(uint32_t type, int32_t pointerX, int32_t pointerY)
649 {
650     std::shared_lock<std::shared_mutex> lock(windowDragHotAreaMutex_);
651     for (auto it = windowDragHotAreaMap_.begin(); it != windowDragHotAreaMap_.end(); ++it) {
652         uint32_t key = it->first;
653         WSRect rect = it->second;
654         if (rect.IsInRegion(pointerX, pointerY)) {
655             type |= key;
656         }
657     }
658     return type;
659 }
660 
AddOrUpdateWindowDragHotArea(uint32_t type,const WSRect & area)661 void SceneSession::AddOrUpdateWindowDragHotArea(uint32_t type, const WSRect& area)
662 {
663     std::unique_lock<std::shared_mutex> lock(windowDragHotAreaMutex_);
664     auto const result = windowDragHotAreaMap_.insert({type, area});
665     if (!result.second) {
666         result.first->second = area;
667     }
668 }
669 
NotifySubModalTypeChange(SubWindowModalType subWindowModalType)670 WSError SceneSession::NotifySubModalTypeChange(SubWindowModalType subWindowModalType)
671 {
672     const char* const where = __func__;
673     PostTask([weakThis = wptr(this), subWindowModalType, where] {
674         auto session = weakThis.promote();
675         if (!session) {
676             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
677             return;
678         }
679         TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s subWindowModalType: %{public}u",
680             where, static_cast<uint32_t>(subWindowModalType));
681         if (session->onSubModalTypeChange_) {
682             session->onSubModalTypeChange_(subWindowModalType);
683         }
684     }, __func__);
685     return WSError::WS_OK;
686 }
687 
RegisterSubModalTypeChangeCallback(NotifySubModalTypeChangeFunc && func)688 void SceneSession::RegisterSubModalTypeChangeCallback(NotifySubModalTypeChangeFunc&& func)
689 {
690     const char* const where = __func__;
691     PostTask([weakThis = wptr(this), func = std::move(func), where] {
692         auto session = weakThis.promote();
693         if (!session || !func) {
694             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session or SessionModalTypeChangeFunc is null", where);
695             return;
696         }
697         session->onSubModalTypeChange_ = std::move(func);
698         TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s id: %{public}d",
699             where, session->GetPersistentId());
700     }, __func__);
701 }
702 
RegisterMainModalTypeChangeCallback(NotifyMainModalTypeChangeFunc && func)703 void SceneSession::RegisterMainModalTypeChangeCallback(NotifyMainModalTypeChangeFunc&& func)
704 {
705     const char* const where = __func__;
706     PostTask([weakThis = wptr(this), func = std::move(func), where] {
707         auto session = weakThis.promote();
708         if (!session || !func) {
709             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session or func is null", where);
710             return;
711         }
712         session->onMainModalTypeChange_ = std::move(func);
713         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, session->GetPersistentId());
714     }, __func__);
715 }
716 
IsDialogWindow() const717 bool SceneSession::IsDialogWindow() const
718 {
719     return WindowHelper::IsDialogWindow(GetSessionProperty()->GetWindowType());
720 }
721 
GetSubWindowModalType() const722 SubWindowModalType SceneSession::GetSubWindowModalType() const
723 {
724     SubWindowModalType modalType = SubWindowModalType::TYPE_UNDEFINED;
725     auto property = GetSessionProperty();
726     if (property == nullptr) {
727         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
728         return modalType;
729     }
730     auto windowType = property->GetWindowType();
731     if (WindowHelper::IsToastSubWindow(windowType, property->GetWindowFlags())) {
732         return SubWindowModalType::TYPE_TOAST;
733     }
734     if (WindowHelper::IsDialogWindow(windowType)) {
735         modalType = SubWindowModalType::TYPE_DIALOG;
736     } else if (WindowHelper::IsModalSubWindow(windowType, property->GetWindowFlags())) {
737         if (WindowHelper::IsApplicationModalSubWindow(windowType, property->GetWindowFlags())) {
738             modalType = SubWindowModalType::TYPE_APPLICATION_MODALITY;
739         } else {
740             modalType = SubWindowModalType::TYPE_WINDOW_MODALITY;
741         }
742     } else if (WindowHelper::IsSubWindow(windowType)) {
743         modalType = SubWindowModalType::TYPE_NORMAL;
744     }
745     return modalType;
746 }
747 
SetSessionEventParam(SessionEventParam param)748 void SceneSession::SetSessionEventParam(SessionEventParam param)
749 {
750     sessionEventParam_ = param;
751 }
752 
RegisterSessionChangeCallback(const sptr<SceneSession::SessionChangeCallback> & sessionChangeCallback)753 void SceneSession::RegisterSessionChangeCallback(const sptr<SceneSession::SessionChangeCallback>&
754     sessionChangeCallback)
755 {
756     std::lock_guard<std::mutex> guard(sessionChangeCbMutex_);
757     sessionChangeCallback_ = sessionChangeCallback;
758 }
759 
RegisterUpdateAppUseControlCallback(UpdateAppUseControlFunc && callback)760 void SceneSession::RegisterUpdateAppUseControlCallback(UpdateAppUseControlFunc&& callback)
761 {
762     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
763         auto session = weakThis.promote();
764         if (!session) {
765             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
766             return;
767         }
768         session->onUpdateAppUseControlFunc_ = std::move(callback);
769         for (const auto& [type, isNeedControl] : session->appUseControlMap_) {
770             session->onUpdateAppUseControlFunc_(type, isNeedControl);
771         }
772     };
773     PostTask(task, __func__);
774 }
775 
NotifyUpdateAppUseControl(ControlAppType type,bool isNeedControl)776 void SceneSession::NotifyUpdateAppUseControl(ControlAppType type, bool isNeedControl)
777 {
778     auto task = [weakThis = wptr(this), type, isNeedControl] {
779         auto session = weakThis.promote();
780         if (!session) {
781             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
782             return;
783         }
784         session->appUseControlMap_[type] = isNeedControl;
785         if (session->onUpdateAppUseControlFunc_) {
786             session->onUpdateAppUseControlFunc_(type, isNeedControl);
787         }
788     };
789     PostTask(task, __func__);
790 }
791 
RegisterDefaultAnimationFlagChangeCallback(NotifyWindowAnimationFlagChangeFunc && callback)792 void SceneSession::RegisterDefaultAnimationFlagChangeCallback(NotifyWindowAnimationFlagChangeFunc&& callback)
793 {
794     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
795         auto session = weakThis.promote();
796         if (!session) {
797             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
798             return;
799         }
800         session->onWindowAnimationFlagChange_ = std::move(callback);
801         session->onWindowAnimationFlagChange_(session->IsNeedDefaultAnimation());
802     };
803     PostTask(task, __func__);
804 }
805 
RegisterDefaultDensityEnabledCallback(NotifyDefaultDensityEnabledFunc && callback)806 void SceneSession::RegisterDefaultDensityEnabledCallback(NotifyDefaultDensityEnabledFunc&& callback)
807 {
808     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
809         auto session = weakThis.promote();
810         if (!session) {
811             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
812             return;
813         }
814         session->onDefaultDensityEnabledFunc_ = std::move(callback);
815     };
816     PostTask(task, __func__);
817 }
818 
RegisterNeedAvoidCallback(NotifyNeedAvoidFunc && callback)819 void SceneSession::RegisterNeedAvoidCallback(NotifyNeedAvoidFunc&& callback)
820 {
821     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
822         auto session = weakThis.promote();
823         if (!session) {
824             TLOGNE(WmsLogTag::WMS_IMMS, "session is null");
825             return;
826         }
827         session->onNeedAvoid_ = std::move(callback);
828     };
829     PostTask(task, __func__);
830 }
831 
RegisterSystemBarPropertyChangeCallback(NotifySystemBarPropertyChangeFunc && callback)832 void SceneSession::RegisterSystemBarPropertyChangeCallback(NotifySystemBarPropertyChangeFunc&& callback)
833 {
834     PostTask([weakThis = wptr(this), callback = std::move(callback)] {
835         auto session = weakThis.promote();
836         if (!session) {
837             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
838             return;
839         }
840         session->onSystemBarPropertyChange_ = std::move(callback);
841     }, __func__);
842 }
843 
RegisterTouchOutsideCallback(NotifyTouchOutsideFunc && callback)844 void SceneSession::RegisterTouchOutsideCallback(NotifyTouchOutsideFunc&& callback)
845 {
846     PostTask([weakThis = wptr(this), callback = std::move(callback)] {
847         auto session = weakThis.promote();
848         if (!session) {
849             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
850             return;
851         }
852         session->onTouchOutside_ = std::move(callback);
853     }, __func__);
854 }
855 
SetGlobalMaximizeMode(MaximizeMode mode)856 WSError SceneSession::SetGlobalMaximizeMode(MaximizeMode mode)
857 {
858     auto task = [weakThis = wptr(this), mode]() {
859         auto session = weakThis.promote();
860         if (!session) {
861             WLOGFE("[WMSCom] session is null");
862             return WSError::WS_ERROR_DESTROYED_OBJECT;
863         }
864         WLOGFD("[WMSCom] mode: %{public}u", static_cast<uint32_t>(mode));
865         session->maximizeMode_ = mode;
866         ScenePersistentStorage::Insert("maximize_state", static_cast<int32_t>(session->maximizeMode_),
867             ScenePersistentStorageType::MAXIMIZE_STATE);
868         return WSError::WS_OK;
869     };
870     return PostSyncTask(task, "SetGlobalMaximizeMode");
871 }
872 
GetGlobalMaximizeMode(MaximizeMode & mode)873 WSError SceneSession::GetGlobalMaximizeMode(MaximizeMode& mode)
874 {
875     auto task = [weakThis = wptr(this), &mode]() {
876         auto session = weakThis.promote();
877         if (!session) {
878             WLOGFE("[WMSCom] session is null");
879             return WSError::WS_ERROR_DESTROYED_OBJECT;
880         }
881         mode = maximizeMode_;
882         WLOGFD("[WMSCom] mode: %{public}u", static_cast<uint32_t>(mode));
883         return WSError::WS_OK;
884     };
885     return PostSyncTask(task, "GetGlobalMaximizeMode");
886 }
887 
CheckAspectRatioValid(const sptr<SceneSession> & session,float ratio,float vpr)888 static WSError CheckAspectRatioValid(const sptr<SceneSession>& session, float ratio, float vpr)
889 {
890     if (MathHelper::NearZero(ratio)) {
891         return WSError::WS_OK;
892     }
893     if (!session) {
894         return WSError::WS_ERROR_INVALID_PARAM;
895     }
896     auto sessionProperty = session->GetSessionProperty();
897     if (!sessionProperty) {
898         return WSError::WS_ERROR_INVALID_PARAM;
899     }
900     auto limits = sessionProperty->GetWindowLimits();
901     if (session->IsDecorEnable()) {
902         if (limits.minWidth_ && limits.maxHeight_ &&
903             MathHelper::LessNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.minWidth_, vpr) /
904             SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr))) {
905             WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
906             return WSError::WS_ERROR_INVALID_PARAM;
907         } else if (limits.minHeight_ && limits.maxWidth_ &&
908             MathHelper::GreatNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr) /
909             SessionUtils::ToLayoutHeight(limits.minHeight_, vpr))) {
910             WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
911             return WSError::WS_ERROR_INVALID_PARAM;
912         }
913     } else {
914         if (limits.minWidth_ && limits.maxHeight_ && MathHelper::LessNotEqual(ratio,
915             static_cast<float>(limits.minWidth_) / limits.maxHeight_)) {
916             WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
917             return WSError::WS_ERROR_INVALID_PARAM;
918         } else if (limits.minHeight_ && limits.maxWidth_ && MathHelper::GreatNotEqual(ratio,
919             static_cast<float>(limits.maxWidth_) / limits.minHeight_)) {
920             WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
921             return WSError::WS_ERROR_INVALID_PARAM;
922         }
923     }
924     return WSError::WS_OK;
925 }
926 
SetAspectRatio(float ratio)927 WSError SceneSession::SetAspectRatio(float ratio)
928 {
929     auto task = [weakThis = wptr(this), ratio]() {
930         auto session = weakThis.promote();
931         if (!session) {
932             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
933             return WSError::WS_ERROR_DESTROYED_OBJECT;
934         }
935         if (!session->GetSessionProperty()) {
936             TLOGE(WmsLogTag::WMS_LAYOUT, "SetAspectRatio failed because property is null");
937             return WSError::WS_ERROR_NULLPTR;
938         }
939         float vpr = 1.5f; // 1.5f: default virtual pixel ratio
940         auto display = DisplayManager::GetInstance().GetDefaultDisplay();
941         if (display) {
942             vpr = display->GetVirtualPixelRatio();
943             WLOGD("vpr = %{public}f", vpr);
944         }
945         WSError ret = CheckAspectRatioValid(session, ratio, vpr);
946         if (ret != WSError::WS_OK) {
947             return ret;
948         }
949         session->aspectRatio_ = ratio;
950         if (session->moveDragController_) {
951             session->moveDragController_->SetAspectRatio(ratio);
952         }
953         session->SaveAspectRatio(session->aspectRatio_);
954         WSRect fixedRect = session->winRect_;
955         TLOGI(WmsLogTag::WMS_LAYOUT, "Before fixing, the id:%{public}d, the current rect: %{public}s, "
956             "ratio: %{public}f", session->GetPersistentId(), fixedRect.ToString().c_str(), ratio);
957         if (session->FixRectByAspectRatio(fixedRect)) {
958             TLOGI(WmsLogTag::WMS_LAYOUT, "After fixing, the id:%{public}d, the fixed rect: %{public}s",
959                 session->GetPersistentId(), fixedRect.ToString().c_str());
960             session->NotifySessionRectChange(fixedRect, SizeChangeReason::RESIZE);
961         }
962         return WSError::WS_OK;
963     };
964     return PostSyncTask(task, "SetAspectRatio");
965 }
966 
UpdateRect(const WSRect & rect,SizeChangeReason reason,const std::string & updateReason,const std::shared_ptr<RSTransaction> & rsTransaction)967 WSError SceneSession::UpdateRect(const WSRect& rect, SizeChangeReason reason,
968     const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction)
969 {
970     const char* const funcName = __func__;
971     auto task = [weakThis = wptr(this), rect, reason, rsTransaction, updateReason, funcName]() {
972         auto session = weakThis.promote();
973         if (!session) {
974             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", funcName);
975             return WSError::WS_ERROR_DESTROYED_OBJECT;
976         }
977         if (session->winRect_ == rect && session->reason_ != SizeChangeReason::DRAG_END &&
978             (session->GetWindowType() != WindowType::WINDOW_TYPE_KEYBOARD_PANEL &&
979              session->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT)) {
980             if (!session->sessionStage_) {
981                 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: skip same rect update id:%{public}d rect:%{public}s",
982                     funcName, session->GetPersistentId(), rect.ToString().c_str());
983                 return WSError::WS_OK;
984             } else if (session->GetClientRect() == rect) {
985                 TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: skip same rect update id:%{public}d rect:%{public}s "
986                     "clientRect:%{public}s", funcName, session->GetPersistentId(), rect.ToString().c_str(),
987                     session->GetClientRect().ToString().c_str());
988                 return WSError::WS_OK;
989             }
990         }
991         if (rect.IsInvalid()) {
992             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d rect:%{public}s is invalid",
993                 funcName, session->GetPersistentId(), rect.ToString().c_str());
994             return WSError::WS_ERROR_INVALID_PARAM;
995         }
996         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
997             "SceneSession::UpdateRect%d [%d, %d, %u, %u]",
998             session->GetPersistentId(), rect.posX_, rect.posY_, rect.width_, rect.height_);
999         // position change no need to notify client, since frame layout finish will notify
1000         if (NearEqual(rect.width_, session->winRect_.width_) && NearEqual(rect.height_, session->winRect_.height_) &&
1001             (session->reason_ != SizeChangeReason::DRAG_MOVE || !session->rectChangeListenerRegistered_)) {
1002             TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: position change no need notify client id:%{public}d, "
1003                 "rect:%{public}s, preRect: %{public}s", funcName,
1004                 session->GetPersistentId(), rect.ToString().c_str(), session->winRect_.ToString().c_str());
1005             session->winRect_ = rect;
1006         } else {
1007             session->winRect_ = rect;
1008             session->NotifyClientToUpdateRect(updateReason, rsTransaction);
1009         }
1010         session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
1011         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, reason:%{public}d %{public}s, "
1012             "rect:%{public}s, clientRect:%{public}s",
1013             funcName, session->GetPersistentId(), session->reason_, updateReason.c_str(),
1014             rect.ToString().c_str(), session->GetClientRect().ToString().c_str());
1015 
1016         return WSError::WS_OK;
1017     };
1018     PostTask(task, "UpdateRect" + GetRectInfo(rect));
1019     return WSError::WS_OK;
1020 }
1021 
IsKeyboardNeedLeftOffset(bool isPhone,const sptr<WindowSessionProperty> & sessionProperty)1022 bool SceneSession::IsKeyboardNeedLeftOffset(bool isPhone, const sptr<WindowSessionProperty>& sessionProperty)
1023 {
1024     static bool isFoldable = ScreenSessionManagerClient::GetInstance().IsFoldable();
1025     bool isFolded = ScreenSessionManagerClient::GetInstance().GetFoldStatus() == OHOS::Rosen::FoldStatus::FOLDED;
1026     bool isDualDevice = FoldScreenStateInternel::IsDualDisplayFoldDevice();
1027     uint32_t screenWidth = 0;
1028     uint32_t screenHeight = 0;
1029     if (!GetScreenWidthAndHeightFromServer(sessionProperty, screenWidth, screenHeight)) {
1030         return false;
1031     }
1032     bool isLandscape = screenWidth > screenHeight ? true : false;
1033     bool result = isPhone && (!isFoldable || isFolded || isDualDevice) && isLandscape;
1034     TLOGI(WmsLogTag::WMS_LAYOUT, "isPhone:%{public}d, isFoldable:%{public}d, isFolded:%{public}d, "
1035         "isDualDevice:%{public}d, isLandscape:%{public}d, screenWidth:%{public}u, screenHeight:%{public}u, "
1036         "isKeyboardNeedLeftOffset:%{public}d", isPhone, isFoldable, isFolded, isDualDevice, isLandscape,
1037         screenWidth, screenHeight, result);
1038     return result;
1039 }
1040 
FixKeyboardPositionByKeyboardPanel(sptr<SceneSession> panelSession,sptr<SceneSession> keyboardSession)1041 void SceneSession::FixKeyboardPositionByKeyboardPanel(sptr<SceneSession> panelSession,
1042     sptr<SceneSession> keyboardSession)
1043 {
1044     if (panelSession == nullptr || keyboardSession == nullptr) {
1045         TLOGE(WmsLogTag::WMS_LAYOUT, "keyboard or panel session is null");
1046         return;
1047     }
1048 
1049     SessionGravity gravity = keyboardSession->GetKeyboardGravity();
1050     if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
1051         keyboardSession->winRect_.posX_ = panelSession->winRect_.posX_;
1052     } else {
1053         auto sessionProperty = keyboardSession->GetSessionProperty();
1054         if (sessionProperty == nullptr) {
1055             TLOGE(WmsLogTag::WMS_LAYOUT, "keyboard property is null");
1056             return;
1057         }
1058         static bool isPhone = systemConfig_.uiType_ == UI_TYPE_PHONE;
1059         if (!IsKeyboardNeedLeftOffset(isPhone, sessionProperty) || panelSession->winRect_.posX_ != 0) {
1060             keyboardSession->winRect_.posX_ = panelSession->winRect_.posX_;
1061         }
1062     }
1063     keyboardSession->winRect_.posY_ = panelSession->winRect_.posY_;
1064     TLOGI(WmsLogTag::WMS_LAYOUT, "panelId:%{public}d, keyboardId:%{public}d, panelRect:%{public}s, "
1065         "keyboardRect:%{public}s, gravity:%{public}d", panelSession->GetPersistentId(),
1066         keyboardSession->GetPersistentId(), panelSession->winRect_.ToString().c_str(),
1067         keyboardSession->winRect_.ToString().c_str(), gravity);
1068 }
1069 
NotifyClientToUpdateRectTask(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)1070 WSError SceneSession::NotifyClientToUpdateRectTask(const std::string& updateReason,
1071     std::shared_ptr<RSTransaction> rsTransaction)
1072 {
1073     TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, reason:%{public}d, rect:%{public}s",
1074         GetPersistentId(), reason_, winRect_.ToString().c_str());
1075     bool isMoveOrDrag = moveDragController_ &&
1076         (moveDragController_->GetStartDragFlag() || moveDragController_->GetStartMoveFlag());
1077     if (isMoveOrDrag && reason_ == SizeChangeReason::UNDEFINED) {
1078         TLOGD(WmsLogTag::WMS_LAYOUT, "skip redundant rect update!");
1079         return WSError::WS_ERROR_REPEAT_OPERATION;
1080     }
1081     WSError ret = WSError::WS_OK;
1082     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
1083         "SceneSession::NotifyClientToUpdateRect%d [%d, %d, %u, %u] reason:%u",
1084         GetPersistentId(), winRect_.posX_, winRect_.posY_, winRect_.width_, winRect_.height_, reason_);
1085 
1086     if (!Session::IsScbCoreEnabled() && isKeyboardPanelEnabled_) {
1087         sptr<SceneSession> self(this);
1088         if (GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
1089             const auto& keyboardSession = GetKeyboardSession();
1090             FixKeyboardPositionByKeyboardPanel(self, keyboardSession);
1091             if (keyboardSession != nullptr) {
1092                 ret = keyboardSession->Session::UpdateRect(keyboardSession->winRect_, reason_, updateReason, nullptr);
1093             }
1094             return ret;
1095         }
1096         if (GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1097             FixKeyboardPositionByKeyboardPanel(GetKeyboardPanelSession(), self);
1098         }
1099     }
1100 
1101     // once reason is undefined, not use rsTransaction
1102     // when rotation, sync cnt++ in marshalling. Although reason is undefined caused by resize
1103     if (reason_ == SizeChangeReason::UNDEFINED || reason_ == SizeChangeReason::RESIZE || IsMoveToOrDragMove(reason_)) {
1104         ret = Session::UpdateRect(winRect_, reason_, updateReason, nullptr);
1105     } else {
1106         ret = Session::UpdateRect(winRect_, reason_, updateReason, rsTransaction);
1107 #ifdef DEVICE_STATUS_ENABLE
1108         // When the drag is in progress, the drag window needs to be notified to rotate.
1109         if (rsTransaction != nullptr) {
1110             RotateDragWindow(rsTransaction);
1111         }
1112 #endif // DEVICE_STATUS_ENABLE
1113     }
1114 
1115     return ret;
1116 }
1117 
NotifyClientToUpdateRect(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)1118 WSError SceneSession::NotifyClientToUpdateRect(const std::string& updateReason,
1119     std::shared_ptr<RSTransaction> rsTransaction)
1120 {
1121     auto task = [weakThis = wptr(this), rsTransaction, updateReason]() {
1122         auto session = weakThis.promote();
1123         if (!session) {
1124             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
1125             return WSError::WS_ERROR_DESTROYED_OBJECT;
1126         }
1127         WSError ret = session->NotifyClientToUpdateRectTask(updateReason, rsTransaction);
1128         if (ret != WSError::WS_OK) {
1129             return ret;
1130         }
1131         if (session->specificCallback_ != nullptr) {
1132             if (Session::IsScbCoreEnabled()) {
1133                 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
1134             } else {
1135                 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
1136             }
1137         }
1138         return ret;
1139     };
1140     PostTask(task, "NotifyClientToUpdateRect");
1141     return WSError::WS_OK;
1142 }
1143 
GetScreenWidthAndHeightFromServer(const sptr<WindowSessionProperty> & sessionProperty,uint32_t & screenWidth,uint32_t & screenHeight)1144 bool SceneSession::GetScreenWidthAndHeightFromServer(const sptr<WindowSessionProperty>& sessionProperty,
1145     uint32_t& screenWidth, uint32_t& screenHeight)
1146 {
1147     if (isScreenAngleMismatch_) {
1148         screenWidth = targetScreenWidth_;
1149         screenHeight = targetScreenHeight_;
1150         TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
1151         return true;
1152     }
1153 
1154     const auto& screenSession = sessionProperty == nullptr ? nullptr :
1155         ScreenSessionManagerClient::GetInstance().GetScreenSession(sessionProperty->GetDisplayId());
1156     if (screenSession != nullptr) {
1157         screenWidth = screenSession->GetScreenProperty().GetBounds().rect_.width_;
1158         screenHeight = screenSession->GetScreenProperty().GetBounds().rect_.height_;
1159     } else {
1160         TLOGI(WmsLogTag::WMS_KEYBOARD, "sessionProperty or screenSession is nullptr, use defaultDisplayInfo");
1161         auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
1162         if (defaultDisplayInfo != nullptr) {
1163             screenWidth = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
1164             screenHeight = static_cast<uint32_t>(defaultDisplayInfo->GetHeight());
1165         } else {
1166             TLOGE(WmsLogTag::WMS_KEYBOARD, "defaultDisplayInfo is null, get screenWidthAndHeight failed");
1167             return false;
1168         }
1169     }
1170     TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
1171     return true;
1172 }
1173 
GetScreenWidthAndHeightFromClient(const sptr<WindowSessionProperty> & sessionProperty,uint32_t & screenWidth,uint32_t & screenHeight)1174 bool SceneSession::GetScreenWidthAndHeightFromClient(const sptr<WindowSessionProperty>& sessionProperty,
1175     uint32_t& screenWidth, uint32_t& screenHeight)
1176 {
1177     if (isScreenAngleMismatch_) {
1178         screenWidth = targetScreenWidth_;
1179         screenHeight = targetScreenHeight_;
1180         TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
1181         return true;
1182     }
1183 
1184     auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
1185     if (defaultDisplayInfo != nullptr) {
1186         screenWidth = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
1187         screenHeight = static_cast<uint32_t>(defaultDisplayInfo->GetHeight());
1188     } else {
1189         TLOGE(WmsLogTag::WMS_KEYBOARD, "defaultDisplayInfo is null, get screenWidthAndHeight failed");
1190         return false;
1191     }
1192     TLOGI(WmsLogTag::WMS_KEYBOARD, "screenWidth: %{public}d, screenHeight: %{public}d", screenWidth, screenHeight);
1193     return true;
1194 }
1195 
NotifyTargetScreenWidthAndHeight(bool isScreenAngleMismatch,uint32_t screenWidth,uint32_t screenHeight)1196 void SceneSession::NotifyTargetScreenWidthAndHeight(bool isScreenAngleMismatch, uint32_t screenWidth,
1197     uint32_t screenHeight)
1198 {
1199     auto task = [weakThis = wptr(this), isScreenAngleMismatch, screenWidth, screenHeight]() {
1200         auto session = weakThis.promote();
1201         if (!session) {
1202             TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboard session is null");
1203             return;
1204         }
1205         session->isScreenAngleMismatch_ = isScreenAngleMismatch;
1206         session->targetScreenWidth_ = screenWidth;
1207         session->targetScreenHeight_ = screenHeight;
1208         TLOGI(WmsLogTag::WMS_KEYBOARD, "target isMismatch: %{public}d, width_: %{public}d, height_: %{public}d",
1209             isScreenAngleMismatch, screenWidth, screenHeight);
1210         return;
1211     };
1212     PostTask(task, "NotifyTargetScreenWidthAndHeight");
1213 }
1214 
UpdateInputMethodSessionRect(const WSRect & rect,WSRect & newWinRect,WSRect & newRequestRect)1215 bool SceneSession::UpdateInputMethodSessionRect(const WSRect& rect, WSRect& newWinRect, WSRect& newRequestRect)
1216 {
1217     uint32_t screenWidth = 0;
1218     uint32_t screenHeight = 0;
1219     auto sessionProperty = GetSessionProperty();
1220     if (!sessionProperty) {
1221         TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1222         return false;
1223     }
1224     SessionGravity gravity = GetKeyboardGravity();
1225     if (GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
1226         (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM || gravity == SessionGravity::SESSION_GRAVITY_DEFAULT)) {
1227         if (!GetScreenWidthAndHeightFromServer(sessionProperty, screenWidth, screenHeight)) {
1228             return false;
1229         }
1230         newWinRect.width_ = (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) ?
1231             static_cast<int32_t>(screenWidth) : rect.width_;
1232         newRequestRect.width_ = newWinRect.width_;
1233         newWinRect.height_ = rect.height_;
1234         newRequestRect.height_ = newWinRect.height_;
1235         newWinRect.posX_ = (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) ? 0 : rect.posX_;
1236         newRequestRect.posX_ = newWinRect.posX_;
1237         newWinRect.posY_ = static_cast<int32_t>(screenHeight) - newWinRect.height_;
1238         newRequestRect.posY_ = newWinRect.posY_;
1239         TLOGI(WmsLogTag::WMS_KEYBOARD, "rect: %{public}s, newRequestRect: %{public}s, newWinRect: %{public}s",
1240             rect.ToString().c_str(), newRequestRect.ToString().c_str(), newWinRect.ToString().c_str());
1241         return true;
1242     }
1243     TLOGD(WmsLogTag::WMS_KEYBOARD, "There is no need to update input rect");
1244     return false;
1245 }
1246 
SetSessionRectChangeCallback(const NotifySessionRectChangeFunc & func)1247 void SceneSession::SetSessionRectChangeCallback(const NotifySessionRectChangeFunc& func)
1248 {
1249     auto task = [weakThis = wptr(this), func]() {
1250         auto session = weakThis.promote();
1251         if (!session) {
1252             WLOGFE("session is null");
1253             return WSError::WS_ERROR_DESTROYED_OBJECT;
1254         }
1255         session->sessionRectChangeFunc_ = func;
1256         if (session->sessionRectChangeFunc_ && session->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1257             auto reason = SizeChangeReason::UNDEFINED;
1258             auto rect = session->GetSessionRequestRect();
1259             if (rect.width_ == 0 && rect.height_ == 0) {
1260                 reason = SizeChangeReason::MOVE;
1261             }
1262             session->sessionRectChangeFunc_(session->GetSessionRequestRect(), reason);
1263         }
1264         return WSError::WS_OK;
1265     };
1266     PostTask(task, "SetSessionRectChangeCallback");
1267 }
1268 
SetMainWindowTopmostChangeCallback(NotifyMainWindowTopmostChangeFunc && func)1269 void SceneSession::SetMainWindowTopmostChangeCallback(NotifyMainWindowTopmostChangeFunc&& func)
1270 {
1271     const char* const where = __func__;
1272     PostTask([weakThis = wptr(this), func = std::move(func), where] {
1273         auto session = weakThis.promote();
1274         if (!session || !func) {
1275             TLOGNE(WmsLogTag::WMS_HIERARCHY, "%{public}s session or func is null", where);
1276             return;
1277         }
1278         session->mainWindowTopmostChangeFunc_ = std::move(func);
1279     }, __func__);
1280 }
1281 
SetTitleAndDockHoverShowChangeCallback(NotifyTitleAndDockHoverShowChangeFunc && func)1282 void SceneSession::SetTitleAndDockHoverShowChangeCallback(NotifyTitleAndDockHoverShowChangeFunc&& func)
1283 {
1284     const char* const funcName = __func__;
1285     PostTask([weakThis = wptr(this), func = std::move(func), funcName] {
1286         auto session = weakThis.promote();
1287         if (!session || !func) {
1288             TLOGNE(WmsLogTag::WMS_IMMS, "session or TitleAndDockHoverShowChangeFunc is null");
1289             return;
1290         }
1291         session->onTitleAndDockHoverShowChangeFunc_ = std::move(func);
1292         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s id: %{public}d",
1293             funcName, session->GetPersistentId());
1294     }, funcName);
1295 }
1296 
SetRestoreMainWindowCallback(NotifyRestoreMainWindowFunc && func)1297 void SceneSession::SetRestoreMainWindowCallback(NotifyRestoreMainWindowFunc&& func)
1298 {
1299     const char* const funcName = __func__;
1300     auto task = [weakThis = wptr(this), func = std::move(func), funcName] {
1301         auto session = weakThis.promote();
1302         if (!session || !func) {
1303             TLOGNE(WmsLogTag::WMS_LIFE, "session or RestoreMainWindowFunc is null");
1304             return;
1305         }
1306         session->onRestoreMainWindowFunc_ = std::move(func);
1307         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d",
1308             funcName, session->GetPersistentId());
1309     };
1310     PostTask(task, funcName);
1311 }
1312 
SetKeyboardGravityChangeCallback(const NotifyKeyboardGravityChangeFunc & func)1313 void SceneSession::SetKeyboardGravityChangeCallback(const NotifyKeyboardGravityChangeFunc& func)
1314 {
1315     auto task = [weakThis = wptr(this), func]() {
1316         auto session = weakThis.promote();
1317         if (!session || !func) {
1318             WLOGFE("session or gravityChangeFunc is null");
1319             return WSError::WS_ERROR_DESTROYED_OBJECT;
1320         }
1321         session->keyboardGravityChangeFunc_ = func;
1322         session->keyboardGravityChangeFunc_(session->GetKeyboardGravity());
1323         TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify gravity change when register, id: %{public}d gravity: %{public}d",
1324             session->GetPersistentId(), session->GetKeyboardGravity());
1325         return WSError::WS_OK;
1326     };
1327     PostTask(task, "SetKeyboardGravityChangeCallback");
1328 }
1329 
SetAdjustKeyboardLayoutCallback(const NotifyKeyboardLayoutAdjustFunc & func)1330 void SceneSession::SetAdjustKeyboardLayoutCallback(const NotifyKeyboardLayoutAdjustFunc& func)
1331 {
1332     auto task = [weakThis = wptr(this), func]() {
1333         auto session = weakThis.promote();
1334         if (!session || !func) {
1335             TLOGE(WmsLogTag::WMS_KEYBOARD, "session or keyboardLayoutFunc is null");
1336             return WSError::WS_ERROR_DESTROYED_OBJECT;
1337         }
1338         session->adjustKeyboardLayoutFunc_ = func;
1339         auto property = session->GetSessionProperty();
1340         if (property == nullptr) {
1341             TLOGE(WmsLogTag::WMS_KEYBOARD, "property is null");
1342             return WSError::WS_ERROR_DESTROYED_OBJECT;
1343         }
1344         KeyboardLayoutParams params = property->GetKeyboardLayoutParams();
1345         session->adjustKeyboardLayoutFunc_(params);
1346         TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify adjust keyboard layout when register, keyboardId: %{public}d, "
1347             "gravity: %{public}u, LandscapeKeyboardRect: %{public}s, PortraitKeyboardRect: %{public}s, "
1348             "LandscapePanelRect: %{public}s, PortraitPanelRect: %{public}s", session->GetPersistentId(),
1349             static_cast<uint32_t>(params.gravity_), params.LandscapeKeyboardRect_.ToString().c_str(),
1350             params.PortraitKeyboardRect_.ToString().c_str(), params.LandscapePanelRect_.ToString().c_str(),
1351             params.PortraitPanelRect_.ToString().c_str());
1352         return WSError::WS_OK;
1353     };
1354     PostTask(task, "SetAdjustKeyboardLayoutCallback");
1355 }
1356 
SetSessionPiPControlStatusChangeCallback(const NotifySessionPiPControlStatusChangeFunc & func)1357 void SceneSession::SetSessionPiPControlStatusChangeCallback(const NotifySessionPiPControlStatusChangeFunc& func)
1358 {
1359     auto task = [weakThis = wptr(this), func]() {
1360         auto session = weakThis.promote();
1361         if (!session) {
1362             TLOGE(WmsLogTag::WMS_PIP, "session is null");
1363             return WSError::WS_ERROR_DESTROYED_OBJECT;
1364         }
1365         session->sessionPiPControlStatusChangeFunc_ = func;
1366         return WSError::WS_OK;
1367     };
1368     PostTask(task, __func__);
1369 }
1370 
SetAutoStartPiPStatusChangeCallback(const NotifyAutoStartPiPStatusChangeFunc & func)1371 void SceneSession::SetAutoStartPiPStatusChangeCallback(const NotifyAutoStartPiPStatusChangeFunc& func)
1372 {
1373     auto task = [weakThis = wptr(this), func] {
1374         auto session = weakThis.promote();
1375         if (!session) {
1376             TLOGNE(WmsLogTag::WMS_PIP, "session is null");
1377             return;
1378         }
1379         session->autoStartPiPStatusChangeFunc_ = func;
1380     };
1381     PostTask(task, __func__);
1382 }
1383 
UpdateSessionRectInner(const WSRect & rect,const SizeChangeReason & reason)1384 void SceneSession::UpdateSessionRectInner(const WSRect& rect, const SizeChangeReason& reason)
1385 {
1386     auto newWinRect = winRect_;
1387     auto newRequestRect = GetSessionRequestRect();
1388     SizeChangeReason newReason = reason;
1389     if (reason == SizeChangeReason::MOVE) {
1390         newWinRect.posX_ = rect.posX_;
1391         newWinRect.posY_ = rect.posY_;
1392         newRequestRect.posX_ = rect.posX_;
1393         newRequestRect.posY_ = rect.posY_;
1394         if (!Session::IsScbCoreEnabled() && !WindowHelper::IsMainWindow(GetWindowType())) {
1395             SetSessionRect(newWinRect);
1396         }
1397         SetSessionRequestRect(newRequestRect);
1398         NotifySessionRectChange(newRequestRect, reason);
1399     } else if (reason == SizeChangeReason::RESIZE) {
1400         bool needUpdateInputMethod = UpdateInputMethodSessionRect(rect, newWinRect, newRequestRect);
1401         if (needUpdateInputMethod) {
1402             newReason = SizeChangeReason::UNDEFINED;
1403             TLOGD(WmsLogTag::WMS_KEYBOARD, "Input rect has totally changed, need to modify reason, id: %{public}d",
1404                 GetPersistentId());
1405         } else if (rect.width_ > 0 && rect.height_ > 0) {
1406             newWinRect.width_ = rect.width_;
1407             newWinRect.height_ = rect.height_;
1408             newRequestRect.width_ = rect.width_;
1409             newRequestRect.height_ = rect.height_;
1410         }
1411         if (!Session::IsScbCoreEnabled() && GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1412             SetSessionRect(newWinRect);
1413         }
1414         SetSessionRequestRect(newRequestRect);
1415         NotifySessionRectChange(newRequestRect, newReason);
1416     } else {
1417         if (!Session::IsScbCoreEnabled()) {
1418             SetSessionRect(rect);
1419         }
1420         NotifySessionRectChange(rect, reason);
1421     }
1422     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d reason:%{public}d newReason:%{public}d rect:%{public}s "
1423         "newRequestRect:%{public}s newWinRect:%{public}s", GetPersistentId(), reason,
1424         newReason, rect.ToString().c_str(), newRequestRect.ToString().c_str(), newWinRect.ToString().c_str());
1425 }
1426 
UpdateSessionRect(const WSRect & rect,const SizeChangeReason reason,bool isGlobal,bool isFromMoveToGlobal)1427 WSError SceneSession::UpdateSessionRect(
1428     const WSRect &rect, const SizeChangeReason reason, bool isGlobal, bool isFromMoveToGlobal)
1429 {
1430     if ((reason == SizeChangeReason::MOVE || reason == SizeChangeReason::RESIZE) &&
1431         GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1432         return WSError::WS_DO_NOTHING;
1433     }
1434     WSRect newRect = rect;
1435     if (isGlobal && WindowHelper::IsSubWindow(Session::GetWindowType()) &&
1436         (systemConfig_.uiType_ == UI_TYPE_PHONE ||
1437          (systemConfig_.uiType_ == UI_TYPE_PAD && !IsFreeMultiWindowMode()))) {
1438         auto parentSession = GetParentSession();
1439         if (parentSession) {
1440             auto parentRect = parentSession->GetSessionRect();
1441             if (!CheckIfRectElementIsTooLarge(parentRect)) {
1442                 newRect.posX_ -= parentRect.posX_;
1443                 newRect.posY_ -= parentRect.posY_;
1444             }
1445         }
1446     }
1447     if (isFromMoveToGlobal && WindowHelper::IsSubWindow(Session::GetWindowType()) &&
1448         (systemConfig_.uiType_ == UI_TYPE_PHONE ||
1449          (systemConfig_.uiType_ == UI_TYPE_PAD && !IsFreeMultiWindowMode()))) {
1450         auto parentSession = GetParentSession();
1451         if (parentSession && parentSession->GetFloatingScale() != 0) {
1452             Rect parentGlobalRect;
1453             WMError errorCode = parentSession->GetGlobalScaledRect(parentGlobalRect);
1454             newRect.posX_ = (newRect.posX_ - parentGlobalRect.posX_) / parentSession->GetFloatingScale();
1455             newRect.posY_ = (newRect.posY_ - parentGlobalRect.posY_) / parentSession->GetFloatingScale();
1456         }
1457     }
1458     Session::RectCheckProcess();
1459     auto task = [weakThis = wptr(this), newRect, reason]() {
1460         auto session = weakThis.promote();
1461         if (!session) {
1462             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
1463             return WSError::WS_ERROR_DESTROYED_OBJECT;
1464         }
1465         session->UpdateSessionRectInner(newRect, reason);
1466         return WSError::WS_OK;
1467     };
1468     PostTask(task, "UpdateSessionRect" + GetRectInfo(rect));
1469     return WSError::WS_OK;
1470 }
1471 
1472 /** @note @window.layout */
UpdateClientRect(const WSRect & rect)1473 WSError SceneSession::UpdateClientRect(const WSRect& rect)
1474 {
1475     const char* const funcName = __func__;
1476     auto task = [weakThis = wptr(this), rect, funcName] {
1477         auto session = weakThis.promote();
1478         if (!session) {
1479             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", funcName);
1480             return;
1481         }
1482         if (rect.IsInvalid()) {
1483             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d rect:%{public}s is invalid",
1484                 funcName, session->GetPersistentId(), rect.ToString().c_str());
1485             return;
1486         }
1487         if (rect == session->GetClientRect()) {
1488             TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d skip same rect",
1489                 funcName, session->GetPersistentId());
1490             return;
1491         }
1492         session->SetClientRect(rect);
1493     };
1494     PostTask(task, "UpdateClientRect" + GetRectInfo(rect));
1495     return WSError::WS_OK;
1496 }
1497 
1498 /** @note @window.hierarchy */
RaiseToAppTop()1499 WSError SceneSession::RaiseToAppTop()
1500 {
1501     auto task = [weakThis = wptr(this)]() {
1502         auto session = weakThis.promote();
1503         if (!session) {
1504             WLOGFE("session is null");
1505             return WSError::WS_ERROR_DESTROYED_OBJECT;
1506         }
1507         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onRaiseToTop_) {
1508             TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", session->GetPersistentId());
1509             session->sessionChangeCallback_->onRaiseToTop_();
1510             session->SetMainSessionUIStateDirty(true);
1511         }
1512         return WSError::WS_OK;
1513     };
1514     return PostSyncTask(task, "RaiseToAppTop");
1515 }
1516 
1517 /** @note @window.hierarchy */
RaiseAboveTarget(int32_t subWindowId)1518 WSError SceneSession::RaiseAboveTarget(int32_t subWindowId)
1519 {
1520     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1521         WLOGFE("RaiseAboveTarget permission denied!");
1522         return WSError::WS_ERROR_NOT_SYSTEM_APP;
1523     }
1524     auto subSession = std::find_if(subSession_.begin(), subSession_.end(), [subWindowId](sptr<SceneSession> session) {
1525         bool res = (session != nullptr && session->GetWindowId() == subWindowId) ? true : false;
1526         return res;
1527     });
1528     int32_t callingPid = IPCSkeleton::GetCallingPid();
1529     if (subSession != subSession_.end() && callingPid != (*subSession)->GetCallingPid()) {
1530         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied! id: %{public}d", subWindowId);
1531         return WSError::WS_ERROR_INVALID_CALLING;
1532     }
1533     auto task = [weakThis = wptr(this), subWindowId]() {
1534         auto session = weakThis.promote();
1535         if (!session) {
1536             WLOGFE("session is null");
1537             return WSError::WS_ERROR_DESTROYED_OBJECT;
1538         }
1539         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onRaiseAboveTarget_) {
1540             session->sessionChangeCallback_->onRaiseAboveTarget_(subWindowId);
1541         }
1542         return WSError::WS_OK;
1543     };
1544     return PostSyncTask(task, "RaiseAboveTarget");
1545 }
1546 
BindDialogSessionTarget(const sptr<SceneSession> & sceneSession)1547 WSError SceneSession::BindDialogSessionTarget(const sptr<SceneSession>& sceneSession)
1548 {
1549     if (sceneSession == nullptr) {
1550         TLOGE(WmsLogTag::WMS_DIALOG, "dialog session is null");
1551         return WSError::WS_ERROR_NULLPTR;
1552     }
1553     if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onBindDialogTarget_) {
1554         TLOGI(WmsLogTag::WMS_DIALOG, "id: %{public}d", sceneSession->GetPersistentId());
1555         sessionChangeCallback_->onBindDialogTarget_(sceneSession);
1556     }
1557     return WSError::WS_OK;
1558 }
1559 
SetSystemBarProperty(WindowType type,SystemBarProperty systemBarProperty)1560 WSError SceneSession::SetSystemBarProperty(WindowType type, SystemBarProperty systemBarProperty)
1561 {
1562     TLOGD(WmsLogTag::WMS_IMMS, "persistentId():%{public}u type:%{public}u"
1563         "enable:%{public}u bgColor:%{public}x Color:%{public}x enableAnimation:%{public}u settingFlag:%{public}u",
1564         GetPersistentId(), static_cast<uint32_t>(type),
1565         systemBarProperty.enable_, systemBarProperty.backgroundColor_, systemBarProperty.contentColor_,
1566         systemBarProperty.enableAnimation_, systemBarProperty.settingFlag_);
1567     auto property = GetSessionProperty();
1568     if (property == nullptr) {
1569         TLOGE(WmsLogTag::WMS_DIALOG, "property is null");
1570         return WSError::WS_ERROR_NULLPTR;
1571     }
1572     property->SetSystemBarProperty(type, systemBarProperty);
1573     if (onSystemBarPropertyChange_) {
1574         onSystemBarPropertyChange_(property->GetSystemBarProperty());
1575     }
1576     return WSError::WS_OK;
1577 }
1578 
SetIsStatusBarVisible(bool isVisible)1579 void SceneSession::SetIsStatusBarVisible(bool isVisible)
1580 {
1581     auto task = [weakThis = wptr(this), isVisible] {
1582         sptr<SceneSession> sceneSession = weakThis.promote();
1583         if (sceneSession == nullptr) {
1584             TLOGNE(WmsLogTag::WMS_IMMS, "session is null");
1585             return;
1586         }
1587         sceneSession->SetIsStatusBarVisibleInner(isVisible);
1588     };
1589     PostTask(task, __func__);
1590 }
1591 
SetIsStatusBarVisibleInner(bool isVisible)1592 WSError SceneSession::SetIsStatusBarVisibleInner(bool isVisible)
1593 {
1594     bool isNeedNotify = isStatusBarVisible_ != isVisible;
1595     TLOGI(WmsLogTag::WMS_IMMS, "Window [%{public}d, %{public}s] status bar visible %{public}u, "
1596         "need notify %{public}u", GetPersistentId(), GetWindowName().c_str(), isVisible, isNeedNotify);
1597     isStatusBarVisible_ = isVisible;
1598     if (!isNeedNotify) {
1599         return WSError::WS_OK;
1600     }
1601     if (isLastFrameLayoutFinishedFunc_ == nullptr) {
1602         TLOGE(WmsLogTag::WMS_IMMS, "isLastFrameLayoutFinishedFunc is null, id: %{public}d", GetPersistentId());
1603         return WSError::WS_ERROR_NULLPTR;
1604     }
1605     bool isLayoutFinished = false;
1606     WSError ret = isLastFrameLayoutFinishedFunc_(isLayoutFinished);
1607     if (ret != WSError::WS_OK) {
1608         TLOGE(WmsLogTag::WMS_IMMS, "isLastFrameLayoutFinishedFunc failed: %{public}d", ret);
1609         return ret;
1610     }
1611     if (isLayoutFinished) {
1612         if (specificCallback_ && specificCallback_->onUpdateAvoidAreaByType_) {
1613             specificCallback_->onUpdateAvoidAreaByType_(GetPersistentId(), AvoidAreaType::TYPE_SYSTEM);
1614         }
1615     } else {
1616         dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
1617     }
1618     return WSError::WS_OK;
1619 }
1620 
NotifyPropertyWhenConnect()1621 void SceneSession::NotifyPropertyWhenConnect()
1622 {
1623     WLOGFI("Notify property when connect.");
1624     auto property = GetSessionProperty();
1625     if (property == nullptr) {
1626         WLOGFD("id: %{public}d property is nullptr", persistentId_);
1627         return;
1628     }
1629     NotifySessionFocusableChange(property->GetFocusable());
1630     NotifySessionTouchableChange(property->GetTouchable());
1631     OnShowWhenLocked(GetShowWhenLockedFlagValue());
1632 }
1633 
1634 /** @note @window.hierarchy */
RaiseAppMainWindowToTop()1635 WSError SceneSession::RaiseAppMainWindowToTop()
1636 {
1637     auto task = [weakThis = wptr(this)]() {
1638         auto session = weakThis.promote();
1639         if (!session) {
1640             WLOGFE("session is null");
1641             return WSError::WS_ERROR_DESTROYED_OBJECT;
1642         }
1643         if (session->IsFocusedOnShow()) {
1644             FocusChangeReason reason = FocusChangeReason::MOVE_UP;
1645             session->NotifyRequestFocusStatusNotifyManager(true, true, reason);
1646             session->NotifyClick();
1647         } else {
1648             session->SetFocusedOnShow(true);
1649         }
1650         return WSError::WS_OK;
1651     };
1652     PostTask(task, "RaiseAppMainWindowToTop");
1653     return WSError::WS_OK;
1654 }
1655 
OnNeedAvoid(bool status)1656 WSError SceneSession::OnNeedAvoid(bool status)
1657 {
1658     auto task = [weakThis = wptr(this), status]() {
1659         auto session = weakThis.promote();
1660         if (!session) {
1661             TLOGE(WmsLogTag::WMS_IMMS, "session is null");
1662             return WSError::WS_ERROR_DESTROYED_OBJECT;
1663         }
1664         TLOGI(WmsLogTag::WMS_IMMS, "SceneSession OnNeedAvoid status:%{public}d, id:%{public}d",
1665             static_cast<int32_t>(status), session->GetPersistentId());
1666         if (session->onNeedAvoid_) {
1667             session->onNeedAvoid_(status);
1668         }
1669         return WSError::WS_OK;
1670     };
1671     PostTask(task, "OnNeedAvoid");
1672     return WSError::WS_OK;
1673 }
1674 
OnShowWhenLocked(bool showWhenLocked)1675 WSError SceneSession::OnShowWhenLocked(bool showWhenLocked)
1676 {
1677     WLOGFD("SceneSession ShowWhenLocked status:%{public}d", static_cast<int32_t>(showWhenLocked));
1678     if (onShowWhenLockedFunc_) {
1679         onShowWhenLockedFunc_(showWhenLocked);
1680     }
1681     return WSError::WS_OK;
1682 }
1683 
IsShowWhenLocked() const1684 bool SceneSession::IsShowWhenLocked() const
1685 {
1686     return (GetSessionProperty()->GetWindowFlags() &
1687         static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) || IsTemporarilyShowWhenLocked();
1688 }
1689 
GetShowWhenLockedFlagValue() const1690 bool SceneSession::GetShowWhenLockedFlagValue() const
1691 {
1692     return GetSessionProperty()->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
1693 }
1694 
CalculateAvoidAreaRect(WSRect & rect,WSRect & avoidRect,AvoidArea & avoidArea) const1695 void SceneSession::CalculateAvoidAreaRect(WSRect& rect, WSRect& avoidRect, AvoidArea& avoidArea) const
1696 {
1697     if (SessionHelper::IsEmptyRect(rect) || SessionHelper::IsEmptyRect(avoidRect)) {
1698         return;
1699     }
1700     Rect avoidAreaRect = SessionHelper::TransferToRect(
1701         SessionHelper::GetOverlap(rect, avoidRect, rect.posX_, rect.posY_));
1702     if (WindowHelper::IsEmptyRect(avoidAreaRect)) {
1703         return;
1704     }
1705 
1706     uint32_t avoidAreaCenterX = static_cast<uint32_t>(avoidAreaRect.posX_) + (avoidAreaRect.width_ >> 1);
1707     uint32_t avoidAreaCenterY = static_cast<uint32_t>(avoidAreaRect.posY_) + (avoidAreaRect.height_ >> 1);
1708     float res1 = float(avoidAreaCenterY) - float(rect.height_) / float(rect.width_) *
1709         float(avoidAreaCenterX);
1710     float res2 = float(avoidAreaCenterY) + float(rect.height_) / float(rect.width_) *
1711         float(avoidAreaCenterX) - float(rect.height_);
1712     if (res1 < 0) {
1713         if (res2 < 0) {
1714             avoidArea.topRect_ = avoidAreaRect;
1715         } else {
1716             avoidArea.rightRect_ = avoidAreaRect;
1717         }
1718     } else {
1719         if (res2 < 0) {
1720             avoidArea.leftRect_ = avoidAreaRect;
1721         } else {
1722             avoidArea.bottomRect_ = avoidAreaRect;
1723         }
1724     }
1725 }
1726 
GetSystemAvoidArea(WSRect & rect,AvoidArea & avoidArea)1727 void SceneSession::GetSystemAvoidArea(WSRect& rect, AvoidArea& avoidArea)
1728 {
1729     auto sessionProperty = GetSessionProperty();
1730     if (sessionProperty == nullptr ||
1731         (sessionProperty->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID))) {
1732         return;
1733     }
1734     uint64_t displayId = sessionProperty->GetDisplayId();
1735     auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
1736     if ((Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ||
1737          Session::GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
1738          Session::GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) &&
1739         WindowHelper::IsMainWindow(Session::GetWindowType()) &&
1740         (systemConfig_.uiType_ == UI_TYPE_PHONE ||
1741          (systemConfig_.uiType_ == UI_TYPE_PAD && !IsFreeMultiWindowMode())) &&
1742         (!screenSession || screenSession->GetName() != "HiCar")) {
1743         float miniScale = 0.316f; // Pressed mini floating Scale with 0.001 precision
1744         if (Session::GetFloatingScale() <= miniScale) {
1745             return;
1746         }
1747         float vpr = 3.5f; // 3.5f: default pixel ratio
1748         auto display = DisplayManager::GetInstance().GetDefaultDisplay();
1749         if (display == nullptr) {
1750             WLOGFE("display is null");
1751             return;
1752         }
1753         vpr = display->GetVirtualPixelRatio();
1754         int32_t floatingBarHeight = 32; // 32: floating windowBar Height
1755         avoidArea.topRect_.height_ = vpr * floatingBarHeight;
1756         avoidArea.topRect_.width_ = static_cast<uint32_t>(display->GetWidth());
1757         return;
1758     }
1759     if (!isStatusBarVisible_) {
1760         TLOGI(WmsLogTag::WMS_IMMS, "status bar not visible");
1761         return;
1762     }
1763     std::vector<sptr<SceneSession>> statusBarVector;
1764     if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByType_) {
1765         statusBarVector = specificCallback_->onGetSceneSessionVectorByType_(
1766             WindowType::WINDOW_TYPE_STATUS_BAR, sessionProperty->GetDisplayId());
1767     }
1768     for (auto& statusBar : statusBarVector) {
1769         WSRect statusBarRect = statusBar->GetSessionRect();
1770         TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s status bar %{public}s",
1771               rect.ToString().c_str(), statusBarRect.ToString().c_str());
1772         CalculateAvoidAreaRect(rect, statusBarRect, avoidArea);
1773     }
1774     return;
1775 }
1776 
GetKeyboardAvoidArea(WSRect & rect,AvoidArea & avoidArea)1777 void SceneSession::GetKeyboardAvoidArea(WSRect& rect, AvoidArea& avoidArea)
1778 {
1779     if (Session::CheckEmptyKeyboardAvoidAreaIfNeeded()) {
1780         TLOGI(WmsLogTag::WMS_IMMS, "Keyboard avoid area needs to be empty when in floating mode");
1781         return;
1782     }
1783     auto sessionProperty = GetSessionProperty();
1784     if (!sessionProperty) {
1785         TLOGE(WmsLogTag::WMS_IMMS, "Failed to get session property");
1786         return;
1787     }
1788     std::vector<sptr<SceneSession>> inputMethodVector;
1789     if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByType_) {
1790         inputMethodVector = specificCallback_->onGetSceneSessionVectorByType_(
1791             WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT, sessionProperty->GetDisplayId());
1792     }
1793     for (auto& inputMethod : inputMethodVector) {
1794         if (inputMethod->GetSessionState() != SessionState::STATE_FOREGROUND &&
1795             inputMethod->GetSessionState() != SessionState::STATE_ACTIVE) {
1796             continue;
1797         }
1798         SessionGravity gravity = inputMethod->GetKeyboardGravity();
1799         if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
1800             continue;
1801         }
1802         if (isKeyboardPanelEnabled_) {
1803             WSRect keyboardRect = {0, 0, 0, 0};
1804             if (inputMethod && inputMethod->GetKeyboardPanelSession()) {
1805                 keyboardRect = inputMethod->GetKeyboardPanelSession()->GetSessionRect();
1806             }
1807             TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s keyboard %{public}s",
1808                   rect.ToString().c_str(), keyboardRect.ToString().c_str());
1809             CalculateAvoidAreaRect(rect, keyboardRect, avoidArea);
1810         } else {
1811             WSRect inputMethodRect = inputMethod->GetSessionRect();
1812             TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s input method %{public}s",
1813                   rect.ToString().c_str(), inputMethodRect.ToString().c_str());
1814             CalculateAvoidAreaRect(rect, inputMethodRect, avoidArea);
1815         }
1816     }
1817     return;
1818 }
1819 
GetCutoutAvoidArea(WSRect & rect,AvoidArea & avoidArea)1820 void SceneSession::GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea)
1821 {
1822     auto display = DisplayManager::GetInstance().GetDisplayById(GetSessionProperty()->GetDisplayId());
1823     if (display == nullptr) {
1824         TLOGE(WmsLogTag::WMS_IMMS, "Failed to get display");
1825         return;
1826     }
1827     sptr<CutoutInfo> cutoutInfo = display->GetCutoutInfo();
1828     if (cutoutInfo == nullptr) {
1829         TLOGI(WmsLogTag::WMS_IMMS, "There is no CutoutInfo");
1830         return;
1831     }
1832     std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
1833     if (cutoutAreas.empty()) {
1834         TLOGI(WmsLogTag::WMS_IMMS, "There is no cutoutAreas");
1835         return;
1836     }
1837     for (auto& cutoutArea : cutoutAreas) {
1838         WSRect cutoutAreaRect = {
1839             cutoutArea.posX_,
1840             cutoutArea.posY_,
1841             cutoutArea.width_,
1842             cutoutArea.height_
1843         };
1844         TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s cutout %{public}s",
1845               rect.ToString().c_str(), cutoutAreaRect.ToString().c_str());
1846         CalculateAvoidAreaRect(rect, cutoutAreaRect, avoidArea);
1847     }
1848 
1849     return;
1850 }
1851 
GetAINavigationBarArea(WSRect rect,AvoidArea & avoidArea) const1852 void SceneSession::GetAINavigationBarArea(WSRect rect, AvoidArea& avoidArea) const
1853 {
1854     if (isDisplayStatusBarTemporarily_.load()) {
1855         TLOGI(WmsLogTag::WMS_IMMS, "temporary show navigation bar, no need to avoid");
1856         return;
1857     }
1858     if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
1859         TLOGI(WmsLogTag::WMS_IMMS, "window mode pip return");
1860         return;
1861     }
1862     auto sessionProperty = GetSessionProperty();
1863     if (!sessionProperty) {
1864         TLOGE(WmsLogTag::WMS_IMMS, "Failed to get session property");
1865         return;
1866     }
1867     WSRect barArea;
1868     if (specificCallback_ != nullptr && specificCallback_->onGetAINavigationBarArea_) {
1869         barArea = specificCallback_->onGetAINavigationBarArea_(sessionProperty->GetDisplayId());
1870     }
1871     TLOGI(WmsLogTag::WMS_IMMS, "window %{public}s AI bar %{public}s",
1872           rect.ToString().c_str(), barArea.ToString().c_str());
1873     CalculateAvoidAreaRect(rect, barArea, avoidArea);
1874 }
1875 
CheckGetAvoidAreaAvailable(AvoidAreaType type)1876 bool SceneSession::CheckGetAvoidAreaAvailable(AvoidAreaType type)
1877 {
1878     if (type == AvoidAreaType::TYPE_KEYBOARD) {
1879         return true;
1880     }
1881     WindowMode mode = GetWindowMode();
1882     WindowType winType = GetWindowType();
1883     std::string uiType = systemConfig_.uiType_;
1884     if (WindowHelper::IsMainWindow(winType)) {
1885         if (mode == WindowMode::WINDOW_MODE_FLOATING && type != AvoidAreaType::TYPE_SYSTEM) {
1886             return false;
1887         }
1888 
1889         if (mode != WindowMode::WINDOW_MODE_FLOATING ||
1890             uiType == UI_TYPE_PHONE || uiType == UI_TYPE_PAD) {
1891             return true;
1892         }
1893     }
1894     if (WindowHelper::IsSubWindow(winType)) {
1895         auto parentSession = GetParentSession();
1896         if (parentSession != nullptr && parentSession->GetSessionRect() == GetSessionRect()) {
1897             return parentSession->CheckGetAvoidAreaAvailable(type);
1898         }
1899     }
1900     TLOGI(WmsLogTag::WMS_IMMS, "Window [%{public}u, %{public}s] type %{public}u "
1901         "avoidAreaType %{public}u windowMode %{public}u, return default avoid area.",
1902         GetPersistentId(), GetWindowName().c_str(), static_cast<uint32_t>(winType),
1903         static_cast<uint32_t>(type), static_cast<uint32_t>(mode));
1904     return false;
1905 }
1906 
AddModalUIExtension(const ExtensionWindowEventInfo & extensionInfo)1907 void SceneSession::AddModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)
1908 {
1909     TLOGD(WmsLogTag::WMS_UIEXT, "parentId=%{public}d, persistentId=%{public}d, pid=%{public}d", GetPersistentId(),
1910         extensionInfo.persistentId, extensionInfo.pid);
1911     {
1912         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1913         modalUIExtensionInfoList_.push_back(extensionInfo);
1914     }
1915     NotifySessionInfoChange();
1916 }
1917 
UpdateModalUIExtension(const ExtensionWindowEventInfo & extensionInfo)1918 void SceneSession::UpdateModalUIExtension(const ExtensionWindowEventInfo& extensionInfo)
1919 {
1920     TLOGD(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d,pid=%{public}d,"
1921         "Rect:[%{public}d %{public}d %{public}d %{public}d]",
1922         extensionInfo.persistentId, extensionInfo.pid, extensionInfo.windowRect.posX_,
1923         extensionInfo.windowRect.posY_, extensionInfo.windowRect.width_, extensionInfo.windowRect.height_);
1924     {
1925         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1926         auto iter = std::find_if(modalUIExtensionInfoList_.begin(), modalUIExtensionInfoList_.end(),
1927             [extensionInfo](const ExtensionWindowEventInfo& eventInfo) {
1928             return extensionInfo.persistentId == eventInfo.persistentId && extensionInfo.pid == eventInfo.pid;
1929         });
1930         if (iter == modalUIExtensionInfoList_.end()) {
1931             return;
1932         }
1933         iter->windowRect = extensionInfo.windowRect;
1934         iter->uiExtRect = extensionInfo.uiExtRect;
1935         iter->hasUpdatedRect = extensionInfo.hasUpdatedRect;
1936     }
1937     NotifySessionInfoChange();
1938 }
1939 
RemoveModalUIExtension(int32_t persistentId)1940 void SceneSession::RemoveModalUIExtension(int32_t persistentId)
1941 {
1942     TLOGI(WmsLogTag::WMS_UIEXT, "parentId=%{public}d, persistentId=%{public}d", GetPersistentId(), persistentId);
1943     {
1944         std::unique_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1945         auto iter = std::find_if(modalUIExtensionInfoList_.begin(), modalUIExtensionInfoList_.end(),
1946             [persistentId](const ExtensionWindowEventInfo& extensionInfo) {
1947             return extensionInfo.persistentId == persistentId;
1948         });
1949         if (iter == modalUIExtensionInfoList_.end()) {
1950             return;
1951         }
1952         modalUIExtensionInfoList_.erase(iter);
1953     }
1954     NotifySessionInfoChange();
1955 }
1956 
GetLastModalUIExtensionEventInfo()1957 std::optional<ExtensionWindowEventInfo> SceneSession::GetLastModalUIExtensionEventInfo()
1958 {
1959     std::shared_lock<std::shared_mutex> lock(modalUIExtensionInfoListMutex_);
1960     return modalUIExtensionInfoList_.empty() ? std::nullopt :
1961         std::make_optional<ExtensionWindowEventInfo>(modalUIExtensionInfoList_.back());
1962 }
1963 
GetSessionGlobalPosition(bool useUIExtension)1964 Vector2f SceneSession::GetSessionGlobalPosition(bool useUIExtension)
1965 {
1966     WSRect windowRect = GetSessionGlobalRect();
1967     if (useUIExtension) {
1968         if (auto modalUIExtensionEventInfo = GetLastModalUIExtensionEventInfo()) {
1969             const auto& rect = modalUIExtensionEventInfo.value().windowRect;
1970             windowRect.posX_ = rect.posX_;
1971             windowRect.posY_ = rect.posY_;
1972         }
1973     }
1974     Vector2f position(windowRect.posX_, windowRect.posY_);
1975     return position;
1976 }
1977 
AddUIExtSurfaceNodeId(uint64_t surfaceNodeId,int32_t persistentId)1978 void SceneSession::AddUIExtSurfaceNodeId(uint64_t surfaceNodeId, int32_t persistentId)
1979 {
1980     std::unique_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
1981     TLOGI(WmsLogTag::WMS_UIEXT, "Add uiExtension pair surfaceNodeId=%{public}" PRIu64 ", persistentId=%{public}d",
1982         surfaceNodeId, persistentId);
1983     uiExtNodeIdToPersistentIdMap_.insert(std::make_pair(surfaceNodeId, persistentId));
1984 }
1985 
RemoveUIExtSurfaceNodeId(int32_t persistentId)1986 void SceneSession::RemoveUIExtSurfaceNodeId(int32_t persistentId)
1987 {
1988     std::unique_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
1989     TLOGI(WmsLogTag::WMS_UIEXT, "Remove uiExtension by persistentId=%{public}d", persistentId);
1990     auto pairIter = std::find_if(uiExtNodeIdToPersistentIdMap_.begin(), uiExtNodeIdToPersistentIdMap_.end(),
1991         [persistentId](const auto& entry) { return entry.second == persistentId; });
1992     if (pairIter != uiExtNodeIdToPersistentIdMap_.end()) {
1993         TLOGI(WmsLogTag::WMS_UIEXT,
1994             "Successfully removed uiExtension pair surfaceNodeId=%{public}" PRIu64 ", persistentId=%{public}d",
1995             pairIter->first, persistentId);
1996         uiExtNodeIdToPersistentIdMap_.erase(pairIter);
1997         return;
1998     }
1999     TLOGE(WmsLogTag::WMS_UIEXT, "Failed to remove uiExtension by persistentId=%{public}d", persistentId);
2000 }
2001 
GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const2002 int32_t SceneSession::GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const
2003 {
2004     std::shared_lock<std::shared_mutex> lock(uiExtNodeIdToPersistentIdMapMutex_);
2005     auto ret = uiExtNodeIdToPersistentIdMap_.find(surfaceNodeId);
2006     if (ret == uiExtNodeIdToPersistentIdMap_.end()) {
2007         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to find uiExtension by surfaceNodeId=%{public}" PRIu64 "", surfaceNodeId);
2008         return 0;
2009     }
2010     return ret->second;
2011 }
2012 
GetAvoidAreaByTypeInner(AvoidAreaType type)2013 AvoidArea SceneSession::GetAvoidAreaByTypeInner(AvoidAreaType type)
2014 {
2015     if (!CheckGetAvoidAreaAvailable(type)) {
2016         return {};
2017     }
2018 
2019     AvoidArea avoidArea;
2020     WSRect rect = GetSessionRect();
2021     switch (type) {
2022         case AvoidAreaType::TYPE_SYSTEM: {
2023             GetSystemAvoidArea(rect, avoidArea);
2024             return avoidArea;
2025         }
2026         case AvoidAreaType::TYPE_CUTOUT: {
2027             GetCutoutAvoidArea(rect, avoidArea);
2028             return avoidArea;
2029         }
2030         case AvoidAreaType::TYPE_SYSTEM_GESTURE: {
2031             return avoidArea;
2032         }
2033         case AvoidAreaType::TYPE_KEYBOARD: {
2034             GetKeyboardAvoidArea(rect, avoidArea);
2035             return avoidArea;
2036         }
2037         case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
2038             GetAINavigationBarArea(rect, avoidArea);
2039             return avoidArea;
2040         }
2041         default: {
2042             TLOGE(WmsLogTag::WMS_IMMS, "cannot find type %{public}u, id %{public}d",
2043                 type, GetPersistentId());
2044             return avoidArea;
2045         }
2046     }
2047 }
2048 
GetAvoidAreaByType(AvoidAreaType type)2049 AvoidArea SceneSession::GetAvoidAreaByType(AvoidAreaType type)
2050 {
2051     auto task = [weakThis = wptr(this), type]() -> AvoidArea {
2052         auto session = weakThis.promote();
2053         if (!session) {
2054             TLOGE(WmsLogTag::WMS_IMMS, "session is null");
2055             return {};
2056         }
2057         return session->GetAvoidAreaByTypeInner(type);
2058     };
2059     return PostSyncTask(task, "GetAvoidAreaByType");
2060 }
2061 
GetAllAvoidAreas(std::map<AvoidAreaType,AvoidArea> & avoidAreas)2062 WSError SceneSession::GetAllAvoidAreas(std::map<AvoidAreaType, AvoidArea>& avoidAreas)
2063 {
2064     auto task = [weakThis = wptr(this), &avoidAreas] {
2065         auto session = weakThis.promote();
2066         if (!session) {
2067             TLOGE(WmsLogTag::WMS_IMMS, "session is null");
2068             return WSError::WS_ERROR_NULLPTR;
2069         }
2070 
2071         using T = std::underlying_type_t<AvoidAreaType>;
2072         for (T avoidType = static_cast<T>(AvoidAreaType::TYPE_SYSTEM);
2073             avoidType <= static_cast<T>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR); avoidType++) {
2074             auto type = static_cast<AvoidAreaType>(avoidType);
2075             avoidAreas[type] = session->GetAvoidAreaByTypeInner(type);
2076         }
2077         return WSError::WS_OK;
2078     };
2079     return PostSyncTask(task, "GetAllAvoidAreas");
2080 }
2081 
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)2082 WSError SceneSession::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
2083 {
2084     if (!sessionStage_) {
2085         return WSError::WS_ERROR_NULLPTR;
2086     }
2087     return sessionStage_->UpdateAvoidArea(avoidArea, type);
2088 }
2089 
SetPipActionEvent(const std::string & action,int32_t status)2090 WSError SceneSession::SetPipActionEvent(const std::string& action, int32_t status)
2091 {
2092     TLOGI(WmsLogTag::WMS_PIP, "action: %{public}s, status: %{public}d", action.c_str(), status);
2093     if (!sessionStage_) {
2094         return WSError::WS_ERROR_NULLPTR;
2095     }
2096     return sessionStage_->SetPipActionEvent(action, status);
2097 }
2098 
SetPiPControlEvent(WsPiPControlType controlType,WsPiPControlStatus status)2099 WSError SceneSession::SetPiPControlEvent(WsPiPControlType controlType, WsPiPControlStatus status)
2100 {
2101     TLOGI(WmsLogTag::WMS_PIP, "controlType: %{public}u, status: %{public}u", controlType, status);
2102     if (GetWindowType() != WindowType::WINDOW_TYPE_PIP || GetWindowMode() != WindowMode::WINDOW_MODE_PIP) {
2103         return WSError::WS_ERROR_INVALID_TYPE;
2104     }
2105     if (!sessionStage_) {
2106         return WSError::WS_ERROR_NULLPTR;
2107     }
2108     return sessionStage_->SetPiPControlEvent(controlType, status);
2109 }
2110 
RegisterProcessPrepareClosePiPCallback(NotifyPrepareClosePiPSessionFunc && callback)2111 void SceneSession::RegisterProcessPrepareClosePiPCallback(NotifyPrepareClosePiPSessionFunc&& callback)
2112 {
2113     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
2114         auto session = weakThis.promote();
2115         if (!session) {
2116             TLOGNE(WmsLogTag::WMS_PIP, "session is null");
2117             return;
2118         }
2119         session->onPrepareClosePiPSession_ = std::move(callback);
2120     };
2121     PostTask(task, __func__);
2122 }
2123 
HandleStyleEvent(MMI::WindowArea area)2124 void SceneSession::HandleStyleEvent(MMI::WindowArea area)
2125 {
2126     static std::pair<int32_t, MMI::WindowArea> preWindowArea =
2127         std::make_pair(INVALID_WINDOW_ID, MMI::WindowArea::EXIT);
2128     if (preWindowArea.first == Session::GetWindowId() && preWindowArea.second == area) {
2129         return;
2130     }
2131     if (area != MMI::WindowArea::EXIT) {
2132         if (Session::SetPointerStyle(area) != WSError::WS_OK) {
2133             WLOGFE("Failed to set the cursor style");
2134         }
2135     }
2136     preWindowArea = { Session::GetWindowId(), area };
2137 }
2138 
HandleEnterWinwdowArea(int32_t displayX,int32_t displayY)2139 WSError SceneSession::HandleEnterWinwdowArea(int32_t displayX, int32_t displayY)
2140 {
2141     if (displayX < 0 || displayY < 0) {
2142         TLOGE(WmsLogTag::WMS_EVENT, "Illegal parameter, displayX:%{private}d, displayY:%{private}d",
2143             displayX, displayY);
2144         return WSError::WS_ERROR_INVALID_PARAM;
2145     }
2146 
2147     auto windowType = Session::GetWindowType();
2148     auto iter = Session::windowAreas_.cend();
2149     if (!IsSystemSession() &&
2150         Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
2151         (windowType == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || WindowHelper::IsSubWindow(windowType))) {
2152         iter = Session::windowAreas_.cbegin();
2153         for (;iter != Session::windowAreas_.cend(); ++iter) {
2154             WSRectF rect = iter->second;
2155             if (rect.IsInRegion(displayX, displayY)) {
2156                 break;
2157             }
2158         }
2159     }
2160 
2161     MMI::WindowArea area = MMI::WindowArea::EXIT;
2162     if (iter == Session::windowAreas_.cend()) {
2163         bool isInRegion = false;
2164         WSRect rect = Session::winRect_;
2165         if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
2166             (windowType == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || WindowHelper::IsSubWindow(windowType))) {
2167             WSRectF rectF = Session::UpdateHotRect(rect);
2168             isInRegion = rectF.IsInRegion(displayX, displayY);
2169         } else {
2170             isInRegion = rect.IsInRegion(displayX, displayY);
2171         }
2172         if (!isInRegion) {
2173             WLOGFE("The wrong event(%{public}d, %{public}d) could not be matched to the region:"
2174                 "[%{public}d, %{public}d, %{public}d, %{public}d]",
2175                 displayX, displayY, rect.posX_, rect.posY_, rect.width_, rect.height_);
2176             return WSError::WS_ERROR_INVALID_TYPE;
2177         }
2178         area = MMI::WindowArea::FOCUS_ON_INNER;
2179     } else {
2180         area = iter->first;
2181     }
2182     HandleStyleEvent(area);
2183     return WSError::WS_OK;
2184 }
2185 
ProcessPointDownSession(int32_t posX,int32_t posY)2186 WSError SceneSession::ProcessPointDownSession(int32_t posX, int32_t posY)
2187 {
2188     const auto& id = GetPersistentId();
2189     WLOGFI("id: %{public}d, type: %{public}d", id, GetWindowType());
2190 
2191     // notify touch outside
2192     if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ &&
2193         sessionInfo_.bundleName_.find("SCBGestureBack") == std::string::npos) {
2194         specificCallback_->onSessionTouchOutside_(id);
2195     }
2196 
2197     // notify outside down event
2198     if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
2199         specificCallback_->onOutsideDownEvent_(posX, posY);
2200     }
2201     return WSError::WS_OK;
2202 }
2203 
SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)2204 WSError SceneSession::SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
2205 {
2206     NotifyOutsideDownEvent(pointerEvent);
2207     TransferPointerEvent(pointerEvent, false);
2208     return WSError::WS_OK;
2209 }
2210 
NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)2211 void SceneSession::NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
2212 {
2213     // notify touchOutside and touchDown event
2214     int32_t action = pointerEvent->GetPointerAction();
2215     if (action != MMI::PointerEvent::POINTER_ACTION_DOWN &&
2216         action != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
2217         return;
2218     }
2219 
2220     MMI::PointerEvent::PointerItem pointerItem;
2221     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
2222         return;
2223     }
2224 
2225     // notify touch outside
2226     if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ &&
2227         sessionInfo_.bundleName_.find("SCBGestureBack") == std::string::npos) {
2228         specificCallback_->onSessionTouchOutside_(GetPersistentId());
2229     }
2230 
2231     // notify outside down event
2232     if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
2233         specificCallback_->onOutsideDownEvent_(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
2234     }
2235 }
2236 
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool needNotifyClient)2237 WSError SceneSession::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2238     bool needNotifyClient)
2239 {
2240     WLOGFD("[WMSCom] TransferPointEvent, id: %{public}d, type: %{public}d, needNotifyClient: %{public}d",
2241         GetPersistentId(), GetWindowType(), needNotifyClient);
2242     if (pointerEvent == nullptr) {
2243         WLOGFE("pointerEvent is null");
2244         return WSError::WS_ERROR_NULLPTR;
2245     }
2246 
2247     int32_t action = pointerEvent->GetPointerAction();
2248     {
2249         bool isSystemWindow = GetSessionInfo().isSystem_;
2250         std::lock_guard<std::mutex> guard(enterSessionMutex_);
2251         if (action == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
2252             WLOGFD("Set enter session, persistentId:%{public}d", GetPersistentId());
2253             enterSession_ = wptr<SceneSession>(this);
2254         }
2255         if ((enterSession_ != nullptr) &&
2256             (isSystemWindow && (action != MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW))) {
2257             WLOGFD("Remove enter session, persistentId:%{public}d", GetPersistentId());
2258             enterSession_ = nullptr;
2259         }
2260     }
2261 
2262     if (!CheckPointerEventDispatch(pointerEvent)) {
2263         WLOGFI("Do not dispatch this pointer event");
2264         return WSError::WS_DO_NOTHING;
2265     }
2266 
2267     bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
2268         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
2269 
2270     auto property = GetSessionProperty();
2271     if (property == nullptr) {
2272         return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
2273     }
2274     auto windowType = property->GetWindowType();
2275     bool isMovableWindowType = IsMovableWindowType();
2276     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
2277     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
2278     bool isDialog = WindowHelper::IsDialogWindow(windowType);
2279     bool isMaxModeAvoidSysBar = property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR;
2280     bool isDragEnabledSystemWindow = WindowHelper::IsSystemWindow(windowType) && property->GetDragEnabled() &&
2281         !isDialog;
2282     bool isMovableSystemWindow = WindowHelper::IsSystemWindow(windowType) && !isDialog;
2283     TLOGD(WmsLogTag::WMS_EVENT, "%{public}s: %{public}d && %{public}d", property->GetWindowName().c_str(),
2284         WindowHelper::IsSystemWindow(windowType), property->GetDragEnabled());
2285     if (isMovableWindowType && !isMaxModeAvoidSysBar &&
2286         (isMainWindow || isSubWindow || isDialog || isDragEnabledSystemWindow || isMovableSystemWindow)) {
2287         if (CheckDialogOnForeground() && isPointDown) {
2288             HandlePointDownDialog();
2289             pointerEvent->MarkProcessed();
2290             TLOGI(WmsLogTag::WMS_DIALOG, "There is dialog window foreground");
2291             return WSError::WS_OK;
2292         }
2293         if (!moveDragController_) {
2294             WLOGE("moveDragController_ is null");
2295             return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
2296         }
2297         if ((property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && property->GetDragEnabled()) ||
2298             isDragEnabledSystemWindow) {
2299             auto isPC = systemConfig_.uiType_ == UI_TYPE_PC;
2300             if ((isPC || IsFreeMultiWindowMode() || (property->GetIsPcAppInPad() && !isMainWindow)) &&
2301                 moveDragController_->ConsumeDragEvent(pointerEvent, winRect_, property, systemConfig_)) {
2302                 moveDragController_->UpdateGravityWhenDrag(pointerEvent, surfaceNode_);
2303                 PresentFoucusIfNeed(pointerEvent->GetPointerAction());
2304                 pointerEvent->MarkProcessed();
2305                 return WSError::WS_OK;
2306             }
2307         }
2308         if ((WindowHelper::IsMainWindow(windowType) ||
2309              WindowHelper::IsSubWindow(windowType) ||
2310              WindowHelper::IsSystemWindow(windowType)) &&
2311             moveDragController_->ConsumeMoveEvent(pointerEvent, winRect_)) {
2312             PresentFoucusIfNeed(pointerEvent->GetPointerAction());
2313             pointerEvent->MarkProcessed();
2314             return WSError::WS_OK;
2315         }
2316     }
2317 
2318     bool raiseEnabled = property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && property->GetRaiseEnabled() &&
2319         (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
2320     if (raiseEnabled) {
2321         RaiseToAppTopForPointDown();
2322     }
2323     // modify the window coordinates when move end
2324     MMI::PointerEvent::PointerItem pointerItem;
2325     if ((action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP || action == MMI::PointerEvent::POINTER_ACTION_MOVE) &&
2326         needNotifyClient && pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
2327         int32_t windowX = pointerItem.GetDisplayX() - winRect_.posX_;
2328         int32_t windowY = pointerItem.GetDisplayY() - winRect_.posY_;
2329         TLOGD(WmsLogTag::WMS_EVENT, "move end position: windowX:%{private}d windowY:%{private}d action:%{public}d",
2330             windowX, windowY, action);
2331         pointerItem.SetWindowX(windowX);
2332         pointerItem.SetWindowY(windowY);
2333         pointerEvent->AddPointerItem(pointerItem);
2334     }
2335     return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
2336 }
2337 
IsMovableWindowType()2338 bool SceneSession::IsMovableWindowType()
2339 {
2340     auto property = GetSessionProperty();
2341     if (property == nullptr) {
2342         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
2343         return false;
2344     }
2345 
2346     return property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ||
2347         property->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
2348         property->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
2349         IsFullScreenMovable();
2350 }
2351 
IsFullScreenMovable()2352 bool SceneSession::IsFullScreenMovable()
2353 {
2354     auto property = GetSessionProperty();
2355     if (property == nullptr) {
2356         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
2357         return false;
2358     }
2359     return property->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2360         WindowHelper::IsWindowModeSupported(property->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING);
2361 }
2362 
RequestSessionBack(bool needMoveToBackground)2363 WSError SceneSession::RequestSessionBack(bool needMoveToBackground)
2364 {
2365     auto task = [weakThis = wptr(this), needMoveToBackground]() {
2366         auto session = weakThis.promote();
2367         if (!session) {
2368             WLOGFE("session is null");
2369             return WSError::WS_ERROR_DESTROYED_OBJECT;
2370         }
2371         if (!session->backPressedFunc_) {
2372             WLOGFW("Session didn't register back event consumer!");
2373             return WSError::WS_DO_NOTHING;
2374         }
2375         if (g_enableForceUIFirst) {
2376             auto rsTransaction = RSTransactionProxy::GetInstance();
2377             if (rsTransaction) {
2378                 rsTransaction->Begin();
2379             }
2380             auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
2381             if (leashWinSurfaceNode) {
2382                 leashWinSurfaceNode->SetForceUIFirst(true);
2383                 WLOGFI("leashWinSurfaceNode_ SetForceUIFirst id:%{public}u!", session->GetPersistentId());
2384             } else {
2385                 WLOGFI("failed, leashWinSurfaceNode_ null id:%{public}u", session->GetPersistentId());
2386             }
2387             if (rsTransaction) {
2388                 rsTransaction->Commit();
2389             }
2390         }
2391         session->backPressedFunc_(needMoveToBackground);
2392         return WSError::WS_OK;
2393     };
2394     PostTask(task, "RequestSessionBack:" + std::to_string(needMoveToBackground));
2395     return WSError::WS_OK;
2396 }
2397 
GetEnterWindow()2398 const wptr<SceneSession> SceneSession::GetEnterWindow()
2399 {
2400     std::lock_guard<std::mutex> guard(enterSessionMutex_);
2401     return enterSession_;
2402 }
2403 
ClearEnterWindow()2404 void SceneSession::ClearEnterWindow()
2405 {
2406     std::lock_guard<std::mutex> guard(enterSessionMutex_);
2407     enterSession_ = nullptr;
2408 }
2409 
2410 #ifdef DEVICE_STATUS_ENABLE
RotateDragWindow(std::shared_ptr<RSTransaction> rsTransaction)2411 void SceneSession::RotateDragWindow(std::shared_ptr<RSTransaction> rsTransaction)
2412 {
2413     Msdp::DeviceStatus::DragState state = Msdp::DeviceStatus::DragState::STOP;
2414     Msdp::DeviceStatus::InteractionManager::GetInstance()->GetDragState(state);
2415     if (state == Msdp::DeviceStatus::DragState::START) {
2416         Msdp::DeviceStatus::InteractionManager::GetInstance()->RotateDragWindowSync(rsTransaction);
2417     }
2418 }
2419 #endif // DEVICE_STATUS_ENABLE
2420 
NotifySessionRectChange(const WSRect & rect,const SizeChangeReason & reason)2421 void SceneSession::NotifySessionRectChange(const WSRect& rect, const SizeChangeReason& reason)
2422 {
2423     auto task = [weakThis = wptr(this), rect, reason]() {
2424         auto session = weakThis.promote();
2425         if (!session) {
2426             WLOGFE("session is null");
2427             return;
2428         }
2429         if (session->sessionRectChangeFunc_) {
2430             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::NotifySessionRectChange");
2431             session->sessionRectChangeFunc_(rect, reason);
2432         }
2433     };
2434     PostTask(task, "NotifySessionRectChange" + GetRectInfo(rect));
2435 }
2436 
IsDecorEnable() const2437 bool SceneSession::IsDecorEnable() const
2438 {
2439     auto property = GetSessionProperty();
2440     if (property == nullptr) {
2441         WLOGE("property is nullptr");
2442         return false;
2443     }
2444     auto windowType = property->GetWindowType();
2445     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
2446     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
2447     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
2448     bool isValidWindow = isMainWindow ||
2449         ((isSubWindow || isDialogWindow) && property->IsDecorEnable());
2450     bool isWindowModeSupported = WindowHelper::IsWindowModeSupported(
2451         systemConfig_.decorWindowModeSupportType_, property->GetWindowMode());
2452     bool enable = isValidWindow && systemConfig_.isSystemDecorEnable_ && isWindowModeSupported;
2453     return enable;
2454 }
2455 
GetRatioPreferenceKey()2456 std::string SceneSession::GetRatioPreferenceKey()
2457 {
2458     std::string key = sessionInfo_.bundleName_ + sessionInfo_.moduleName_ + sessionInfo_.abilityName_;
2459     if (key.length() > ScenePersistentStorage::MAX_KEY_LEN) {
2460         return key.substr(key.length() - ScenePersistentStorage::MAX_KEY_LEN);
2461     }
2462     return key;
2463 }
2464 
SaveAspectRatio(float ratio)2465 bool SceneSession::SaveAspectRatio(float ratio)
2466 {
2467     std::string key = GetRatioPreferenceKey();
2468     if (!key.empty()) {
2469         ScenePersistentStorage::Insert(key, ratio, ScenePersistentStorageType::ASPECT_RATIO);
2470         WLOGD("SceneSession save aspectRatio , key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
2471         return true;
2472     }
2473     return false;
2474 }
2475 
FixRectByLimits(WindowLimits limits,WSRect & rect,float ratio,bool isDecor,float vpr)2476 void SceneSession::FixRectByLimits(WindowLimits limits, WSRect& rect, float ratio, bool isDecor, float vpr)
2477 {
2478     if (isDecor) {
2479         rect.width_ = SessionUtils::ToLayoutWidth(rect.width_, vpr);
2480         rect.height_ = SessionUtils::ToLayoutHeight(rect.height_, vpr);
2481         limits.minWidth_ = SessionUtils::ToLayoutWidth(limits.minWidth_, vpr);
2482         limits.maxWidth_ = SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr);
2483         limits.minHeight_ = SessionUtils::ToLayoutHeight(limits.minHeight_, vpr);
2484         limits.maxHeight_ = SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr);
2485     }
2486     if (static_cast<uint32_t>(rect.height_) > limits.maxHeight_) {
2487         rect.height_ = static_cast<int32_t>(limits.maxHeight_);
2488         rect.width_ = floor(rect.height_ * ratio);
2489     } else if (static_cast<uint32_t>(rect.width_) > limits.maxWidth_) {
2490         rect.width_ = static_cast<int32_t>(limits.maxWidth_);
2491         rect.height_ = floor(rect.width_ / ratio);
2492     } else if (static_cast<uint32_t>(rect.width_) < limits.minWidth_) {
2493         rect.width_ = static_cast<int32_t>(limits.minWidth_);
2494         rect.height_ = ceil(rect.width_ / ratio);
2495     } else if (static_cast<uint32_t>(rect.height_) < limits.minHeight_) {
2496         rect.height_ = static_cast<int32_t>(limits.minHeight_);
2497         rect.width_ = ceil(rect.height_ * ratio);
2498     }
2499     if (isDecor) {
2500         rect.height_ = SessionUtils::ToWinHeight(rect.height_, vpr) ;
2501         rect.width_ = SessionUtils::ToWinWidth(rect.width_, vpr);
2502     }
2503 }
FixRectByAspectRatio(WSRect & rect)2504 bool SceneSession::FixRectByAspectRatio(WSRect& rect)
2505 {
2506     const int tolerancePx = 2; // 2: tolerance delta pixel value, unit: px
2507     WSRect originalRect = rect;
2508     auto property = GetSessionProperty();
2509     if (!property || property->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING ||
2510         !WindowHelper::IsMainWindow(GetWindowType())) {
2511         return false;
2512     }
2513 
2514     if (MathHelper::NearZero(aspectRatio_)) {
2515         return false;
2516     }
2517     float vpr = 1.5f; // 1.5f: default virtual pixel ratio
2518     auto display = DisplayManager::GetInstance().GetDefaultDisplay();
2519     if (display) {
2520         vpr = display->GetVirtualPixelRatio();
2521     }
2522     int32_t minW;
2523     int32_t maxW;
2524     int32_t minH;
2525     int32_t maxH;
2526     SessionUtils::CalcFloatWindowRectLimits(property->GetWindowLimits(), systemConfig_.maxFloatingWindowSize_, vpr,
2527         minW, maxW, minH, maxH);
2528     rect.width_ = std::max(minW, static_cast<int32_t>(rect.width_));
2529     rect.width_ = std::min(maxW, static_cast<int32_t>(rect.width_));
2530     rect.height_ = std::max(minH, static_cast<int32_t>(rect.height_));
2531     rect.height_ = std::min(maxH, static_cast<int32_t>(rect.height_));
2532     if (IsDecorEnable()) {
2533         if (SessionUtils::ToLayoutWidth(rect.width_, vpr) >
2534                 SessionUtils::ToLayoutHeight(rect.height_, vpr) * aspectRatio_) {
2535             rect.width_ = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(rect.height_, vpr)* aspectRatio_, vpr);
2536         } else {
2537             rect.height_ = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(rect.width_, vpr) / aspectRatio_, vpr);
2538         }
2539     } else {
2540         if (rect.width_ > rect.height_ * aspectRatio_) {
2541             rect.width_ = rect.height_ * aspectRatio_;
2542         } else {
2543             rect.height_ = rect.width_ / aspectRatio_;
2544         }
2545     }
2546     FixRectByLimits(property->GetWindowLimits(), rect, aspectRatio_, IsDecorEnable(), vpr);
2547     if (std::abs(static_cast<int32_t>(originalRect.width_) - static_cast<int32_t>(rect.width_)) <= tolerancePx &&
2548         std::abs(static_cast<int32_t>(originalRect.height_) - static_cast<int32_t>(rect.height_)) <= tolerancePx) {
2549         rect = originalRect;
2550         return false;
2551     }
2552     return true;
2553 }
2554 
HandleCompatibleModeMoveDrag(WSRect & rect,const SizeChangeReason & reason,bool isSupportDragInPcCompatibleMode)2555 void SceneSession::HandleCompatibleModeMoveDrag(WSRect& rect, const SizeChangeReason& reason,
2556     bool isSupportDragInPcCompatibleMode)
2557 {
2558     auto sessionProperty = GetSessionProperty();
2559     if (!sessionProperty) {
2560         TLOGE(WmsLogTag::WMS_SCB, "sessionProperty is null");
2561         return;
2562     }
2563     WindowLimits windowLimits = sessionProperty->GetWindowLimits();
2564     const int32_t compatibleInPcPortraitWidth = sessionProperty->GetCompatibleInPcPortraitWidth();
2565     const int32_t compatibleInPcPortraitHeight = sessionProperty->GetCompatibleInPcPortraitHeight();
2566     const int32_t compatibleInPcLandscapeWidth = sessionProperty->GetCompatibleInPcLandscapeWidth();
2567     const int32_t compatibleInPcLandscapeHeight = sessionProperty->GetCompatibleInPcLandscapeHeight();
2568     const int32_t compatibleInPcDragLimit = compatibleInPcLandscapeWidth - compatibleInPcPortraitWidth;
2569     WSRect windowRect = GetSessionRect();
2570     auto windowWidth = windowRect.width_;
2571     auto windowHeight = windowRect.height_;
2572 
2573     if (reason != SizeChangeReason::DRAG_MOVE) {
2574         if (isSupportDragInPcCompatibleMode && windowWidth > windowHeight &&
2575             (rect.width_ < compatibleInPcLandscapeWidth - compatibleInPcDragLimit ||
2576              rect.width_ == static_cast<int32_t>(windowLimits.minWidth_))) {
2577             rect.width_ = compatibleInPcPortraitWidth;
2578             rect.height_ = compatibleInPcPortraitHeight;
2579             SetSurfaceBounds(rect);
2580             UpdateSizeChangeReason(reason);
2581             UpdateRect(rect, reason, "compatibleInPcPortrait");
2582         } else if (isSupportDragInPcCompatibleMode && windowWidth < windowHeight &&
2583             rect.width_ > compatibleInPcPortraitWidth + compatibleInPcDragLimit) {
2584             rect.width_ = compatibleInPcLandscapeWidth;
2585             rect.height_ = compatibleInPcLandscapeHeight;
2586             SetSurfaceBounds(rect);
2587             UpdateSizeChangeReason(reason);
2588             UpdateRect(rect, reason, "compatibleInPcLandscape");
2589         } else {
2590             if (windowWidth < windowHeight) {
2591                 rect.width_ = compatibleInPcPortraitWidth;
2592                 rect.height_ = compatibleInPcPortraitHeight;
2593             } else {
2594                 rect.width_ = compatibleInPcLandscapeWidth;
2595                 rect.height_ = compatibleInPcLandscapeHeight;
2596             }
2597             rect.posX_ = windowRect.posX_;
2598             rect.posY_ = windowRect.posY_;
2599             SetSurfaceBounds(rect);
2600             UpdateSizeChangeReason(reason);
2601         }
2602     } else {
2603         SetSurfaceBounds(rect);
2604         UpdateSizeChangeReason(reason);
2605     }
2606 }
2607 
SetMoveDragCallback()2608 void SceneSession::SetMoveDragCallback()
2609 {
2610     if (moveDragController_) {
2611         MoveDragCallback callBack = [this](const SizeChangeReason& reason) {
2612             this->OnMoveDragCallback(reason);
2613         };
2614         moveDragController_->RegisterMoveDragCallback(callBack);
2615     }
2616 }
2617 
OnMoveDragCallback(const SizeChangeReason & reason)2618 void SceneSession::OnMoveDragCallback(const SizeChangeReason& reason)
2619 {
2620     if (!moveDragController_) {
2621         WLOGE("moveDragController_ is null");
2622         return;
2623     }
2624 
2625     auto property = GetSessionProperty();
2626     if (property == nullptr) {
2627         TLOGE(WmsLogTag::WMS_SCB, "property is null");
2628         return;
2629     }
2630     bool isCompatibleModeInPc = property->GetCompatibleModeInPc();
2631     bool isSupportDragInPcCompatibleMode = property->GetIsSupportDragInPcCompatibleMode();
2632     bool isMainWindow = WindowHelper::IsMainWindow(property->GetWindowType());
2633     WSRect rect = moveDragController_->GetTargetRect();
2634     WLOGFD("OnMoveDragCallback rect: [%{public}d, %{public}d, %{public}u, %{public}u], reason : %{public}d "
2635         "isCompatibleMode: %{public}d, isSupportDragInPcCompatibleMode: %{public}d",
2636         rect.posX_, rect.posY_, rect.width_, rect.height_, reason, isCompatibleModeInPc,
2637         isSupportDragInPcCompatibleMode);
2638     if (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_END) {
2639         UpdateWinRectForSystemBar(rect);
2640     }
2641     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
2642         "SceneSession::OnMoveDragCallback [%d, %d, %u, %u]", rect.posX_, rect.posY_, rect.width_, rect.height_);
2643     if (isCompatibleModeInPc && !IsFreeMultiWindowMode()) {
2644         HandleCompatibleModeMoveDrag(rect, reason, isSupportDragInPcCompatibleMode);
2645     } else {
2646         if (IsDragResizeWhenEnd(reason)) {
2647             OnSessionEvent(SessionEvent::EVENT_DRAG);
2648             return;
2649         }
2650         SetSurfaceBounds(rect);
2651         UpdateSizeChangeReason(reason);
2652         if (reason != SizeChangeReason::MOVE) {
2653             UpdateRect(rect, reason, "OnMoveDragCallback");
2654         }
2655     }
2656 
2657     if (reason == SizeChangeReason::DRAG_END) {
2658         if (GetOriPosYBeforeRaisedByKeyboard() != 0) {
2659             TLOGI(WmsLogTag::WMS_KEYBOARD, "Calling session is moved and reset oriPosYBeforeRaisedByKeyboard");
2660             SetOriPosYBeforeRaisedByKeyboard(0);
2661         }
2662         NotifySessionRectChange(rect, reason);
2663         OnSessionEvent(SessionEvent::EVENT_END_MOVE);
2664     }
2665     if (reason == SizeChangeReason::DRAG_START) {
2666         OnSessionEvent(SessionEvent::EVENT_DRAG_START);
2667     }
2668 }
2669 
IsDragResizeWhenEnd(SizeChangeReason reason)2670 bool SceneSession::IsDragResizeWhenEnd(SizeChangeReason reason)
2671 {
2672     auto property = GetSessionProperty();
2673     if (property == nullptr) {
2674         TLOGE(WmsLogTag::WMS_LAYOUT, "property is null");
2675         return true;
2676     }
2677     bool isPcOrPcModeMainWindow = (systemConfig_.uiType_ == UI_TYPE_PC || IsFreeMultiWindowMode()) &&
2678         WindowHelper::IsMainWindow(property->GetWindowType());
2679     return reason == SizeChangeReason::DRAG && isPcOrPcModeMainWindow &&
2680         GetDragResizeTypeDuringDrag() == DragResizeType::RESIZE_WHEN_DRAG_END;
2681 }
2682 
UpdateWinRectForSystemBar(WSRect & rect)2683 void SceneSession::UpdateWinRectForSystemBar(WSRect& rect)
2684 {
2685     if (!specificCallback_) {
2686         WLOGFE("specificCallback_ is null!");
2687         return;
2688     }
2689     auto sessionProperty = GetSessionProperty();
2690     if (!sessionProperty) {
2691         WLOGFE("get session property is null!");
2692         return;
2693     }
2694     float tmpPosY = 0.0;
2695     std::vector<sptr<SceneSession>> statusBarVector;
2696     if (specificCallback_->onGetSceneSessionVectorByType_) {
2697         statusBarVector = specificCallback_->onGetSceneSessionVectorByType_(
2698             WindowType::WINDOW_TYPE_STATUS_BAR, sessionProperty->GetDisplayId());
2699     }
2700     for (auto& statusBar : statusBarVector) {
2701         if (!(statusBar->isVisible_)) {
2702             continue;
2703         }
2704         WSRect statusBarRect = statusBar->GetSessionRect();
2705         if ((rect.posY_ < statusBarRect.posY_ + static_cast<int32_t>(statusBarRect.height_)) &&
2706             (rect.height_ != winRect_.height_ || rect.width_ != winRect_.width_)) {
2707             tmpPosY = rect.posY_ + rect.height_;
2708             rect.posY_ = statusBarRect.posY_ + statusBarRect.height_;
2709             rect.height_ = tmpPosY - rect.posY_;
2710         }
2711     }
2712     WLOGFD("after UpdateWinRectForSystemBar rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
2713         rect.posX_, rect.posY_, rect.width_, rect.height_);
2714 }
2715 
SetSurfaceBounds(const WSRect & rect)2716 void SceneSession::SetSurfaceBounds(const WSRect& rect)
2717 {
2718     auto rsTransaction = RSTransactionProxy::GetInstance();
2719     if (rsTransaction != nullptr) {
2720         rsTransaction->Begin();
2721     }
2722     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
2723     if (surfaceNode_ && leashWinSurfaceNode) {
2724         leashWinSurfaceNode->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2725         leashWinSurfaceNode->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2726         surfaceNode_->SetBounds(0, 0, rect.width_, rect.height_);
2727         surfaceNode_->SetFrame(0, 0, rect.width_, rect.height_);
2728     } else if (WindowHelper::IsPipWindow(GetWindowType()) && surfaceNode_) {
2729         TLOGD(WmsLogTag::WMS_PIP, "PipWindow setSurfaceBounds");
2730         surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2731         surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2732     } else if (WindowHelper::IsSubWindow(GetWindowType()) && surfaceNode_) {
2733         WLOGFD("subwindow setSurfaceBounds");
2734         surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2735         surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2736     } else if (WindowHelper::IsDialogWindow(GetWindowType()) && surfaceNode_) {
2737         TLOGD(WmsLogTag::WMS_DIALOG, "dialogWindow setSurfaceBounds");
2738         surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2739         surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2740     } else if (WindowHelper::IsSystemWindow(GetWindowType()) && surfaceNode_) {
2741         TLOGD(WmsLogTag::WMS_SYSTEM, "system window setSurfaceBounds");
2742         surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
2743         surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
2744     } else {
2745         WLOGE("SetSurfaceBounds surfaceNode is null!");
2746     }
2747     if (rsTransaction != nullptr) {
2748         rsTransaction->Commit();
2749     }
2750 }
2751 
SetZOrder(uint32_t zOrder)2752 void SceneSession::SetZOrder(uint32_t zOrder)
2753 {
2754     auto task = [weakThis = wptr(this), zOrder]() {
2755         auto session = weakThis.promote();
2756         if (session == nullptr) {
2757             WLOGFE("session is null");
2758             return;
2759         }
2760         if (session->zOrder_ != zOrder) {
2761             session->Session::SetZOrder(zOrder);
2762             if (session->specificCallback_ != nullptr) {
2763                 session->specificCallback_->onWindowInfoUpdate_(session->GetPersistentId(),
2764                     WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2765             }
2766         }
2767     };
2768     PostTask(task, "SetZOrder");
2769 }
2770 
SetFloatingScale(float floatingScale)2771 void SceneSession::SetFloatingScale(float floatingScale)
2772 {
2773     if (floatingScale_ != floatingScale) {
2774         Session::SetFloatingScale(floatingScale);
2775         if (specificCallback_ != nullptr) {
2776             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2777             if (Session::IsScbCoreEnabled()) {
2778                 dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
2779             } else {
2780                 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
2781             }
2782         }
2783     }
2784 }
2785 
SetParentPersistentId(int32_t parentId)2786 void SceneSession::SetParentPersistentId(int32_t parentId)
2787 {
2788     auto property = GetSessionProperty();
2789     if (property) {
2790         property->SetParentPersistentId(parentId);
2791     }
2792 }
2793 
GetParentPersistentId() const2794 int32_t SceneSession::GetParentPersistentId() const
2795 {
2796     auto property = GetSessionProperty();
2797     if (property) {
2798         return property->GetParentPersistentId();
2799     }
2800     return INVALID_SESSION_ID;
2801 }
2802 
GetMainSessionId()2803 int32_t SceneSession::GetMainSessionId()
2804 {
2805     const auto& mainSession = GetMainSession();
2806     if (mainSession) {
2807         return mainSession->GetPersistentId();
2808     }
2809     return INVALID_SESSION_ID;
2810 }
2811 
GetWindowNameAllType() const2812 std::string SceneSession::GetWindowNameAllType() const
2813 {
2814     if (GetSessionInfo().isSystem_) {
2815         return GetSessionInfo().abilityName_;
2816     } else {
2817         return GetWindowName();
2818     }
2819 }
2820 
SetTurnScreenOn(bool turnScreenOn)2821 WSError SceneSession::SetTurnScreenOn(bool turnScreenOn)
2822 {
2823     GetSessionProperty()->SetTurnScreenOn(turnScreenOn);
2824     return WSError::WS_OK;
2825 }
2826 
IsTurnScreenOn() const2827 bool SceneSession::IsTurnScreenOn() const
2828 {
2829     return GetSessionProperty()->IsTurnScreenOn();
2830 }
2831 
SetWindowEnableDragBySystem(bool enableDrag)2832 WMError SceneSession::SetWindowEnableDragBySystem(bool enableDrag)
2833 {
2834     TLOGI(WmsLogTag::WMS_LAYOUT, "enableDrag: %{public}d", enableDrag);
2835     auto task = [weakThis = wptr(this), enableDrag] {
2836         auto session = weakThis.promote();
2837         if (!session) {
2838             TLOGNE(WmsLogTag::WMS_LAYOUT, "session is null");
2839             return;
2840         }
2841         session->SetClientDragEnable(enableDrag);
2842         TLOGNI(WmsLogTag::WMS_LAYOUT, "id: %{public}d, enableDrag: %{public}d",
2843             session->GetPersistentId(), enableDrag);
2844         auto sessionProperty = session->GetSessionProperty();
2845         if (!sessionProperty) {
2846             TLOGNE(WmsLogTag::WMS_LAYOUT, "sessionProperty is null");
2847             return;
2848         }
2849         sessionProperty->SetDragEnabled(enableDrag);
2850         if (session->sessionStage_) {
2851             session->sessionStage_->SetEnableDragBySystem(enableDrag);
2852         }
2853     };
2854     PostTask(task, __func__);
2855     return WMError::WM_OK;
2856 }
2857 
SetKeepScreenOn(bool keepScreenOn)2858 WSError SceneSession::SetKeepScreenOn(bool keepScreenOn)
2859 {
2860     GetSessionProperty()->SetKeepScreenOn(keepScreenOn);
2861     return WSError::WS_OK;
2862 }
2863 
IsKeepScreenOn() const2864 bool SceneSession::IsKeepScreenOn() const
2865 {
2866     return GetSessionProperty()->IsKeepScreenOn();
2867 }
2868 
GetSessionSnapshotFilePath() const2869 std::string SceneSession::GetSessionSnapshotFilePath() const
2870 {
2871     WLOGFI("GetSessionSnapshotFilePath id %{public}d", GetPersistentId());
2872     if (Session::GetSessionState() < SessionState::STATE_BACKGROUND) {
2873         WLOGFI("GetSessionSnapshotFilePath UpdateSnapshot");
2874         auto snapshot = Snapshot();
2875         if (scenePersistence_ != nullptr) {
2876             scenePersistence_->SaveSnapshot(snapshot);
2877         }
2878     }
2879     if (scenePersistence_ != nullptr) {
2880         return scenePersistence_->GetSnapshotFilePath();
2881     }
2882     return "";
2883 }
2884 
SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap> & icon)2885 void SceneSession::SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap>& icon)
2886 {
2887     WLOGFI("run SaveUpdatedIcon");
2888     if (scenePersistence_ != nullptr) {
2889         scenePersistence_->SaveUpdatedIcon(icon);
2890     }
2891 }
2892 
GetUpdatedIconPath() const2893 std::string SceneSession::GetUpdatedIconPath() const
2894 {
2895     WLOGFI("run GetUpdatedIconPath");
2896     if (scenePersistence_ != nullptr) {
2897         return scenePersistence_->GetUpdatedIconPath();
2898     }
2899     return "";
2900 }
2901 
UpdateNativeVisibility(bool visible)2902 void SceneSession::UpdateNativeVisibility(bool visible)
2903 {
2904     auto task = [weakThis = wptr(this), visible]() {
2905         auto session = weakThis.promote();
2906         if (!session) {
2907             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
2908             return;
2909         }
2910         int32_t persistentId = session->GetPersistentId();
2911         WLOGFI("[WMSSCB] name: %{public}s, id: %{public}u, visible: %{public}u",
2912             session->sessionInfo_.bundleName_.c_str(), persistentId, visible);
2913         session->isVisible_ = visible;
2914         if (session->specificCallback_ == nullptr) {
2915             WLOGFW("specific callback is null.");
2916             return;
2917         }
2918 
2919         if (visible) {
2920             session->specificCallback_->onWindowInfoUpdate_(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
2921         } else {
2922             session->specificCallback_->onWindowInfoUpdate_(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
2923         }
2924         session->NotifyAccessibilityVisibilityChange();
2925         session->specificCallback_->onUpdateAvoidArea_(persistentId);
2926         // update private state
2927         if (!session->GetSessionProperty()) {
2928             WLOGFE("UpdateNativeVisibility property is null");
2929             return;
2930         }
2931         if (session->updatePrivateStateAndNotifyFunc_ != nullptr) {
2932             session->updatePrivateStateAndNotifyFunc_(persistentId);
2933         }
2934     };
2935     PostTask(task, "UpdateNativeVisibility");
2936 }
2937 
IsVisible() const2938 bool SceneSession::IsVisible() const
2939 {
2940     return isVisible_;
2941 }
2942 
UpdateRotationAvoidArea()2943 void SceneSession::UpdateRotationAvoidArea()
2944 {
2945     if (specificCallback_) {
2946         if (Session::IsScbCoreEnabled()) {
2947             dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
2948         } else {
2949             specificCallback_->onUpdateAvoidArea_(GetPersistentId());
2950         }
2951     }
2952 }
2953 
SetPrivacyMode(bool isPrivacy)2954 void SceneSession::SetPrivacyMode(bool isPrivacy)
2955 {
2956     auto property = GetSessionProperty();
2957     if (!property) {
2958         WLOGFE("SetPrivacyMode property is null");
2959         return;
2960     }
2961     if (!surfaceNode_) {
2962         WLOGFE("surfaceNode_ is null");
2963         return;
2964     }
2965     bool lastPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
2966     if (lastPrivacyMode == isPrivacy) {
2967         WLOGFW("privacy mode is not change, do nothing, isPrivacy:%{public}d", isPrivacy);
2968         return;
2969     }
2970     property->SetPrivacyMode(isPrivacy);
2971     property->SetSystemPrivacyMode(isPrivacy);
2972     auto rsTransaction = RSTransactionProxy::GetInstance();
2973     if (rsTransaction != nullptr) {
2974         rsTransaction->Begin();
2975     }
2976     surfaceNode_->SetSecurityLayer(isPrivacy);
2977     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
2978     if (leashWinSurfaceNode != nullptr) {
2979         leashWinSurfaceNode->SetSecurityLayer(isPrivacy);
2980     }
2981     if (rsTransaction != nullptr) {
2982         rsTransaction->Commit();
2983     }
2984 }
2985 
SetSnapshotSkip(bool isSkip)2986 void SceneSession::SetSnapshotSkip(bool isSkip)
2987 {
2988     auto property = GetSessionProperty();
2989     if (!property) {
2990         TLOGE(WmsLogTag::DEFAULT, "property is null");
2991         return;
2992     }
2993     if (!surfaceNode_) {
2994         TLOGE(WmsLogTag::DEFAULT, "surfaceNode_ is null");
2995         return;
2996     }
2997     bool lastSnapshotSkip = property->GetSnapshotSkip();
2998     if (lastSnapshotSkip == isSkip) {
2999         TLOGW(WmsLogTag::DEFAULT, "Snapshot skip does not change, do nothing, isSkip: %{public}d, "
3000             "id: %{public}d", isSkip, GetPersistentId());
3001         return;
3002     }
3003     property->SetSnapshotSkip(isSkip);
3004     auto rsTransaction = RSTransactionProxy::GetInstance();
3005     if (rsTransaction != nullptr) {
3006         rsTransaction->Begin();
3007     }
3008     surfaceNode_->SetSkipLayer(isSkip);
3009     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3010     if (leashWinSurfaceNode != nullptr) {
3011         leashWinSurfaceNode->SetSkipLayer(isSkip);
3012     }
3013     if (rsTransaction != nullptr) {
3014         rsTransaction->Commit();
3015     }
3016 }
3017 
SetPiPTemplateInfo(const PiPTemplateInfo & pipTemplateInfo)3018 void SceneSession::SetPiPTemplateInfo(const PiPTemplateInfo& pipTemplateInfo)
3019 {
3020     pipTemplateInfo_ = pipTemplateInfo;
3021 }
3022 
SetSystemSceneOcclusionAlpha(double alpha)3023 void SceneSession::SetSystemSceneOcclusionAlpha(double alpha)
3024 {
3025     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetAbilityBGAlpha");
3026     if (alpha < 0 || alpha > 1.0) {
3027         WLOGFE("OnSetSystemSceneOcclusionAlpha property is null");
3028         return;
3029     }
3030     if (!surfaceNode_) {
3031         WLOGFE("surfaceNode_ is null");
3032         return;
3033     }
3034     uint8_t alpha8bit = static_cast<uint8_t>(alpha * 255);
3035     WLOGFI("SetAbilityBGAlpha alpha8bit=%{public}u.", alpha8bit);
3036     auto rsTransaction = RSTransactionProxy::GetInstance();
3037     if (rsTransaction != nullptr) {
3038         rsTransaction->Begin();
3039     }
3040     surfaceNode_->SetAbilityBGAlpha(alpha8bit);
3041     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3042     if (leashWinSurfaceNode != nullptr) {
3043         leashWinSurfaceNode->SetAbilityBGAlpha(alpha8bit);
3044     }
3045     if (rsTransaction != nullptr) {
3046         rsTransaction->Commit();
3047     }
3048 }
3049 
SetSystemSceneForceUIFirst(bool forceUIFirst)3050 void SceneSession::SetSystemSceneForceUIFirst(bool forceUIFirst)
3051 {
3052     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetForceUIFirst");
3053     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3054     if (leashWinSurfaceNode == nullptr && surfaceNode_ == nullptr) {
3055         TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
3056         return;
3057     }
3058     auto rsTransaction = RSTransactionProxy::GetInstance();
3059     if (rsTransaction != nullptr) {
3060         rsTransaction->Begin();
3061     }
3062     if (leashWinSurfaceNode != nullptr) {
3063         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " forceUIFirst=%{public}d.",
3064             leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), forceUIFirst);
3065         leashWinSurfaceNode->SetForceUIFirst(forceUIFirst);
3066     } else if (surfaceNode_ != nullptr) {
3067         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " forceUIFirst=%{public}d.",
3068             surfaceNode_->GetName().c_str(), surfaceNode_->GetId(), forceUIFirst);
3069         surfaceNode_->SetForceUIFirst(forceUIFirst);
3070     }
3071     if (rsTransaction != nullptr) {
3072         rsTransaction->Commit();
3073     }
3074 }
3075 
MarkSystemSceneUIFirst(bool isForced,bool isUIFirstEnabled)3076 void SceneSession::MarkSystemSceneUIFirst(bool isForced, bool isUIFirstEnabled)
3077 {
3078     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::MarkSystemSceneUIFirst");
3079     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
3080     if (leashWinSurfaceNode == nullptr && surfaceNode_ == nullptr) {
3081         TLOGE(WmsLogTag::DEFAULT, "leashWindow and surfaceNode are nullptr");
3082         return;
3083     }
3084     if (leashWinSurfaceNode != nullptr) {
3085         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " isForced=%{public}d. isUIFirstEnabled=%{public}d",
3086             leashWinSurfaceNode->GetName().c_str(), leashWinSurfaceNode->GetId(), isForced, isUIFirstEnabled);
3087         leashWinSurfaceNode->MarkUifirstNode(isForced, isUIFirstEnabled);
3088     } else {
3089         TLOGI(WmsLogTag::DEFAULT, "%{public}s %{public}" PRIu64 " isForced=%{public}d. isUIFirstEnabled=%{public}d",
3090             surfaceNode_->GetName().c_str(), surfaceNode_->GetId(), isForced, isUIFirstEnabled);
3091         surfaceNode_->MarkUifirstNode(isForced, isUIFirstEnabled);
3092     }
3093 }
3094 
UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)3095 WSError SceneSession::UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)
3096 {
3097     auto task = [weakThis = wptr(this), needDefaultAnimationFlag] {
3098         auto session = weakThis.promote();
3099         if (!session) {
3100             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
3101             return WSError::WS_ERROR_DESTROYED_OBJECT;
3102         }
3103         session->needDefaultAnimationFlag_ = needDefaultAnimationFlag;
3104         if (session->onWindowAnimationFlagChange_) {
3105             session->onWindowAnimationFlagChange_(needDefaultAnimationFlag);
3106         }
3107         return WSError::WS_OK;
3108     };
3109     return PostSyncTask(task, __func__);
3110 }
3111 
SetWindowAnimationFlag(bool needDefaultAnimationFlag)3112 void SceneSession::SetWindowAnimationFlag(bool needDefaultAnimationFlag)
3113 {
3114     needDefaultAnimationFlag_ = needDefaultAnimationFlag;
3115     if (onWindowAnimationFlagChange_) {
3116         onWindowAnimationFlagChange_(needDefaultAnimationFlag);
3117     }
3118     return;
3119 }
3120 
IsNeedDefaultAnimation() const3121 bool SceneSession::IsNeedDefaultAnimation() const
3122 {
3123     return needDefaultAnimationFlag_;
3124 }
3125 
IsAppSession() const3126 bool SceneSession::IsAppSession() const
3127 {
3128     if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3129         return true;
3130     }
3131     if (GetParentSession() && GetParentSession()->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3132         return true;
3133     }
3134     return false;
3135 }
3136 
3137 /** @note @window.focus */
IsAppOrLowerSystemSession() const3138 bool SceneSession::IsAppOrLowerSystemSession() const
3139 {
3140     WindowType windowType = GetWindowType();
3141     if (windowType == WindowType::WINDOW_TYPE_NEGATIVE_SCREEN ||
3142         windowType == WindowType::WINDOW_TYPE_GLOBAL_SEARCH ||
3143         windowType == WindowType::WINDOW_TYPE_DESKTOP) {
3144         return true;
3145     }
3146     return IsAppSession();
3147 }
3148 
3149 /** @note @window.focus */
IsSystemSessionAboveApp() const3150 bool SceneSession::IsSystemSessionAboveApp() const
3151 {
3152     WindowType windowType = GetWindowType();
3153     if (windowType == WindowType::WINDOW_TYPE_DIALOG || windowType == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
3154         return true;
3155     }
3156     if (windowType == WindowType::WINDOW_TYPE_PANEL &&
3157         sessionInfo_.bundleName_.find("SCBDropdownPanel") != std::string::npos) {
3158         return true;
3159     }
3160     return false;
3161 }
3162 
NotifyIsCustomAnimationPlaying(bool isPlaying)3163 void SceneSession::NotifyIsCustomAnimationPlaying(bool isPlaying)
3164 {
3165     WLOGFI("id %{public}d %{public}u", GetPersistentId(), isPlaying);
3166     if (onIsCustomAnimationPlaying_) {
3167         onIsCustomAnimationPlaying_(isPlaying);
3168     }
3169 }
3170 
UpdateWindowSceneAfterCustomAnimation(bool isAdd)3171 WSError SceneSession::UpdateWindowSceneAfterCustomAnimation(bool isAdd)
3172 {
3173     if (!SessionPermission::IsSystemCalling()) {
3174         TLOGE(WmsLogTag::WMS_SYSTEM, "failed to update with id:%{public}u!", GetPersistentId());
3175         return WSError::WS_ERROR_NOT_SYSTEM_APP;
3176     }
3177     auto task = [weakThis = wptr(this), isAdd]() {
3178         auto session = weakThis.promote();
3179         if (!session) {
3180             WLOGFE("session is null");
3181             return WSError::WS_ERROR_DESTROYED_OBJECT;
3182         }
3183         WLOGFI("UpdateWindowSceneAfterCustomAnimation, id %{public}d, isAdd: %{public}d",
3184             session->GetPersistentId(), isAdd);
3185         if (isAdd) {
3186             WLOGFE("SetOpacityFunc not register %{public}d", session->GetPersistentId());
3187             return WSError::WS_ERROR_INVALID_OPERATION;
3188         } else {
3189             WLOGFI("background after custom animation id %{public}d", session->GetPersistentId());
3190             // since background will remove surfaceNode
3191             session->Background();
3192             session->NotifyIsCustomAnimationPlaying(false);
3193         }
3194         return WSError::WS_OK;
3195     };
3196     PostTask(task, "UpdateWindowSceneAfterCustomAnimation:" + std::to_string(isAdd));
3197     return WSError::WS_OK;
3198 }
3199 
IsFloatingWindowAppType() const3200 bool SceneSession::IsFloatingWindowAppType() const
3201 {
3202     auto property = GetSessionProperty();
3203     if (property == nullptr) {
3204         return false;
3205     }
3206     return property->IsFloatingWindowAppType();
3207 }
3208 
GetTouchHotAreas() const3209 std::vector<Rect> SceneSession::GetTouchHotAreas() const
3210 {
3211     std::vector<Rect> touchHotAreas;
3212     auto property = GetSessionProperty();
3213     if (property) {
3214         property->GetTouchHotAreas(touchHotAreas);
3215     }
3216     return touchHotAreas;
3217 }
3218 
GetPiPTemplateInfo() const3219 PiPTemplateInfo SceneSession::GetPiPTemplateInfo() const
3220 {
3221     return pipTemplateInfo_;
3222 }
3223 
DumpSessionElementInfo(const std::vector<std::string> & params)3224 void SceneSession::DumpSessionElementInfo(const std::vector<std::string>& params)
3225 {
3226     if (!sessionStage_) {
3227         return;
3228     }
3229     return sessionStage_->DumpSessionElementInfo(params);
3230 }
3231 
NotifyTouchOutside()3232 void SceneSession::NotifyTouchOutside()
3233 {
3234     WLOGFI("id: %{public}d, type: %{public}d", GetPersistentId(), GetWindowType());
3235     if (sessionStage_) {
3236         WLOGFD("Notify sessionStage TouchOutside");
3237         sessionStage_->NotifyTouchOutside();
3238     }
3239     if (onTouchOutside_) {
3240         WLOGFD("Notify sessionChangeCallback TouchOutside");
3241         onTouchOutside_();
3242     }
3243 }
3244 
NotifyWindowVisibility()3245 void SceneSession::NotifyWindowVisibility()
3246 {
3247     if (sessionStage_) {
3248         sessionStage_->NotifyWindowVisibility(GetRSVisible());
3249     } else {
3250         WLOGFE("Notify window(id:%{public}d) visibility failed, for this session stage is nullptr", GetPersistentId());
3251     }
3252 }
3253 
CheckTouchOutsideCallbackRegistered()3254 bool SceneSession::CheckTouchOutsideCallbackRegistered()
3255 {
3256     return onTouchOutside_ != nullptr;
3257 }
3258 
SetRequestedOrientation(Orientation orientation)3259 void SceneSession::SetRequestedOrientation(Orientation orientation)
3260 {
3261     WLOGFI("id: %{public}d orientation: %{public}u", GetPersistentId(), static_cast<uint32_t>(orientation));
3262     GetSessionProperty()->SetRequestedOrientation(orientation);
3263     if (onRequestedOrientationChange_) {
3264         onRequestedOrientationChange_(static_cast<uint32_t>(orientation));
3265     }
3266 }
3267 
SetDefaultRequestedOrientation(Orientation orientation)3268 WSError SceneSession::SetDefaultRequestedOrientation(Orientation orientation)
3269 {
3270     auto task = [weakThis = wptr(this), orientation]() -> WSError {
3271         auto session = weakThis.promote();
3272         if (!session) {
3273             TLOGNE(WmsLogTag::DEFAULT, "session is null");
3274             return WSError::WS_ERROR_NULLPTR;
3275         }
3276         TLOGNI(WmsLogTag::DEFAULT, "id: %{public}d defaultRequestedOrientation: %{public}u",
3277             session->GetPersistentId(), static_cast<uint32_t>(orientation));
3278         auto property = session->GetSessionProperty();
3279         if (property == nullptr) {
3280             TLOGNE(WmsLogTag::DEFAULT, "get session property failed");
3281             return WSError::WS_ERROR_NULLPTR;
3282         }
3283         property->SetRequestedOrientation(orientation);
3284         property->SetDefaultRequestedOrientation(orientation);
3285         return WSError::WS_OK;
3286     };
3287     return PostSyncTask(task, __func__);
3288 }
3289 
NotifyForceHideChange(bool hide)3290 void SceneSession::NotifyForceHideChange(bool hide)
3291 {
3292     WLOGFI("id: %{public}d forceHide: %{public}u", persistentId_, hide);
3293     auto property = GetSessionProperty();
3294     if (property == nullptr) {
3295         WLOGFD("id: %{public}d property is nullptr", persistentId_);
3296         return;
3297     }
3298     property->SetForceHide(hide);
3299     if (onForceHideChangeFunc_) {
3300         onForceHideChangeFunc_(hide);
3301     }
3302     SetForceTouchable(!hide);
3303     if (hide) {
3304         if (isFocused_) {
3305             FocusChangeReason reason = FocusChangeReason::DEFAULT;
3306             NotifyRequestFocusStatusNotifyManager(false, true, reason);
3307             SetForceHideState(ForceHideState::HIDDEN_WHEN_FOCUSED);
3308         } else if (forceHideState_ == ForceHideState::NOT_HIDDEN) {
3309             SetForceHideState(ForceHideState::HIDDEN_WHEN_UNFOCUSED);
3310         }
3311     } else {
3312         if (forceHideState_ == ForceHideState::HIDDEN_WHEN_FOCUSED) {
3313             SetForceHideState(ForceHideState::NOT_HIDDEN);
3314             FocusChangeReason reason = FocusChangeReason::DEFAULT;
3315             NotifyRequestFocusStatusNotifyManager(true, true, reason);
3316         } else {
3317             SetForceHideState(ForceHideState::NOT_HIDDEN);
3318         }
3319     }
3320 }
3321 
GetRequestedOrientation() const3322 Orientation SceneSession::GetRequestedOrientation() const
3323 {
3324     return GetSessionProperty()->GetRequestedOrientation();
3325 }
3326 
IsAnco() const3327 bool SceneSession::IsAnco() const
3328 {
3329     return collaboratorType_ == static_cast<int32_t>(CollaboratorType::RESERVE_TYPE);
3330 }
3331 
SetBlankFlag(bool isAddBlank)3332 void SceneSession::SetBlankFlag(bool isAddBlank)
3333 {
3334     isAddBlank_ = isAddBlank;
3335 }
3336 
GetBlankFlag() const3337 bool SceneSession::GetBlankFlag() const
3338 {
3339     return isAddBlank_;
3340 }
3341 
SetBufferAvailableCallbackEnable(bool enable)3342 void SceneSession::SetBufferAvailableCallbackEnable(bool enable)
3343 {
3344     bufferAvailableCallbackEnable_ = enable;
3345 }
3346 
GetBufferAvailableCallbackEnable() const3347 bool SceneSession::GetBufferAvailableCallbackEnable() const
3348 {
3349     return bufferAvailableCallbackEnable_;
3350 }
3351 
GetCollaboratorType() const3352 int32_t SceneSession::GetCollaboratorType() const
3353 {
3354     return collaboratorType_;
3355 }
3356 
SetCollaboratorType(int32_t collaboratorType)3357 void SceneSession::SetCollaboratorType(int32_t collaboratorType)
3358 {
3359     collaboratorType_ = collaboratorType;
3360     sessionInfo_.collaboratorType_ = collaboratorType;
3361 }
3362 
GetClientIdentityToken() const3363 std::string SceneSession::GetClientIdentityToken() const
3364 {
3365     return clientIdentityToken_;
3366 }
3367 
SetClientIdentityToken(const std::string & clientIdentityToken)3368 void SceneSession::SetClientIdentityToken(const std::string& clientIdentityToken)
3369 {
3370     clientIdentityToken_ = clientIdentityToken;
3371 }
3372 
DumpSessionInfo(std::vector<std::string> & info) const3373 void SceneSession::DumpSessionInfo(std::vector<std::string>& info) const
3374 {
3375     std::string dumpInfo = "      Session ID #" + std::to_string(persistentId_);
3376     info.push_back(dumpInfo);
3377     dumpInfo = "        session name [" + SessionUtils::ConvertSessionName(sessionInfo_.bundleName_,
3378         sessionInfo_.abilityName_, sessionInfo_.moduleName_, sessionInfo_.appIndex_) + "]";
3379     info.push_back(dumpInfo);
3380     dumpInfo = "        runningState [" + std::string(isActive_ ? "FOREGROUND" : "BACKGROUND") + "]";
3381     info.push_back(dumpInfo);
3382     dumpInfo = "        lockedState [" + std::to_string(sessionInfo_.lockedState) + "]";
3383     info.push_back(dumpInfo);
3384     auto abilityInfo = sessionInfo_.abilityInfo;
3385     dumpInfo = "        continuable [" + (abilityInfo ? std::to_string(abilityInfo->continuable) : " ") + "]";
3386     info.push_back(dumpInfo);
3387     dumpInfo = "        timeStamp [" + sessionInfo_.time + "]";
3388     info.push_back(dumpInfo);
3389     dumpInfo = "        label [" + (abilityInfo ? abilityInfo->label : " ") + "]";
3390     info.push_back(dumpInfo);
3391     dumpInfo = "        iconPath [" + (abilityInfo ? abilityInfo->iconPath : " ") + "]";
3392     info.push_back(dumpInfo);
3393     dumpInfo = "        want [" + (sessionInfo_.want ? sessionInfo_.want->ToUri() : " ") + "]";
3394     info.push_back(dumpInfo);
3395 }
3396 
GetAbilityInfo() const3397 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSession::GetAbilityInfo() const
3398 {
3399     const SessionInfo& sessionInfo = GetSessionInfo();
3400     return sessionInfo.abilityInfo;
3401 }
3402 
SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)3403 void SceneSession::SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
3404 {
3405     SetSessionInfoAbilityInfo(abilityInfo);
3406 }
3407 
SetSessionState(SessionState state)3408 void SceneSession::SetSessionState(SessionState state)
3409 {
3410     Session::SetSessionState(state);
3411     NotifyAccessibilityVisibilityChange();
3412 }
3413 
UpdateSessionState(SessionState state)3414 void SceneSession::UpdateSessionState(SessionState state)
3415 {
3416     Session::UpdateSessionState(state);
3417     NotifyAccessibilityVisibilityChange();
3418 }
3419 
IsVisibleForAccessibility() const3420 bool SceneSession::IsVisibleForAccessibility() const
3421 {
3422     if (Session::IsScbCoreEnabled()) {
3423         return GetSystemTouchable() && GetForegroundInteractiveStatus() && IsVisibleForeground();
3424     }
3425     return GetSystemTouchable() && GetForegroundInteractiveStatus() &&
3426         (IsVisible() || state_ == SessionState::STATE_ACTIVE || state_ == SessionState::STATE_FOREGROUND);
3427 }
3428 
SetForegroundInteractiveStatus(bool interactive)3429 void SceneSession::SetForegroundInteractiveStatus(bool interactive)
3430 {
3431     Session::SetForegroundInteractiveStatus(interactive);
3432     NotifyAccessibilityVisibilityChange();
3433     if (interactive) {
3434         return;
3435     }
3436     for (auto toastSession : toastSession_) {
3437         if (toastSession == nullptr) {
3438             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
3439             continue;
3440         }
3441         auto state = toastSession->GetSessionState();
3442         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
3443             continue;
3444         }
3445         toastSession->SetActive(false);
3446         toastSession->BackgroundTask();
3447     }
3448 }
3449 
NotifyAccessibilityVisibilityChange()3450 void SceneSession::NotifyAccessibilityVisibilityChange()
3451 {
3452     bool isVisibleForAccessibilityNew = IsVisibleForAccessibility();
3453     if (isVisibleForAccessibilityNew == isVisibleForAccessibility_.load()) {
3454         return;
3455     }
3456     WLOGFD("[WMSAccess] NotifyAccessibilityVisibilityChange id: %{public}d, access: %{public}d ",
3457         GetPersistentId(), isVisibleForAccessibilityNew);
3458     isVisibleForAccessibility_.store(isVisibleForAccessibilityNew);
3459     if (specificCallback_ && specificCallback_->onWindowInfoUpdate_) {
3460         if (isVisibleForAccessibilityNew) {
3461             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
3462         } else {
3463             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
3464         }
3465     } else {
3466         WLOGFD("specificCallback_->onWindowInfoUpdate_ not exist, persistent id: %{public}d", GetPersistentId());
3467     }
3468 }
3469 
SetSystemTouchable(bool touchable)3470 void SceneSession::SetSystemTouchable(bool touchable)
3471 {
3472     Session::SetSystemTouchable(touchable);
3473     NotifyAccessibilityVisibilityChange();
3474 }
3475 
ChangeSessionVisibilityWithStatusBar(const sptr<AAFwk::SessionInfo> abilitySessionInfo,bool visible)3476 WSError SceneSession::ChangeSessionVisibilityWithStatusBar(
3477     const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool visible)
3478 {
3479     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
3480         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
3481         return WSError::WS_ERROR_INVALID_PERMISSION;
3482     }
3483     auto task = [weakThis = wptr(this), abilitySessionInfo, visible]() {
3484         auto session = weakThis.promote();
3485         if (!session) {
3486             WLOGFE("session is null");
3487             return WSError::WS_ERROR_DESTROYED_OBJECT;
3488         }
3489         if (abilitySessionInfo == nullptr) {
3490             WLOGFE("abilitySessionInfo is null");
3491             return WSError::WS_ERROR_NULLPTR;
3492         }
3493 
3494         SessionInfo info;
3495         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
3496         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
3497         info.moduleName_ = abilitySessionInfo->want.GetModuleName();
3498         int32_t appCloneIndex = abilitySessionInfo->want.GetIntParam(APP_CLONE_INDEX, 0);
3499         info.appIndex_ = appCloneIndex == 0 ? abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0) : appCloneIndex;
3500         info.persistentId_ = abilitySessionInfo->persistentId;
3501         info.callerPersistentId_ = session->GetPersistentId();
3502         info.callerBundleName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_BUNDLE_NAME);
3503         info.callerAbilityName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_ABILITY_NAME);
3504         info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
3505         info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
3506         info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
3507         info.requestCode = abilitySessionInfo->requestCode;
3508         info.callerToken_ = abilitySessionInfo->callerToken;
3509         info.startSetting = abilitySessionInfo->startSetting;
3510         info.callingTokenId_ = abilitySessionInfo->callingTokenId;
3511         info.reuse = abilitySessionInfo->reuse;
3512         info.processOptions = abilitySessionInfo->processOptions;
3513 
3514         if (session->changeSessionVisibilityWithStatusBarFunc_) {
3515             session->changeSessionVisibilityWithStatusBarFunc_(info, visible);
3516         }
3517 
3518         return WSError::WS_OK;
3519     };
3520     PostTask(task, "ChangeSessionVisibilityWithStatusBar");
3521     return WSError::WS_OK;
3522 }
3523 
MakeSessionInfoDuringPendingActivation(const sptr<AAFwk::SessionInfo> & abilitySessionInfo,const sptr<SceneSession> & session)3524 static SessionInfo MakeSessionInfoDuringPendingActivation(const sptr<AAFwk::SessionInfo>& abilitySessionInfo,
3525     const sptr<SceneSession>& session)
3526 {
3527     SessionInfo info;
3528     info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
3529     info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
3530     info.moduleName_ = abilitySessionInfo->want.GetModuleName();
3531     int32_t appCloneIndex = abilitySessionInfo->want.GetIntParam(APP_CLONE_INDEX, 0);
3532     info.appIndex_ = appCloneIndex == 0 ? abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0) : appCloneIndex;
3533     info.persistentId_ = abilitySessionInfo->persistentId;
3534     info.callerPersistentId_ = session->GetPersistentId();
3535     info.callerBundleName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_BUNDLE_NAME);
3536     info.callerAbilityName_ = abilitySessionInfo->want.GetStringParam(AAFwk::Want::PARAM_RESV_CALLER_ABILITY_NAME);
3537     info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
3538     info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
3539     info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
3540     info.requestCode = abilitySessionInfo->requestCode;
3541     info.callerToken_ = abilitySessionInfo->callerToken;
3542     info.startSetting = abilitySessionInfo->startSetting;
3543     info.callingTokenId_ = abilitySessionInfo->callingTokenId;
3544     info.reuse = abilitySessionInfo->reuse;
3545     info.processOptions = abilitySessionInfo->processOptions;
3546     info.isAtomicService_ = abilitySessionInfo->isAtomicService;
3547     info.isBackTransition_ = abilitySessionInfo->isBackTransition;
3548     info.needClearInNotShowRecent_ = abilitySessionInfo->needClearInNotShowRecent;
3549     info.isFromIcon_ = abilitySessionInfo->isFromIcon;
3550 
3551     if (session->IsPcOrPadEnableActivation()) {
3552         info.startWindowOption = abilitySessionInfo->startWindowOption;
3553         if (!abilitySessionInfo->supportWindowModes.empty()) {
3554             info.supportWindowModes.assign(abilitySessionInfo->supportWindowModes.begin(),
3555                 abilitySessionInfo->supportWindowModes.end());
3556         }
3557     }
3558     if (info.want != nullptr) {
3559         info.windowMode = info.want->GetIntParam(AAFwk::Want::PARAM_RESV_WINDOW_MODE, 0);
3560         info.sessionAffinity = info.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
3561         info.screenId_ = static_cast<uint64_t>(info.want->GetIntParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, -1));
3562         TLOGI(WmsLogTag::WMS_LIFE, "want: screenId %{public}" PRIu64, info.screenId_);
3563     }
3564     if (info.windowMode == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN)) {
3565         info.fullScreenStart_ = true;
3566     }
3567     TLOGI(WmsLogTag::WMS_LIFE, "bundleName:%{public}s, moduleName:%{public}s, abilityName:%{public}s, "
3568         "appIndex:%{public}d, affinity:%{public}s. callState:%{public}d, want persistentId:%{public}d, "
3569         "uiAbilityId:%{public}" PRIu64 ", windowMode:%{public}d, callerId:%{public}d, "
3570         "needClearInNotShowRecent:%{public}u, isFromIcon:%{public}d, supportWindowModes.size:%{public}zu",
3571         info.bundleName_.c_str(), info.moduleName_.c_str(), info.abilityName_.c_str(), info.appIndex_,
3572         info.sessionAffinity.c_str(), info.callState_, info.persistentId_, info.uiAbilityId_, info.windowMode,
3573         info.callerPersistentId_, info.needClearInNotShowRecent_, info.isFromIcon_, info.supportWindowModes.size());
3574     return info;
3575 }
3576 
PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)3577 WSError SceneSession::PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
3578 {
3579     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
3580         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
3581         return WSError::WS_ERROR_INVALID_PERMISSION;
3582     }
3583     bool isFoundationCall = SessionPermission::IsFoundationCall();
3584     auto task = [weakThis = wptr(this), abilitySessionInfo, isFoundationCall]() {
3585         auto session = weakThis.promote();
3586         if (!session) {
3587             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
3588             return WSError::WS_ERROR_DESTROYED_OBJECT;
3589         }
3590         if (abilitySessionInfo == nullptr) {
3591             TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
3592             return WSError::WS_ERROR_NULLPTR;
3593         }
3594         bool isFromAncoAndToAnco = session->IsAnco() && AbilityInfoManager::GetInstance().IsAnco(
3595             abilitySessionInfo->want.GetElement().GetBundleName(),
3596             abilitySessionInfo->want.GetElement().GetAbilityName(), abilitySessionInfo->want.GetModuleName());
3597         if (!session->IsPcOrPadEnableActivation() && WindowHelper::IsMainWindow(session->GetWindowType())) {
3598             SessionState sessionState = session->GetSessionState();
3599             TLOGI(WmsLogTag::WMS_LIFE, "sceneSession state:%{public}d, isFoundationCall:%{public}u, "
3600                 "canStartAbilityFromBackground:%{public}u, foregroundInteractiveStatus:%{public}u",
3601                 sessionState, isFoundationCall, abilitySessionInfo->canStartAbilityFromBackground,
3602                 session->GetForegroundInteractiveStatus());
3603             bool isSessionForeground = sessionState == SessionState::STATE_FOREGROUND ||
3604                 sessionState == SessionState::STATE_ACTIVE;
3605             if (isSessionForeground && !session->GetForegroundInteractiveStatus()) {
3606                 TLOGW(WmsLogTag::WMS_LIFE, "start ability invalid, sceneSession in a non interactive state");
3607                 return WSError::WS_ERROR_INVALID_OPERATION;
3608             }
3609             if (!isSessionForeground && !isFromAncoAndToAnco &&
3610                 !(isFoundationCall && abilitySessionInfo->canStartAbilityFromBackground)) {
3611                 TLOGW(WmsLogTag::WMS_LIFE, "no permission to start ability from Background");
3612                 return WSError::WS_ERROR_INVALID_OPERATION;
3613             }
3614         }
3615         session->sessionInfo_.startMethod = StartMethod::START_CALL;
3616         SessionInfo info = MakeSessionInfoDuringPendingActivation(abilitySessionInfo, session);
3617         session->HandleCastScreenConnection(info, session);
3618         if (session->pendingSessionActivationFunc_) {
3619             session->pendingSessionActivationFunc_(info);
3620         }
3621         return WSError::WS_OK;
3622     };
3623     PostTask(task, "PendingSessionActivation");
3624     return WSError::WS_OK;
3625 }
3626 
HandleCastScreenConnection(SessionInfo & info,sptr<SceneSession> session)3627 void SceneSession::HandleCastScreenConnection(SessionInfo& info, sptr<SceneSession> session)
3628 {
3629     ScreenId defScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
3630     if (defScreenId == info.screenId_) {
3631         return;
3632     }
3633     auto flag = Rosen::ScreenManager::GetInstance().GetVirtualScreenFlag(info.screenId_);
3634     if (flag != VirtualScreenFlag::CAST) {
3635         return;
3636     }
3637     TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state :%{public}d persistentId:%{public}d",
3638         session->GetSessionState(), info.callerPersistentId_);
3639     if (session->GetSessionState() != SessionState::STATE_FOREGROUND &&
3640         session->GetSessionState() != SessionState::STATE_ACTIVE) {
3641         TLOGI(WmsLogTag::WMS_LIFE, "Get exist session state is not foreground");
3642         return;
3643     }
3644     info.isCastSession_ = true;
3645     std::vector<uint64_t> mirrorIds { info.screenId_ };
3646     Rosen::DMError ret = Rosen::ScreenManager::GetInstance().MakeUniqueScreen(mirrorIds);
3647     if (ret != Rosen::DMError::DM_OK) {
3648         TLOGE(WmsLogTag::WMS_LIFE, "MakeUniqueScreen failed,ret: %{public}d", ret);
3649         return;
3650     }
3651 }
3652 
IsNeedSystemPermissionByAction(WSPropertyChangeAction action,const sptr<WindowSessionProperty> & property,const sptr<WindowSessionProperty> & sessionProperty)3653 static bool IsNeedSystemPermissionByAction(WSPropertyChangeAction action,
3654     const sptr<WindowSessionProperty>& property, const sptr<WindowSessionProperty>& sessionProperty)
3655 {
3656     switch (action) {
3657         case WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON:
3658         case WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP:
3659         case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
3660         case WSPropertyChangeAction::ACTION_UPDATE_TOPMOST:
3661         case WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE:
3662         case WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO:
3663             return true;
3664         case WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG:
3665             return property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM);
3666         case WSPropertyChangeAction::ACTION_UPDATE_FLAGS: {
3667             uint32_t oldFlags = sessionProperty->GetWindowFlags();
3668             uint32_t flags = property->GetWindowFlags();
3669             if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) {
3670                 return true;
3671             }
3672             break;
3673         }
3674         default:
3675             break;
3676     }
3677     return false;
3678 }
3679 
UpdateSessionPropertyByAction(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)3680 WMError SceneSession::UpdateSessionPropertyByAction(const sptr<WindowSessionProperty>& property,
3681     WSPropertyChangeAction action)
3682 {
3683     if (property == nullptr) {
3684         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
3685         return WMError::WM_ERROR_NULLPTR;
3686     }
3687     auto sessionProperty = GetSessionProperty();
3688     if (sessionProperty == nullptr) {
3689         TLOGE(WmsLogTag::DEFAULT, "get session property failed");
3690         return WMError::WM_ERROR_NULLPTR;
3691     }
3692     if (action == WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE) {
3693         if (!SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
3694             return WMError::WM_ERROR_INVALID_PERMISSION;
3695         }
3696     }
3697     if (action == WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST) {
3698         uint32_t accessTokenId = property->GetAccessTokenId();
3699         if (!SessionPermission::VerifyPermissionByCallerToken(accessTokenId,
3700             PermissionConstants::PERMISSION_MAIN_WINDOW_TOPMOST)) {
3701             TLOGE(WmsLogTag::WMS_HIERARCHY, "The caller has no permission granted.");
3702             return WMError::WM_ERROR_INVALID_PERMISSION;
3703         }
3704     }
3705 
3706     bool isSystemCalling = SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd();
3707     if (!isSystemCalling && IsNeedSystemPermissionByAction(action, property, sessionProperty)) {
3708         TLOGE(WmsLogTag::DEFAULT, "permission denied! action: %{public}u", action);
3709         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3710     }
3711     property->SetSystemCalling(isSystemCalling);
3712     wptr<SceneSession> weak = this;
3713     auto task = [weak, property, action]() -> WMError {
3714         auto sceneSession = weak.promote();
3715         if (sceneSession == nullptr) {
3716             TLOGE(WmsLogTag::DEFAULT, "the session is nullptr");
3717             return WMError::WM_DO_NOTHING;
3718         }
3719         TLOGD(WmsLogTag::DEFAULT, "Id: %{public}d, action: %{public}u", sceneSession->GetPersistentId(), action);
3720         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession:UpdateProperty");
3721         return sceneSession->HandleUpdatePropertyByAction(property, sceneSession, action);
3722     };
3723     if (AppExecFwk::EventRunner::IsAppMainThread()) {
3724         PostTask(task, "UpdateProperty");
3725         return WMError::WM_OK;
3726     }
3727     return PostSyncTask(task, "UpdateProperty");
3728 }
3729 
SetGestureBackEnabled(bool isEnabled)3730 WMError SceneSession::SetGestureBackEnabled(bool isEnabled)
3731 {
3732     auto task = [weakThis = wptr(this), isEnabled] {
3733         auto sceneSession = weakThis.promote();
3734         if (!sceneSession) {
3735             TLOGNE(WmsLogTag::WMS_IMMS, "session is invalid");
3736             return;
3737         }
3738         if (sceneSession->isEnableGestureBack_ == isEnabled) {
3739             TLOGNI(WmsLogTag::WMS_IMMS, "isEnabled equals last.");
3740             return;
3741         }
3742         TLOGNI(WmsLogTag::WMS_IMMS, "id: %{public}d, isEnabled: %{public}d",
3743             sceneSession->GetPersistentId(), isEnabled);
3744         sceneSession->isEnableGestureBack_ = isEnabled;
3745         sceneSession->isEnableGestureBackHadSet_ = true;
3746         sceneSession->UpdateGestureBackEnabled();
3747     };
3748     PostTask(task, __func__);
3749     return WMError::WM_OK;
3750 }
3751 
GetGestureBackEnabled()3752 bool SceneSession::GetGestureBackEnabled()
3753 {
3754     return isEnableGestureBack_;
3755 }
3756 
GetEnableGestureBackHadSet()3757 bool SceneSession::GetEnableGestureBackHadSet()
3758 {
3759     return isEnableGestureBackHadSet_;
3760 }
3761 
SetSessionChangeByActionNotifyManagerListener(const SessionChangeByActionNotifyManagerFunc & func)3762 void SceneSession::SetSessionChangeByActionNotifyManagerListener(const SessionChangeByActionNotifyManagerFunc& func)
3763 {
3764     TLOGD(WmsLogTag::DEFAULT, "setListener success");
3765     sessionChangeByActionNotifyManagerFunc_ = func;
3766 }
3767 
HandleUpdatePropertyByAction(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3768 WMError SceneSession::HandleUpdatePropertyByAction(const sptr<WindowSessionProperty>& property,
3769     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3770 {
3771     if (sceneSession == nullptr) {
3772         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
3773         return WMError::WM_ERROR_NULLPTR;
3774     }
3775     if (property == nullptr) {
3776         TLOGE(WmsLogTag::DEFAULT, "property is nullptr");
3777         return WMError::WM_ERROR_NULLPTR;
3778     }
3779 
3780     return ProcessUpdatePropertyByAction(property, sceneSession, action);
3781 }
3782 
ProcessUpdatePropertyByAction(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3783 WMError SceneSession::ProcessUpdatePropertyByAction(const sptr<WindowSessionProperty>& property,
3784     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3785 {
3786     switch (static_cast<uint32_t>(action)) {
3787         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON):
3788             return HandleActionUpdateTurnScreenOn(property, sceneSession, action);
3789         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON):
3790             return HandleActionUpdateKeepScreenOn(property, sceneSession, action);
3791         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE):
3792             return HandleActionUpdateFocusable(property, sceneSession, action);
3793         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE):
3794             return HandleActionUpdateTouchable(property, sceneSession, action);
3795         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS):
3796             return HandleActionUpdateSetBrightness(property, sceneSession, action);
3797         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_ORIENTATION):
3798             return HandleActionUpdateOrientation(property, sceneSession, action);
3799         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE):
3800             return HandleActionUpdatePrivacyMode(property, sceneSession, action);
3801         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE):
3802             return HandleActionUpdatePrivacyMode(property, sceneSession, action);
3803         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP):
3804             return HandleActionUpdateSnapshotSkip(property, sceneSession, action);
3805         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE):
3806             return HandleActionUpdateMaximizeState(property, sceneSession, action);
3807         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS):
3808             return HandleActionUpdateOtherProps(property, sceneSession, action);
3809         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS):
3810             return HandleActionUpdateStatusProps(property, sceneSession, action);
3811         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS):
3812             return HandleActionUpdateNavigationProps(property, sceneSession, action);
3813         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS):
3814             return HandleActionUpdateNavigationIndicatorProps(property, sceneSession, action);
3815         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_FLAGS):
3816             return HandleActionUpdateFlags(property, sceneSession, action);
3817         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_MODE):
3818             return HandleActionUpdateMode(property, sceneSession, action);
3819         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG):
3820             return HandleActionUpdateAnimationFlag(property, sceneSession, action);
3821         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA):
3822             return HandleActionUpdateTouchHotArea(property, sceneSession, action);
3823         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE):
3824             return HandleActionUpdateDecorEnable(property, sceneSession, action);
3825         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS):
3826             return HandleActionUpdateWindowLimits(property, sceneSession, action);
3827         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED):
3828             return HandleActionUpdateDragenabled(property, sceneSession, action);
3829         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED):
3830             return HandleActionUpdateRaiseenabled(property, sceneSession, action);
3831         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS):
3832             return HandleActionUpdateHideNonSystemFloatingWindows(property, sceneSession, action);
3833         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO):
3834             return HandleActionUpdateTextfieldAvoidInfo(property, sceneSession, action);
3835         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK):
3836             return HandleActionUpdateWindowMask(property, sceneSession, action);
3837         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_TOPMOST):
3838             return HandleActionUpdateTopmost(property, sceneSession, action);
3839         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST):
3840             return HandleActionUpdateMainWindowTopmost(property, action);
3841         case static_cast<uint32_t>(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO):
3842             return HandleActionUpdateWindowModeSupportType(property, sceneSession, action);
3843         default:
3844             TLOGE(WmsLogTag::DEFAULT, "Failed to find func handler!");
3845             return WMError::WM_DO_NOTHING;
3846     }
3847 }
3848 
HandleActionUpdateTurnScreenOn(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3849 WMError SceneSession::HandleActionUpdateTurnScreenOn(const sptr<WindowSessionProperty>& property,
3850     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3851 {
3852     sceneSession->SetTurnScreenOn(property->IsTurnScreenOn());
3853 #ifdef POWER_MANAGER_ENABLE
3854     auto task = [this, sceneSession]() {
3855         if (sceneSession == nullptr) {
3856             TLOGE(WmsLogTag::DEFAULT, "session is invalid");
3857             return;
3858         }
3859         TLOGD(WmsLogTag::DEFAULT, "Win: %{public}s, is turn on: %{public}d",
3860             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
3861         std::string identity = IPCSkeleton::ResetCallingIdentity();
3862         if (sceneSession->IsTurnScreenOn()) {
3863             TLOGI(WmsLogTag::DEFAULT, "turn screen on");
3864             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
3865         }
3866         // set ipc identity to raw
3867         IPCSkeleton::SetCallingIdentity(identity);
3868     };
3869     PostTask(task, "HandleTurnScreenOn");
3870 #else
3871     TLOGD(WmsLogTag::DEFAULT, "Can not found the sub system of PowerMgr");
3872 #endif
3873     return WMError::WM_OK;
3874 }
3875 
HandleActionUpdateKeepScreenOn(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3876 WMError SceneSession::HandleActionUpdateKeepScreenOn(const sptr<WindowSessionProperty>& property,
3877     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3878 {
3879     sceneSession->SetKeepScreenOn(property->IsKeepScreenOn());
3880     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3881     return WMError::WM_OK;
3882 }
3883 
HandleActionUpdateFocusable(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3884 WMError SceneSession::HandleActionUpdateFocusable(const sptr<WindowSessionProperty>& property,
3885     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3886 {
3887     sceneSession->SetFocusable(property->GetFocusable());
3888     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3889     return WMError::WM_OK;
3890 }
3891 
HandleActionUpdateTouchable(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3892 WMError SceneSession::HandleActionUpdateTouchable(const sptr<WindowSessionProperty>& property,
3893     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3894 {
3895     sceneSession->SetTouchable(property->GetTouchable());
3896     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3897     return WMError::WM_OK;
3898 }
3899 
HandleActionUpdateSetBrightness(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3900 WMError SceneSession::HandleActionUpdateSetBrightness(const sptr<WindowSessionProperty>& property,
3901     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3902 {
3903     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3904         TLOGW(WmsLogTag::DEFAULT, "only app main window can set brightness");
3905         return WMError::WM_OK;
3906     }
3907     if (!sceneSession->IsSessionValid()) {
3908         TLOGW(WmsLogTag::WMS_MAIN, "Session is invalid, id: %{public}d state: %{public}u",
3909             sceneSession->GetPersistentId(), sceneSession->GetSessionState());
3910         return WMError::WM_ERROR_INVALID_SESSION;
3911     }
3912     float brightness = property->GetBrightness();
3913     if (std::abs(brightness - sceneSession->GetBrightness()) < std::numeric_limits<float>::epsilon()) {
3914         TLOGD(WmsLogTag::DEFAULT, "Session brightness do not change: [%{public}f]", brightness);
3915         return WMError::WM_OK;
3916     }
3917     sceneSession->SetBrightness(brightness);
3918     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3919     return WMError::WM_OK;
3920 }
3921 
HandleActionUpdateOrientation(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3922 WMError SceneSession::HandleActionUpdateOrientation(const sptr<WindowSessionProperty>& property,
3923     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3924 {
3925     sceneSession->SetRequestedOrientation(property->GetRequestedOrientation());
3926     return WMError::WM_OK;
3927 }
3928 
HandleActionUpdatePrivacyMode(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3929 WMError SceneSession::HandleActionUpdatePrivacyMode(const sptr<WindowSessionProperty>& property,
3930     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3931 {
3932     bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
3933     sceneSession->SetPrivacyMode(isPrivacyMode);
3934     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3935     return WMError::WM_OK;
3936 }
3937 
HandleActionUpdateSnapshotSkip(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3938 WMError SceneSession::HandleActionUpdateSnapshotSkip(const sptr<WindowSessionProperty>& property,
3939     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3940 {
3941     sceneSession->SetSnapshotSkip(property->GetSnapshotSkip());
3942     return WMError::WM_OK;
3943 }
3944 
HandleActionUpdateMaximizeState(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3945 WMError SceneSession::HandleActionUpdateMaximizeState(const sptr<WindowSessionProperty>& property,
3946     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3947 {
3948     auto sessionProperty = sceneSession->GetSessionProperty();
3949     if (sessionProperty != nullptr) {
3950         sessionProperty->SetMaximizeMode(property->GetMaximizeMode());
3951         sessionProperty->SetIsLayoutFullScreen(property->IsLayoutFullScreen());
3952     }
3953     return WMError::WM_OK;
3954 }
3955 
HandleActionUpdateOtherProps(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3956 WMError SceneSession::HandleActionUpdateOtherProps(const sptr<WindowSessionProperty>& property,
3957     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3958 {
3959     auto systemBarProperties = property->GetSystemBarProperty();
3960     for (auto iter : systemBarProperties) {
3961         sceneSession->SetSystemBarProperty(iter.first, iter.second);
3962     }
3963     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3964     return WMError::WM_OK;
3965 }
3966 
HandleActionUpdateStatusProps(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3967 WMError SceneSession::HandleActionUpdateStatusProps(const sptr<WindowSessionProperty>& property,
3968     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3969 {
3970     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, property, sceneSession);
3971     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3972     return WMError::WM_OK;
3973 }
3974 
HandleActionUpdateNavigationProps(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3975 WMError SceneSession::HandleActionUpdateNavigationProps(const sptr<WindowSessionProperty>& property,
3976     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3977 {
3978     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, property, sceneSession);
3979     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3980     return WMError::WM_OK;
3981 }
3982 
HandleActionUpdateNavigationIndicatorProps(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3983 WMError SceneSession::HandleActionUpdateNavigationIndicatorProps(const sptr<WindowSessionProperty>& property,
3984     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3985 {
3986     HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, property, sceneSession);
3987     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3988     return WMError::WM_OK;
3989 }
3990 
HandleActionUpdateFlags(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3991 WMError SceneSession::HandleActionUpdateFlags(const sptr<WindowSessionProperty>& property,
3992     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
3993 {
3994     SetWindowFlags(sceneSession, property);
3995     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
3996     return WMError::WM_OK;
3997 }
3998 
HandleActionUpdateMode(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)3999 WMError SceneSession::HandleActionUpdateMode(const sptr<WindowSessionProperty>& property,
4000     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4001 {
4002     auto sessionProperty = sceneSession->GetSessionProperty();
4003     if (sessionProperty != nullptr) {
4004         sessionProperty->SetWindowMode(property->GetWindowMode());
4005     }
4006     sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
4007     return WMError::WM_OK;
4008 }
4009 
HandleActionUpdateAnimationFlag(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4010 WMError SceneSession::HandleActionUpdateAnimationFlag(const sptr<WindowSessionProperty>& property,
4011     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4012 {
4013     auto sessionProperty = sceneSession->GetSessionProperty();
4014     if (sessionProperty != nullptr) {
4015         sessionProperty->SetAnimationFlag(property->GetAnimationFlag());
4016     }
4017     return WMError::WM_OK;
4018 }
4019 
HandleActionUpdateTouchHotArea(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4020 WMError SceneSession::HandleActionUpdateTouchHotArea(const sptr<WindowSessionProperty>& property,
4021     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4022 {
4023     auto sessionProperty = sceneSession->GetSessionProperty();
4024     if (sessionProperty != nullptr) {
4025         std::vector<Rect> touchHotAreas;
4026         property->GetTouchHotAreas(touchHotAreas);
4027         sessionProperty->SetTouchHotAreas(touchHotAreas);
4028     }
4029     return WMError::WM_OK;
4030 }
4031 
HandleActionUpdateDecorEnable(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4032 WMError SceneSession::HandleActionUpdateDecorEnable(const sptr<WindowSessionProperty>& property,
4033     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4034 {
4035     if (property != nullptr && !property->GetSystemCalling()) {
4036         TLOGE(WmsLogTag::DEFAULT, "update decor enable permission denied!");
4037         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4038     }
4039     auto sessionProperty = sceneSession->GetSessionProperty();
4040     if (sessionProperty != nullptr) {
4041         sessionProperty->SetDecorEnable(property->IsDecorEnable());
4042     }
4043     return WMError::WM_OK;
4044 }
4045 
HandleActionUpdateWindowLimits(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4046 WMError SceneSession::HandleActionUpdateWindowLimits(const sptr<WindowSessionProperty>& property,
4047     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4048 {
4049     auto sessionProperty = sceneSession->GetSessionProperty();
4050     if (sessionProperty != nullptr) {
4051         sessionProperty->SetWindowLimits(property->GetWindowLimits());
4052         WindowLimits windowLimits = sessionProperty->GetWindowLimits();
4053         TLOGI(WmsLogTag::WMS_LAYOUT, "UpdateWindowLimits minWidth:%{public}u, minHeight:%{public}u, "
4054             "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", windowLimits.minWidth_,
4055             windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
4056     }
4057     return WMError::WM_OK;
4058 }
4059 
HandleActionUpdateDragenabled(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4060 WMError SceneSession::HandleActionUpdateDragenabled(const sptr<WindowSessionProperty>& property,
4061     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4062 {
4063     auto sessionProperty = sceneSession->GetSessionProperty();
4064     if (sessionProperty != nullptr) {
4065         sessionProperty->SetDragEnabled(property->GetDragEnabled());
4066     }
4067     return WMError::WM_OK;
4068 }
4069 
HandleActionUpdateRaiseenabled(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4070 WMError SceneSession::HandleActionUpdateRaiseenabled(const sptr<WindowSessionProperty>& property,
4071     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4072 {
4073     auto sessionProperty = sceneSession->GetSessionProperty();
4074     if (sessionProperty != nullptr) {
4075         TLOGI(WmsLogTag::WMS_HIERARCHY, "id: %{public}d, raise enabled: %{public}d", GetPersistentId(),
4076             property->GetRaiseEnabled());
4077         sessionProperty->SetRaiseEnabled(property->GetRaiseEnabled());
4078     }
4079     return WMError::WM_OK;
4080 }
4081 
HandleActionUpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4082 WMError SceneSession::HandleActionUpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
4083     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4084 {
4085     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4086         TLOGE(WmsLogTag::DEFAULT, "Update property hideNonSystemFloatingWindows permission denied!");
4087         return WMError::WM_OK;
4088     }
4089     auto currentProperty = sceneSession->GetSessionProperty();
4090     if (currentProperty != nullptr) {
4091         sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
4092         currentProperty->SetHideNonSystemFloatingWindows(property->GetHideNonSystemFloatingWindows());
4093     }
4094     return WMError::WM_OK;
4095 }
4096 
HandleActionUpdateTextfieldAvoidInfo(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4097 WMError SceneSession::HandleActionUpdateTextfieldAvoidInfo(const sptr<WindowSessionProperty>& property,
4098     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4099 {
4100     auto sessionProperty = sceneSession->GetSessionProperty();
4101     if (sessionProperty != nullptr) {
4102         sessionProperty->SetTextFieldPositionY(property->GetTextFieldPositionY());
4103         sessionProperty->SetTextFieldHeight(property->GetTextFieldHeight());
4104     }
4105     return WMError::WM_OK;
4106 }
4107 
HandleActionUpdateWindowMask(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4108 WMError SceneSession::HandleActionUpdateWindowMask(const sptr<WindowSessionProperty>& property,
4109     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4110 {
4111     auto sessionProperty = sceneSession->GetSessionProperty();
4112     if (sessionProperty != nullptr) {
4113         sessionProperty->SetWindowMask(property->GetWindowMask());
4114         sessionProperty->SetIsShaped(property->GetIsShaped());
4115         sceneSession->NotifySessionChangeByActionNotifyManager(sceneSession, property, action);
4116     }
4117     return WMError::WM_OK;
4118 }
4119 
HandleActionUpdateTopmost(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4120 WMError SceneSession::HandleActionUpdateTopmost(const sptr<WindowSessionProperty>& property,
4121     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4122 {
4123     if (!SessionPermission::IsSystemCalling()) {
4124         TLOGE(WmsLogTag::WMS_LAYOUT, "UpdateTopmostProperty permission denied!");
4125         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4126     }
4127 
4128     sceneSession->SetTopmost(property->IsTopmost());
4129     return WMError::WM_OK;
4130 }
4131 
HandleActionUpdateMainWindowTopmost(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4132 WMError SceneSession::HandleActionUpdateMainWindowTopmost(const sptr<WindowSessionProperty>& property,
4133     WSPropertyChangeAction action)
4134 {
4135     SetMainWindowTopmost(property->IsMainWindowTopmost());
4136     return WMError::WM_OK;
4137 }
4138 
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4139 void SceneSession::HandleSpecificSystemBarProperty(WindowType type,
4140     const sptr<WindowSessionProperty>& property, const sptr<SceneSession>& sceneSession)
4141 {
4142     auto systemBarProperties = property->GetSystemBarProperty();
4143     if (auto iter = systemBarProperties.find(type); iter != systemBarProperties.end()) {
4144         if (GetIsDisplayStatusBarTemporarily() && specificCallback_ && specificCallback_->onUpdateAvoidArea_) {
4145             SetIsDisplayStatusBarTemporarily(false);
4146             if (Session::IsScbCoreEnabled()) {
4147                 dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
4148             } else {
4149                 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
4150             }
4151         }
4152         SetSystemBarProperty(iter->first, iter->second);
4153         TLOGD(WmsLogTag::WMS_IMMS, "%{public}d, enable: %{public}d",
4154             static_cast<int32_t>(iter->first), iter->second.enable_);
4155     }
4156 }
4157 
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)4158 void SceneSession::SetWindowFlags(const sptr<SceneSession>& sceneSession,
4159     const sptr<WindowSessionProperty>& property)
4160 {
4161     if (sceneSession == nullptr) {
4162         TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
4163         return;
4164     }
4165     auto sessionProperty = sceneSession->GetSessionProperty();
4166     if (sessionProperty == nullptr) {
4167         TLOGE(WmsLogTag::DEFAULT, "get session property failed");
4168         return;
4169     }
4170     uint32_t flags = property->GetWindowFlags();
4171     uint32_t oldFlags = sessionProperty->GetWindowFlags();
4172     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
4173          (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
4174         !property->GetSystemCalling()) {
4175         TLOGE(WmsLogTag::DEFAULT, "Set window flags permission denied");
4176         return;
4177     }
4178     sessionProperty->SetWindowFlags(flags);
4179     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
4180         sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
4181     }
4182     TLOGI(WmsLogTag::DEFAULT, "flags: %{public}u", flags);
4183 }
4184 
NotifySessionChangeByActionNotifyManager(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)4185 void SceneSession::NotifySessionChangeByActionNotifyManager(const sptr<SceneSession>& sceneSession,
4186     const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)
4187 {
4188     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, action: %{public}d",
4189         GetPersistentId(), action);
4190     if (sessionChangeByActionNotifyManagerFunc_ == nullptr) {
4191         TLOGW(WmsLogTag::DEFAULT, "func is null");
4192         return;
4193     }
4194     sessionChangeByActionNotifyManagerFunc_(sceneSession, property, action);
4195 }
4196 
TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)4197 WSError SceneSession::TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
4198 {
4199     auto task = [weakThis = wptr(this), abilitySessionInfo]() {
4200         auto session = weakThis.promote();
4201         if (!session) {
4202             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
4203             return WSError::WS_ERROR_DESTROYED_OBJECT;
4204         }
4205         if (abilitySessionInfo == nullptr) {
4206             TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
4207             return WSError::WS_ERROR_NULLPTR;
4208         }
4209         if (session->isTerminating_) {
4210             TLOGE(WmsLogTag::WMS_LIFE, "TerminateSession: is terminating, return!");
4211             return WSError::WS_ERROR_INVALID_OPERATION;
4212         }
4213         session->isTerminating_ = true;
4214         SessionInfo info;
4215         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
4216         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
4217         info.callerToken_ = abilitySessionInfo->callerToken;
4218         info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
4219         {
4220             std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
4221             session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
4222             session->sessionInfo_.resultCode = abilitySessionInfo->resultCode;
4223         }
4224         if (session->terminateSessionFunc_) {
4225             session->terminateSessionFunc_(info);
4226         }
4227         return WSError::WS_OK;
4228     };
4229     PostLifeCycleTask(task, "TerminateSession", LifeCycleTaskType::STOP);
4230     return WSError::WS_OK;
4231 }
4232 
NotifySessionExceptionInner(const sptr<AAFwk::SessionInfo> abilitySessionInfo,bool needRemoveSession,bool isFromClient,bool startFail)4233 WSError SceneSession::NotifySessionExceptionInner(const sptr<AAFwk::SessionInfo> abilitySessionInfo,
4234     bool needRemoveSession, bool isFromClient, bool startFail)
4235 {
4236     auto task = [weakThis = wptr(this), abilitySessionInfo, needRemoveSession, isFromClient, startFail]() {
4237         auto session = weakThis.promote();
4238         if (!session) {
4239             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
4240             return WSError::WS_ERROR_DESTROYED_OBJECT;
4241         }
4242         if (abilitySessionInfo == nullptr) {
4243             TLOGE(WmsLogTag::WMS_LIFE, "abilitySessionInfo is null");
4244             return WSError::WS_ERROR_NULLPTR;
4245         }
4246         if (SessionHelper::IsMainWindow(session->GetWindowType()) && isFromClient &&
4247             !session->clientIdentityToken_.empty() &&
4248             session->clientIdentityToken_ != abilitySessionInfo->identityToken) {
4249             TLOGE(WmsLogTag::WMS_LIFE, "client exception not matched: %{public}s, %{public}s",
4250                 session->clientIdentityToken_.c_str(), abilitySessionInfo->identityToken.c_str());
4251             return WSError::WS_ERROR_INVALID_PARAM;
4252         }
4253         if (session->isTerminating_) {
4254             TLOGE(WmsLogTag::WMS_LIFE, "NotifySessionExceptionInner: is terminating, return!");
4255             return WSError::WS_ERROR_INVALID_OPERATION;
4256         }
4257         session->isTerminating_ = true;
4258         SessionInfo info;
4259         info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
4260         info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
4261         info.callerToken_ = abilitySessionInfo->callerToken;
4262         info.errorCode = abilitySessionInfo->errorCode;
4263         info.errorReason = abilitySessionInfo->errorReason;
4264         info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
4265         {
4266             std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
4267             session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
4268             session->sessionInfo_.errorCode = abilitySessionInfo->errorCode;
4269             session->sessionInfo_.errorReason = abilitySessionInfo->errorReason;
4270         }
4271         if (session->sessionExceptionFunc_) {
4272             session->sessionExceptionFunc_(info, needRemoveSession, false);
4273         }
4274         if (session->jsSceneSessionExceptionFunc_) {
4275             session->jsSceneSessionExceptionFunc_(info, needRemoveSession, startFail);
4276         }
4277         return WSError::WS_OK;
4278     };
4279     PostLifeCycleTask(task, "NotifySessionExceptionInner", LifeCycleTaskType::STOP);
4280     return WSError::WS_OK;
4281 }
4282 
NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo,bool needRemoveSession)4283 WSError SceneSession::NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool needRemoveSession)
4284 {
4285     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
4286         TLOGE(WmsLogTag::WMS_LIFE, "permission failed.");
4287         return WSError::WS_ERROR_INVALID_PERMISSION;
4288     }
4289     return NotifySessionExceptionInner(abilitySessionInfo, needRemoveSession, true);
4290 }
4291 
GetLastSafeRect() const4292 WSRect SceneSession::GetLastSafeRect() const
4293 {
4294     return lastSafeRect;
4295 }
4296 
SetLastSafeRect(WSRect rect)4297 void SceneSession::SetLastSafeRect(WSRect rect)
4298 {
4299     lastSafeRect.posX_ = rect.posX_;
4300     lastSafeRect.posY_ = rect.posY_;
4301     lastSafeRect.width_ = rect.width_;
4302     lastSafeRect.height_ = rect.height_;
4303     return;
4304 }
4305 
GetOriPosYBeforeRaisedByKeyboard() const4306 int32_t SceneSession::GetOriPosYBeforeRaisedByKeyboard() const
4307 {
4308     return oriPosYBeforeRaisedByKeyboard_;
4309 }
4310 
SetOriPosYBeforeRaisedByKeyboard(int32_t posY)4311 void SceneSession::SetOriPosYBeforeRaisedByKeyboard(int32_t posY)
4312 {
4313     oriPosYBeforeRaisedByKeyboard_ = posY;
4314 }
4315 
AddSubSession(const sptr<SceneSession> & subSession)4316 bool SceneSession::AddSubSession(const sptr<SceneSession>& subSession)
4317 {
4318     if (subSession == nullptr) {
4319         TLOGE(WmsLogTag::WMS_SUB, "subSession is nullptr");
4320         return false;
4321     }
4322     const auto& persistentId = subSession->GetPersistentId();
4323     auto iter = std::find_if(subSession_.begin(), subSession_.end(),
4324         [persistentId](sptr<SceneSession> session) {
4325             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
4326             return res;
4327         });
4328     if (iter != subSession_.end()) {
4329         TLOGE(WmsLogTag::WMS_SUB, "Sub ession is already exists, id: %{public}d, parentId: %{public}d",
4330             subSession->GetPersistentId(), GetPersistentId());
4331         return false;
4332     }
4333     TLOGD(WmsLogTag::WMS_SUB, "Success, id: %{public}d, parentId: %{public}d",
4334         subSession->GetPersistentId(), GetPersistentId());
4335     subSession_.push_back(subSession);
4336     return true;
4337 }
4338 
RemoveSubSession(int32_t persistentId)4339 bool SceneSession::RemoveSubSession(int32_t persistentId)
4340 {
4341     auto iter = std::find_if(subSession_.begin(), subSession_.end(),
4342         [persistentId](sptr<SceneSession> session) {
4343             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
4344             return res;
4345         });
4346     if (iter == subSession_.end()) {
4347         TLOGE(WmsLogTag::WMS_SUB, "Could not find subsession, id: %{public}d, parentId: %{public}d",
4348             persistentId, GetPersistentId());
4349         return false;
4350     }
4351     TLOGD(WmsLogTag::WMS_SUB, "Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
4352     subSession_.erase(iter);
4353     return true;
4354 }
4355 
AddToastSession(const sptr<SceneSession> & toastSession)4356 bool SceneSession::AddToastSession(const sptr<SceneSession>& toastSession)
4357 {
4358     if (toastSession == nullptr) {
4359         TLOGE(WmsLogTag::WMS_TOAST, "toastSession is nullptr");
4360         return false;
4361     }
4362     const auto& persistentId = toastSession->GetPersistentId();
4363     auto iter = std::find_if(toastSession_.begin(), toastSession_.end(),
4364         [persistentId](sptr<SceneSession> session) {
4365             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
4366             return res;
4367         });
4368     if (iter != toastSession_.end()) {
4369         TLOGE(WmsLogTag::WMS_TOAST, "Toast ession is already exists, id: %{public}d, parentId: %{public}d",
4370             toastSession->GetPersistentId(), GetPersistentId());
4371         return false;
4372     }
4373     TLOGD(WmsLogTag::WMS_TOAST, "Success, id: %{public}d, parentId: %{public}d",
4374         toastSession->GetPersistentId(), GetPersistentId());
4375     toastSession_.push_back(toastSession);
4376     return true;
4377 }
4378 
RemoveToastSession(int32_t persistentId)4379 bool SceneSession::RemoveToastSession(int32_t persistentId)
4380 {
4381     auto iter = std::find_if(toastSession_.begin(), toastSession_.end(),
4382         [persistentId](sptr<SceneSession> session) {
4383             bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
4384             return res;
4385         });
4386     if (iter == toastSession_.end()) {
4387         TLOGE(WmsLogTag::WMS_TOAST, "Could not find toastSession, id: %{public}d, parentId: %{public}d",
4388             persistentId, GetPersistentId());
4389         return false;
4390     }
4391     TLOGD(WmsLogTag::WMS_TOAST, "Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
4392     toastSession_.erase(iter);
4393     return true;
4394 }
4395 
NotifyPiPWindowPrepareClose()4396 void SceneSession::NotifyPiPWindowPrepareClose()
4397 {
4398     TLOGD(WmsLogTag::WMS_PIP, "NotifyPiPWindowPrepareClose");
4399     int32_t callingPid = IPCSkeleton::GetCallingPid();
4400     auto task = [weakThis = wptr(this), callingPid]() {
4401         auto session = weakThis.promote();
4402         if (!session) {
4403             TLOGE(WmsLogTag::WMS_PIP, "session is null");
4404             return;
4405         }
4406         if (callingPid != session->GetCallingPid()) {
4407             TLOGW(WmsLogTag::WMS_PIP, "permission denied, not call by the same process");
4408             return;
4409         }
4410         if (session->onPrepareClosePiPSession_) {
4411             session->onPrepareClosePiPSession_();
4412         }
4413         TLOGD(WmsLogTag::WMS_PIP, "NotifyPiPWindowPrepareClose, id: %{public}d", session->GetPersistentId());
4414         return;
4415     };
4416     PostTask(task, "NotifyPiPWindowPrepareClose");
4417 }
4418 
SetLandscapeMultiWindow(bool isLandscapeMultiWindow)4419 WSError SceneSession::SetLandscapeMultiWindow(bool isLandscapeMultiWindow)
4420 {
4421     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "NotifySetLandscapeMultiWindow");
4422     int32_t callingPid = IPCSkeleton::GetCallingPid();
4423     auto task = [weakThis = wptr(this), isLandscapeMultiWindow, callingPid]() {
4424         auto session = weakThis.promote();
4425         if (!session) {
4426             TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "session is null");
4427             return WSError::WS_ERROR_DESTROYED_OBJECT;
4428         }
4429         if (callingPid != session->GetCallingPid()) {
4430             TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "premission denied, not call by the same process");
4431             return WSError::WS_ERROR_INVALID_PERMISSION;
4432         }
4433         if (session->sessionChangeCallback_ &&
4434             session->sessionChangeCallback_->onSetLandscapeMultiWindowFunc_) {
4435             session->sessionChangeCallback_->onSetLandscapeMultiWindowFunc_(
4436                 isLandscapeMultiWindow);
4437         }
4438         TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "NotifySetLandscapeMultiWindow, id: %{public}d,"
4439             "isLandscapeMultiWindow: %{public}u", session->GetPersistentId(), isLandscapeMultiWindow);
4440         return WSError::WS_OK;
4441     };
4442     PostTask(task, "NotifySetLandscapeMultiWindow");
4443     return WSError::WS_OK;
4444 }
4445 
GetSubSession() const4446 std::vector<sptr<SceneSession>> SceneSession::GetSubSession() const
4447 {
4448     return subSession_;
4449 }
4450 
GetToastSession() const4451 std::vector<sptr<SceneSession>> SceneSession::GetToastSession() const
4452 {
4453     return toastSession_;
4454 }
4455 
GetSessionTargetRect() const4456 WSRect SceneSession::GetSessionTargetRect() const
4457 {
4458     WSRect rect;
4459     if (moveDragController_) {
4460         rect = moveDragController_->GetTargetRect();
4461     } else {
4462         WLOGFI("moveDragController_ is null");
4463     }
4464     return rect;
4465 }
4466 
SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc & func)4467 void SceneSession::SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc& func)
4468 {
4469     if (moveDragController_) {
4470         moveDragController_->SetWindowDragHotAreaFunc(func);
4471     }
4472 }
4473 
NotifySessionForeground(uint32_t reason,bool withAnimation)4474 void SceneSession::NotifySessionForeground(uint32_t reason, bool withAnimation)
4475 {
4476     if (!sessionStage_) {
4477         return;
4478     }
4479     return sessionStage_->NotifySessionForeground(reason, withAnimation);
4480 }
4481 
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)4482 void SceneSession::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
4483 {
4484     if (!sessionStage_) {
4485         return;
4486     }
4487     return sessionStage_->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
4488 }
4489 
NotifySessionFullScreen(bool fullScreen)4490 void SceneSession::NotifySessionFullScreen(bool fullScreen)
4491 {
4492     if (!sessionStage_) {
4493         TLOGE(WmsLogTag::WMS_LAYOUT, "sessionStage is null");
4494         return;
4495     }
4496     sessionStage_->NotifySessionFullScreen(fullScreen);
4497 }
4498 
UpdatePiPRect(const Rect & rect,SizeChangeReason reason)4499 WSError SceneSession::UpdatePiPRect(const Rect& rect, SizeChangeReason reason)
4500 {
4501     if (!WindowHelper::IsPipWindow(GetWindowType())) {
4502         return WSError::WS_DO_NOTHING;
4503     }
4504     int32_t callingPid = IPCSkeleton::GetCallingPid();
4505     auto task = [weakThis = wptr(this), rect, reason, callingPid]() {
4506         auto session = weakThis.promote();
4507         if (!session || session->isTerminating_) {
4508             TLOGE(WmsLogTag::WMS_PIP, "SceneSession::UpdatePiPRect session is null or is terminating");
4509             return WSError::WS_ERROR_INVALID_OPERATION;
4510         }
4511         if (callingPid != session->GetCallingPid()) {
4512             TLOGW(WmsLogTag::WMS_PIP, "permission denied, not call by the same process");
4513             return WSError::WS_ERROR_INVALID_PERMISSION;
4514         }
4515         WSRect wsRect = SessionHelper::TransferToWSRect(rect);
4516         if (reason == SizeChangeReason::PIP_START) {
4517             session->SetSessionRequestRect(wsRect);
4518         }
4519         TLOGI(WmsLogTag::WMS_PIP, "rect:%{public}s, reason: %{public}u", wsRect.ToString().c_str(),
4520             static_cast<uint32_t>(reason));
4521         session->NotifySessionRectChange(wsRect, reason);
4522         return WSError::WS_OK;
4523     };
4524     if (mainHandler_ != nullptr) {
4525         mainHandler_->PostTask(std::move(task), "wms:UpdatePiPRect", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
4526     } else {
4527         PostTask(task, "UpdatePiPRect");
4528     }
4529     return WSError::WS_OK;
4530 }
4531 
UpdatePiPControlStatus(WsPiPControlType controlType,WsPiPControlStatus status)4532 WSError SceneSession::UpdatePiPControlStatus(WsPiPControlType controlType, WsPiPControlStatus status)
4533 {
4534     TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, status:%{public}d", controlType, status);
4535     if (!WindowHelper::IsPipWindow(GetWindowType())) {
4536         return WSError::WS_DO_NOTHING;
4537     }
4538     int32_t callingPid = IPCSkeleton::GetCallingPid();
4539     auto task = [weakThis = wptr(this), controlType, status, callingPid]() {
4540         auto session = weakThis.promote();
4541         if (!session || session->isTerminating_) {
4542             TLOGE(WmsLogTag::WMS_PIP, "session is null or is terminating");
4543             return WSError::WS_ERROR_INVALID_OPERATION;
4544         }
4545         if (callingPid != session->GetCallingPid()) {
4546             TLOGW(WmsLogTag::WMS_PIP, "permission denied, not call by the same process");
4547             return WSError::WS_ERROR_INVALID_PERMISSION;
4548         }
4549         if (session->sessionPiPControlStatusChangeFunc_) {
4550             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::UpdatePiPControlStatus");
4551             session->sessionPiPControlStatusChangeFunc_(controlType, status);
4552         }
4553         return WSError::WS_OK;
4554     };
4555     PostTask(task, "UpdatePiPControlStatus");
4556     return WSError::WS_OK;
4557 }
4558 
SetAutoStartPiP(bool isAutoStart,uint32_t priority)4559 WSError SceneSession::SetAutoStartPiP(bool isAutoStart, uint32_t priority)
4560 {
4561     TLOGI(WmsLogTag::WMS_PIP, "isAutoStart:%{public}u priority:%{public}u", isAutoStart, priority);
4562     auto task = [weakThis = wptr(this), isAutoStart, priority] {
4563         auto session = weakThis.promote();
4564         if (!session || session->isTerminating_) {
4565             TLOGNE(WmsLogTag::WMS_PIP, "session is null or is terminating");
4566             return;
4567         }
4568         if (session->autoStartPiPStatusChangeFunc_) {
4569             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetAutoStartPiP");
4570             session->autoStartPiPStatusChangeFunc_(isAutoStart, priority);
4571         }
4572     };
4573     PostTask(task, __func__);
4574     return WSError::WS_OK;
4575 }
4576 
SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)4577 void SceneSession::SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)
4578 {
4579     NotifySystemSessionPointerEventFunc systemSessionPointerEventFunc = nullptr;
4580     {
4581         std::lock_guard<std::mutex> lock(pointerEventMutex_);
4582         systemSessionPointerEventFunc = systemSessionPointerEventFunc_;
4583     }
4584     if (systemSessionPointerEventFunc != nullptr) {
4585         systemSessionPointerEventFunc(pointerEvent);
4586     } else {
4587         TLOGE(WmsLogTag::WMS_EVENT, "PointerEventFunc_ nullptr, id:%{public}d", pointerEvent->GetId());
4588         pointerEvent->MarkProcessed();
4589     }
4590 }
4591 
SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent,bool isPreImeEvent)4592 bool SceneSession::SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent, bool isPreImeEvent)
4593 {
4594     NotifySystemSessionKeyEventFunc systemSessionKeyEventFunc = nullptr;
4595     {
4596         std::shared_lock<std::shared_mutex> lock(keyEventMutex_);
4597         systemSessionKeyEventFunc = systemSessionKeyEventFunc_;
4598     }
4599     if (systemSessionKeyEventFunc != nullptr) {
4600         return systemSessionKeyEventFunc(keyEvent, isPreImeEvent);
4601     } else {
4602         TLOGE(WmsLogTag::WMS_EVENT, "id:%{public}d systemSessionKeyEventFunc_ is null", keyEvent->GetId());
4603         keyEvent->MarkProcessed();
4604     }
4605     return false;
4606 }
4607 
UpdateSizeChangeReason(SizeChangeReason reason)4608 WSError SceneSession::UpdateSizeChangeReason(SizeChangeReason reason)
4609 {
4610     auto task = [weakThis = wptr(this), reason]() {
4611         auto session = weakThis.promote();
4612         if (!session) {
4613             WLOGFE("session is null");
4614             return WSError::WS_ERROR_DESTROYED_OBJECT;
4615         }
4616         session->reason_ = reason;
4617         if (reason != SizeChangeReason::UNDEFINED) {
4618             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
4619                 "SceneSession::UpdateSizeChangeReason%d reason:%d",
4620                 session->GetPersistentId(), static_cast<uint32_t>(reason));
4621             TLOGD(WmsLogTag::WMS_LAYOUT, "UpdateSizeChangeReason Id: %{public}d, reason: %{public}d",
4622                 session->GetPersistentId(), reason);
4623         }
4624         return WSError::WS_OK;
4625     };
4626     PostTask(task, "UpdateSizeChangeReason");
4627     return WSError::WS_OK;
4628 }
4629 
ResetSizeChangeReasonIfDirty()4630 void SceneSession::ResetSizeChangeReasonIfDirty()
4631 {
4632     if (IsDirtyWindow() && GetSizeChangeReason() != SizeChangeReason::DRAG) {
4633         UpdateSizeChangeReason(SizeChangeReason::UNDEFINED);
4634     }
4635 }
4636 
IsDirtyWindow()4637 bool SceneSession::IsDirtyWindow()
4638 {
4639     return dirtyFlags_ & static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
4640 }
4641 
NotifyUILostFocus()4642 void SceneSession::NotifyUILostFocus()
4643 {
4644     if (moveDragController_) {
4645         moveDragController_->OnLostFocus();
4646     }
4647     Session::NotifyUILostFocus();
4648 }
4649 
SetScale(float scaleX,float scaleY,float pivotX,float pivotY)4650 void SceneSession::SetScale(float scaleX, float scaleY, float pivotX, float pivotY)
4651 {
4652     if (scaleX_ != scaleX || scaleY_ != scaleY || pivotX_ != pivotX || pivotY_ != pivotY) {
4653         Session::SetScale(scaleX, scaleY, pivotX, pivotY);
4654         if (specificCallback_ != nullptr) {
4655             specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
4656         }
4657         if (sessionStage_ != nullptr) {
4658             Transform transform;
4659             transform.scaleX_ = scaleX;
4660             transform.scaleY_ = scaleY;
4661             transform.pivotX_ = pivotX;
4662             transform.pivotY_ = pivotY;
4663             sessionStage_->NotifyTransformChange(transform);
4664         } else {
4665             WLOGFE("sessionStage_ is nullptr");
4666         }
4667     }
4668 }
4669 
RequestHideKeyboard(bool isAppColdStart)4670 void SceneSession::RequestHideKeyboard(bool isAppColdStart)
4671 {
4672 #ifdef IMF_ENABLE
4673     auto task = [weakThis = wptr(this), isAppColdStart]() {
4674         auto session = weakThis.promote();
4675         if (!session) {
4676             TLOGE(WmsLogTag::WMS_KEYBOARD, "Session is null, notify inputMethod framework hide keyboard failed!");
4677             return;
4678         }
4679         TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify inputMethod framework hide keyboard start, id: %{public}d,"
4680             "isAppColdStart: %{public}d", session->GetPersistentId(), isAppColdStart);
4681         if (MiscServices::InputMethodController::GetInstance()) {
4682             MiscServices::InputMethodController::GetInstance()->RequestHideInput();
4683             TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify inputMethod framework hide keyboard end, id: %{public}d",
4684                 session->GetPersistentId());
4685         }
4686     };
4687     PostExportTask(task, "RequestHideKeyboard");
4688 #endif
4689 }
4690 
IsStartMoving()4691 bool SceneSession::IsStartMoving()
4692 {
4693     return isStartMoving_.load();
4694 }
4695 
SetIsStartMoving(bool startMoving)4696 void SceneSession::SetIsStartMoving(bool startMoving)
4697 {
4698     isStartMoving_.store(startMoving);
4699 }
4700 
SetShouldHideNonSecureWindows(bool shouldHide)4701 void SceneSession::SetShouldHideNonSecureWindows(bool shouldHide)
4702 {
4703     shouldHideNonSecureWindows_.store(shouldHide);
4704 }
4705 
CalculateCombinedExtWindowFlags()4706 void SceneSession::CalculateCombinedExtWindowFlags()
4707 {
4708     // Only correct when each flag is true when active, and once a uiextension is active, the host is active
4709     std::unique_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
4710     combinedExtWindowFlags_.bitData = 0;
4711     for (const auto& iter: extWindowFlagsMap_) {
4712         combinedExtWindowFlags_.bitData |= iter.second.bitData;
4713     }
4714 }
4715 
UpdateExtWindowFlags(int32_t extPersistentId,const ExtensionWindowFlags & extWindowFlags,const ExtensionWindowFlags & extWindowActions)4716 void SceneSession::UpdateExtWindowFlags(int32_t extPersistentId, const ExtensionWindowFlags& extWindowFlags,
4717     const ExtensionWindowFlags& extWindowActions)
4718 {
4719     auto iter = extWindowFlagsMap_.find(extPersistentId);
4720     // Each flag is false when inactive, 0 means all flags are inactive
4721     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
4722     ExtensionWindowFlags newFlags((extWindowFlags.bitData & extWindowActions.bitData) |
4723         (oldFlags.bitData & ~extWindowActions.bitData));
4724     if (newFlags.bitData == 0) {
4725         extWindowFlagsMap_.erase(extPersistentId);
4726     } else {
4727         extWindowFlagsMap_[extPersistentId] = newFlags;
4728     }
4729     CalculateCombinedExtWindowFlags();
4730 }
4731 
GetCombinedExtWindowFlags()4732 ExtensionWindowFlags SceneSession::GetCombinedExtWindowFlags()
4733 {
4734     std::shared_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
4735     auto combinedExtWindowFlags = combinedExtWindowFlags_;
4736     combinedExtWindowFlags.hideNonSecureWindowsFlag = IsSessionForeground() &&
4737         (combinedExtWindowFlags.hideNonSecureWindowsFlag || shouldHideNonSecureWindows_.load());
4738     return combinedExtWindowFlags;
4739 }
4740 
NotifyDisplayMove(DisplayId from,DisplayId to)4741 void SceneSession::NotifyDisplayMove(DisplayId from, DisplayId to)
4742 {
4743     if (sessionStage_) {
4744         sessionStage_->NotifyDisplayMove(from, to);
4745     } else {
4746         WLOGFE("Notify display move failed, sessionStage is null");
4747     }
4748 }
4749 
RemoveExtWindowFlags(int32_t extPersistentId)4750 void SceneSession::RemoveExtWindowFlags(int32_t extPersistentId)
4751 {
4752     extWindowFlagsMap_.erase(extPersistentId);
4753     CalculateCombinedExtWindowFlags();
4754 }
4755 
ClearExtWindowFlags()4756 void SceneSession::ClearExtWindowFlags()
4757 {
4758     std::unique_lock<std::shared_mutex> lock(combinedExtWindowFlagsMutex_);
4759     extWindowFlagsMap_.clear();
4760     combinedExtWindowFlags_.bitData = 0;
4761 }
4762 
UpdateRectChangeListenerRegistered(bool isRegister)4763 WSError SceneSession::UpdateRectChangeListenerRegistered(bool isRegister)
4764 {
4765     auto task = [weakThis = wptr(this), isRegister]() {
4766         auto session = weakThis.promote();
4767         if (!session) {
4768             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
4769             return WSError::WS_ERROR_DESTROYED_OBJECT;
4770         }
4771         session->rectChangeListenerRegistered_ = isRegister;
4772         return WSError::WS_OK;
4773     };
4774     PostTask(task, "UpdateRectChangeListenerRegistered");
4775     return WSError::WS_OK;
4776 }
4777 
SetIsLayoutFullScreen(bool isLayoutFullScreen)4778 void SceneSession::SetIsLayoutFullScreen(bool isLayoutFullScreen)
4779 {
4780     isLayoutFullScreen_ = isLayoutFullScreen;
4781 }
4782 
IsLayoutFullScreen() const4783 bool SceneSession::IsLayoutFullScreen() const
4784 {
4785     return isLayoutFullScreen_;
4786 }
4787 
OnLayoutFullScreenChange(bool isLayoutFullScreen)4788 WSError SceneSession::OnLayoutFullScreenChange(bool isLayoutFullScreen)
4789 {
4790     auto task = [weakThis = wptr(this), isLayoutFullScreen]() {
4791         auto session = weakThis.promote();
4792         if (!session) {
4793             TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
4794             return WSError::WS_ERROR_DESTROYED_OBJECT;
4795         }
4796         TLOGI(WmsLogTag::WMS_LAYOUT, "OnLayoutFullScreenChange, isLayoutFullScreen: %{public}d",
4797             isLayoutFullScreen);
4798         if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onLayoutFullScreenChangeFunc_) {
4799             session->SetIsLayoutFullScreen(isLayoutFullScreen);
4800             session->sessionChangeCallback_->onLayoutFullScreenChangeFunc_(isLayoutFullScreen);
4801         }
4802         return WSError::WS_OK;
4803     };
4804     PostTask(task, "OnLayoutFullScreenChange");
4805     return WSError::WS_OK;
4806 }
4807 
OnDefaultDensityEnabled(bool isDefaultDensityEnabled)4808 WSError SceneSession::OnDefaultDensityEnabled(bool isDefaultDensityEnabled)
4809 {
4810     auto task = [weakThis = wptr(this), isDefaultDensityEnabled] {
4811         auto session = weakThis.promote();
4812         if (!session) {
4813             TLOGNE(WmsLogTag::WMS_LAYOUT, "OnDefaultDensityEnabled session is null");
4814             return;
4815         }
4816         TLOGNI(WmsLogTag::WMS_LAYOUT, "OnDefaultDensityEnabled, isDefaultDensityEnabled: %{public}d",
4817             isDefaultDensityEnabled);
4818         if (session->onDefaultDensityEnabledFunc_) {
4819             session->onDefaultDensityEnabledFunc_(isDefaultDensityEnabled);
4820         }
4821     };
4822     PostTask(task, "OnDefaultDensityEnabled");
4823     return WSError::WS_OK;
4824 }
4825 
SetForceHideState(ForceHideState forceHideState)4826 void SceneSession::SetForceHideState(ForceHideState forceHideState)
4827 {
4828     forceHideState_ = forceHideState;
4829 }
4830 
GetForceHideState() const4831 ForceHideState SceneSession::GetForceHideState() const
4832 {
4833     return forceHideState_;
4834 }
4835 
SetIsDisplayStatusBarTemporarily(bool isTemporary)4836 void SceneSession::SetIsDisplayStatusBarTemporarily(bool isTemporary)
4837 {
4838     isDisplayStatusBarTemporarily_.store(isTemporary);
4839 }
4840 
GetIsDisplayStatusBarTemporarily() const4841 bool SceneSession::GetIsDisplayStatusBarTemporarily() const
4842 {
4843     return isDisplayStatusBarTemporarily_.load();
4844 }
4845 
RetrieveStatusBarDefaultVisibility()4846 void SceneSession::RetrieveStatusBarDefaultVisibility()
4847 {
4848     if (specificCallback_ && specificCallback_->onGetStatusBarDefaultVisibilityByDisplayId_) {
4849         isStatusBarVisible_ = specificCallback_->onGetStatusBarDefaultVisibilityByDisplayId_(
4850             GetSessionProperty()->GetDisplayId());
4851     }
4852 }
4853 
IsDeviceWakeupByApplication() const4854 bool SceneSession::IsDeviceWakeupByApplication() const
4855 {
4856     return isDeviceWakeupByApplication_.load();
4857 }
4858 
SetIsLastFrameLayoutFinishedFunc(IsLastFrameLayoutFinishedFunc && func)4859 void SceneSession::SetIsLastFrameLayoutFinishedFunc(IsLastFrameLayoutFinishedFunc&& func)
4860 {
4861     isLastFrameLayoutFinishedFunc_ = std::move(func);
4862 }
4863 
SetStartingWindowExitAnimationFlag(bool enable)4864 void SceneSession::SetStartingWindowExitAnimationFlag(bool enable)
4865 {
4866     TLOGI(WmsLogTag::DEFAULT, "SetStartingWindowExitAnimationFlag %{public}d", enable);
4867     needStartingWindowExitAnimation_.store(enable);
4868 }
4869 
NeedStartingWindowExitAnimation() const4870 bool SceneSession::NeedStartingWindowExitAnimation() const
4871 {
4872     return needStartingWindowExitAnimation_.load();
4873 }
4874 
IsSystemSpecificSession() const4875 bool SceneSession::IsSystemSpecificSession() const
4876 {
4877     return isSystemSpecificSession_;
4878 }
4879 
SetIsSystemSpecificSession(bool isSystemSpecificSession)4880 void SceneSession::SetIsSystemSpecificSession(bool isSystemSpecificSession)
4881 {
4882     isSystemSpecificSession_ = isSystemSpecificSession;
4883 }
4884 
SetTemporarilyShowWhenLocked(bool isTemporarilyShowWhenLocked)4885 void SceneSession::SetTemporarilyShowWhenLocked(bool isTemporarilyShowWhenLocked)
4886 {
4887     if (isTemporarilyShowWhenLocked_.load() == isTemporarilyShowWhenLocked) {
4888         return;
4889     }
4890     isTemporarilyShowWhenLocked_.store(isTemporarilyShowWhenLocked);
4891     TLOGI(WmsLogTag::WMS_SCB, "SetTemporarilyShowWhenLocked successfully, target:%{public}u",
4892         isTemporarilyShowWhenLocked);
4893 }
4894 
IsTemporarilyShowWhenLocked() const4895 bool SceneSession::IsTemporarilyShowWhenLocked() const
4896 {
4897     return isTemporarilyShowWhenLocked_.load();
4898 }
4899 
SetSkipDraw(bool skip)4900 void SceneSession::SetSkipDraw(bool skip)
4901 {
4902     if (!surfaceNode_) {
4903         WLOGFE("surfaceNode_ is null");
4904         return;
4905     }
4906     auto rsTransaction = RSTransactionProxy::GetInstance();
4907     if (rsTransaction != nullptr) {
4908         rsTransaction->Begin();
4909     }
4910     surfaceNode_->SetSkipDraw(skip);
4911     auto leashWinSurfaceNode = GetLeashWinSurfaceNode();
4912     if (leashWinSurfaceNode != nullptr) {
4913         leashWinSurfaceNode->SetSkipDraw(skip);
4914     }
4915     if (rsTransaction != nullptr) {
4916         rsTransaction->Commit();
4917     }
4918 }
4919 
SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)4920 void SceneSession::SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)
4921 {
4922     TLOGW(WmsLogTag::WMS_SCB, "in sceneSession, do nothing");
4923     return;
4924 }
4925 
SetUniqueDensityDpi(bool useUnique,float dpi)4926 WMError SceneSession::SetUniqueDensityDpi(bool useUnique, float dpi)
4927 {
4928     TLOGI(WmsLogTag::DEFAULT, "SceneSession set unique dpi: id = %{public}d, dpi = %{public}f",
4929         GetPersistentId(), dpi);
4930     if (useUnique && (dpi > DOT_PER_INCH_MAXIMUM_VALUE || dpi < DOT_PER_INCH_MINIMUM_VALUE)) {
4931         TLOGE(WmsLogTag::DEFAULT, "Invalid input dpi value, valid input range for DPI is %{public}u ~ %{public}u",
4932             DOT_PER_INCH_MINIMUM_VALUE, DOT_PER_INCH_MAXIMUM_VALUE);
4933         return WMError::WM_ERROR_INVALID_PARAM;
4934     }
4935     float density = static_cast<float>(dpi) / 160; // 160 is the coefficient between density and dpi;
4936     if (!IsSessionValid()) {
4937         return WMError::WM_ERROR_INVALID_SESSION;
4938     }
4939     if (!sessionStage_) {
4940         TLOGE(WmsLogTag::DEFAULT, "sessionStage_ is nullptr");
4941         return WMError::WM_ERROR_NULLPTR;
4942     }
4943     sessionStage_->SetUniqueVirtualPixelRatio(useUnique, density);
4944     return WMError::WM_OK;
4945 }
4946 
SetSystemWindowEnableDrag(bool enableDrag)4947 WMError SceneSession::SetSystemWindowEnableDrag(bool enableDrag)
4948 {
4949     if (!SessionPermission::IsSystemCalling()) {
4950         TLOGE(WmsLogTag::WMS_LAYOUT, "id:%{public}d, permission denied!", GetPersistentId());
4951         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4952     }
4953 
4954     if (!WindowHelper::IsSystemWindow(GetWindowType())) {
4955         TLOGE(WmsLogTag::WMS_LAYOUT, "id:%{public}d, this is not system window", GetPersistentId());
4956         return WMError::WM_ERROR_INVALID_CALLING;
4957     }
4958 
4959     const char* const funcName = __func__;
4960     PostTask([weakThis = wptr(this), enableDrag, funcName] {
4961         auto session = weakThis.promote();
4962         if (!session) {
4963             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: session is null", funcName);
4964             return;
4965         }
4966         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}d, enableDrag:%{public}d",
4967             funcName, session->GetPersistentId(), enableDrag);
4968         session->GetSessionProperty()->SetDragEnabled(enableDrag);
4969         session->NotifySessionInfoChange();
4970     }, funcName);
4971     return WMError::WM_OK;
4972 }
4973 
HandleActionUpdateWindowModeSupportType(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession,WSPropertyChangeAction action)4974 WMError SceneSession::HandleActionUpdateWindowModeSupportType(const sptr<WindowSessionProperty>& property,
4975     const sptr<SceneSession>& sceneSession, WSPropertyChangeAction action)
4976 {
4977     if (!property->GetSystemCalling()) {
4978         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
4979         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4980     }
4981 
4982     auto sessionProperty = sceneSession->GetSessionProperty();
4983     if (sessionProperty != nullptr) {
4984         sessionProperty->SetWindowModeSupportType(property->GetWindowModeSupportType());
4985     }
4986     return WMError::WM_OK;
4987 }
4988 
RegisterForceSplitListener(const NotifyForceSplitFunc & func)4989 void SceneSession::RegisterForceSplitListener(const NotifyForceSplitFunc& func)
4990 {
4991     forceSplitFunc_ = func;
4992 }
4993 
RegisterRequestedOrientationChangeCallback(NotifyReqOrientationChangeFunc && callback)4994 void SceneSession::RegisterRequestedOrientationChangeCallback(NotifyReqOrientationChangeFunc&& callback)
4995 {
4996     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
4997         auto session = weakThis.promote();
4998         if (!session) {
4999             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
5000             return;
5001         }
5002         session->onRequestedOrientationChange_ = std::move(callback);
5003     };
5004     PostTask(task, __func__);
5005 }
5006 
RegisterIsCustomAnimationPlayingCallback(NotifyIsCustomAnimationPlayingCallback && callback)5007 void SceneSession::RegisterIsCustomAnimationPlayingCallback(NotifyIsCustomAnimationPlayingCallback&& callback)
5008 {
5009     auto task = [weakThis = wptr(this), callback = std::move(callback)] {
5010         auto session = weakThis.promote();
5011         if (!session) {
5012             TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
5013             return;
5014         }
5015         session->onIsCustomAnimationPlaying_ = std::move(callback);
5016     };
5017     PostTask(task, __func__);
5018 }
5019 
GetAppForceLandscapeConfig(AppForceLandscapeConfig & config)5020 WMError SceneSession::GetAppForceLandscapeConfig(AppForceLandscapeConfig& config)
5021 {
5022     if (forceSplitFunc_ == nullptr) {
5023         return WMError::WM_ERROR_NULLPTR;
5024     }
5025     config = forceSplitFunc_(sessionInfo_.bundleName_);
5026     return WMError::WM_OK;
5027 }
5028 
CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty> & property) const5029 bool SceneSession::CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty>& property) const
5030 {
5031     if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
5032         if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5033             TLOGE(WmsLogTag::WMS_LIFE, "Not system app, no permission");
5034             return false;
5035         }
5036     }
5037     return true;
5038 }
5039 
SetNotifyVisibleChangeFunc(const NotifyVisibleChangeFunc & func)5040 void SceneSession::SetNotifyVisibleChangeFunc(const NotifyVisibleChangeFunc& func)
5041 {
5042     notifyVisibleChangeFunc_ = func;
5043 }
5044 
SetUpdatePrivateStateAndNotifyFunc(const UpdatePrivateStateAndNotifyFunc & func)5045 void SceneSession::SetUpdatePrivateStateAndNotifyFunc(const UpdatePrivateStateAndNotifyFunc& func)
5046 {
5047     updatePrivateStateAndNotifyFunc_ = func;
5048 }
5049 
IsPcOrPadEnableActivation() const5050 bool SceneSession::IsPcOrPadEnableActivation() const
5051 {
5052     auto isPC = system::GetParameter("const.product.devicetype", "unknown") == "2in1";
5053     auto property = GetSessionProperty();
5054     bool isPcAppInPad = false;
5055     if (property != nullptr) {
5056         isPcAppInPad = property->GetIsPcAppInPad();
5057     }
5058     return isPC || IsFreeMultiWindowMode() || isPcAppInPad;
5059 }
5060 
UnregisterSessionChangeListeners()5061 void SceneSession::UnregisterSessionChangeListeners()
5062 {
5063     auto task = [weakThis = wptr(this)] {
5064         auto session = weakThis.promote();
5065         if (session == nullptr) {
5066             WLOGFE("UnregisterSessionChangeListeners session is null");
5067             return;
5068         }
5069         if (session->sessionChangeCallback_) {
5070             session->sessionChangeCallback_->onBindDialogTarget_ = nullptr;
5071             session->sessionChangeCallback_->onSessionTopmostChange_ = nullptr;
5072             session->sessionChangeCallback_->onRaiseToTop_ = nullptr;
5073             session->sessionChangeCallback_->OnSessionEvent_ = nullptr;
5074             session->sessionChangeCallback_->onRaiseAboveTarget_ = nullptr;
5075             session->sessionChangeCallback_->onSetLandscapeMultiWindowFunc_ = nullptr;
5076             session->sessionChangeCallback_->onLayoutFullScreenChangeFunc_ = nullptr;
5077         }
5078         session->Session::UnregisterSessionChangeListeners();
5079     };
5080     PostTask(task, "UnregisterSessionChangeListeners");
5081 }
5082 
UpdateUIParam(const SessionUIParam & uiParam)5083 uint32_t SceneSession::UpdateUIParam(const SessionUIParam& uiParam)
5084 {
5085     bool lastVisible = IsVisible();
5086     dirtyFlags_ |= UpdateInteractiveInner(uiParam.interactive_) ?
5087         static_cast<uint32_t>(SessionUIDirtyFlag::INTERACTIVE) : 0;
5088     if (!uiParam.interactive_) {
5089         // keep ui state in recent
5090         return dirtyFlags_;
5091     }
5092     dirtyFlags_ |= UpdateVisibilityInner(true) ? static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE) : 0;
5093 
5094     dirtyFlags_ |= UpdateRectInner(uiParam, reason_) ?
5095         static_cast<uint32_t>(SessionUIDirtyFlag::RECT) : 0;
5096     dirtyFlags_ |= UpdateScaleInner(uiParam.scaleX_, uiParam.scaleY_, uiParam.pivotX_, uiParam.pivotY_) ?
5097         static_cast<uint32_t>(SessionUIDirtyFlag::SCALE) : 0;
5098     dirtyFlags_ |= UpdateZOrderInner(uiParam.zOrder_) ? static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER) : 0;
5099     if (!lastVisible && IsVisible() && !isFocused_ && !postProcessFocusState_.enabled_ &&
5100         GetForegroundInteractiveStatus()) {
5101         postProcessFocusState_.enabled_ = true;
5102         postProcessFocusState_.isFocused_ = true;
5103         postProcessFocusState_.reason_ = isStarting_ ?
5104             FocusChangeReason::SCB_START_APP : FocusChangeReason::FOREGROUND;
5105     }
5106     return dirtyFlags_;
5107 }
5108 
UpdateUIParam()5109 uint32_t SceneSession::UpdateUIParam()
5110 {
5111     bool lastVisible = IsVisible();
5112     dirtyFlags_ |= UpdateVisibilityInner(false) ? static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE) : 0;
5113     if (lastVisible && !IsVisible() && isFocused_) {
5114         postProcessFocusState_.enabled_ = true;
5115         postProcessFocusState_.isFocused_ = false;
5116         postProcessFocusState_.reason_ = FocusChangeReason::BACKGROUND;
5117     }
5118     return dirtyFlags_;
5119 }
5120 
UpdateVisibilityInner(bool visibility)5121 bool SceneSession::UpdateVisibilityInner(bool visibility)
5122 {
5123     if (isVisible_ == visibility) {
5124         return false;
5125     }
5126     TLOGI(WmsLogTag::WMS_PIPELINE, "id: %{public}d, visibility: %{public}u -> %{public}u",
5127         GetPersistentId(), isVisible_, visibility);
5128     isVisible_ = visibility;
5129     if (updatePrivateStateAndNotifyFunc_ != nullptr) {
5130         updatePrivateStateAndNotifyFunc_(GetPersistentId());
5131     }
5132     if (notifyVisibleChangeFunc_ != nullptr) {
5133         notifyVisibleChangeFunc_(GetPersistentId());
5134     }
5135     return true;
5136 }
5137 
UpdateInteractiveInner(bool interactive)5138 bool SceneSession::UpdateInteractiveInner(bool interactive)
5139 {
5140     if (GetForegroundInteractiveStatus() == interactive) {
5141         return false;
5142     }
5143     SetForegroundInteractiveStatus(interactive);
5144     NotifyClientToUpdateInteractive(interactive);
5145     return true;
5146 }
5147 
PipelineNeedNotifyClientToUpdateRect() const5148 bool SceneSession::PipelineNeedNotifyClientToUpdateRect() const
5149 {
5150     return IsVisibleForeground() && GetForegroundInteractiveStatus();
5151 }
5152 
UpdateRectInner(const SessionUIParam & uiParam,SizeChangeReason reason)5153 bool SceneSession::UpdateRectInner(const SessionUIParam& uiParam, SizeChangeReason reason)
5154 {
5155     if (!((NotifyServerToUpdateRect(uiParam, reason) || IsDirtyWindow()) && PipelineNeedNotifyClientToUpdateRect())) {
5156         return false;
5157     }
5158     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
5159     auto transactionController = RSSyncTransactionController::GetInstance();
5160     if (transactionController) {
5161         rsTransaction = transactionController->GetRSTransaction();
5162     }
5163     NotifyClientToUpdateRect("WMSPipeline", rsTransaction);
5164     return true;
5165 }
5166 
NotifyServerToUpdateRect(const SessionUIParam & uiParam,SizeChangeReason reason)5167 bool SceneSession::NotifyServerToUpdateRect(const SessionUIParam& uiParam, SizeChangeReason reason)
5168 {
5169     if (!GetForegroundInteractiveStatus()) {
5170         TLOGD(WmsLogTag::WMS_PIPELINE, "skip recent, id:%{public}d", GetPersistentId());
5171         return false;
5172     }
5173     if (uiParam.rect_.IsInvalid()) {
5174         TLOGE(WmsLogTag::WMS_PIPELINE, "id:%{public}d rect:%{public}s is invalid",
5175             GetPersistentId(), uiParam.rect_.ToString().c_str());
5176         return false;
5177     }
5178     auto globalRect = GetSessionGlobalRect();
5179     if (globalRect != uiParam.rect_) {
5180         UpdateAllModalUIExtensions(uiParam.rect_);
5181     }
5182     SetSessionGlobalRect(uiParam.rect_);
5183     if (!uiParam.needSync_ || !isNeedSyncSessionRect_) {
5184         TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, scenePanelNeedSync:%{public}u needSyncSessionRect:%{public}u "
5185             "rectAfter:%{public}s preRect:%{public}s preGlobalRect:%{public}s", GetPersistentId(), uiParam.needSync_,
5186             isNeedSyncSessionRect_, uiParam.rect_.ToString().c_str(), winRect_.ToString().c_str(),
5187             globalRect.ToString().c_str());
5188         return false;
5189     }
5190     WSRect rect = { uiParam.rect_.posX_ - uiParam.transX_, uiParam.rect_.posY_ - uiParam.transY_,
5191         uiParam.rect_.width_, uiParam.rect_.height_ };
5192     if (winRect_ == rect) {
5193         TLOGD(WmsLogTag::WMS_PIPELINE, "skip same rect update id:%{public}d rect:%{public}s preGlobalRect:%{public}s!",
5194             GetPersistentId(), rect.ToString().c_str(), globalRect.ToString().c_str());
5195         return false;
5196     }
5197     if (rect.IsInvalid()) {
5198         TLOGE(WmsLogTag::WMS_PIPELINE, "id:%{public}d rect:%{public}s is invalid, preGlobalRect:%{public}s",
5199             GetPersistentId(), rect.ToString().c_str(), globalRect.ToString().c_str());
5200         return false;
5201     }
5202     TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, updateRect rectAfter:%{public}s preRect:%{public}s "
5203         "preGlobalRect:%{public}s", GetPersistentId(), rect.ToString().c_str(),
5204         winRect_.ToString().c_str(), globalRect.ToString().c_str());
5205     winRect_ = rect;
5206     RectCheckProcess();
5207     return true;
5208 }
5209 
PostProcessNotifyAvoidArea()5210 void SceneSession::PostProcessNotifyAvoidArea()
5211 {
5212     if (PipelineNeedNotifyClientToUpdateAvoidArea(dirtyFlags_)) {
5213         NotifyClientToUpdateAvoidArea();
5214     }
5215 }
5216 
PipelineNeedNotifyClientToUpdateAvoidArea(uint32_t dirty) const5217 bool SceneSession::PipelineNeedNotifyClientToUpdateAvoidArea(uint32_t dirty) const
5218 {
5219     return ((dirty & static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE)) && IsImmersiveType()) ||
5220         ((dirty & static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) && isVisible_);
5221 }
5222 
NotifyClientToUpdateAvoidArea()5223 void SceneSession::NotifyClientToUpdateAvoidArea()
5224 {
5225     if (specificCallback_ == nullptr) {
5226         return;
5227     }
5228     if (specificCallback_->onUpdateAvoidArea_) {
5229         specificCallback_->onUpdateAvoidArea_(GetPersistentId());
5230     }
5231     if (specificCallback_->onUpdateOccupiedAreaIfNeed_) {
5232         specificCallback_->onUpdateOccupiedAreaIfNeed_(GetPersistentId());
5233     }
5234 }
5235 
IsTransformNeedChange(float scaleX,float scaleY,float pivotX,float pivotY)5236 bool SceneSession::IsTransformNeedChange(float scaleX, float scaleY, float pivotX, float pivotY)
5237 {
5238     bool nearEqual = NearEqual(scaleX_, scaleX) && NearEqual(scaleY_, scaleY) &&
5239         NearEqual(pivotX_, pivotX) && NearEqual(pivotY_, pivotY) &&
5240         NearEqual(clientScaleX_, scaleX) && NearEqual(clientScaleY_, scaleY) &&
5241         NearEqual(clientPivotX_, pivotX) && NearEqual(clientPivotY_, pivotY);
5242     return !nearEqual;
5243 }
5244 
UpdateScaleInner(float scaleX,float scaleY,float pivotX,float pivotY)5245 bool SceneSession::UpdateScaleInner(float scaleX, float scaleY, float pivotX, float pivotY)
5246 {
5247     if (!IsTransformNeedChange(scaleX, scaleY, pivotX, pivotY)) {
5248         return false;
5249     }
5250     Session::SetScale(scaleX, scaleY, pivotX, pivotY);
5251     if (!IsSessionForeground()) {
5252         TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, session is not foreground!", GetPersistentId());
5253         return false;
5254     }
5255     if (sessionStage_ != nullptr) {
5256         Transform transform;
5257         transform.scaleX_ = scaleX;
5258         transform.scaleY_ = scaleY;
5259         transform.pivotX_ = pivotX;
5260         transform.pivotY_ = pivotY;
5261         sessionStage_->NotifyTransformChange(transform);
5262         Session::SetClientScale(scaleX, scaleY, pivotX, pivotY);
5263     } else {
5264         WLOGFE("sessionStage is nullptr");
5265     }
5266     return true;
5267 }
5268 
UpdateZOrderInner(uint32_t zOrder)5269 bool SceneSession::UpdateZOrderInner(uint32_t zOrder)
5270 {
5271     if (zOrder_ == zOrder) {
5272         return false;
5273     }
5274     TLOGI(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}u -> %{public}u, lastZOrder: %{public}u",
5275           GetPersistentId(), zOrder_, zOrder, lastZOrder_);
5276     lastZOrder_ = zOrder_;
5277     zOrder_ = zOrder;
5278     return true;
5279 }
5280 
SetPostProcessFocusState(PostProcessFocusState state)5281 void SceneSession::SetPostProcessFocusState(PostProcessFocusState state)
5282 {
5283     postProcessFocusState_ = state;
5284 }
5285 
GetPostProcessFocusState() const5286 PostProcessFocusState SceneSession::GetPostProcessFocusState() const
5287 {
5288     return postProcessFocusState_;
5289 }
5290 
ResetPostProcessFocusState()5291 void SceneSession::ResetPostProcessFocusState()
5292 {
5293     postProcessFocusState_.Reset();
5294 }
5295 
SetPostProcessProperty(bool state)5296 void SceneSession::SetPostProcessProperty(bool state)
5297 {
5298     postProcessProperty_ = state;
5299 }
5300 
GetPostProcessProperty() const5301 bool SceneSession::GetPostProcessProperty() const
5302 {
5303     return postProcessProperty_;
5304 }
5305 
IsImmersiveType() const5306 bool SceneSession::IsImmersiveType() const
5307 {
5308     WindowType type = GetWindowType();
5309     return type == WindowType::WINDOW_TYPE_STATUS_BAR ||
5310         type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
5311         type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
5312 }
5313 
SetDefaultDisplayIdIfNeed()5314 void SceneSession::SetDefaultDisplayIdIfNeed()
5315 {
5316     if (sessionInfo_.screenId_ == SCREEN_ID_INVALID) {
5317         auto defaultDisplayId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5318         sessionInfo_.screenId_ = defaultDisplayId;
5319         TLOGI(WmsLogTag::WMS_LIFE, "winId: %{public}d, update screen id %{public}" PRIu64,
5320             GetPersistentId(), defaultDisplayId);
5321         auto sessionProperty = GetSessionProperty();
5322         if (sessionProperty) {
5323             sessionProperty->SetDisplayId(defaultDisplayId);
5324         }
5325     }
5326 }
5327 
UpdateGestureBackEnabled()5328 void SceneSession::UpdateGestureBackEnabled()
5329 {
5330     if (specificCallback_ != nullptr &&
5331         specificCallback_->onUpdateGestureBackEnabled_ != nullptr) {
5332         specificCallback_->onUpdateGestureBackEnabled_(GetPersistentId());
5333     }
5334 }
5335 
CheckIdentityTokenIfMatched(const std::string & identityToken)5336 bool SceneSession::CheckIdentityTokenIfMatched(const std::string& identityToken)
5337 {
5338     if (!identityToken.empty() && !clientIdentityToken_.empty() && identityToken != clientIdentityToken_) {
5339         TLOGW(WmsLogTag::WMS_LIFE,
5340             "failed, clientIdentityToken: %{public}s, identityToken: %{public}s, bundleName: %{public}s",
5341             clientIdentityToken_.c_str(), identityToken.c_str(), GetSessionInfo().bundleName_.c_str());
5342         return false;
5343     }
5344     return true;
5345 }
5346 
CheckPidIfMatched()5347 bool SceneSession::CheckPidIfMatched()
5348 {
5349     int32_t callingPid = IPCSkeleton::GetCallingPid();
5350     if (callingPid != -1 && callingPid != GetCallingPid()) {
5351         TLOGW(WmsLogTag::WMS_LIFE,
5352             "failed, callingPid_: %{public}d, callingPid: %{public}d, bundleName: %{public}s",
5353             GetCallingPid(), callingPid, GetSessionInfo().bundleName_.c_str());
5354         return false;
5355     }
5356     return true;
5357 }
5358 
SetNeedSyncSessionRect(bool needSync)5359 void SceneSession::SetNeedSyncSessionRect(bool needSync)
5360 {
5361     auto task = [weakThis = wptr(this), needSync]() -> void {
5362         auto session = weakThis.promote();
5363         if (session == nullptr) {
5364             TLOGNE(WmsLogTag::WMS_PIPELINE, "SetNeedSyncSessionRect session is null");
5365             return;
5366         }
5367         TLOGNI(WmsLogTag::WMS_PIPELINE,
5368             "SetNeedSyncSessionRect: change isNeedSync from %{public}d to %{public}d, id:%{public}d",
5369             session->isNeedSyncSessionRect_, needSync, session->GetPersistentId());
5370         session->isNeedSyncSessionRect_ = needSync;
5371     };
5372     PostTask(task, __func__);
5373 }
5374 
SetWindowRectAutoSaveCallback(NotifySetWindowRectAutoSaveFunc && func)5375 void SceneSession::SetWindowRectAutoSaveCallback(NotifySetWindowRectAutoSaveFunc&& func)
5376 {
5377     const char* const where = __func__;
5378     auto task = [weakThis = wptr(this), where, func = std::move(func)] {
5379         auto session = weakThis.promote();
5380         if (!session || !func) {
5381             TLOGNE(WmsLogTag::WMS_MAIN, "session or onSetWindowRectAutoSaveFunc is null");
5382             return;
5383         }
5384         session->onSetWindowRectAutoSaveFunc_ = std::move(func);
5385         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where,
5386             session->GetPersistentId());
5387     };
5388     PostTask(task, __func__);
5389 }
5390 
SetFrameGravity(Gravity gravity)5391 bool SceneSession::SetFrameGravity(Gravity gravity)
5392 {
5393     if (surfaceNode_ == nullptr) {
5394         TLOGW(WmsLogTag::WMS_LAYOUT, "fail id:%{public}d gravity:%{public}d", GetPersistentId(), gravity);
5395         return false;
5396     }
5397     TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d gravity:%{public}d", GetPersistentId(), gravity);
5398     surfaceNode_->SetFrameGravity(gravity);
5399     return true;
5400 }
5401 
MarkAvoidAreaAsDirty()5402 void SceneSession::MarkAvoidAreaAsDirty()
5403 {
5404     dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
5405 }
5406 
UpdateAllModalUIExtensions(const WSRect & globalRect)5407 void SceneSession::UpdateAllModalUIExtensions(const WSRect& globalRect)
5408 {
5409     const char* const where = __func__;
5410     PostTask([weakThis = wptr(this), where, globalRect] {
5411         auto session = weakThis.promote();
5412         if (!session) {
5413             TLOGNE(WmsLogTag::WMS_UIEXT, "session is null");
5414             return;
5415         }
5416         auto parentTransX = globalRect.posX_ - session->GetSessionRect().posX_;
5417         auto parentTransY = globalRect.posY_ - session->GetSessionRect().posY_;
5418         {
5419             std::unique_lock<std::shared_mutex> lock(session->modalUIExtensionInfoListMutex_);
5420             for (auto& extensionInfo : session->modalUIExtensionInfoList_) {
5421                 if (!extensionInfo.hasUpdatedRect) {
5422                     continue;
5423                 }
5424                 extensionInfo.windowRect = extensionInfo.uiExtRect;
5425                 extensionInfo.windowRect.posX_ += parentTransX;
5426                 extensionInfo.windowRect.posX_ += parentTransY;
5427             }
5428         }
5429         session->NotifySessionInfoChange();
5430         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: id: %{public}d, globalRect: %{public}s, parentTransX: %{public}d, "
5431             "parentTransY: %{public}d", where, session->GetPersistentId(), globalRect.ToString().c_str(),
5432             parentTransX, parentTransY);
5433     }, __func__);
5434 }
5435 } // namespace OHOS::Rosen
5436