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