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