• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "window_session_impl.h"
17 
18 #include <cstdlib>
19 #include <optional>
20 
21 #include <common/rs_common_def.h>
22 #include <filesystem>
23 #include <fstream>
24 #include <ipc_skeleton.h>
25 #include <hisysevent.h>
26 #include <parameters.h>
27 #ifdef IMF_ENABLE
28 #include <input_method_controller.h>
29 #endif // IMF_ENABLE
30 #include <transaction/rs_interfaces.h>
31 #include <transaction/rs_transaction.h>
32 
33 #include "anr_handler.h"
34 #include "color_parser.h"
35 #include "display_info.h"
36 #include "display_manager.h"
37 #include "hitrace_meter.h"
38 #include "session_permission.h"
39 #include "key_event.h"
40 #include "session/container/include/window_event_channel.h"
41 #include "session_manager/include/session_manager.h"
42 #include "vsync_station.h"
43 #include "window_adapter.h"
44 #include "window_manager_hilog.h"
45 #include "window_helper.h"
46 #include "color_parser.h"
47 #include "singleton_container.h"
48 #include "perform_reporter.h"
49 #include "picture_in_picture_manager.h"
50 #include "parameters.h"
51 
52 namespace OHOS::Accessibility {
53 class AccessibilityEventInfo;
54 }
55 namespace OHOS {
56 namespace Rosen {
57 namespace {
58 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowSessionImpl"};
59 constexpr int32_t FULL_CIRCLE_DEGREE = 360;
60 constexpr int32_t ONE_FOURTH_FULL_CIRCLE_DEGREE = 90;
61 constexpr int32_t FORCE_SPLIT_MODE = 5;
62 
63 /**
64  * DFX
65  */
66 const std::string SET_UIEXTENSION_DESTROY_TIMEOUT_LISTENER_TASK_NAME = "SetUIExtDestroyTimeoutListener";
67 constexpr int64_t SET_UIEXTENSION_DESTROY_TIMEOUT_TIME_MS = 4000;
68 
CheckIfNeedCommitRsTransaction(WindowSizeChangeReason wmReason)69 bool CheckIfNeedCommitRsTransaction(WindowSizeChangeReason wmReason)
70 {
71     if (wmReason == WindowSizeChangeReason::FULL_TO_SPLIT ||
72         wmReason == WindowSizeChangeReason::FULL_TO_FLOATING || wmReason == WindowSizeChangeReason::RECOVER ||
73         wmReason == WindowSizeChangeReason::MAXIMIZE) {
74         return false;
75     }
76     return true;
77 }
78 
GetAceContentInfoType(BackupAndRestoreType type)79 Ace::ContentInfoType GetAceContentInfoType(BackupAndRestoreType type)
80 {
81     auto contentInfoType = Ace::ContentInfoType::NONE;
82     switch (type) {
83         case BackupAndRestoreType::CONTINUATION:
84             contentInfoType = Ace::ContentInfoType::CONTINUATION;
85             break;
86         case BackupAndRestoreType::APP_RECOVERY:
87             contentInfoType = Ace::ContentInfoType::APP_RECOVERY;
88             break;
89         case BackupAndRestoreType::RESOURCESCHEDULE_RECOVERY:
90             contentInfoType = Ace::ContentInfoType::RESOURCESCHEDULE_RECOVERY;
91             break;
92         case BackupAndRestoreType::NONE:
93             [[fallthrough]];
94         default:
95             break;
96     }
97     return contentInfoType;
98 }
99 
FillViewportConfig(Rect rect,float density,int32_t orientation,uint32_t transformHint)100 Ace::ViewportConfig FillViewportConfig(Rect rect, float density, int32_t orientation, uint32_t transformHint)
101 {
102     Ace::ViewportConfig config;
103     config.SetSize(rect.width_, rect.height_);
104     config.SetPosition(rect.posX_, rect.posY_);
105     config.SetDensity(density);
106     config.SetOrientation(orientation);
107     config.SetTransformHint(transformHint);
108     return config;
109 }
110 }
111 
112 std::map<int32_t, std::vector<sptr<IWindowLifeCycle>>> WindowSessionImpl::lifecycleListeners_;
113 std::map<int32_t, std::vector<sptr<IDisplayMoveListener>>> WindowSessionImpl::displayMoveListeners_;
114 std::map<int32_t, std::vector<sptr<IWindowChangeListener>>> WindowSessionImpl::windowChangeListeners_;
115 std::map<int32_t, std::vector<sptr<IAvoidAreaChangedListener>>> WindowSessionImpl::avoidAreaChangeListeners_;
116 std::map<int32_t, std::vector<sptr<IDialogDeathRecipientListener>>> WindowSessionImpl::dialogDeathRecipientListeners_;
117 std::map<int32_t, std::vector<sptr<IDialogTargetTouchListener>>> WindowSessionImpl::dialogTargetTouchListener_;
118 std::map<int32_t, std::vector<sptr<IOccupiedAreaChangeListener>>> WindowSessionImpl::occupiedAreaChangeListeners_;
119 std::map<int32_t, std::vector<sptr<IScreenshotListener>>> WindowSessionImpl::screenshotListeners_;
120 std::map<int32_t, std::vector<sptr<ITouchOutsideListener>>> WindowSessionImpl::touchOutsideListeners_;
121 std::map<int32_t, std::vector<IWindowVisibilityListenerSptr>> WindowSessionImpl::windowVisibilityChangeListeners_;
122 std::mutex WindowSessionImpl::displayIdChangeListenerMutex_;
123 std::map<int32_t, std::vector<IDisplayIdChangeListenerSptr>> WindowSessionImpl::displayIdChangeListeners_;
124 std::mutex WindowSessionImpl::systemDensityChangeListenerMutex_;
125 std::unordered_map<int32_t, std::vector<ISystemDensityChangeListenerSptr>>
126     WindowSessionImpl::systemDensityChangeListeners_;
127 std::map<int32_t, std::vector<IWindowNoInteractionListenerSptr>> WindowSessionImpl::windowNoInteractionListeners_;
128 std::map<int32_t, std::vector<sptr<IWindowTitleButtonRectChangedListener>>>
129     WindowSessionImpl::windowTitleButtonRectChangeListeners_;
130 std::map<int32_t, std::vector<sptr<IWindowRectChangeListener>>> WindowSessionImpl::windowRectChangeListeners_;
131 std::map<int32_t, sptr<ISubWindowCloseListener>> WindowSessionImpl::subWindowCloseListeners_;
132 std::map<int32_t, sptr<IMainWindowCloseListener>> WindowSessionImpl::mainWindowCloseListeners_;
133 std::unordered_map<int32_t, std::vector<sptr<IWindowWillCloseListener>>> WindowSessionImpl::windowWillCloseListeners_;
134 std::map<int32_t, std::vector<sptr<ISwitchFreeMultiWindowListener>>> WindowSessionImpl::switchFreeMultiWindowListeners_;
135 std::map<int32_t, std::vector<sptr<IWindowHighlightChangeListener>>> WindowSessionImpl::highlightChangeListeners_;
136 std::recursive_mutex WindowSessionImpl::lifeCycleListenerMutex_;
137 std::recursive_mutex WindowSessionImpl::windowChangeListenerMutex_;
138 std::recursive_mutex WindowSessionImpl::avoidAreaChangeListenerMutex_;
139 std::recursive_mutex WindowSessionImpl::dialogDeathRecipientListenerMutex_;
140 std::recursive_mutex WindowSessionImpl::dialogTargetTouchListenerMutex_;
141 std::recursive_mutex WindowSessionImpl::occupiedAreaChangeListenerMutex_;
142 std::recursive_mutex WindowSessionImpl::screenshotListenerMutex_;
143 std::recursive_mutex WindowSessionImpl::touchOutsideListenerMutex_;
144 std::recursive_mutex WindowSessionImpl::windowVisibilityChangeListenerMutex_;
145 std::recursive_mutex WindowSessionImpl::windowNoInteractionListenerMutex_;
146 std::recursive_mutex WindowSessionImpl::windowStatusChangeListenerMutex_;
147 std::recursive_mutex WindowSessionImpl::windowTitleButtonRectChangeListenerMutex_;
148 std::mutex WindowSessionImpl::displayMoveListenerMutex_;
149 std::mutex WindowSessionImpl::windowRectChangeListenerMutex_;
150 std::mutex WindowSessionImpl::subWindowCloseListenersMutex_;
151 std::mutex WindowSessionImpl::mainWindowCloseListenersMutex_;
152 std::mutex WindowSessionImpl::windowWillCloseListenersMutex_;
153 std::mutex WindowSessionImpl::switchFreeMultiWindowListenerMutex_;
154 std::mutex WindowSessionImpl::highlightChangeListenerMutex_;
155 std::map<std::string, std::pair<int32_t, sptr<WindowSessionImpl>>> WindowSessionImpl::windowSessionMap_;
156 std::shared_mutex WindowSessionImpl::windowSessionMutex_;
157 std::set<sptr<WindowSessionImpl>> WindowSessionImpl::windowExtensionSessionSet_;
158 std::shared_mutex WindowSessionImpl::windowExtensionSessionMutex_;
159 std::map<int32_t, std::vector<sptr<WindowSessionImpl>>> WindowSessionImpl::subWindowSessionMap_;
160 std::map<int32_t, std::vector<sptr<IWindowStatusChangeListener>>> WindowSessionImpl::windowStatusChangeListeners_;
161 bool WindowSessionImpl::isUIExtensionAbilityProcess_ = false;
162 
163 #define CALL_LIFECYCLE_LISTENER(windowLifecycleCb, listeners) \
164     do {                                                      \
165         for (auto& listener : (listeners)) {                  \
166             if (listener != nullptr) {            \
167                 listener->windowLifecycleCb();    \
168             }                                                 \
169         }                                                     \
170     } while (0)
171 
172 #define CALL_LIFECYCLE_LISTENER_WITH_PARAM(windowLifecycleCb, listeners, param) \
173     do {                                                                        \
174         for (auto& listener : (listeners)) {                                    \
175             if (listener != nullptr) {                                         \
176                 listener->windowLifecycleCb(param);                 \
177             }                                                                   \
178         }                                                                       \
179     } while (0)
180 
181 #define CALL_UI_CONTENT(uiContentCb)                                           \
182     do {                                                                       \
183         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();   \
184         if (uiContent != nullptr) {                                            \
185             uiContent->uiContentCb();                                          \
186         }                                                                      \
187     } while (0)
188 
189 #define CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession)                         \
190     do {                                                                       \
191         if ((hostSession) == nullptr) {                                        \
192             TLOGE(WmsLogTag::DEFAULT, "hostSession is null");                  \
193             return;                                                            \
194         }                                                                      \
195     } while (false)
196 
197 #define CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, ret)              \
198     do {                                                                       \
199         if ((hostSession) == nullptr) {                                        \
200             TLOGE(WmsLogTag::DEFAULT, "hostSession is null");                  \
201             return ret;                                                        \
202         }                                                                      \
203     } while (false)
204 
WindowSessionImpl(const sptr<WindowOption> & option)205 WindowSessionImpl::WindowSessionImpl(const sptr<WindowOption>& option)
206 {
207     WLOGFD("[WMSCom]WindowSessionImpl");
208     property_ = new (std::nothrow) WindowSessionProperty();
209     if (property_ == nullptr) {
210         WLOGFE("[WMSCom]Property is null");
211         return;
212     }
213     WindowType optionWindowType = option->GetWindowType();
214     SessionInfo sessionInfo;
215     sessionInfo.bundleName_ = option->GetBundleName();
216     property_->SetSessionInfo(sessionInfo);
217     property_->SetWindowName(option->GetWindowName());
218     property_->SetRequestRect(option->GetWindowRect());
219     property_->SetWindowType(optionWindowType);
220     property_->SetFocusable(option->GetFocusable());
221     property_->SetTouchable(option->GetTouchable());
222     property_->SetDisplayId(option->GetDisplayId());
223     property_->SetParentId(option->GetParentId());
224     property_->SetTurnScreenOn(option->IsTurnScreenOn());
225     property_->SetKeepScreenOn(option->IsKeepScreenOn());
226     property_->SetWindowMode(option->GetWindowMode());
227     property_->SetWindowFlags(option->GetWindowFlags());
228     property_->SetCallingSessionId(option->GetCallingWindow());
229     property_->SetExtensionFlag(option->GetExtensionTag());
230     property_->SetTopmost(option->GetWindowTopmost());
231     property_->SetRealParentId(option->GetRealParentId());
232     property_->SetParentWindowType(option->GetParentWindowType());
233     property_->SetUIExtensionUsage(static_cast<UIExtensionUsage>(option->GetUIExtensionUsage()));
234     property_->SetConstrainedModal(option->IsConstrainedModal());
235     layoutCallback_ = sptr<FutureCallback>::MakeSptr();
236     property_->SetIsUIExtensionSubWindowFlag(option->GetIsUIExtensionSubWindowFlag());
237     isMainHandlerAvailable_ = option->GetMainHandlerAvailable();
238     isIgnoreSafeArea_ = WindowHelper::IsSubWindow(optionWindowType);
239     windowOption_ = option;
240     surfaceNode_ = CreateSurfaceNode(property_->GetWindowName(), optionWindowType);
241     handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
242     if (surfaceNode_ != nullptr) {
243         vsyncStation_ = std::make_shared<VsyncStation>(surfaceNode_->GetId());
244         if (WindowHelper::IsSubWindow(GetType())) {
245             surfaceNode_->SetFrameGravity(Gravity::TOP_LEFT);
246         }
247     }
248 }
249 
IsPcWindow() const250 bool WindowSessionImpl::IsPcWindow() const
251 {
252     return windowSystemConfig_.uiType_ == UI_TYPE_PC;
253 }
254 
IsPcOrPadCapabilityEnabled() const255 bool WindowSessionImpl::IsPcOrPadCapabilityEnabled() const
256 {
257     return WindowSessionImpl::IsPcOrPadFreeMultiWindowMode() || property_->GetIsPcAppInPad();
258 }
259 
IsPcOrPadFreeMultiWindowMode() const260 bool WindowSessionImpl::IsPcOrPadFreeMultiWindowMode() const
261 {
262     return windowSystemConfig_.uiType_ == UI_TYPE_PC || IsFreeMultiWindowMode();
263 }
264 
MakeSubOrDialogWindowDragableAndMoveble()265 void WindowSessionImpl::MakeSubOrDialogWindowDragableAndMoveble()
266 {
267     TLOGI(WmsLogTag::WMS_LIFE, "Called %{public}d.", GetPersistentId());
268     if (IsPcOrPadCapabilityEnabled() && windowOption_ != nullptr) {
269         if (WindowHelper::IsSubWindow(property_->GetWindowType())) {
270             TLOGI(WmsLogTag::WMS_LIFE, "create subwindow, title: %{public}s, decorEnable: %{public}d",
271                 windowOption_->GetSubWindowTitle().c_str(), windowOption_->GetSubWindowDecorEnable());
272             property_->SetDecorEnable(windowOption_->GetSubWindowDecorEnable());
273             property_->SetDragEnabled(windowOption_->GetSubWindowDecorEnable());
274             UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED);
275             subWindowTitle_ = windowOption_->GetSubWindowTitle();
276         }
277         bool isDialog = WindowHelper::IsDialogWindow(property_->GetWindowType());
278         if (isDialog) {
279             bool dialogDecorEnable = windowOption_->GetDialogDecorEnable();
280             property_->SetDecorEnable(dialogDecorEnable);
281             property_->SetDragEnabled(dialogDecorEnable);
282             UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED);
283             dialogTitle_ = windowOption_->GetDialogTitle();
284             TLOGI(WmsLogTag::WMS_LIFE, "create dialogWindow, title: %{public}s, decorEnable: %{public}d",
285                 dialogTitle_.c_str(), dialogDecorEnable);
286         }
287     }
288 }
289 
CreateSurfaceNode(std::string name,WindowType type)290 RSSurfaceNode::SharedPtr WindowSessionImpl::CreateSurfaceNode(std::string name, WindowType type)
291 {
292     struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
293     rsSurfaceNodeConfig.SurfaceNodeName = name;
294     RSSurfaceNodeType rsSurfaceNodeType = RSSurfaceNodeType::DEFAULT;
295     switch (type) {
296         case WindowType::WINDOW_TYPE_BOOT_ANIMATION:
297         case WindowType::WINDOW_TYPE_POINTER:
298             rsSurfaceNodeType = RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
299             break;
300         case WindowType::WINDOW_TYPE_APP_MAIN_WINDOW:
301             rsSurfaceNodeType = RSSurfaceNodeType::APP_WINDOW_NODE;
302             break;
303         case WindowType::WINDOW_TYPE_UI_EXTENSION:
304             TLOGI(WmsLogTag::WMS_LIFE, "uiExtensionUsage = %{public}u", property_->GetUIExtensionUsage());
305             if (property_->GetUIExtensionUsage() == UIExtensionUsage::CONSTRAINED_EMBEDDED) {
306                 rsSurfaceNodeType = RSSurfaceNodeType::UI_EXTENSION_SECURE_NODE;
307             } else {
308                 rsSurfaceNodeType = RSSurfaceNodeType::UI_EXTENSION_COMMON_NODE;
309             }
310             break;
311         case WindowType::WINDOW_TYPE_PIP:
312             rsSurfaceNodeType = RSSurfaceNodeType::APP_WINDOW_NODE;
313             break;
314         default:
315             rsSurfaceNodeType = RSSurfaceNodeType::DEFAULT;
316             break;
317     }
318     return RSSurfaceNode::Create(rsSurfaceNodeConfig, rsSurfaceNodeType, true, property_->IsConstrainedModal());
319 }
320 
~WindowSessionImpl()321 WindowSessionImpl::~WindowSessionImpl()
322 {
323     WLOGFD("[WMSCom]~WindowSessionImpl, id: %{public}d", GetPersistentId());
324     Destroy(true, false);
325 }
326 
GetWindowId() const327 uint32_t WindowSessionImpl::GetWindowId() const
328 {
329     return static_cast<uint32_t>(GetPersistentId()) & 0xffffffff; // 0xffffffff: to get low 32 bits
330 }
331 
GetDisplayId() const332 uint64_t WindowSessionImpl::GetDisplayId() const
333 {
334     return property_->GetDisplayId();
335 }
336 
GetParentId() const337 int32_t WindowSessionImpl::GetParentId() const
338 {
339     // 0xffffffff: to get low 32 bits
340     uint32_t parentID = static_cast<uint32_t>(property_->GetParentPersistentId()) & 0x7fffffff;
341     return static_cast<int32_t>(parentID);
342 }
343 
IsWindowSessionInvalid() const344 bool WindowSessionImpl::IsWindowSessionInvalid() const
345 {
346     bool res = ((GetHostSession() == nullptr) || (GetPersistentId() == INVALID_SESSION_ID) ||
347         (state_ == WindowState::STATE_DESTROYED));
348     if (res) {
349         TLOGW(WmsLogTag::WMS_LIFE, "already destroyed or not created! id: %{public}d state_: %{public}u",
350             GetPersistentId(), state_);
351     }
352     return res;
353 }
354 
IsMainHandlerAvailable() const355 bool WindowSessionImpl::IsMainHandlerAvailable() const
356 {
357     TLOGI(WmsLogTag::DEFAULT, "id:%{public}d, isAvailable:%{public}u",
358         GetPersistentId(), isMainHandlerAvailable_);
359     return isMainHandlerAvailable_;
360 }
361 
GetPersistentId() const362 int32_t WindowSessionImpl::GetPersistentId() const
363 {
364     if (property_) {
365         return property_->GetPersistentId();
366     }
367     return INVALID_SESSION_ID;
368 }
369 
GetProperty() const370 sptr<WindowSessionProperty> WindowSessionImpl::GetProperty() const
371 {
372     return property_;
373 }
374 
GetSystemSessionConfig() const375 SystemSessionConfig WindowSessionImpl::GetSystemSessionConfig() const
376 {
377     return windowSystemConfig_;
378 }
379 
GetHostSession() const380 sptr<ISession> WindowSessionImpl::GetHostSession() const
381 {
382     std::lock_guard<std::mutex> lock(hostSessionMutex_);
383     return hostSession_;
384 }
385 
GetColorSpaceFromSurfaceGamut(GraphicColorGamut colorGamut)386 ColorSpace WindowSessionImpl::GetColorSpaceFromSurfaceGamut(GraphicColorGamut colorGamut)
387 {
388     if (colorGamut == GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB) {
389         return ColorSpace::COLOR_SPACE_DEFAULT;
390     } else if (colorGamut == GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3) {
391         return ColorSpace::COLOR_SPACE_WIDE_GAMUT;
392     } else {
393         WLOGFE("try to get not exist ColorSpace");
394         return ColorSpace::COLOR_SPACE_DEFAULT;
395     }
396 }
397 
GetSurfaceGamutFromColorSpace(ColorSpace colorSpace)398 GraphicColorGamut WindowSessionImpl::GetSurfaceGamutFromColorSpace(ColorSpace colorSpace)
399 {
400     if (colorSpace == ColorSpace::COLOR_SPACE_DEFAULT) {
401         return GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
402     } else if (colorSpace == ColorSpace::COLOR_SPACE_WIDE_GAMUT) {
403         return GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3;
404     } else {
405         WLOGFE("try to get not exist colorGamut");
406         return GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
407     }
408 }
409 
IsSupportWideGamut()410 bool WindowSessionImpl::IsSupportWideGamut()
411 {
412     return true;
413 }
414 
SetColorSpace(ColorSpace colorSpace)415 void WindowSessionImpl::SetColorSpace(ColorSpace colorSpace)
416 {
417     if (IsWindowSessionInvalid() || surfaceNode_ == nullptr) {
418         TLOGE(WmsLogTag::DEFAULT, "session is invalid");
419         return;
420     }
421     auto colorGamut = GetSurfaceGamutFromColorSpace(colorSpace);
422     surfaceNode_->SetColorSpace(colorGamut);
423 }
424 
GetColorSpace()425 ColorSpace WindowSessionImpl::GetColorSpace()
426 {
427     if (IsWindowSessionInvalid() || surfaceNode_ == nullptr) {
428         TLOGE(WmsLogTag::DEFAULT, "session is invalid");
429         return ColorSpace::COLOR_SPACE_DEFAULT;
430     }
431     GraphicColorGamut colorGamut = surfaceNode_->GetColorSpace();
432     return GetColorSpaceFromSurfaceGamut(colorGamut);
433 }
434 
WindowSessionCreateCheck()435 WMError WindowSessionImpl::WindowSessionCreateCheck()
436 {
437     if (!property_ || vsyncStation_ == nullptr || !vsyncStation_->IsVsyncReceiverCreated()) {
438         return WMError::WM_ERROR_NULLPTR;
439     }
440     const auto& name = property_->GetWindowName();
441     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
442     // check window name, same window names are forbidden
443     if (windowSessionMap_.find(name) != windowSessionMap_.end()) {
444         WLOGFE("WindowName(%{public}s) already exists.", name.c_str());
445         return WMError::WM_ERROR_REPEAT_OPERATION;
446     }
447 
448     // check if camera floating window is already exists
449     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA ||
450         property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
451         for (const auto& item : windowSessionMap_) {
452             if (item.second.second && item.second.second->property_ &&
453                 item.second.second->property_->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
454                     WLOGFE("Camera floating window is already exists.");
455                 return WMError::WM_ERROR_REPEAT_OPERATION;
456             }
457         }
458         uint32_t accessTokenId = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID());
459         property_->SetAccessTokenId(accessTokenId);
460         TLOGI(WmsLogTag::DEFAULT, "Create camera float window, TokenId = %{private}u", accessTokenId);
461     }
462     return WMError::WM_OK;
463 }
464 
SetDefaultDisplayIdIfNeed()465 void WindowSessionImpl::SetDefaultDisplayIdIfNeed()
466 {
467     TLOGI(WmsLogTag::WMS_LIFE, "Called");
468     auto displayId = property_->GetDisplayId();
469     if (displayId == DISPLAY_ID_INVALID) {
470         auto defaultDisplayId = SingletonContainer::IsDestroyed() ? DISPLAY_ID_INVALID :
471             SingletonContainer::Get<DisplayManager>().GetDefaultDisplayId();
472         defaultDisplayId = (defaultDisplayId == DISPLAY_ID_INVALID) ? 0 : defaultDisplayId;
473         property_->SetDisplayId(defaultDisplayId);
474         TLOGI(WmsLogTag::WMS_LIFE, "Reset displayId to %{public}" PRIu64, defaultDisplayId);
475     }
476 }
477 
Create(const std::shared_ptr<AbilityRuntime::Context> & context,const sptr<Rosen::ISession> & iSession,const std::string & identityToken)478 WMError WindowSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
479     const sptr<Rosen::ISession>& iSession, const std::string& identityToken)
480 {
481     return WMError::WM_OK;
482 }
483 
Connect()484 WMError WindowSessionImpl::Connect()
485 {
486     TLOGI(WmsLogTag::WMS_LIFE, "Called");
487     auto hostSession = GetHostSession();
488     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
489     sptr<ISessionStage> iSessionStage(this);
490     auto windowEventChannel = new (std::nothrow) WindowEventChannel(iSessionStage);
491     if (windowEventChannel && property_) {
492         windowEventChannel->SetIsUIExtension(property_->GetWindowType() == WindowType::WINDOW_TYPE_UI_EXTENSION);
493         windowEventChannel->SetUIExtensionUsage(property_->GetUIExtensionUsage());
494     }
495     sptr<IWindowEventChannel> iWindowEventChannel(windowEventChannel);
496     sptr<IRemoteObject> token = context_ ? context_->GetToken() : nullptr;
497     if (token) {
498         property_->SetTokenState(true);
499     }
500     auto ret = hostSession->Connect(
501         iSessionStage, iWindowEventChannel, surfaceNode_, windowSystemConfig_, property_,
502         token, identityToken_);
503     TLOGI(WmsLogTag::WMS_LIFE, "Window Connect [name:%{public}s, id:%{public}d, type:%{public}u], ret:%{public}u",
504         property_->GetWindowName().c_str(), GetPersistentId(), property_->GetWindowType(), ret);
505     return static_cast<WMError>(ret);
506 }
507 
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)508 void WindowSessionImpl::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
509 {
510     NotifyPointerEvent(pointerEvent);
511 }
512 
ConsumeKeyEvent(std::shared_ptr<MMI::KeyEvent> & keyEvent)513 void WindowSessionImpl::ConsumeKeyEvent(std::shared_ptr<MMI::KeyEvent>& keyEvent)
514 {
515     bool isConsumed = false;
516     NotifyKeyEvent(keyEvent, isConsumed, false);
517 }
518 
PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)519 bool WindowSessionImpl::PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
520 {
521     TLOGI(WmsLogTag::WMS_EVENT, "id: %{public}d", keyEvent->GetId());
522     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
523     if (uiContent != nullptr) {
524         return uiContent->ProcessKeyEvent(keyEvent, true);
525     }
526     return false;
527 }
528 
NotifyOnKeyPreImeEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)529 bool WindowSessionImpl::NotifyOnKeyPreImeEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
530 {
531     return PreNotifyKeyEvent(keyEvent);
532 }
533 
UpdateSubWindowStateAndNotify(int32_t parentPersistentId,const WindowState newState)534 void WindowSessionImpl::UpdateSubWindowStateAndNotify(int32_t parentPersistentId, const WindowState newState)
535 {
536     auto iter = subWindowSessionMap_.find(parentPersistentId);
537     if (iter == subWindowSessionMap_.end()) {
538         TLOGD(WmsLogTag::WMS_SUB, "parent window: %{public}d has no child node", parentPersistentId);
539         return;
540     }
541     const auto& subWindows = iter->second;
542     if (subWindows.empty()) {
543         TLOGD(WmsLogTag::WMS_SUB, "parent window: %{public}d, its subWindowMap is empty", parentPersistentId);
544         return;
545     }
546 
547     // when parent window hide and subwindow whose state is shown should hide and notify user
548     if (newState == WindowState::STATE_HIDDEN) {
549         for (auto subwindow : subWindows) {
550             if (subwindow != nullptr && subwindow->GetWindowState() == WindowState::STATE_SHOWN) {
551                 subwindow->state_ = WindowState::STATE_HIDDEN;
552                 subwindow->NotifyAfterBackground();
553                 TLOGD(WmsLogTag::WMS_SUB, "Notify subWindow background, id:%{public}d", subwindow->GetPersistentId());
554                 UpdateSubWindowStateAndNotify(subwindow->GetPersistentId(), newState);
555             }
556         }
557     // when parent window show and subwindow whose state is shown should show and notify user
558     } else if (newState == WindowState::STATE_SHOWN) {
559         for (auto subwindow : subWindows) {
560             if (subwindow != nullptr && subwindow->GetWindowState() == WindowState::STATE_HIDDEN &&
561                 subwindow->GetRequestWindowState() == WindowState::STATE_SHOWN) {
562                 subwindow->state_ = WindowState::STATE_SHOWN;
563                 subwindow->NotifyAfterForeground();
564                 TLOGD(WmsLogTag::WMS_SUB, "Notify subWindow foreground, id:%{public}d", subwindow->GetPersistentId());
565                 UpdateSubWindowStateAndNotify(subwindow->GetPersistentId(), newState);
566             }
567         }
568     }
569 }
570 
Show(uint32_t reason,bool withAnimation,bool withFocus)571 WMError WindowSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus)
572 {
573     TLOGI(WmsLogTag::WMS_LIFE, "name:%{public}s, id:%{public}d, type:%{public}u, reason:%{public}u, state:%{public}u",
574         property_->GetWindowName().c_str(), property_->GetPersistentId(), GetType(), reason, state_);
575     if (IsWindowSessionInvalid()) {
576         WLOGFE("session is invalid");
577         return WMError::WM_ERROR_INVALID_WINDOW;
578     }
579     if (state_ == WindowState::STATE_SHOWN) {
580         TLOGD(WmsLogTag::WMS_LIFE, "window session is alreay shown [name:%{public}s, id:%{public}d, type: %{public}u]",
581             property_->GetWindowName().c_str(), GetPersistentId(), property_->GetWindowType());
582         NotifyAfterForeground(true, false);
583         return WMError::WM_OK;
584     }
585 
586     auto hostSession = GetHostSession();
587     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
588     WSError ret = hostSession->Foreground(property_);
589     // delete after replace WSError with WMError
590     WMError res = static_cast<WMError>(ret);
591     if (res == WMError::WM_OK) {
592         UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_SHOWN);
593         state_ = WindowState::STATE_SHOWN;
594         requestState_ = WindowState::STATE_SHOWN;
595         NotifyAfterForeground();
596     } else {
597         NotifyForegroundFailed(res);
598     }
599     return res;
600 }
601 
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)602 WMError WindowSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
603 {
604     TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d Hide, reason:%{public}u, state:%{public}u",
605         GetPersistentId(), reason, state_);
606     if (IsWindowSessionInvalid()) {
607         WLOGFE("session is invalid");
608         return WMError::WM_ERROR_INVALID_WINDOW;
609     }
610     if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
611         TLOGD(WmsLogTag::WMS_LIFE, "window session is alreay hidden [name:%{public}s, id:%{public}d, type: %{public}u]",
612             property_->GetWindowName().c_str(), GetPersistentId(), property_->GetWindowType());
613         NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
614         return WMError::WM_OK;
615     }
616     UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_HIDDEN);
617     state_ = WindowState::STATE_HIDDEN;
618     requestState_ = WindowState::STATE_HIDDEN;
619     NotifyAfterBackground();
620     return WMError::WM_OK;
621 }
622 
DestroySubWindow()623 void WindowSessionImpl::DestroySubWindow()
624 {
625     int32_t parentPersistentId = property_->GetParentPersistentId();
626     const int32_t persistentId = GetPersistentId();
627     if (property_->GetExtensionFlag() == true) {
628         auto extensionWindow = FindExtensionWindowWithContext();
629         if (extensionWindow != nullptr) {
630             parentPersistentId = extensionWindow->GetPersistentId();
631         }
632     }
633     TLOGI(WmsLogTag::WMS_SUB, "Id: %{public}d, parentId: %{public}d", persistentId, parentPersistentId);
634     // remove from subWindowMap_ when destroy sub window
635     auto subIter = subWindowSessionMap_.find(parentPersistentId);
636     if (subIter != subWindowSessionMap_.end()) {
637         auto& subWindows = subIter->second;
638         for (auto iter = subWindows.begin(); iter != subWindows.end(); iter++) {
639             auto subWindow = *iter;
640             if (subWindow == nullptr) {
641                 continue;
642             }
643             if (subWindow->GetPersistentId() == persistentId) {
644                 TLOGD(WmsLogTag::WMS_SUB, "Destroy sub window, persistentId: %{public}d", persistentId);
645                 subWindows.erase(iter);
646                 break;
647             } else {
648                 TLOGD(WmsLogTag::WMS_SUB, "Exists other sub window, persistentId: %{public}d", persistentId);
649             }
650         }
651         if (property_->GetExtensionFlag() && subWindowSessionMap_.empty()) {
652             auto extensionWindow = FindExtensionWindowWithContext();
653             if (extensionWindow != nullptr && extensionWindow->GetUIContentSharedPtr() == nullptr) {
654                 extensionWindow->AddSetUIExtensionDestroyTimeoutCheck();
655             }
656         }
657     }
658     // remove from subWindowMap_ when destroy parent window
659     auto mainIter = subWindowSessionMap_.find(persistentId);
660     if (mainIter != subWindowSessionMap_.end()) {
661         auto& subWindows = mainIter->second;
662         for (auto iter = subWindows.begin(); iter != subWindows.end(); iter = subWindows.begin()) {
663             auto subWindow = *iter;
664             if (subWindow == nullptr) {
665                 TLOGW(WmsLogTag::WMS_SUB, "Destroy sub window which is nullptr");
666                 subWindows.erase(iter);
667                 continue;
668             }
669             bool isExtDestroyed = subWindow->property_->GetExtensionFlag();
670             TLOGD(WmsLogTag::WMS_SUB, "Destroy sub window, persistentId: %{public}d, isExtDestroyed: %{public}d",
671                 subWindow->GetPersistentId(), isExtDestroyed);
672             auto ret = subWindow->Destroy(isExtDestroyed);
673             if (ret != WMError::WM_OK) {
674                 TLOGE(WmsLogTag::WMS_SUB, "Destroy failed. persistentId: %{public}d", subWindow->GetPersistentId());
675                 subWindows.erase(iter);
676             }
677         }
678         mainIter->second.clear();
679         subWindowSessionMap_.erase(mainIter);
680     }
681 }
682 
Destroy(bool needNotifyServer,bool needClearListener)683 WMError WindowSessionImpl::Destroy(bool needNotifyServer, bool needClearListener)
684 {
685     TLOGI(WmsLogTag::WMS_LIFE, "Id: %{public}d Destroy, state_:%{public}u, needNotifyServer: %{public}d, "
686         "needClearListener: %{public}d", GetPersistentId(), state_, needNotifyServer, needClearListener);
687     if (IsWindowSessionInvalid()) {
688         WLOGFW("[WMSLife]session is invalid");
689         return WMError::WM_ERROR_INVALID_WINDOW;
690     }
691     {
692         auto hostSession = GetHostSession();
693         if (hostSession != nullptr) {
694             hostSession->Disconnect();
695         }
696     }
697     NotifyBeforeDestroy(GetWindowName());
698     {
699         std::lock_guard<std::recursive_mutex> lock(mutex_);
700         state_ = WindowState::STATE_DESTROYED;
701         requestState_ = WindowState::STATE_DESTROYED;
702     }
703     DestroySubWindow();
704     {
705         std::lock_guard<std::mutex> lock(hostSessionMutex_);
706         hostSession_ = nullptr;
707     }
708     {
709         std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
710         windowSessionMap_.erase(property_->GetWindowName());
711     }
712     NotifyAfterDestroy();
713     if (needClearListener) {
714         ClearListenersById(GetPersistentId());
715     }
716     if (context_) {
717         context_.reset();
718     }
719     ClearVsyncStation();
720     return WMError::WM_OK;
721 }
722 
Destroy()723 WMError WindowSessionImpl::Destroy()
724 {
725     return Destroy(true);
726 }
727 
SetActive(bool active)728 WSError WindowSessionImpl::SetActive(bool active)
729 {
730     WLOGFD("active status: %{public}d", active);
731     if (active) {
732         NotifyAfterActive();
733     } else {
734         NotifyAfterInactive();
735     }
736     return WSError::WS_OK;
737 }
738 
UpdateRect(const WSRect & rect,SizeChangeReason reason,const SceneAnimationConfig & config,const std::map<AvoidAreaType,AvoidArea> & avoidAreas)739 WSError WindowSessionImpl::UpdateRect(const WSRect& rect, SizeChangeReason reason,
740     const SceneAnimationConfig& config, const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
741 {
742     // delete after replace ws_common.h with wm_common.h
743     auto wmReason = static_cast<WindowSizeChangeReason>(reason);
744     Rect wmRect = { rect.posX_, rect.posY_, rect.width_, rect.height_ };
745     auto preRect = GetRect();
746     if (preRect.width_ != wmRect.width_ || preRect.height_ != wmRect.height_) {
747         windowSizeChanged_ = true;
748     }
749     property_->SetWindowRect(wmRect);
750     property_->SetRequestRect(wmRect);
751 
752     TLOGI(WmsLogTag::WMS_LAYOUT, "%{public}s, preRect:%{public}s, reason:%{public}u, hasRSTransaction:%{public}d"
753         ",duration:%{public}d, [name:%{public}s, id:%{public}d]", rect.ToString().c_str(), preRect.ToString().c_str(),
754         wmReason, config.rsTransaction_ != nullptr, config.animationDuration_,
755         GetWindowName().c_str(), GetPersistentId());
756     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
757         "WindowSessionImpl::UpdateRect id: %d [%d, %d, %u, %u] reason: %u hasRSTransaction: %u", GetPersistentId(),
758         wmRect.posX_, wmRect.posY_, wmRect.width_, wmRect.height_, wmReason, config.rsTransaction_ != nullptr);
759     if (handler_ != nullptr && wmReason == WindowSizeChangeReason::ROTATION) {
760         postTaskDone_ = false;
761         UpdateRectForRotation(wmRect, preRect, wmReason, config, avoidAreas);
762     } else {
763         UpdateRectForOtherReason(wmRect, preRect, wmReason, config.rsTransaction_, avoidAreas);
764     }
765 
766     if (wmReason == WindowSizeChangeReason::MOVE || wmReason == WindowSizeChangeReason::RESIZE) {
767         layoutCallback_->OnUpdateSessionRect(wmRect, wmReason, GetPersistentId());
768     }
769 
770     return WSError::WS_OK;
771 }
772 
773 /** @note @window.layout */
UpdateVirtualPixelRatio(const sptr<Display> & display)774 void WindowSessionImpl::UpdateVirtualPixelRatio(const sptr<Display>& display)
775 {
776     if (display == nullptr) {
777         TLOGE(WmsLogTag::WMS_LAYOUT, "display is null when rotation!");
778         return;
779     }
780     sptr<DisplayInfo> displayInfo = display->GetDisplayInfo();
781     if (displayInfo == nullptr) {
782         TLOGE(WmsLogTag::WMS_LAYOUT, "displayInfo is null when rotation!");
783         return;
784     }
785     virtualPixelRatio_ = GetVirtualPixelRatio(displayInfo);
786     TLOGD(WmsLogTag::WMS_LAYOUT, "virtualPixelRatio: %{public}f", virtualPixelRatio_);
787 }
788 
UpdateRectForRotation(const Rect & wmRect,const Rect & preRect,WindowSizeChangeReason wmReason,const SceneAnimationConfig & config,const std::map<AvoidAreaType,AvoidArea> & avoidAreas)789 void WindowSessionImpl::UpdateRectForRotation(const Rect& wmRect, const Rect& preRect,
790     WindowSizeChangeReason wmReason, const SceneAnimationConfig& config,
791     const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
792 {
793     handler_->PostTask([weak = wptr(this), wmReason, wmRect, preRect, config, avoidAreas]() mutable {
794         HITRACE_METER_NAME(HITRACE_TAG_WINDOW_MANAGER, "WindowSessionImpl::UpdateRectForRotation");
795         auto window = weak.promote();
796         if (!window) {
797             return;
798         }
799         auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(window->property_->GetDisplayId());
800         sptr<DisplayInfo> displayInfo = display ? display->GetDisplayInfo() : nullptr;
801         window->UpdateVirtualPixelRatio(display);
802         const std::shared_ptr<RSTransaction>& rsTransaction = config.rsTransaction_;
803         if (rsTransaction) {
804             RSTransaction::FlushImplicitTransaction();
805             rsTransaction->Begin();
806         }
807         window->rotationAnimationCount_++;
808         RSAnimationTimingProtocol protocol;
809         protocol.SetDuration(config.animationDuration_);
810         // animation curve: cubic [0.2, 0.0, 0.2, 1.0]
811         auto curve = RSAnimationTimingCurve::CreateCubicCurve(0.2, 0.0, 0.2, 1.0);
812         RSNode::OpenImplicitAnimation(protocol, curve, [weak]() {
813             auto window = weak.promote();
814             if (!window) {
815                 return;
816             }
817             window->rotationAnimationCount_--;
818             if (window->rotationAnimationCount_ == 0) {
819                 window->NotifyRotationAnimationEnd();
820             }
821         });
822         if ((wmRect != preRect) || (wmReason != window->lastSizeChangeReason_)) {
823             window->NotifySizeChange(wmRect, wmReason);
824             window->lastSizeChangeReason_ = wmReason;
825         }
826         window->UpdateViewportConfig(wmRect, wmReason, rsTransaction, displayInfo, avoidAreas);
827         RSNode::CloseImplicitAnimation();
828         if (rsTransaction) {
829             rsTransaction->Commit();
830         } else {
831             RSTransaction::FlushImplicitTransaction();
832         }
833         window->postTaskDone_ = true;
834     }, "WMS_WindowSessionImpl_UpdateRectForRotation");
835 }
836 
UpdateRectForOtherReasonTask(const Rect & wmRect,const Rect & preRect,WindowSizeChangeReason wmReason,const std::shared_ptr<RSTransaction> & rsTransaction,const std::map<AvoidAreaType,AvoidArea> & avoidAreas)837 void WindowSessionImpl::UpdateRectForOtherReasonTask(const Rect& wmRect, const Rect& preRect,
838     WindowSizeChangeReason wmReason, const std::shared_ptr<RSTransaction>& rsTransaction,
839     const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
840 {
841     if ((wmRect != preRect) || (wmReason != lastSizeChangeReason_) || !postTaskDone_) {
842         NotifySizeChange(wmRect, wmReason);
843         lastSizeChangeReason_ = wmReason;
844         postTaskDone_ = true;
845     }
846     UpdateViewportConfig(wmRect, wmReason, rsTransaction, nullptr, avoidAreas);
847     UpdateFrameLayoutCallbackIfNeeded(wmReason);
848 }
849 
UpdateRectForOtherReason(const Rect & wmRect,const Rect & preRect,WindowSizeChangeReason wmReason,const std::shared_ptr<RSTransaction> & rsTransaction,const std::map<AvoidAreaType,AvoidArea> & avoidAreas)850 void WindowSessionImpl::UpdateRectForOtherReason(const Rect& wmRect, const Rect& preRect,
851     WindowSizeChangeReason wmReason, const std::shared_ptr<RSTransaction>& rsTransaction,
852     const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
853 {
854     if (handler_ == nullptr) {
855         UpdateRectForOtherReasonTask(wmRect, preRect, wmReason, rsTransaction, avoidAreas);
856         return;
857     }
858 
859     auto task = [weak = wptr(this), wmReason, wmRect, preRect, rsTransaction, avoidAreas] {
860         auto window = weak.promote();
861         if (!window) {
862             TLOGE(WmsLogTag::WMS_LAYOUT, "window is null, updateViewPortConfig failed");
863             return;
864         }
865         bool ifNeedCommitRsTransaction = CheckIfNeedCommitRsTransaction(wmReason);
866         if (rsTransaction && ifNeedCommitRsTransaction) {
867             RSTransaction::FlushImplicitTransaction();
868             rsTransaction->Begin();
869         }
870         window->UpdateRectForOtherReasonTask(wmRect, preRect, wmReason, rsTransaction, avoidAreas);
871         if (rsTransaction && ifNeedCommitRsTransaction) {
872             rsTransaction->Commit();
873         }
874     };
875     handler_->PostTask(task, "WMS_WindowSessionImpl_UpdateRectForOtherReason");
876 }
877 
NotifyRotationAnimationEnd()878 void WindowSessionImpl::NotifyRotationAnimationEnd()
879 {
880     auto task = [weak = wptr(this)] {
881         auto window = weak.promote();
882         if (!window) {
883             TLOGE(WmsLogTag::WMS_LAYOUT, "window is null");
884             return;
885         }
886         std::shared_ptr<Ace::UIContent> uiContent = window->GetUIContentSharedPtr();
887         if (uiContent == nullptr) {
888             WLOGFW("uiContent is null!");
889             return;
890         }
891         uiContent->NotifyRotationAnimationEnd();
892     };
893     if (handler_ == nullptr) {
894         TLOGW(WmsLogTag::WMS_LAYOUT, "handler is null!");
895         task();
896     } else {
897         handler_->PostTask(task, "WMS_WindowSessionImpl_NotifyRotationAnimationEnd");
898     }
899 }
900 
FlushLayoutSize(int32_t width,int32_t height)901 void WindowSessionImpl::FlushLayoutSize(int32_t width, int32_t height)
902 {
903     if (!WindowHelper::IsMainWindow(GetType())) {
904         return;
905     }
906     WSRect rect = { 0, 0, width, height };
907     bool windowSizeChanged = true;
908     bool enableFrameLayoutFinishCb = true;
909     if (windowSizeChanged_.compare_exchange_strong(windowSizeChanged, false) ||
910         enableFrameLayoutFinishCb_.compare_exchange_strong(enableFrameLayoutFinishCb, false) || layoutRect_ != rect) {
911         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
912             "NotifyFrameLayoutFinishFromApp, id: %u, rect: %s, notifyListener: %d",
913             GetWindowId(), rect.ToString().c_str(), enableFrameLayoutFinishCb_.load());
914         TLOGI(WmsLogTag::WMS_LAYOUT,
915             "NotifyFrameLayoutFinishFromApp, id: %{public}u, rect: %{public}s, notifyListener: %{public}d",
916             GetWindowId(), rect.ToString().c_str(), enableFrameLayoutFinishCb_.load());
917         if (auto session = GetHostSession()) {
918             session->NotifyFrameLayoutFinishFromApp(enableFrameLayoutFinishCb_, rect);
919         }
920         layoutRect_ = rect;
921         enableFrameLayoutFinishCb_ = false;
922     }
923 }
924 
GetTitleButtonVisible(bool & hideMaximizeButton,bool & hideMinimizeButton,bool & hideSplitButton,bool & hideCloseButton)925 void WindowSessionImpl::GetTitleButtonVisible(bool& hideMaximizeButton, bool& hideMinimizeButton,
926     bool& hideSplitButton, bool& hideCloseButton)
927 {
928     if (!IsPcOrPadFreeMultiWindowMode()) {
929         TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
930         return;
931     }
932     if (hideMaximizeButton > !windowTitleVisibleFlags_.isMaximizeVisible) {
933         TLOGW(WmsLogTag::WMS_LAYOUT, "isMaximizeVisible param INVALID");
934     }
935     hideMaximizeButton = hideMaximizeButton || (!windowTitleVisibleFlags_.isMaximizeVisible);
936     if (hideMinimizeButton > !windowTitleVisibleFlags_.isMinimizeVisible) {
937         TLOGW(WmsLogTag::WMS_LAYOUT, "isMinimizeVisible param INVALID");
938     }
939     hideMinimizeButton = hideMinimizeButton || (!windowTitleVisibleFlags_.isMinimizeVisible);
940     if (hideSplitButton > !windowTitleVisibleFlags_.isSplitVisible) {
941         TLOGW(WmsLogTag::WMS_LAYOUT, "isSplitVisible param INVALID");
942     }
943     hideSplitButton = hideSplitButton || (!windowTitleVisibleFlags_.isSplitVisible);
944     if (hideCloseButton > !windowTitleVisibleFlags_.isCloseVisible) {
945         TLOGW(WmsLogTag::WMS_LAYOUT, "isCloseVisible param INVALID");
946     }
947     hideCloseButton = hideCloseButton || (!windowTitleVisibleFlags_.isCloseVisible);
948 }
949 
UpdateDensity()950 void WindowSessionImpl::UpdateDensity()
951 {
952     auto preRect = GetRect();
953     UpdateViewportConfig(preRect, WindowSizeChangeReason::UNDEFINED);
954     WLOGFI("WindowSessionImpl::UpdateDensity [%{public}d, %{public}d, %{public}u, %{public}u]",
955         preRect.posX_, preRect.posY_, preRect.width_, preRect.height_);
956 }
957 
SetUniqueVirtualPixelRatio(bool useUniqueDensity,float virtualPixelRatio)958 void WindowSessionImpl::SetUniqueVirtualPixelRatio(bool useUniqueDensity, float virtualPixelRatio)
959 {
960     TLOGI(WmsLogTag::DEFAULT, "old {useUniqueDensity: %{public}d, virtualPixelRatio: %{public}f}, "\
961         "new {useUniqueDensity: %{public}d, virtualPixelRatio: %{public}f}",
962         useUniqueDensity_, virtualPixelRatio_, useUniqueDensity, virtualPixelRatio);
963     bool oldUseUniqueDensity = useUniqueDensity_;
964     useUniqueDensity_ = useUniqueDensity;
965     if (useUniqueDensity_) {
966         float oldVirtualPixelRatio = virtualPixelRatio_;
967         virtualPixelRatio_ = virtualPixelRatio;
968         if (!MathHelper::NearZero(oldVirtualPixelRatio - virtualPixelRatio)) {
969             UpdateDensity();
970             SetUniqueVirtualPixelRatioForSub(useUniqueDensity, virtualPixelRatio);
971         }
972     } else {
973         if (oldUseUniqueDensity) {
974             UpdateDensity();
975             SetUniqueVirtualPixelRatioForSub(useUniqueDensity, virtualPixelRatio);
976         }
977     }
978 }
979 
CopyUniqueDensityParameter(sptr<WindowSessionImpl> parentWindow)980 void WindowSessionImpl::CopyUniqueDensityParameter(sptr<WindowSessionImpl> parentWindow)
981 {
982     if (parentWindow) {
983         useUniqueDensity_ = parentWindow->useUniqueDensity_;
984         virtualPixelRatio_ = parentWindow->virtualPixelRatio_;
985     }
986 }
987 
FindMainWindowWithContext()988 sptr<WindowSessionImpl> WindowSessionImpl::FindMainWindowWithContext()
989 {
990     if (context_ == nullptr) {
991         return nullptr;
992     }
993     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
994     for (const auto& winPair : windowSessionMap_) {
995         auto win = winPair.second.second;
996         if (win && win->GetType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
997             context_.get() == win->GetContext().get()) {
998             return win;
999         }
1000     }
1001     TLOGD(WmsLogTag::WMS_MAIN, "Can not find main window, not app type");
1002     return nullptr;
1003 }
1004 
FindExtensionWindowWithContext()1005 sptr<WindowSessionImpl> WindowSessionImpl::FindExtensionWindowWithContext()
1006 {
1007     if (context_ == nullptr) {
1008         return nullptr;
1009     }
1010     std::shared_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
1011     for (const auto& window : windowExtensionSessionSet_) {
1012         if (window && context_.get() == window->GetContext().get()) {
1013             return window;
1014         }
1015     }
1016     return nullptr;
1017 }
1018 
SetUniqueVirtualPixelRatioForSub(bool useUniqueDensity,float virtualPixelRatio)1019 void WindowSessionImpl::SetUniqueVirtualPixelRatioForSub(bool useUniqueDensity, float virtualPixelRatio)
1020 {
1021     if (subWindowSessionMap_.count(GetPersistentId()) == 0) {
1022         return;
1023     }
1024     for (auto& subWindowSession : subWindowSessionMap_.at(GetPersistentId())) {
1025         subWindowSession->SetUniqueVirtualPixelRatio(useUniqueDensity, virtualPixelRatio);
1026     }
1027 }
1028 
UpdateOrientation()1029 WSError WindowSessionImpl::UpdateOrientation()
1030 {
1031     TLOGD(WmsLogTag::DMS, "UpdateOrientation, wid: %{public}d", GetPersistentId());
1032     return WSError::WS_OK;
1033 }
1034 
UpdateDisplayId(uint64_t displayId)1035 WSError WindowSessionImpl::UpdateDisplayId(uint64_t displayId)
1036 {
1037     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, displayId: %{public}" PRIu64, GetPersistentId(), displayId);
1038     property_->SetDisplayId(displayId);
1039     return WSError::WS_OK;
1040 }
1041 
UpdateFocus(bool isFocused)1042 WSError WindowSessionImpl::UpdateFocus(bool isFocused)
1043 {
1044     TLOGI(WmsLogTag::WMS_FOCUS, "Report update focus: %{public}u, id: %{public}d", isFocused, GetPersistentId());
1045     isFocused_ = isFocused;
1046     if (isFocused) {
1047         HiSysEventWrite(
1048             OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
1049             "FOCUS_WINDOW",
1050             OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
1051             "PID", getpid(),
1052             "UID", getuid(),
1053             "BUNDLE_NAME", property_->GetSessionInfo().bundleName_);
1054         NotifyAfterFocused();
1055     } else {
1056         NotifyAfterUnfocused();
1057     }
1058     return WSError::WS_OK;
1059 }
1060 
IsFocused() const1061 bool WindowSessionImpl::IsFocused() const
1062 {
1063     if (IsWindowSessionInvalid()) {
1064         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
1065         return false;
1066     }
1067 
1068     TLOGD(WmsLogTag::WMS_FOCUS, "window id = %{public}d, isFocused = %{public}d", GetPersistentId(), isFocused_.load());
1069     return isFocused_;
1070 }
1071 
RequestFocus() const1072 WMError WindowSessionImpl::RequestFocus() const
1073 {
1074     if (IsWindowSessionInvalid()) {
1075         WLOGFD("session is invalid");
1076         return WMError::WM_ERROR_INVALID_WINDOW;
1077     }
1078     return SingletonContainer::Get<WindowAdapter>().RequestFocusStatus(GetPersistentId(), true);
1079 }
1080 
1081 /** @note @window.focus */
RequestFocusByClient(bool isFocused) const1082 WMError WindowSessionImpl::RequestFocusByClient(bool isFocused) const
1083 {
1084     if (!SessionPermission::IsSystemCalling()) {
1085         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
1086         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1087     }
1088     if (IsWindowSessionInvalid()) {
1089         TLOGD(WmsLogTag::WMS_FOCUS, "session is invalid");
1090         return WMError::WM_ERROR_INVALID_WINDOW;
1091     }
1092     auto hostSession = GetHostSession();
1093     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1094     auto ret = hostSession->RequestFocus(isFocused);
1095     return static_cast<WMError>(ret);
1096 }
1097 
IsNotifyInteractiveDuplicative(bool interactive)1098 bool WindowSessionImpl::IsNotifyInteractiveDuplicative(bool interactive)
1099 {
1100     if (interactive == interactive_ && hasFirstNotifyInteractive_) {
1101         return true;
1102     }
1103     hasFirstNotifyInteractive_ = true;
1104     if (interactive_ != interactive) {
1105         interactive_ = interactive;
1106     }
1107     return false;
1108 }
1109 
NotifyForegroundInteractiveStatus(bool interactive)1110 void WindowSessionImpl::NotifyForegroundInteractiveStatus(bool interactive)
1111 {
1112     WLOGFI("NotifyForegroundInteractiveStatus %{public}d", interactive);
1113     if (IsWindowSessionInvalid() || state_ != WindowState::STATE_SHOWN) {
1114         return;
1115     }
1116     if (IsNotifyInteractiveDuplicative(interactive)) {
1117         return;
1118     }
1119     if (interactive) {
1120         NotifyAfterResumed();
1121     } else {
1122         NotifyAfterPaused();
1123     }
1124 }
1125 
UpdateWindowMode(WindowMode mode)1126 WSError WindowSessionImpl::UpdateWindowMode(WindowMode mode)
1127 {
1128     return WSError::WS_OK;
1129 }
1130 
1131 /** @note @window.layout */
GetVirtualPixelRatio()1132 float WindowSessionImpl::GetVirtualPixelRatio()
1133 {
1134     TLOGD(WmsLogTag::WMS_LAYOUT, "virtualPixelRatio: %{public}f", virtualPixelRatio_);
1135     return virtualPixelRatio_;
1136 }
1137 
GetVirtualPixelRatio(const sptr<DisplayInfo> & displayInfo)1138 float WindowSessionImpl::GetVirtualPixelRatio(const sptr<DisplayInfo>& displayInfo)
1139 {
1140     if (useUniqueDensity_) {
1141         return virtualPixelRatio_;
1142     }
1143     return displayInfo->GetVirtualPixelRatio();
1144 }
1145 
UpdateViewportConfig(const Rect & rect,WindowSizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction,const sptr<DisplayInfo> & info,const std::map<AvoidAreaType,AvoidArea> & avoidAreas)1146 void WindowSessionImpl::UpdateViewportConfig(const Rect& rect, WindowSizeChangeReason reason,
1147     const std::shared_ptr<RSTransaction>& rsTransaction, const sptr<DisplayInfo>& info,
1148     const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
1149 {
1150     // update avoid areas to listeners
1151     for (const auto& [type, avoidArea] : avoidAreas) {
1152         TLOGD(WmsLogTag::WMS_IMMS, "avoid type %{public}u area %{public}s",
1153             type, avoidArea.ToString().c_str());
1154         if (lastAvoidAreaMap_[type] != avoidArea) {
1155             lastAvoidAreaMap_[type] = avoidArea;
1156             NotifyAvoidAreaChange(new AvoidArea(avoidArea), type);
1157         }
1158     }
1159 
1160     sptr<DisplayInfo> displayInfo;
1161     if (info == nullptr) {
1162         auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
1163         if (display == nullptr) {
1164             WLOGFE("display is null!");
1165             return;
1166         }
1167         displayInfo = display->GetDisplayInfo();
1168     } else {
1169         displayInfo = info;
1170     }
1171     if (displayInfo == nullptr) {
1172         WLOGFE("displayInfo is null!");
1173         return;
1174     }
1175     if (rect.width_ <= 0 || rect.height_ <= 0) {
1176         TLOGW(WmsLogTag::WMS_LAYOUT, "invalid width: %{public}d, height: %{public}d, id: %{public}d",
1177               rect.width_, rect.height_, GetPersistentId());
1178         return;
1179     }
1180     auto rotation =  ONE_FOURTH_FULL_CIRCLE_DEGREE * static_cast<uint32_t>(displayInfo->GetOriginRotation());
1181     auto deviceRotation = static_cast<uint32_t>(displayInfo->GetDefaultDeviceRotationOffset());
1182     uint32_t transformHint = (rotation + deviceRotation) % FULL_CIRCLE_DEGREE;
1183     float density = GetVirtualPixelRatio(displayInfo);
1184     int32_t orientation = static_cast<int32_t>(displayInfo->GetDisplayOrientation());
1185     virtualPixelRatio_ = density;
1186     TLOGI(WmsLogTag::WMS_LAYOUT, "[rotation,deviceRotation,transformHint,virtualPixelRatio]:[%{public}u,"
1187         "%{public}u,%{public}u,%{public}f]", rotation, deviceRotation, transformHint, virtualPixelRatio_);
1188     auto config = FillViewportConfig(rect, density, orientation, transformHint);
1189     {
1190         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1191         if (uiContent == nullptr) {
1192             WLOGFW("uiContent is null!");
1193             return;
1194         }
1195         uiContent->UpdateViewportConfig(config, reason, rsTransaction, lastAvoidAreaMap_);
1196     }
1197     if (WindowHelper::IsUIExtensionWindow(GetType())) {
1198         TLOGD(WmsLogTag::WMS_LAYOUT, "Id:%{public}d reason:%{public}d windowRect:[%{public}d,%{public}d,"
1199             "%{public}u,%{public}u] displayOrientation:%{public}d",
1200             GetPersistentId(), reason, rect.posX_, rect.posY_, rect.width_, rect.height_, orientation);
1201     } else {
1202         TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d reason:%{public}d windowRect:[%{public}d,%{public}d,"
1203             "%{public}u,%{public}u] displayOrientation:%{public}d",
1204             GetPersistentId(), reason, rect.posX_, rect.posY_, rect.width_, rect.height_, orientation);
1205     }
1206 }
1207 
GetFloatingWindowParentId()1208 int32_t WindowSessionImpl::GetFloatingWindowParentId()
1209 {
1210     if (context_.get() == nullptr) {
1211         return INVALID_SESSION_ID;
1212     }
1213     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
1214     for (const auto& winPair : windowSessionMap_) {
1215         if (winPair.second.second && WindowHelper::IsMainWindow(winPair.second.second->GetType()) &&
1216             winPair.second.second->GetProperty() &&
1217             context_.get() == winPair.second.second->GetContext().get()) {
1218             WLOGFD("Find parent, [parentName: %{public}s, selfPersistentId: %{public}d]",
1219                 winPair.second.second->GetProperty()->GetWindowName().c_str(), GetPersistentId());
1220             return winPair.second.second->GetProperty()->GetPersistentId();
1221         }
1222     }
1223     return INVALID_SESSION_ID;
1224 }
1225 
GetRect() const1226 Rect WindowSessionImpl::GetRect() const
1227 {
1228     return property_->GetWindowRect();
1229 }
1230 
UpdateTitleButtonVisibility()1231 void WindowSessionImpl::UpdateTitleButtonVisibility()
1232 {
1233     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1234     if (uiContent == nullptr || !IsDecorEnable()) {
1235         return;
1236     }
1237     WindowType windowType = GetType();
1238     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
1239     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
1240     if (IsPcOrPadCapabilityEnabled() && (isSubWindow || isDialogWindow)) {
1241         WLOGFD("hide other buttons except close");
1242         uiContent->HideWindowTitleButton(true, true, true, false);
1243         return;
1244     }
1245     auto windowModeSupportType = property_->GetWindowModeSupportType();
1246     bool hideSplitButton = !(windowModeSupportType & WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
1247     // not support fullscreen in split and floating mode, or not support float in fullscreen mode
1248     bool hideMaximizeButton = (!(windowModeSupportType & WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN) &&
1249         (GetMode() == WindowMode::WINDOW_MODE_FLOATING || WindowHelper::IsSplitWindowMode(GetMode()))) ||
1250         (!(windowModeSupportType & WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING) &&
1251         GetMode() == WindowMode::WINDOW_MODE_FULLSCREEN);
1252     bool hideMinimizeButton = false;
1253     bool hideCloseButton = false;
1254     GetTitleButtonVisible(hideMaximizeButton, hideMinimizeButton, hideSplitButton, hideCloseButton);
1255     TLOGI(WmsLogTag::WMS_LAYOUT, "[hideSplit, hideMaximize, hideMinimizeButton, hideCloseButton]:"
1256         "[%{public}d, %{public}d, %{public}d, %{public}d]",
1257         hideSplitButton, hideMaximizeButton, hideMinimizeButton, hideCloseButton);
1258     if (property_->GetCompatibleModeInPc()) {
1259         if (IsFreeMultiWindowMode()) {
1260             uiContent->HideWindowTitleButton(true, hideMaximizeButton, hideMinimizeButton, hideCloseButton);
1261         } else {
1262             uiContent->HideWindowTitleButton(hideSplitButton, true, hideMinimizeButton, hideCloseButton);
1263         }
1264     } else {
1265         uiContent->HideWindowTitleButton(hideSplitButton, hideMaximizeButton, hideMinimizeButton, hideCloseButton);
1266     }
1267 }
1268 
NapiSetUIContent(const std::string & contentInfo,napi_env env,napi_value storage,BackupAndRestoreType type,sptr<IRemoteObject> token,AppExecFwk::Ability * ability)1269 WMError WindowSessionImpl::NapiSetUIContent(const std::string& contentInfo, napi_env env, napi_value storage,
1270     BackupAndRestoreType type, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
1271 {
1272     return SetUIContentInner(contentInfo, env, storage,
1273         type == BackupAndRestoreType::NONE ? WindowSetUIContentType::DEFAULT : WindowSetUIContentType::RESTORE,
1274         type, ability);
1275 }
1276 
SetUIContentByName(const std::string & contentInfo,napi_env env,napi_value storage,AppExecFwk::Ability * ability)1277 WMError WindowSessionImpl::SetUIContentByName(
1278     const std::string& contentInfo, napi_env env, napi_value storage, AppExecFwk::Ability* ability)
1279 {
1280     return SetUIContentInner(contentInfo, env, storage, WindowSetUIContentType::BY_NAME,
1281         BackupAndRestoreType::NONE, ability);
1282 }
1283 
SetUIContentByAbc(const std::string & contentInfo,napi_env env,napi_value storage,AppExecFwk::Ability * ability)1284 WMError WindowSessionImpl::SetUIContentByAbc(
1285     const std::string& contentInfo, napi_env env, napi_value storage, AppExecFwk::Ability* ability)
1286 {
1287     return SetUIContentInner(contentInfo, env, storage, WindowSetUIContentType::BY_ABC,
1288         BackupAndRestoreType::NONE, ability);
1289 }
1290 
DestroyExistUIContent()1291 void WindowSessionImpl::DestroyExistUIContent()
1292 {
1293     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1294     if (uiContent) {
1295         uiContent->Destroy();
1296     }
1297 }
1298 
InitUIContent(const std::string & contentInfo,napi_env env,napi_value storage,WindowSetUIContentType setUIContentType,BackupAndRestoreType restoreType,AppExecFwk::Ability * ability,OHOS::Ace::UIContentErrorCode & aceRet)1299 WMError WindowSessionImpl::InitUIContent(const std::string& contentInfo, napi_env env, napi_value storage,
1300     WindowSetUIContentType setUIContentType, BackupAndRestoreType restoreType, AppExecFwk::Ability* ability,
1301     OHOS::Ace::UIContentErrorCode& aceRet)
1302 {
1303     {
1304         DestroyExistUIContent();
1305     }
1306     std::unique_ptr<Ace::UIContent> uiContent = ability != nullptr ? Ace::UIContent::Create(ability) :
1307         Ace::UIContent::Create(context_.get(), reinterpret_cast<NativeEngine*>(env));
1308     if (uiContent == nullptr) {
1309         TLOGE(WmsLogTag::WMS_LIFE, "fail to NapiSetUIContent id: %{public}d", GetPersistentId());
1310         return WMError::WM_ERROR_NULLPTR;
1311     }
1312     switch (setUIContentType) {
1313         default:
1314         case WindowSetUIContentType::DEFAULT: {
1315             if (isUIExtensionAbilityProcess_ && property_->GetExtensionFlag() == true) {
1316                 // subWindow created by UIExtensionAbility
1317                 uiContent->SetUIExtensionSubWindow(true);
1318                 uiContent->SetUIExtensionAbilityProcess(true);
1319             } else {
1320                 auto routerStack = GetRestoredRouterStack();
1321                 auto type = GetAceContentInfoType(BackupAndRestoreType::RESOURCESCHEDULE_RECOVERY);
1322                 if (!routerStack.empty() &&
1323                     uiContent->Restore(this, routerStack, storage, type) == Ace::UIContentErrorCode::NO_ERRORS) {
1324                     TLOGI(WmsLogTag::WMS_LIFE, "Restore router stack succeed.");
1325                     break;
1326                 }
1327             }
1328             aceRet = uiContent->Initialize(this, contentInfo, storage);
1329             break;
1330         }
1331         case WindowSetUIContentType::RESTORE:
1332             aceRet = uiContent->Restore(this, contentInfo, storage, restoreType == BackupAndRestoreType::CONTINUATION ?
1333                 Ace::ContentInfoType::CONTINUATION : Ace::ContentInfoType::APP_RECOVERY);
1334             break;
1335         case WindowSetUIContentType::BY_NAME:
1336             aceRet = uiContent->InitializeByName(this, contentInfo, storage);
1337             break;
1338         case WindowSetUIContentType::BY_ABC:
1339             auto abcContent = GetAbcContent(contentInfo);
1340             aceRet = uiContent->Initialize(this, abcContent, storage, contentInfo);
1341             break;
1342     }
1343     // make uiContent available after Initialize/Restore
1344     {
1345         std::unique_lock<std::shared_mutex> lock(uiContentMutex_);
1346         uiContent_ = std::move(uiContent);
1347         WLOGFI("UIContent Initialize, isUIExtensionSubWindow:%{public}d, isUIExtensionAbilityProcess:%{public}d",
1348             uiContent_->IsUIExtensionSubWindow(), uiContent_->IsUIExtensionAbilityProcess());
1349     }
1350     return WMError::WM_OK;
1351 }
1352 
SetUIContentInner(const std::string & contentInfo,napi_env env,napi_value storage,WindowSetUIContentType setUIContentType,BackupAndRestoreType restoreType,AppExecFwk::Ability * ability)1353 WMError WindowSessionImpl::SetUIContentInner(const std::string& contentInfo, napi_env env, napi_value storage,
1354     WindowSetUIContentType setUIContentType, BackupAndRestoreType restoreType, AppExecFwk::Ability* ability)
1355 {
1356     TLOGD(WmsLogTag::WMS_LIFE, "NapiSetUIContent: %{public}s state:%{public}u", contentInfo.c_str(), state_);
1357     if (IsWindowSessionInvalid()) {
1358         WLOGFE("[WMSLife]interrupt set uicontent because window is invalid! window state: %{public}d", state_);
1359         return WMError::WM_ERROR_INVALID_WINDOW;
1360     }
1361     NotifySetUIContentComplete();
1362     OHOS::Ace::UIContentErrorCode aceRet = OHOS::Ace::UIContentErrorCode::NO_ERRORS;
1363     WMError initUIContentRet = InitUIContent(contentInfo, env, storage, setUIContentType, restoreType, ability, aceRet);
1364     if (initUIContentRet != WMError::WM_OK) {
1365         TLOGE(WmsLogTag::WMS_LIFE, "Init UIContent fail, ret:%{public}u", initUIContentRet);
1366         return initUIContentRet;
1367     }
1368     if (auto uiContent = GetUIContentSharedPtr()) {
1369         TLOGI(WmsLogTag::WMS_LAYOUT, "single hand, id:%{public}d, posX:%{public}d, posY:%{public}d, "
1370               "scaleX:%{public}f, scaleY:%{public}f", GetPersistentId(),
1371               singleHandTransform_.posX, singleHandTransform_.posY,
1372               singleHandTransform_.scaleX, singleHandTransform_.scaleY);
1373         uiContent->UpdateSingleHandTransform(singleHandTransform_);
1374     }
1375     WindowType winType = GetType();
1376     bool isSubWindow = WindowHelper::IsSubWindow(winType);
1377     bool isDialogWindow = WindowHelper::IsDialogWindow(winType);
1378     if (IsDecorEnable()) {
1379         if (isSubWindow) {
1380             SetAPPWindowLabel(subWindowTitle_);
1381         } else if (isDialogWindow) {
1382             SetAPPWindowLabel(dialogTitle_);
1383         }
1384     }
1385 
1386     AppForceLandscapeConfig config = {};
1387     if (WindowHelper::IsMainWindow(winType) && GetAppForceLandscapeConfig(config) == WMError::WM_OK &&
1388         config.mode_ == FORCE_SPLIT_MODE) {
1389         SetForceSplitEnable(true, config.homePage_);
1390     }
1391 
1392     uint32_t version = 0;
1393     if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
1394         version = context_->GetApplicationInfo()->apiCompatibleVersion;
1395     }
1396     // 10 ArkUI new framework support after API10
1397     if (version < 10) {
1398         SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
1399         if (!isSystembarPropertiesSet_) {
1400             SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty());
1401         }
1402     } else if (isIgnoreSafeAreaNeedNotify_) {
1403         SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
1404     } else if (isSubWindow) {
1405         SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
1406         isIgnoreSafeAreaNeedNotify_ = false;
1407     }
1408 
1409     // UIContent may be nullptr on setting system bar properties, need to set menubar color on UIContent init.
1410     if (auto uiContent = GetUIContentSharedPtr()) {
1411         auto property = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
1412         uiContent->SetStatusBarItemColor(property.contentColor_);
1413     }
1414 
1415     UpdateDecorEnable(true);
1416     if (state_ == WindowState::STATE_SHOWN) {
1417         // UIContent may be nullptr when show window, need to notify again when window is shown
1418         {
1419             std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1420             if (uiContent != nullptr) {
1421                 uiContent->Foreground();
1422             }
1423         }
1424         UpdateTitleButtonVisibility();
1425     }
1426     UpdateViewportConfig(GetRect(), WindowSizeChangeReason::UNDEFINED);
1427     if (shouldReNotifyFocus_) {
1428         // uiContent may be nullptr when notify focus status, need to notify again when uiContent is not empty.
1429         NotifyUIContentFocusStatus();
1430         shouldReNotifyFocus_ = false;
1431     }
1432     if (aceRet != OHOS::Ace::UIContentErrorCode::NO_ERRORS) {
1433         WLOGFE("failed to init or restore uicontent with file %{public}s. errorCode: %{public}d",
1434             contentInfo.c_str(), static_cast<uint16_t>(aceRet));
1435         return WMError::WM_ERROR_INVALID_PARAM;
1436     }
1437     TLOGD(WmsLogTag::WMS_LIFE, "notify uiContent window size change end");
1438     return WMError::WM_OK;
1439 }
1440 
GetAbcContent(const std::string & abcPath)1441 std::shared_ptr<std::vector<uint8_t>> WindowSessionImpl::GetAbcContent(const std::string& abcPath)
1442 {
1443     std::filesystem::path abcFile { abcPath };
1444     if (abcFile.empty() || !abcFile.is_absolute() || !std::filesystem::exists(abcFile)) {
1445         WLOGFE("abc file path is not valid");
1446         return nullptr;
1447     }
1448     int begin, end;
1449     std::fstream file(abcFile, std::ios::in | std::ios::binary);
1450     if (!file) {
1451         WLOGFE("abc file is not valid");
1452         return nullptr;
1453     }
1454     begin = file.tellg();
1455     file.seekg(0, std::ios::end);
1456     end = file.tellg();
1457     int len = end - begin;
1458     WLOGFD("abc file: %{public}s, size: %{public}d", abcPath.c_str(), len);
1459 
1460     if (len <= 0) {
1461         WLOGFE("abc file size is 0");
1462         return nullptr;
1463     }
1464     std::vector<uint8_t> abcBytes(len);
1465     file.seekg(0, std::ios::beg);
1466     file.read(reinterpret_cast<char *>(abcBytes.data()), len);
1467     return std::make_shared<std::vector<uint8_t>>(abcBytes);
1468 }
1469 
UpdateDecorEnableToAce(bool isDecorEnable)1470 void WindowSessionImpl::UpdateDecorEnableToAce(bool isDecorEnable)
1471 {
1472     {
1473         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1474         if (uiContent != nullptr) {
1475             WindowMode mode = GetMode();
1476             bool decorVisible = mode == WindowMode::WINDOW_MODE_FLOATING ||
1477                 mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
1478                 (mode == WindowMode::WINDOW_MODE_FULLSCREEN && !property_->IsLayoutFullScreen());
1479             WLOGFD("[WSLayout]Notify uiContent window mode change end,decorVisible:%{public}d", decorVisible);
1480             if (windowSystemConfig_.freeMultiWindowSupport_) {
1481                 auto isSubWindow = WindowHelper::IsSubWindow(GetType());
1482                 decorVisible = decorVisible && ((property_->GetIsPcAppInPad() && isSubWindow) ||
1483                     (windowSystemConfig_.freeMultiWindowEnable_ && mode != WindowMode::WINDOW_MODE_FULLSCREEN));
1484             }
1485             uiContent->UpdateDecorVisible(decorVisible, isDecorEnable);
1486             return;
1487         }
1488     }
1489     std::lock_guard<std::recursive_mutex> lockListener(windowChangeListenerMutex_);
1490     auto windowChangeListeners = GetListeners<IWindowChangeListener>();
1491     for (auto& listener : windowChangeListeners) {
1492         if (listener.GetRefPtr() != nullptr) {
1493             listener.GetRefPtr()->OnModeChange(GetMode(), isDecorEnable);
1494         }
1495     }
1496 }
1497 
UpdateDecorEnable(bool needNotify,WindowMode mode)1498 void WindowSessionImpl::UpdateDecorEnable(bool needNotify, WindowMode mode)
1499 {
1500     if (mode == WindowMode::WINDOW_MODE_UNDEFINED) {
1501         mode = GetMode();
1502     }
1503     if (needNotify) {
1504         {
1505             std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1506             if (uiContent != nullptr) {
1507                 bool decorVisible = mode == WindowMode::WINDOW_MODE_FLOATING ||
1508                     mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
1509                     (mode == WindowMode::WINDOW_MODE_FULLSCREEN && !property_->IsLayoutFullScreen());
1510                 if (windowSystemConfig_.freeMultiWindowSupport_) {
1511                     auto isSubWindow = WindowHelper::IsSubWindow(GetType());
1512                     decorVisible = decorVisible && ((property_->GetIsPcAppInPad() && isSubWindow) ||
1513                         (windowSystemConfig_.freeMultiWindowEnable_ && mode != WindowMode::WINDOW_MODE_FULLSCREEN));
1514                 }
1515                 WLOGFD("[WSLayout]Notify uiContent window mode change end,decorVisible:%{public}d", decorVisible);
1516                 uiContent->UpdateDecorVisible(decorVisible, IsDecorEnable());
1517             }
1518         }
1519         NotifyModeChange(mode, IsDecorEnable());
1520     }
1521 }
1522 
NotifyModeChange(WindowMode mode,bool hasDeco)1523 void WindowSessionImpl::NotifyModeChange(WindowMode mode, bool hasDeco)
1524 {
1525     {
1526         std::lock_guard<std::recursive_mutex> lockListener(windowChangeListenerMutex_);
1527         auto windowChangeListeners = GetListeners<IWindowChangeListener>();
1528         for (auto& listener : windowChangeListeners) {
1529             if (listener.GetRefPtr() != nullptr) {
1530                 listener.GetRefPtr()->OnModeChange(mode, hasDeco);
1531             }
1532         }
1533     }
1534 
1535     if (GetHostSession()) {
1536         property_->SetWindowMode(mode);
1537         property_->SetDecorEnable(hasDeco);
1538     }
1539     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE);
1540     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE);
1541 }
1542 
GetSurfaceNode() const1543 std::shared_ptr<RSSurfaceNode> WindowSessionImpl::GetSurfaceNode() const
1544 {
1545     TLOGI(WmsLogTag::DEFAULT, "name:%{public}s, id:%{public}d",
1546         property_->GetWindowName().c_str(), GetPersistentId());
1547     return surfaceNode_;
1548 }
1549 
GetContext() const1550 const std::shared_ptr<AbilityRuntime::Context> WindowSessionImpl::GetContext() const
1551 {
1552     TLOGI(WmsLogTag::DEFAULT, "name:%{public}s, id:%{public}d",
1553         property_->GetWindowName().c_str(), GetPersistentId());
1554     return context_;
1555 }
1556 
GetRequestRect() const1557 Rect WindowSessionImpl::GetRequestRect() const
1558 {
1559     return property_->GetRequestRect();
1560 }
1561 
GetType() const1562 WindowType WindowSessionImpl::GetType() const
1563 {
1564     return property_->GetWindowType();
1565 }
1566 
GetWindowName() const1567 const std::string& WindowSessionImpl::GetWindowName() const
1568 {
1569     return property_->GetWindowName();
1570 }
1571 
GetWindowState() const1572 WindowState WindowSessionImpl::GetWindowState() const
1573 {
1574     return state_;
1575 }
1576 
GetRequestWindowState() const1577 WindowState WindowSessionImpl::GetRequestWindowState() const
1578 {
1579     return requestState_;
1580 }
1581 
1582 /** @note @window.focus */
SetExclusivelyHighlighted(bool isExclusivelyHighlighted)1583 WMError WindowSessionImpl::SetExclusivelyHighlighted(bool isExclusivelyHighlighted)
1584 {
1585     if (IsWindowSessionInvalid()) {
1586         return WMError::WM_ERROR_INVALID_WINDOW;
1587     }
1588     TLOGI(WmsLogTag::WMS_FOCUS, "windowId: %{public}d, isExclusivelyHighlighted: %{public}d",
1589         property_->GetPersistentId(), isExclusivelyHighlighted);
1590     if (WindowHelper::IsMainWindow(GetType()) || WindowHelper::IsDialogWindow(GetType()) ||
1591         WindowHelper::IsModalWindow(property_->GetWindowFlags())) {
1592         TLOGE(WmsLogTag::WMS_FOCUS, "unsupport window, type: %{public}u, windowFlags: %{public}u ",
1593             GetType(), property_->GetWindowFlags());
1594         return WMError::WM_ERROR_INVALID_CALLING;
1595     }
1596     if (property_->GetExclusivelyHighlighted() == isExclusivelyHighlighted) {
1597         TLOGD(WmsLogTag::WMS_FOCUS, "already exclusivelyHighlighted");
1598         return WMError::WM_OK;
1599     }
1600     property_->SetExclusivelyHighlighted(isExclusivelyHighlighted);
1601     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_EXCLUSIVE_HIGHLIGHTED);
1602 }
1603 
1604 /** @note @window.focus */
GetExclusivelyHighlighted() const1605 bool WindowSessionImpl::GetExclusivelyHighlighted() const
1606 {
1607     bool isExclusivelyHighlighted = property_->GetExclusivelyHighlighted();
1608     TLOGD(WmsLogTag::WMS_FOCUS, "windowId: %{public}d, isExclusivelyHighlighted: %{public}d",
1609         property_->GetPersistentId(), isExclusivelyHighlighted);
1610     return isExclusivelyHighlighted;
1611 }
1612 
1613 /** @note @window.focus */
NotifyHighlightChange(bool isHighlight)1614 WSError WindowSessionImpl::NotifyHighlightChange(bool isHighlight)
1615 {
1616     TLOGI(WmsLogTag::WMS_FOCUS, "windowId: %{public}d, isHighlight: %{public}u,", GetPersistentId(), isHighlight);
1617     isHighlighted_ = isHighlight;
1618     std::lock_guard<std::mutex> lockListener(highlightChangeListenerMutex_);
1619     auto highlightChangeListeners = GetListeners<IWindowHighlightChangeListener>();
1620     for (const auto& listener : highlightChangeListeners) {
1621         if (listener != nullptr) {
1622             listener->OnWindowHighlightChange(isHighlight);
1623         }
1624     }
1625     return WSError::WS_OK;
1626 }
1627 
1628 /** @note @window.focus */
IsWindowHighlighted(bool & highlighted) const1629 WMError WindowSessionImpl::IsWindowHighlighted(bool& highlighted) const
1630 {
1631     if (IsWindowSessionInvalid()) {
1632         TLOGE(WmsLogTag::WMS_FOCUS, "session is invalid");
1633         return WMError::WM_ERROR_INVALID_WINDOW;
1634     }
1635     highlighted = isHighlighted_.load();
1636     TLOGD(WmsLogTag::WMS_FOCUS, "windowId: %{public}d, isWindowHighlighted: %{public}d",
1637         GetPersistentId(), isHighlighted_.load());
1638     return WMError::WM_OK;
1639 }
1640 
SetFocusable(bool isFocusable)1641 WMError WindowSessionImpl::SetFocusable(bool isFocusable)
1642 {
1643     if (IsWindowSessionInvalid()) {
1644         return WMError::WM_ERROR_INVALID_WINDOW;
1645     }
1646     TLOGI(WmsLogTag::WMS_FOCUS, "set focusable: windowId = %{public}d, isFocusable = %{public}d",
1647         property_->GetPersistentId(), isFocusable);
1648     property_->SetFocusable(isFocusable);
1649     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE);
1650 }
1651 
GetFocusable() const1652 bool WindowSessionImpl::GetFocusable() const
1653 {
1654     bool isFocusable = property_->GetFocusable();
1655     TLOGD(WmsLogTag::WMS_FOCUS, "get focusable: windowId = %{public}d, isFocusable = %{public}d",
1656         property_->GetPersistentId(), isFocusable);
1657     return isFocusable;
1658 }
1659 
SetTouchable(bool isTouchable)1660 WMError WindowSessionImpl::SetTouchable(bool isTouchable)
1661 {
1662     WLOGFD("set touchable");
1663     if (IsWindowSessionInvalid()) {
1664         return WMError::WM_ERROR_INVALID_WINDOW;
1665     }
1666     property_->SetTouchable(isTouchable);
1667     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE);
1668 }
1669 
1670 /** @note @window.hierarchy */
SetTopmost(bool topmost)1671 WMError WindowSessionImpl::SetTopmost(bool topmost)
1672 {
1673     TLOGD(WmsLogTag::WMS_LAYOUT, "set topmost");
1674     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
1675     if (!isPC) {
1676         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
1677     }
1678     if (IsWindowSessionInvalid()) {
1679         return WMError::WM_ERROR_INVALID_WINDOW;
1680     }
1681     property_->SetTopmost(topmost);
1682     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TOPMOST);
1683 }
1684 
1685 /** @note @window.hierarchy */
IsTopmost() const1686 bool WindowSessionImpl::IsTopmost() const
1687 {
1688     return property_->IsTopmost();
1689 }
1690 
1691 /** @note @window.hierarchy */
SetMainWindowTopmost(bool isTopmost)1692 WMError WindowSessionImpl::SetMainWindowTopmost(bool isTopmost)
1693 {
1694     if (IsWindowSessionInvalid()) {
1695         return WMError::WM_ERROR_INVALID_WINDOW;
1696     }
1697     if (!IsPcOrPadFreeMultiWindowMode()) {
1698         TLOGE(WmsLogTag::WMS_HIERARCHY, "device not support");
1699         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
1700     }
1701     if (!WindowHelper::IsMainWindow(GetType())) {
1702         TLOGE(WmsLogTag::WMS_HIERARCHY, "window type is not supported");
1703         return WMError::WM_ERROR_INVALID_CALLING;
1704     }
1705     property_->SetMainWindowTopmost(isTopmost);
1706     uint32_t accessTokenId = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID());
1707     property_->SetAccessTokenId(accessTokenId);
1708     TLOGD(WmsLogTag::WMS_HIERARCHY, "tokenId=%{private}u, isTopmost=%{public}d", accessTokenId, isTopmost);
1709     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAIN_WINDOW_TOPMOST);
1710 }
1711 
IsMainWindowTopmost() const1712 bool WindowSessionImpl::IsMainWindowTopmost() const
1713 {
1714     return property_->IsMainWindowTopmost();
1715 }
1716 
SetResizeByDragEnabled(bool dragEnabled)1717 WMError WindowSessionImpl::SetResizeByDragEnabled(bool dragEnabled)
1718 {
1719     TLOGD(WmsLogTag::DEFAULT, "%{public}d", dragEnabled);
1720     if (IsWindowSessionInvalid()) {
1721         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
1722         return WMError::WM_ERROR_INVALID_WINDOW;
1723     }
1724     if (WindowHelper::IsMainWindow(GetType()) ||
1725         (WindowHelper::IsSubWindow(GetType()) && windowOption_->GetSubWindowDecorEnable())) {
1726         property_->SetDragEnabled(dragEnabled);
1727     } else {
1728         TLOGE(WmsLogTag::DEFAULT, "This is not main window or decor enabled sub window.");
1729         return WMError::WM_ERROR_INVALID_TYPE;
1730     }
1731     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED);
1732 }
1733 
1734 /** @note @window.hierarchy */
SetRaiseByClickEnabled(bool raiseEnabled)1735 WMError WindowSessionImpl::SetRaiseByClickEnabled(bool raiseEnabled)
1736 {
1737     WLOGFD("%{public}d", raiseEnabled);
1738     auto parentId = GetParentId();
1739     if (parentId == INVALID_SESSION_ID) {
1740         TLOGE(WmsLogTag::WMS_HIERARCHY, "Window id: %{public}d Parent id is invalid!",
1741               GetPersistentId());
1742         return WMError::WM_ERROR_INVALID_PARENT;
1743     }
1744     if (!WindowHelper::IsSubWindow(GetType())) {
1745         TLOGE(WmsLogTag::WMS_HIERARCHY, "Window id: %{public}d Must be app sub window!",
1746               GetPersistentId());
1747         return WMError::WM_ERROR_INVALID_CALLING;
1748     }
1749     if (state_ != WindowState::STATE_SHOWN) {
1750         TLOGE(WmsLogTag::WMS_HIERARCHY, "Window id: %{public}d The sub window must be shown!",
1751               GetPersistentId());
1752         return WMError::WM_DO_NOTHING;
1753     }
1754     if (IsWindowSessionInvalid()) {
1755         return WMError::WM_ERROR_INVALID_WINDOW;
1756     }
1757 
1758     property_->SetRaiseEnabled(raiseEnabled);
1759     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED);
1760 }
1761 
HideNonSystemFloatingWindows(bool shouldHide)1762 WMError WindowSessionImpl::HideNonSystemFloatingWindows(bool shouldHide)
1763 {
1764     WLOGFD("hide non-system floating windows");
1765     if (IsWindowSessionInvalid()) {
1766         return WMError::WM_ERROR_INVALID_WINDOW;
1767     }
1768     property_->SetHideNonSystemFloatingWindows(shouldHide);
1769     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS);
1770 }
1771 
SetLandscapeMultiWindow(bool isLandscapeMultiWindow)1772 WMError WindowSessionImpl::SetLandscapeMultiWindow(bool isLandscapeMultiWindow)
1773 {
1774     TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "SetLandscapeMultiWindow, isLandscapeMultiWindow:%{public}d",
1775         isLandscapeMultiWindow);
1776     if (IsWindowSessionInvalid()) {
1777         TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "Session is invalid");
1778         return WMError::WM_ERROR_INVALID_WINDOW;
1779     }
1780     auto hostSession = GetHostSession();
1781     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1782     hostSession->SetLandscapeMultiWindow(isLandscapeMultiWindow);
1783     return WMError::WM_OK;
1784 }
1785 
SetSingleFrameComposerEnabled(bool enable)1786 WMError WindowSessionImpl::SetSingleFrameComposerEnabled(bool enable)
1787 {
1788     WLOGFD("Set the enable flag of single frame composer.");
1789     if (IsWindowSessionInvalid()) {
1790         WLOGE("The window state is invalid ");
1791         return WMError::WM_ERROR_INVALID_WINDOW;
1792     }
1793 
1794     if (surfaceNode_ == nullptr) {
1795         WLOGE("The surface node is nullptr");
1796         return WMError::WM_ERROR_INVALID_WINDOW;
1797     }
1798 
1799     surfaceNode_->MarkNodeSingleFrameComposer(enable);
1800     RSTransaction::FlushImplicitTransaction();
1801     return WMError::WM_OK;
1802 }
1803 
IsFloatingWindowAppType() const1804 bool WindowSessionImpl::IsFloatingWindowAppType() const
1805 {
1806     if (IsWindowSessionInvalid()) {
1807         return false;
1808     }
1809     return property_ != nullptr && property_->IsFloatingWindowAppType();
1810 }
1811 
GetTouchable() const1812 bool WindowSessionImpl::GetTouchable() const
1813 {
1814     return property_->GetTouchable();
1815 }
1816 
SetWindowType(WindowType type)1817 WMError WindowSessionImpl::SetWindowType(WindowType type)
1818 {
1819     TLOGD(WmsLogTag::DEFAULT, "SetWindowType %{public}u type %{public}u", GetWindowId(), static_cast<uint32_t>(type));
1820     if (type != WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW && !SessionPermission::IsSystemCalling()) {
1821         TLOGE(WmsLogTag::DEFAULT, "set window type permission denied!");
1822         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1823     }
1824     if (IsWindowSessionInvalid()) {
1825         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
1826         return WMError::WM_ERROR_INVALID_WINDOW;
1827     }
1828     property_->SetWindowType(type);
1829     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS);
1830     return WMError::WM_OK;
1831 }
1832 
SetBrightness(float brightness)1833 WMError WindowSessionImpl::SetBrightness(float brightness)
1834 {
1835     if ((brightness < MINIMUM_BRIGHTNESS &&
1836         std::fabs(brightness - UNDEFINED_BRIGHTNESS) >= std::numeric_limits<float>::min()) ||
1837         brightness > MAXIMUM_BRIGHTNESS) {
1838         TLOGE(WmsLogTag::DEFAULT, "invalid brightness value: %{public}f", brightness);
1839         return WMError::WM_ERROR_INVALID_PARAM;
1840     }
1841     if (!WindowHelper::IsAppWindow(GetType())) {
1842         TLOGE(WmsLogTag::DEFAULT, "non app window does not support set brightness, type: %{public}u", GetType());
1843         return WMError::WM_ERROR_INVALID_TYPE;
1844     }
1845     if (!property_) {
1846         TLOGE(WmsLogTag::DEFAULT, "window property is not existed");
1847         return WMError::WM_ERROR_NULLPTR;
1848     }
1849     property_->SetBrightness(brightness);
1850     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS);
1851 }
1852 
GetBrightness() const1853 float WindowSessionImpl::GetBrightness() const
1854 {
1855     return property_->GetBrightness();
1856 }
1857 
SetRequestedOrientation(Orientation orientation)1858 void WindowSessionImpl::SetRequestedOrientation(Orientation orientation)
1859 {
1860     if (IsWindowSessionInvalid()) {
1861         TLOGE(WmsLogTag::DEFAULT, "windowSession is invalid");
1862         return;
1863     }
1864     TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}u lastReqOrientation:%{public}u target:%{public}u state:%{public}u",
1865         GetPersistentId(), property_->GetRequestedOrientation(), orientation, state_);
1866     bool isUserOrientation = IsUserOrientation(orientation);
1867     if (property_->GetRequestedOrientation() == orientation && !isUserOrientation) {
1868         return;
1869     }
1870     property_->SetRequestedOrientation(orientation);
1871     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_ORIENTATION);
1872 }
1873 
GetRequestedOrientation()1874 Orientation WindowSessionImpl::GetRequestedOrientation()
1875 {
1876     if (IsWindowSessionInvalid()) {
1877         TLOGE(WmsLogTag::DEFAULT, "windowSession is invalid");
1878         return Orientation::UNSPECIFIED;
1879     }
1880     return property_->GetRequestedOrientation();
1881 }
1882 
GetContentInfo(BackupAndRestoreType type)1883 std::string WindowSessionImpl::GetContentInfo(BackupAndRestoreType type)
1884 {
1885     WLOGFD("in");
1886     if (type == BackupAndRestoreType::NONE) {
1887         return "";
1888     }
1889 
1890     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1891     if (uiContent == nullptr) {
1892         WLOGFE("fail to GetContentInfo id: %{public}d", GetPersistentId());
1893         return "";
1894     }
1895 
1896     return uiContent->GetContentInfo(GetAceContentInfoType(type));
1897 }
1898 
SetRestoredRouterStack(const std::string & routerStack)1899 WMError WindowSessionImpl::SetRestoredRouterStack(const std::string& routerStack)
1900 {
1901     TLOGD(WmsLogTag::WMS_LIFE, "Set restored router stack.");
1902     restoredRouterStack_ = routerStack;
1903     return WMError::WM_OK;
1904 }
1905 
GetRestoredRouterStack()1906 std::string WindowSessionImpl::GetRestoredRouterStack()
1907 {
1908     TLOGD(WmsLogTag::WMS_LIFE, "Get restored router stack.");
1909     return std::move(restoredRouterStack_);
1910 }
1911 
GetUIContent() const1912 Ace::UIContent* WindowSessionImpl::GetUIContent() const
1913 {
1914     std::shared_lock<std::shared_mutex> lock(uiContentMutex_);
1915     return uiContent_.get();
1916 }
1917 
GetUIContentSharedPtr() const1918 std::shared_ptr<Ace::UIContent> WindowSessionImpl::GetUIContentSharedPtr() const
1919 {
1920     std::shared_lock<std::shared_mutex> lock(uiContentMutex_);
1921     return uiContent_;
1922 }
1923 
GetUIContentWithId(uint32_t winId) const1924 Ace::UIContent* WindowSessionImpl::GetUIContentWithId(uint32_t winId) const
1925 {
1926     sptr<Window> targetWindow = FindWindowById(winId);
1927     if (targetWindow == nullptr) {
1928         WLOGE("target window is null");
1929         return nullptr;
1930     }
1931     return targetWindow->GetUIContent();
1932 }
1933 
OnNewWant(const AAFwk::Want & want)1934 void WindowSessionImpl::OnNewWant(const AAFwk::Want& want)
1935 {
1936     WLOGFI("Window [name:%{public}s, id:%{public}d]",
1937         property_->GetWindowName().c_str(), GetPersistentId());
1938     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1939     if (uiContent != nullptr) {
1940         uiContent->OnNewWant(want);
1941     }
1942 }
1943 
SetAPPWindowLabel(const std::string & label)1944 WMError WindowSessionImpl::SetAPPWindowLabel(const std::string& label)
1945 {
1946     TLOGI(WmsLogTag::DEFAULT, "Enter");
1947     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1948     if (uiContent == nullptr) {
1949         WLOGFE("uicontent is empty");
1950         return WMError::WM_ERROR_NULLPTR;
1951     }
1952     uiContent->SetAppWindowTitle(label);
1953     return WMError::WM_OK;
1954 }
1955 
SetAPPWindowIcon(const std::shared_ptr<Media::PixelMap> & icon)1956 WMError WindowSessionImpl::SetAPPWindowIcon(const std::shared_ptr<Media::PixelMap>& icon)
1957 {
1958     if (icon == nullptr) {
1959         WLOGFE("window icon is empty");
1960         return WMError::WM_ERROR_NULLPTR;
1961     }
1962     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1963     if (uiContent == nullptr) {
1964         WLOGFE("uicontent is empty");
1965         return WMError::WM_ERROR_NULLPTR;
1966     }
1967     uiContent->SetAppWindowIcon(icon);
1968     WLOGI("Set app window icon success");
1969     return WMError::WM_OK;
1970 }
1971 
RegisterLifeCycleListener(const sptr<IWindowLifeCycle> & listener)1972 WMError WindowSessionImpl::RegisterLifeCycleListener(const sptr<IWindowLifeCycle>& listener)
1973 {
1974     WLOGFD("Start register");
1975     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
1976     return RegisterListener(lifecycleListeners_[GetPersistentId()], listener);
1977 }
1978 
RegisterDisplayMoveListener(sptr<IDisplayMoveListener> & listener)1979 WMError WindowSessionImpl::RegisterDisplayMoveListener(sptr<IDisplayMoveListener>& listener)
1980 {
1981     WLOGFD("Start register");
1982     std::lock_guard<std::mutex> lockListener(displayMoveListenerMutex_);
1983     return RegisterListener(displayMoveListeners_[GetPersistentId()], listener);
1984 }
1985 
UnregisterDisplayMoveListener(sptr<IDisplayMoveListener> & listener)1986 WMError WindowSessionImpl::UnregisterDisplayMoveListener(sptr<IDisplayMoveListener>& listener)
1987 {
1988     WLOGFD("Start unregister");
1989     std::lock_guard<std::mutex> lockListener(displayMoveListenerMutex_);
1990     return UnregisterListener(displayMoveListeners_[GetPersistentId()], listener);
1991 }
1992 
1993 /**
1994  * Currently only supports system windows.
1995  */
EnableDrag(bool enableDrag)1996 WMError WindowSessionImpl::EnableDrag(bool enableDrag)
1997 {
1998     bool isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
1999     if (!isPC && !IsFreeMultiWindowMode()) {
2000         TLOGE(WmsLogTag::WMS_LAYOUT, "The device is not supported");
2001         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2002     }
2003     property_->SetDragEnabled(enableDrag);
2004     auto hostSession = GetHostSession();
2005     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2006     WMError errorCode = hostSession->SetSystemWindowEnableDrag(enableDrag);
2007     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, enableDrag:%{public}d, errcode:%{public}d",
2008         GetPersistentId(), enableDrag, static_cast<int>(errorCode));
2009     return static_cast<WMError>(errorCode);
2010 }
2011 
RegisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)2012 WMError WindowSessionImpl::RegisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener>& listener)
2013 {
2014     WLOGFD("Start register");
2015     std::lock_guard<std::recursive_mutex> lockListener(occupiedAreaChangeListenerMutex_);
2016     return RegisterListener(occupiedAreaChangeListeners_[GetPersistentId()], listener);
2017 }
2018 
UnregisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)2019 WMError WindowSessionImpl::UnregisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener>& listener)
2020 {
2021     WLOGFD("Start unregister");
2022     std::lock_guard<std::recursive_mutex> lockListener(occupiedAreaChangeListenerMutex_);
2023     return UnregisterListener(occupiedAreaChangeListeners_[GetPersistentId()], listener);
2024 }
2025 
UnregisterLifeCycleListener(const sptr<IWindowLifeCycle> & listener)2026 WMError WindowSessionImpl::UnregisterLifeCycleListener(const sptr<IWindowLifeCycle>& listener)
2027 {
2028     WLOGFD("Start unregister");
2029     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
2030     return UnregisterListener(lifecycleListeners_[GetPersistentId()], listener);
2031 }
2032 
RegisterWindowChangeListener(const sptr<IWindowChangeListener> & listener)2033 WMError WindowSessionImpl::RegisterWindowChangeListener(const sptr<IWindowChangeListener>& listener)
2034 {
2035     WLOGFD("Start register");
2036     std::lock_guard<std::recursive_mutex> lockListener(windowChangeListenerMutex_);
2037     return RegisterListener(windowChangeListeners_[GetPersistentId()], listener);
2038 }
2039 
UnregisterWindowChangeListener(const sptr<IWindowChangeListener> & listener)2040 WMError WindowSessionImpl::UnregisterWindowChangeListener(const sptr<IWindowChangeListener>& listener)
2041 {
2042     WLOGFD("Start register");
2043     std::lock_guard<std::recursive_mutex> lockListener(windowChangeListenerMutex_);
2044     return UnregisterListener(windowChangeListeners_[GetPersistentId()], listener);
2045 }
2046 
RegisterWindowStatusChangeListener(const sptr<IWindowStatusChangeListener> & listener)2047 WMError WindowSessionImpl::RegisterWindowStatusChangeListener(const sptr<IWindowStatusChangeListener>& listener)
2048 {
2049     WLOGFD("Start register");
2050     std::lock_guard<std::recursive_mutex> lockListener(windowStatusChangeListenerMutex_);
2051     return RegisterListener(windowStatusChangeListeners_[GetPersistentId()], listener);
2052 }
2053 
UnregisterWindowStatusChangeListener(const sptr<IWindowStatusChangeListener> & listener)2054 WMError WindowSessionImpl::UnregisterWindowStatusChangeListener(const sptr<IWindowStatusChangeListener>& listener)
2055 {
2056     WLOGFD("Start register");
2057     std::lock_guard<std::recursive_mutex> lockListener(windowStatusChangeListenerMutex_);
2058     return UnregisterListener(windowStatusChangeListeners_[GetPersistentId()], listener);
2059 }
2060 
SetDecorVisible(bool isVisible)2061 WMError WindowSessionImpl::SetDecorVisible(bool isVisible)
2062 {
2063     if (IsWindowSessionInvalid()) {
2064         return WMError::WM_ERROR_INVALID_WINDOW;
2065     }
2066     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2067     if (uiContent == nullptr) {
2068         WLOGFE("uicontent is empty");
2069         return WMError::WM_ERROR_NULLPTR;
2070     }
2071     uiContent->SetContainerModalTitleVisible(isVisible, true);
2072     WLOGI("Change the visibility of decor success");
2073     return WMError::WM_OK;
2074 }
2075 
SetWindowTitleMoveEnabled(bool enable)2076 WMError WindowSessionImpl::SetWindowTitleMoveEnabled(bool enable)
2077 {
2078     if (IsWindowSessionInvalid()) {
2079         return WMError::WM_ERROR_INVALID_WINDOW;
2080     }
2081     if (!IsPcOrPadFreeMultiWindowMode()) {
2082         TLOGE(WmsLogTag::WMS_LAYOUT, "The device is not supported");
2083         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2084     }
2085     if (!WindowHelper::IsMainWindow(GetType()) && !WindowHelper::IsSubWindow(GetType())) {
2086         TLOGE(WmsLogTag::WMS_LAYOUT, "called by invalid window type, type:%{public}d", GetType());
2087         return WMError::WM_ERROR_INVALID_CALLING;
2088     }
2089     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2090     if (uiContent == nullptr) {
2091         TLOGE(WmsLogTag::WMS_LAYOUT, "uicontent is null");
2092         return WMError::WM_ERROR_NULLPTR;
2093     }
2094     uiContent->EnableContainerModalGesture(enable);
2095     TLOGI(WmsLogTag::WMS_LAYOUT, "enable:%{public}d end", enable);
2096     return WMError::WM_OK;
2097 }
2098 
SetSubWindowModal(bool isModal,ModalityType modalityType)2099 WMError WindowSessionImpl::SetSubWindowModal(bool isModal, ModalityType modalityType)
2100 {
2101     if (IsWindowSessionInvalid()) {
2102         return WMError::WM_ERROR_INVALID_WINDOW;
2103     }
2104     if (!WindowHelper::IsSubWindow(GetType())) {
2105         TLOGE(WmsLogTag::WMS_SUB, "called by invalid window type, type:%{public}d", GetType());
2106         return WMError::WM_ERROR_INVALID_CALLING;
2107     }
2108     if (modalityType == ModalityType::APPLICATION_MODALITY && !IsPcOrPadFreeMultiWindowMode()) {
2109         TLOGE(WmsLogTag::WMS_SUB, "device not support");
2110         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2111     }
2112 
2113     WMError modalRet = isModal ?
2114         AddWindowFlag(WindowFlag::WINDOW_FLAG_IS_MODAL) :
2115         RemoveWindowFlag(WindowFlag::WINDOW_FLAG_IS_MODAL);
2116     if (modalRet != WMError::WM_OK) {
2117         return modalRet;
2118     }
2119     modalRet = isModal && modalityType == ModalityType::APPLICATION_MODALITY ?
2120         AddWindowFlag(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL) :
2121         RemoveWindowFlag(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL);
2122     auto hostSession = GetHostSession();
2123     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2124     SubWindowModalType subWindowModalType = SubWindowModalType::TYPE_NORMAL;
2125     if (isModal) {
2126         subWindowModalType = modalityType == ModalityType::WINDOW_MODALITY ?
2127             SubWindowModalType::TYPE_WINDOW_MODALITY :
2128             SubWindowModalType::TYPE_APPLICATION_MODALITY;
2129     }
2130     hostSession->NotifySubModalTypeChange(subWindowModalType);
2131     return modalRet;
2132 }
2133 
SetWindowModal(bool isModal)2134 WMError WindowSessionImpl::SetWindowModal(bool isModal)
2135 {
2136     if (IsWindowSessionInvalid()) {
2137         return WMError::WM_ERROR_INVALID_WINDOW;
2138     }
2139     if (!IsPcOrPadFreeMultiWindowMode()) {
2140         TLOGE(WmsLogTag::WMS_MAIN, "device not support");
2141         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2142     }
2143     if (!WindowHelper::IsMainWindow(GetType())) {
2144         TLOGE(WmsLogTag::WMS_MAIN, "called by invalid window type, type:%{public}d", GetType());
2145         return WMError::WM_ERROR_INVALID_CALLING;
2146     }
2147     WMError modalRet = isModal ?
2148         AddWindowFlag(WindowFlag::WINDOW_FLAG_IS_MODAL) :
2149         RemoveWindowFlag(WindowFlag::WINDOW_FLAG_IS_MODAL);
2150     if (modalRet != WMError::WM_OK) {
2151         return modalRet;
2152     }
2153     auto hostSession = GetHostSession();
2154     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
2155     hostSession->NotifyMainModalTypeChange(isModal);
2156     return modalRet;
2157 }
2158 
SetDecorHeight(int32_t decorHeight)2159 WMError WindowSessionImpl::SetDecorHeight(int32_t decorHeight)
2160 {
2161     if (IsWindowSessionInvalid()) {
2162         return WMError::WM_ERROR_INVALID_WINDOW;
2163     }
2164     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2165     if (display == nullptr) {
2166         WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2167         return WMError::WM_ERROR_NULLPTR;
2168     }
2169     auto displayInfo = display->GetDisplayInfo();
2170     if (displayInfo == nullptr) {
2171         WLOGFE("get display info failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2172         return WMError::WM_ERROR_NULLPTR;
2173     }
2174     float vpr = GetVirtualPixelRatio(displayInfo);
2175     int32_t decorHeightWithPx = static_cast<int32_t>(decorHeight * vpr);
2176     {
2177         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2178         if (uiContent == nullptr) {
2179             WLOGFE("uicontent is empty");
2180             return WMError::WM_ERROR_NULLPTR;
2181         }
2182         uiContent->SetContainerModalTitleHeight(decorHeightWithPx);
2183     }
2184     auto hostSession = GetHostSession();
2185     if (hostSession != nullptr) {
2186         hostSession->SetCustomDecorHeight(decorHeight);
2187     }
2188     WLOGI("Set app window decor height success, height : %{public}d", decorHeight);
2189     return WMError::WM_OK;
2190 }
2191 
GetDecorHeight(int32_t & height)2192 WMError WindowSessionImpl::GetDecorHeight(int32_t& height)
2193 {
2194     if (IsWindowSessionInvalid()) {
2195         return WMError::WM_ERROR_INVALID_WINDOW;
2196     }
2197     {
2198         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2199         if (uiContent == nullptr) {
2200             TLOGE(WmsLogTag::WMS_DECOR, "uiContent is null, windowId: %{public}u", GetWindowId());
2201             return WMError::WM_ERROR_NULLPTR;
2202         }
2203         height = uiContent->GetContainerModalTitleHeight();
2204     }
2205     if (height == -1) {
2206         height = 0;
2207         TLOGW(WmsLogTag::WMS_DECOR, "Get app window decor height failed");
2208         return WMError::WM_OK;
2209     }
2210     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2211     if (display == nullptr) {
2212         TLOGE(WmsLogTag::WMS_LAYOUT, "get display failed displayId: %{public}" PRIu64, property_->GetDisplayId());
2213         return WMError::WM_ERROR_NULLPTR;
2214     }
2215     auto displayInfo = display->GetDisplayInfo();
2216     if (displayInfo == nullptr) {
2217         TLOGE(WmsLogTag::WMS_LAYOUT, "get display info failed displayId: %{public}" PRIu64, property_->GetDisplayId());
2218         return WMError::WM_ERROR_NULLPTR;
2219     }
2220     float vpr = GetVirtualPixelRatio(displayInfo);
2221     if (MathHelper::NearZero(vpr)) {
2222         TLOGE(WmsLogTag::WMS_LAYOUT, "get decor height failed, because of wrong vpr: %{public}f", vpr);
2223         return WMError::WM_ERROR_INVALID_WINDOW;
2224     }
2225     height = static_cast<int32_t>(height / vpr);
2226     TLOGD(WmsLogTag::WMS_DECOR, "end, height: %{public}d", height);
2227     return WMError::WM_OK;
2228 }
2229 
GetTitleButtonArea(TitleButtonRect & titleButtonRect)2230 WMError WindowSessionImpl::GetTitleButtonArea(TitleButtonRect& titleButtonRect)
2231 {
2232     if (IsWindowSessionInvalid()) {
2233         return WMError::WM_ERROR_INVALID_WINDOW;
2234     }
2235     Rect decorRect;
2236     Rect titleButtonLeftRect;
2237     bool res = false;
2238     {
2239         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2240         if (uiContent == nullptr) {
2241             WLOGFE("uicontent is empty");
2242             return WMError::WM_ERROR_NULLPTR;
2243         }
2244         res = uiContent->GetContainerModalButtonsRect(decorRect, titleButtonLeftRect);
2245     }
2246     if (!res) {
2247         WLOGFE("get window title buttons area failed");
2248         titleButtonRect.IsUninitializedRect();
2249         return WMError::WM_OK;
2250     }
2251     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2252     if (display == nullptr) {
2253         WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2254         return WMError::WM_ERROR_NULLPTR;
2255     }
2256     auto displayInfo = display->GetDisplayInfo();
2257     if (displayInfo == nullptr) {
2258         WLOGFE("get display info failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2259         return WMError::WM_ERROR_NULLPTR;
2260     }
2261     float vpr = GetVirtualPixelRatio(displayInfo);
2262     if (MathHelper::NearZero(vpr)) {
2263         WLOGFE("get title buttons area failed, because of wrong vpr: %{public}f", vpr);
2264         return WMError::WM_ERROR_INVALID_WINDOW;
2265     }
2266     titleButtonRect.posX_ = static_cast<int32_t>(decorRect.width_) -
2267         static_cast<int32_t>(titleButtonLeftRect.width_) - titleButtonLeftRect.posX_;
2268     titleButtonRect.posX_ = static_cast<int32_t>(titleButtonRect.posX_ / vpr);
2269     titleButtonRect.posY_ = static_cast<int32_t>(titleButtonLeftRect.posY_ / vpr);
2270     titleButtonRect.width_ = static_cast<uint32_t>(titleButtonLeftRect.width_ / vpr);
2271     titleButtonRect.height_ = static_cast<uint32_t>(titleButtonLeftRect.height_ / vpr);
2272     return WMError::WM_OK;
2273 }
2274 
GetUIContentRemoteObj(sptr<IRemoteObject> & uiContentRemoteObj)2275 WSError WindowSessionImpl::GetUIContentRemoteObj(sptr<IRemoteObject>& uiContentRemoteObj)
2276 {
2277     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2278     if (uiContent == nullptr) {
2279         TLOGE(WmsLogTag::DEFAULT, "uiContent is nullptr. Failed to get uiContentRemoteObj");
2280         return WSError::WS_ERROR_NULLPTR;
2281     }
2282     uiContentRemoteObj = uiContent->GetRemoteObj();
2283     return WSError::WS_OK;
2284 }
2285 
RegisterWindowTitleButtonRectChangeListener(const sptr<IWindowTitleButtonRectChangedListener> & listener)2286 WMError WindowSessionImpl::RegisterWindowTitleButtonRectChangeListener(
2287     const sptr<IWindowTitleButtonRectChangedListener>& listener)
2288 {
2289     if (IsWindowSessionInvalid()) {
2290         return WMError::WM_ERROR_INVALID_WINDOW;
2291     }
2292     auto persistentId = GetPersistentId();
2293     WLOGFD("Start register windowTitleButtonRectChange listener, id:%{public}d", persistentId);
2294     if (listener == nullptr) {
2295         WLOGFE("listener is nullptr");
2296         return WMError::WM_ERROR_NULLPTR;
2297     }
2298 
2299     {
2300         std::lock_guard<std::recursive_mutex> lockListener(windowTitleButtonRectChangeListenerMutex_);
2301         WMError ret = RegisterListener(windowTitleButtonRectChangeListeners_[persistentId], listener);
2302         if (ret != WMError::WM_OK) {
2303             WLOGFE("register the listener of window title button rect change failed");
2304             return ret;
2305         }
2306     }
2307     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2308     if (display == nullptr) {
2309         WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2310         return WMError::WM_ERROR_NULLPTR;
2311     }
2312     auto displayInfo = display->GetDisplayInfo();
2313     if (displayInfo == nullptr) {
2314         WLOGFE("get display info failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2315         return WMError::WM_ERROR_NULLPTR;
2316     }
2317     float vpr = GetVirtualPixelRatio(displayInfo);
2318     if (MathHelper::NearZero(vpr)) {
2319         WLOGFE("register title button rect change listener failed, because of wrong vpr: %{public}f", vpr);
2320         return WMError::WM_ERROR_INVALID_WINDOW;
2321     }
2322     if (auto uiContent = GetUIContentSharedPtr()) {
2323         uiContent->SubscribeContainerModalButtonsRectChange(
2324             [vpr, weakThis = wptr(this)](Rect& decorRect, Rect& titleButtonLeftRect) {
2325             auto window = weakThis.promote();
2326             if (!window) {
2327                 TLOGNE(WmsLogTag::WMS_LAYOUT, "window is null");
2328                 return;
2329             }
2330             TitleButtonRect titleButtonRect;
2331             titleButtonRect.posX_ = static_cast<int32_t>(decorRect.width_) -
2332                 static_cast<int32_t>(titleButtonLeftRect.width_) - titleButtonLeftRect.posX_;
2333             titleButtonRect.posX_ = static_cast<int32_t>(titleButtonRect.posX_ / vpr);
2334             titleButtonRect.posY_ = static_cast<int32_t>(titleButtonLeftRect.posY_ / vpr);
2335             titleButtonRect.width_ = static_cast<uint32_t>(titleButtonLeftRect.width_ / vpr);
2336             titleButtonRect.height_ = static_cast<uint32_t>(titleButtonLeftRect.height_ / vpr);
2337             window->NotifyWindowTitleButtonRectChange(titleButtonRect);
2338         });
2339     }
2340     return WMError::WM_OK;
2341 }
2342 
UnregisterWindowTitleButtonRectChangeListener(const sptr<IWindowTitleButtonRectChangedListener> & listener)2343 WMError WindowSessionImpl::UnregisterWindowTitleButtonRectChangeListener(
2344     const sptr<IWindowTitleButtonRectChangedListener>& listener)
2345 {
2346     if (IsWindowSessionInvalid()) {
2347         return WMError::WM_ERROR_INVALID_WINDOW;
2348     }
2349     WMError ret = WMError::WM_OK;
2350     auto persistentId = GetPersistentId();
2351     WLOGFD("Start unregister windowTitleButtonRectChange listener, id:%{public}d", persistentId);
2352     if (listener == nullptr) {
2353         WLOGFE("listener is nullptr");
2354         return WMError::WM_ERROR_NULLPTR;
2355     }
2356     {
2357         std::lock_guard<std::recursive_mutex> lockListener(windowTitleButtonRectChangeListenerMutex_);
2358         ret = UnregisterListener(windowTitleButtonRectChangeListeners_[persistentId], listener);
2359         if (ret != WMError::WM_OK) {
2360             WLOGFE("unregister the listener of window title button rect change failed");
2361             return ret;
2362         }
2363     }
2364     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2365     if (uiContent != nullptr) {
2366         uiContent->SubscribeContainerModalButtonsRectChange(nullptr);
2367     }
2368     return ret;
2369 }
2370 
2371 template<typename T>
2372 EnableIfSame<T, IWindowTitleButtonRectChangedListener,
GetListeners()2373     std::vector<sptr<IWindowTitleButtonRectChangedListener>>> WindowSessionImpl::GetListeners()
2374 {
2375     std::vector<sptr<IWindowTitleButtonRectChangedListener>> windowTitleButtonRectListeners;
2376         for (auto& listener : windowTitleButtonRectChangeListeners_[GetPersistentId()]) {
2377             windowTitleButtonRectListeners.push_back(listener);
2378         }
2379     return windowTitleButtonRectListeners;
2380 }
2381 
NotifyWindowTitleButtonRectChange(TitleButtonRect titleButtonRect)2382 void WindowSessionImpl::NotifyWindowTitleButtonRectChange(TitleButtonRect titleButtonRect)
2383 {
2384     std::lock_guard<std::recursive_mutex> lockListener(windowTitleButtonRectChangeListenerMutex_);
2385     auto windowTitleButtonRectListeners = GetListeners<IWindowTitleButtonRectChangedListener>();
2386     for (auto& listener : windowTitleButtonRectListeners) {
2387         if (listener != nullptr) {
2388             listener->OnWindowTitleButtonRectChanged(titleButtonRect);
2389         }
2390     }
2391 }
2392 
2393 template<typename T>
2394 EnableIfSame<T, IWindowRectChangeListener,
GetListeners()2395     std::vector<sptr<IWindowRectChangeListener>>> WindowSessionImpl::GetListeners()
2396 {
2397     std::vector<sptr<IWindowRectChangeListener>> windowRectChangeListeners;
2398     for (auto& listener : windowRectChangeListeners_[GetPersistentId()]) {
2399         windowRectChangeListeners.push_back(listener);
2400     }
2401     return windowRectChangeListeners;
2402 }
2403 
RegisterWindowRectChangeListener(const sptr<IWindowRectChangeListener> & listener)2404 WMError WindowSessionImpl::RegisterWindowRectChangeListener(const sptr<IWindowRectChangeListener>& listener)
2405 {
2406     WMError ret = WMError::WM_OK;
2407     {
2408         std::lock_guard<std::mutex> lockListener(windowRectChangeListenerMutex_);
2409         ret = RegisterListener(windowRectChangeListeners_[GetPersistentId()], listener);
2410     }
2411     auto hostSession = GetHostSession();
2412     if (hostSession != nullptr && ret == WMError::WM_OK) {
2413         hostSession->UpdateRectChangeListenerRegistered(true);
2414     }
2415     return ret;
2416 }
2417 
UnregisterWindowRectChangeListener(const sptr<IWindowRectChangeListener> & listener)2418 WMError WindowSessionImpl::UnregisterWindowRectChangeListener(const sptr<IWindowRectChangeListener>& listener)
2419 {
2420     WMError ret = WMError::WM_OK;
2421     bool windowRectChangeListenersEmpty = false;
2422     {
2423         std::lock_guard<std::mutex> lockListener(windowRectChangeListenerMutex_);
2424         ret = UnregisterListener(windowRectChangeListeners_[GetPersistentId()], listener);
2425         windowRectChangeListenersEmpty = windowRectChangeListeners_.count(GetPersistentId()) == 0 ||
2426                                          windowRectChangeListeners_[GetPersistentId()].empty();
2427     }
2428     auto hostSession = GetHostSession();
2429     if (hostSession != nullptr && windowRectChangeListenersEmpty) {
2430         hostSession->UpdateRectChangeListenerRegistered(false);
2431     }
2432     return ret;
2433 }
2434 
2435 template<typename T>
GetListeners()2436 EnableIfSame<T, ISubWindowCloseListener, sptr<ISubWindowCloseListener>> WindowSessionImpl::GetListeners()
2437 {
2438     sptr<ISubWindowCloseListener> subWindowCloseListeners;
2439     subWindowCloseListeners = subWindowCloseListeners_[GetPersistentId()];
2440     return subWindowCloseListeners;
2441 }
2442 
RegisterSubWindowCloseListeners(const sptr<ISubWindowCloseListener> & listener)2443 WMError WindowSessionImpl::RegisterSubWindowCloseListeners(const sptr<ISubWindowCloseListener>& listener)
2444 {
2445     if (listener == nullptr) {
2446         WLOGFE("listener is nullptr");
2447         return WMError::WM_ERROR_NULLPTR;
2448     }
2449     if (!WindowHelper::IsSubWindow(GetType()) && !WindowHelper::IsSystemSubWindow(GetType())) {
2450         WLOGFE("window type is not supported");
2451         return WMError::WM_ERROR_INVALID_CALLING;
2452     }
2453     std::lock_guard<std::mutex> lockListener(subWindowCloseListenersMutex_);
2454     subWindowCloseListeners_[GetPersistentId()] = listener;
2455     return WMError::WM_OK;
2456 }
2457 
UnregisterSubWindowCloseListeners(const sptr<ISubWindowCloseListener> & listener)2458 WMError WindowSessionImpl::UnregisterSubWindowCloseListeners(const sptr<ISubWindowCloseListener>& listener)
2459 {
2460     if (listener == nullptr) {
2461         WLOGFE("listener could not be null");
2462         return WMError::WM_ERROR_NULLPTR;
2463     }
2464     if (!WindowHelper::IsSubWindow(GetType()) && !WindowHelper::IsSystemSubWindow(GetType())) {
2465         WLOGFE("window type is not supported");
2466         return WMError::WM_ERROR_INVALID_CALLING;
2467     }
2468     std::lock_guard<std::mutex> lockListener(subWindowCloseListenersMutex_);
2469     subWindowCloseListeners_[GetPersistentId()] = nullptr;
2470     return WMError::WM_OK;
2471 }
2472 
2473 template<typename T>
2474 EnableIfSame<T, IWindowHighlightChangeListener, std::vector<sptr<IWindowHighlightChangeListener>>>
GetListeners()2475     WindowSessionImpl::GetListeners()
2476 {
2477     std::vector<sptr<IWindowHighlightChangeListener>> highlightChangeListeners;
2478     for (auto& listener : highlightChangeListeners_[GetPersistentId()]) {
2479         highlightChangeListeners.push_back(listener);
2480     }
2481     return highlightChangeListeners;
2482 }
2483 
RegisterWindowHighlightChangeListeners(const sptr<IWindowHighlightChangeListener> & listener)2484 WMError WindowSessionImpl::RegisterWindowHighlightChangeListeners(const sptr<IWindowHighlightChangeListener>& listener)
2485 {
2486     TLOGD(WmsLogTag::WMS_FOCUS, "name=%{public}s, id=%{public}u", GetWindowName().c_str(), GetPersistentId());
2487     std::lock_guard<std::mutex> lockListener(highlightChangeListenerMutex_);
2488     return RegisterListener(highlightChangeListeners_[GetPersistentId()], listener);
2489 }
2490 
UnregisterWindowHighlightChangeListeners(const sptr<IWindowHighlightChangeListener> & listener)2491 WMError WindowSessionImpl::UnregisterWindowHighlightChangeListeners(
2492     const sptr<IWindowHighlightChangeListener>& listener)
2493 {
2494     TLOGD(WmsLogTag::WMS_FOCUS, "name=%{public}s, id=%{public}u", GetWindowName().c_str(), GetPersistentId());
2495     std::lock_guard<std::mutex> lockListener(highlightChangeListenerMutex_);
2496     return UnregisterListener(highlightChangeListeners_[GetPersistentId()], listener);
2497 }
2498 
2499 template<typename T>
GetListeners()2500 EnableIfSame<T, IMainWindowCloseListener, sptr<IMainWindowCloseListener>> WindowSessionImpl::GetListeners()
2501 {
2502     return mainWindowCloseListeners_[GetPersistentId()];
2503 }
2504 
RegisterMainWindowCloseListeners(const sptr<IMainWindowCloseListener> & listener)2505 WMError WindowSessionImpl::RegisterMainWindowCloseListeners(const sptr<IMainWindowCloseListener>& listener)
2506 {
2507     if (IsWindowSessionInvalid()) {
2508         return WMError::WM_ERROR_INVALID_WINDOW;
2509     }
2510     if (listener == nullptr) {
2511         TLOGE(WmsLogTag::DEFAULT, "listener is null");
2512         return WMError::WM_ERROR_NULLPTR;
2513     }
2514     if (!WindowHelper::IsMainWindow(GetType())) {
2515         TLOGE(WmsLogTag::DEFAULT, "window type is not supported");
2516         return WMError::WM_ERROR_INVALID_CALLING;
2517     }
2518     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
2519     if (!(isPC || IsFreeMultiWindowMode())) {
2520         TLOGE(WmsLogTag::DEFAULT, "The device is not supported");
2521         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2522     }
2523     std::lock_guard<std::mutex> lockListener(mainWindowCloseListenersMutex_);
2524     mainWindowCloseListeners_[GetPersistentId()] = listener;
2525     return WMError::WM_OK;
2526 }
2527 
UnregisterMainWindowCloseListeners(const sptr<IMainWindowCloseListener> & listener)2528 WMError WindowSessionImpl::UnregisterMainWindowCloseListeners(const sptr<IMainWindowCloseListener>& listener)
2529 {
2530     if (IsWindowSessionInvalid()) {
2531         return WMError::WM_ERROR_INVALID_WINDOW;
2532     }
2533     if (listener == nullptr) {
2534         TLOGE(WmsLogTag::DEFAULT, "listener could not be null");
2535         return WMError::WM_ERROR_NULLPTR;
2536     }
2537     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
2538     if (!(isPC || IsFreeMultiWindowMode())) {
2539         TLOGE(WmsLogTag::DEFAULT, "The device is not supported");
2540         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2541     }
2542     if (!WindowHelper::IsMainWindow(GetType())) {
2543         TLOGE(WmsLogTag::DEFAULT, "window type is not supported");
2544         return WMError::WM_ERROR_INVALID_CALLING;
2545     }
2546     std::lock_guard<std::mutex> lockListener(mainWindowCloseListenersMutex_);
2547     mainWindowCloseListeners_[GetPersistentId()] = nullptr;
2548     return WMError::WM_OK;
2549 }
2550 
2551 template<typename T>
GetListeners()2552 EnableIfSame<T, IWindowWillCloseListener, std::vector<sptr<IWindowWillCloseListener>>> WindowSessionImpl::GetListeners()
2553 {
2554     return windowWillCloseListeners_[GetPersistentId()];
2555 }
2556 
RegisterWindowWillCloseListeners(const sptr<IWindowWillCloseListener> & listener)2557 WMError WindowSessionImpl::RegisterWindowWillCloseListeners(const sptr<IWindowWillCloseListener>& listener)
2558 {
2559     if (IsWindowSessionInvalid()) {
2560         return WMError::WM_ERROR_INVALID_WINDOW;
2561     }
2562     if (listener == nullptr) {
2563         TLOGE(WmsLogTag::WMS_DECOR, "listener is null");
2564         return WMError::WM_ERROR_NULLPTR;
2565     }
2566     if (!IsPcOrPadCapabilityEnabled()) {
2567         TLOGE(WmsLogTag::WMS_DECOR, "The device is not supported");
2568         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2569     }
2570     if (!WindowHelper::IsAppWindow(GetType())) {
2571         TLOGE(WmsLogTag::WMS_DECOR, "window type is not supported");
2572         return WMError::WM_ERROR_INVALID_CALLING;
2573     }
2574     std::lock_guard<std::mutex> lockListener(windowWillCloseListenersMutex_);
2575     return RegisterListener(windowWillCloseListeners_[GetPersistentId()], listener);
2576 }
2577 
UnRegisterWindowWillCloseListeners(const sptr<IWindowWillCloseListener> & listener)2578 WMError WindowSessionImpl::UnRegisterWindowWillCloseListeners(const sptr<IWindowWillCloseListener>& listener)
2579 {
2580     if (IsWindowSessionInvalid()) {
2581         return WMError::WM_ERROR_INVALID_WINDOW;
2582     }
2583     if (listener == nullptr) {
2584         TLOGE(WmsLogTag::WMS_DECOR, "listener could not be null");
2585         return WMError::WM_ERROR_NULLPTR;
2586     }
2587     if (!IsPcOrPadCapabilityEnabled()) {
2588         TLOGE(WmsLogTag::WMS_DECOR, "The device is not supported");
2589         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2590     }
2591     if (!WindowHelper::IsAppWindow(GetType())) {
2592         TLOGE(WmsLogTag::WMS_DECOR, "window type is not supported");
2593         return WMError::WM_ERROR_INVALID_CALLING;
2594     }
2595     std::lock_guard<std::mutex> lockListener(windowWillCloseListenersMutex_);
2596     return UnregisterListener(windowWillCloseListeners_[GetPersistentId()], listener);
2597 }
2598 
2599 template<typename T>
2600 EnableIfSame<T, ISwitchFreeMultiWindowListener,
GetListeners()2601     std::vector<sptr<ISwitchFreeMultiWindowListener>>> WindowSessionImpl::GetListeners()
2602 {
2603     std::vector<sptr<ISwitchFreeMultiWindowListener>> switchFreeMultiWindowListeners;
2604     for (auto& listener : switchFreeMultiWindowListeners_[GetPersistentId()]) {
2605         switchFreeMultiWindowListeners.push_back(listener);
2606     }
2607     return switchFreeMultiWindowListeners;
2608 }
2609 
RegisterSwitchFreeMultiWindowListener(const sptr<ISwitchFreeMultiWindowListener> & listener)2610 WMError WindowSessionImpl::RegisterSwitchFreeMultiWindowListener(const sptr<ISwitchFreeMultiWindowListener>& listener)
2611 {
2612     if (listener == nullptr) {
2613         WLOGFE("listener is nullptr");
2614         return WMError::WM_ERROR_NULLPTR;
2615     }
2616     if (!WindowHelper::IsMainWindow(GetType())) {
2617         WLOGFE("window type is not supported");
2618         return WMError::WM_ERROR_INVALID_CALLING;
2619     }
2620     WLOGFD("Start register");
2621     std::lock_guard<std::mutex> lockListener(switchFreeMultiWindowListenerMutex_);
2622     return RegisterListener(switchFreeMultiWindowListeners_[GetPersistentId()], listener);
2623 }
2624 
UnregisterSwitchFreeMultiWindowListener(const sptr<ISwitchFreeMultiWindowListener> & listener)2625 WMError WindowSessionImpl::UnregisterSwitchFreeMultiWindowListener(const sptr<ISwitchFreeMultiWindowListener>& listener)
2626 {
2627     if (listener == nullptr) {
2628         WLOGFE("listener could not be null");
2629         return WMError::WM_ERROR_NULLPTR;
2630     }
2631     if (!WindowHelper::IsMainWindow(GetType())) {
2632         WLOGFE("window type is not supported");
2633         return WMError::WM_ERROR_INVALID_CALLING;
2634     }
2635     WLOGFD("Start unregister");
2636     std::lock_guard<std::mutex> lockListener(switchFreeMultiWindowListenerMutex_);
2637     return UnregisterListener(switchFreeMultiWindowListeners_[GetPersistentId()], listener);
2638 }
2639 
RecoverSessionListener()2640 void WindowSessionImpl::RecoverSessionListener()
2641 {
2642     auto persistentId = GetPersistentId();
2643     TLOGI(WmsLogTag::WMS_RECOVER, "with persistentId=%{public}d", persistentId);
2644     {
2645         std::lock_guard<std::recursive_mutex> lockListener(avoidAreaChangeListenerMutex_);
2646         if (avoidAreaChangeListeners_.find(persistentId) != avoidAreaChangeListeners_.end() &&
2647             !avoidAreaChangeListeners_[persistentId].empty()) {
2648             SingletonContainer::Get<WindowAdapter>().UpdateSessionAvoidAreaListener(persistentId, true);
2649         }
2650     }
2651     {
2652         std::lock_guard<std::recursive_mutex> lockListener(touchOutsideListenerMutex_);
2653         if (touchOutsideListeners_.find(persistentId) != touchOutsideListeners_.end() &&
2654             !touchOutsideListeners_[persistentId].empty()) {
2655             SingletonContainer::Get<WindowAdapter>().UpdateSessionTouchOutsideListener(persistentId, true);
2656         }
2657     }
2658     {
2659         std::lock_guard<std::recursive_mutex> lockListener(windowVisibilityChangeListenerMutex_);
2660         if (windowVisibilityChangeListeners_.find(persistentId) != windowVisibilityChangeListeners_.end() &&
2661             !windowVisibilityChangeListeners_[persistentId].empty()) {
2662             SingletonContainer::Get<WindowAdapter>().UpdateSessionWindowVisibilityListener(persistentId, true);
2663         }
2664     }
2665     {
2666         std::lock_guard<std::mutex> lockListener(windowRectChangeListenerMutex_);
2667         if (windowRectChangeListeners_.find(persistentId) != windowRectChangeListeners_.end() &&
2668             !windowRectChangeListeners_[persistentId].empty()) {
2669             if (auto hostSession = GetHostSession()) {
2670                 hostSession->UpdateRectChangeListenerRegistered(true);
2671             }
2672         }
2673     }
2674 }
2675 
2676 template<typename T>
GetListeners()2677 EnableIfSame<T, IWindowLifeCycle, std::vector<sptr<IWindowLifeCycle>>> WindowSessionImpl::GetListeners()
2678 {
2679     std::vector<sptr<IWindowLifeCycle>> lifecycleListeners;
2680     for (auto& listener : lifecycleListeners_[GetPersistentId()]) {
2681         lifecycleListeners.push_back(listener);
2682     }
2683     return lifecycleListeners;
2684 }
2685 
2686 template<typename T>
GetListeners()2687 EnableIfSame<T, IWindowChangeListener, std::vector<sptr<IWindowChangeListener>>> WindowSessionImpl::GetListeners()
2688 {
2689     std::vector<sptr<IWindowChangeListener>> windowChangeListeners;
2690     for (auto& listener : windowChangeListeners_[GetPersistentId()]) {
2691         windowChangeListeners.push_back(listener);
2692     }
2693     return windowChangeListeners;
2694 }
2695 
2696 template<typename T>
2697 EnableIfSame<T, IOccupiedAreaChangeListener,
GetListeners()2698     std::vector<sptr<IOccupiedAreaChangeListener>>> WindowSessionImpl::GetListeners()
2699 {
2700     std::vector<sptr<IOccupiedAreaChangeListener>> occupiedAreaChangeListeners;
2701     for (auto& listener : occupiedAreaChangeListeners_[GetPersistentId()]) {
2702         occupiedAreaChangeListeners.push_back(listener);
2703     }
2704     return occupiedAreaChangeListeners;
2705 }
2706 
2707 template<typename T>
RegisterListener(std::vector<sptr<T>> & holder,const sptr<T> & listener)2708 WMError WindowSessionImpl::RegisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
2709 {
2710     if (listener == nullptr) {
2711         WLOGFE("listener is nullptr");
2712         return WMError::WM_ERROR_NULLPTR;
2713     }
2714     if (std::find(holder.begin(), holder.end(), listener) != holder.end()) {
2715         WLOGFE("Listener already registered");
2716         return WMError::WM_OK;
2717     }
2718     holder.emplace_back(listener);
2719     return WMError::WM_OK;
2720 }
2721 
2722 template<typename T>
UnregisterListener(std::vector<sptr<T>> & holder,const sptr<T> & listener)2723 WMError WindowSessionImpl::UnregisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
2724 {
2725     if (listener == nullptr) {
2726         WLOGFE("listener could not be null");
2727         return WMError::WM_ERROR_NULLPTR;
2728     }
2729     holder.erase(std::remove_if(holder.begin(), holder.end(),
2730         [listener](sptr<T> registeredListener) {
2731             return registeredListener == listener;
2732         }), holder.end());
2733     return WMError::WM_OK;
2734 }
2735 
2736 template<typename T>
ClearUselessListeners(std::map<int32_t,T> & listeners,int32_t persistentId)2737 void WindowSessionImpl::ClearUselessListeners(std::map<int32_t, T>& listeners, int32_t persistentId)
2738 {
2739     listeners.erase(persistentId);
2740 }
2741 
2742 template<typename T>
ClearUselessListeners(std::unordered_map<int32_t,T> & listeners,int32_t persistentId)2743 void WindowSessionImpl::ClearUselessListeners(std::unordered_map<int32_t, T>& listeners, int32_t persistentId)
2744 {
2745     listeners.erase(persistentId);
2746 }
2747 
2748 template<typename T>
GetListeners()2749 EnableIfSame<T, IWindowStatusChangeListener, std::vector<sptr<IWindowStatusChangeListener>>> WindowSessionImpl::GetListeners()
2750 {
2751     std::vector<sptr<IWindowStatusChangeListener>> windowStatusChangeListeners;
2752     for (auto& listener : windowStatusChangeListeners_[GetPersistentId()]) {
2753         windowStatusChangeListeners.push_back(listener);
2754     }
2755     return windowStatusChangeListeners;
2756 }
2757 
ClearListenersById(int32_t persistentId)2758 void WindowSessionImpl::ClearListenersById(int32_t persistentId)
2759 {
2760     TLOGI(WmsLogTag::WMS_LIFE, "Called id: %{public}d.", GetPersistentId());
2761     {
2762         std::lock_guard<std::mutex> lockListener(displayMoveListenerMutex_);
2763         ClearUselessListeners(displayMoveListeners_, persistentId);
2764     }
2765     {
2766         std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
2767         ClearUselessListeners(lifecycleListeners_, persistentId);
2768     }
2769     {
2770         std::lock_guard<std::recursive_mutex> lockListener(windowChangeListenerMutex_);
2771         ClearUselessListeners(windowChangeListeners_, persistentId);
2772     }
2773     {
2774         std::lock_guard<std::recursive_mutex> lockListener(avoidAreaChangeListenerMutex_);
2775         ClearUselessListeners(avoidAreaChangeListeners_, persistentId);
2776     }
2777     {
2778         std::lock_guard<std::recursive_mutex> lockListener(dialogDeathRecipientListenerMutex_);
2779         ClearUselessListeners(dialogDeathRecipientListeners_, persistentId);
2780     }
2781     {
2782         std::lock_guard<std::recursive_mutex> lockListener(dialogTargetTouchListenerMutex_);
2783         ClearUselessListeners(dialogTargetTouchListener_, persistentId);
2784     }
2785     {
2786         std::lock_guard<std::recursive_mutex> lockListener(screenshotListenerMutex_);
2787         ClearUselessListeners(screenshotListeners_, persistentId);
2788     }
2789     {
2790         std::lock_guard<std::recursive_mutex> lockListener(windowStatusChangeListenerMutex_);
2791         ClearUselessListeners(windowStatusChangeListeners_, persistentId);
2792     }
2793     {
2794         std::lock_guard<std::recursive_mutex> lockListener(windowTitleButtonRectChangeListenerMutex_);
2795         ClearUselessListeners(windowTitleButtonRectChangeListeners_, persistentId);
2796     }
2797     {
2798         std::lock_guard<std::mutex> lockListener(displayIdChangeListenerMutex_);
2799         ClearUselessListeners(displayIdChangeListeners_, persistentId);
2800     }
2801     {
2802         std::lock_guard<std::mutex> lockListener(systemDensityChangeListenerMutex_);
2803         ClearUselessListeners(systemDensityChangeListeners_, persistentId);
2804     }
2805     {
2806         std::lock_guard<std::recursive_mutex> lockListener(windowNoInteractionListenerMutex_);
2807         ClearUselessListeners(windowNoInteractionListeners_, persistentId);
2808     }
2809     {
2810         std::lock_guard<std::mutex> lockListener(windowRectChangeListenerMutex_);
2811         ClearUselessListeners(windowRectChangeListeners_, persistentId);
2812     }
2813     {
2814         std::lock_guard<std::mutex> lockListener(subWindowCloseListenersMutex_);
2815         ClearUselessListeners(subWindowCloseListeners_, persistentId);
2816     }
2817     {
2818         std::lock_guard<std::mutex> lockListener(mainWindowCloseListenersMutex_);
2819         ClearUselessListeners(mainWindowCloseListeners_, persistentId);
2820     }
2821     {
2822         std::lock_guard<std::mutex> lockListener(windowWillCloseListenersMutex_);
2823         ClearUselessListeners(windowWillCloseListeners_, persistentId);
2824     }
2825     {
2826         std::lock_guard<std::recursive_mutex> lockListener(occupiedAreaChangeListenerMutex_);
2827         ClearUselessListeners(occupiedAreaChangeListeners_, persistentId);
2828     }
2829     {
2830         std::lock_guard<std::mutex> lockListener(highlightChangeListenerMutex_);
2831         ClearUselessListeners(highlightChangeListeners_, persistentId);
2832     }
2833     ClearSwitchFreeMultiWindowListenersById(persistentId);
2834     TLOGI(WmsLogTag::WMS_LIFE, "Clear success, id: %{public}d.", GetPersistentId());
2835 }
2836 
ClearSwitchFreeMultiWindowListenersById(int32_t persistentId)2837 void WindowSessionImpl::ClearSwitchFreeMultiWindowListenersById(int32_t persistentId)
2838 {
2839     std::lock_guard<std::mutex> lockListener(switchFreeMultiWindowListenerMutex_);
2840     ClearUselessListeners(switchFreeMultiWindowListeners_, persistentId);
2841 }
2842 
RegisterWindowDestroyedListener(const NotifyNativeWinDestroyFunc & func)2843 void WindowSessionImpl::RegisterWindowDestroyedListener(const NotifyNativeWinDestroyFunc& func)
2844 {
2845     notifyNativeFunc_ = std::move(func);
2846 }
2847 
ClearVsyncStation()2848 void WindowSessionImpl::ClearVsyncStation()
2849 {
2850     std::lock_guard<std::recursive_mutex> lock(mutex_);
2851     if (vsyncStation_ != nullptr) {
2852         vsyncStation_.reset();
2853     }
2854 }
2855 
SetInputEventConsumer(const std::shared_ptr<IInputEventConsumer> & inputEventConsumer)2856 void WindowSessionImpl::SetInputEventConsumer(const std::shared_ptr<IInputEventConsumer>& inputEventConsumer)
2857 {
2858     TLOGI(WmsLogTag::WMS_EVENT, "called");
2859     std::lock_guard<std::recursive_mutex> lock(mutex_);
2860     inputEventConsumer_ = inputEventConsumer;
2861 }
2862 
SetTitleButtonVisible(bool isMaximizeVisible,bool isMinimizeVisible,bool isSplitVisible,bool isCloseVisible)2863 WMError WindowSessionImpl::SetTitleButtonVisible(bool isMaximizeVisible, bool isMinimizeVisible, bool isSplitVisible,
2864     bool isCloseVisible)
2865 {
2866     if (IsWindowSessionInvalid()) {
2867         return WMError::WM_ERROR_INVALID_WINDOW;
2868     }
2869     if (!WindowHelper::IsMainWindow(GetType())) {
2870         return WMError::WM_ERROR_INVALID_CALLING;
2871     }
2872     if (!IsPcOrPadCapabilityEnabled()) {
2873         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2874     }
2875     if (GetUIContentSharedPtr() == nullptr || !IsDecorEnable()) {
2876         return WMError::WM_ERROR_INVALID_WINDOW;
2877     }
2878     windowTitleVisibleFlags_ = { isMaximizeVisible, isMinimizeVisible, isSplitVisible, isCloseVisible };
2879     UpdateTitleButtonVisibility();
2880     return WMError::WM_OK;
2881 }
2882 
GetIsMidScene(bool & isMidScene)2883 WMError WindowSessionImpl::GetIsMidScene(bool& isMidScene)
2884 {
2885     if (IsWindowSessionInvalid()) {
2886         return WMError::WM_ERROR_INVALID_WINDOW;
2887     }
2888     auto hostSession = GetHostSession();
2889     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2890     hostSession->GetIsMidScene(isMidScene);
2891     return WMError::WM_OK;
2892 }
2893 
NotifyAfterForeground(bool needNotifyListeners,bool needNotifyUiContent)2894 void WindowSessionImpl::NotifyAfterForeground(bool needNotifyListeners, bool needNotifyUiContent)
2895 {
2896     if (needNotifyListeners) {
2897         std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
2898         auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
2899         CALL_LIFECYCLE_LISTENER(AfterForeground, lifecycleListeners);
2900     }
2901     if (needNotifyUiContent) {
2902         CALL_UI_CONTENT(Foreground);
2903     }
2904     if (vsyncStation_ == nullptr) {
2905         TLOGE(WmsLogTag::WMS_MAIN, "SetFrameRateLinkerEnable true failed, vsyncStation is nullptr");
2906         return;
2907     }
2908     TLOGD(WmsLogTag::WMS_MAIN, "SetFrameRateLinkerEnable: true, linkerId = %{public}" PRIu64,
2909         vsyncStation_->GetFrameRateLinkerId());
2910     vsyncStation_->SetFrameRateLinkerEnable(true);
2911     if (WindowHelper::IsMainWindow(GetType())) {
2912         TLOGD(WmsLogTag::WMS_MAIN, "IsMainWindow: %{public}d, WindowType: %{public}d",
2913             WindowHelper::IsMainWindow(GetType()), GetType());
2914         vsyncStation_->SetDisplaySoloistFrameRateLinkerEnable(true);
2915     }
2916 }
2917 
NotifyAfterBackground(bool needNotifyListeners,bool needNotifyUiContent)2918 void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool needNotifyUiContent)
2919 {
2920     if (needNotifyListeners) {
2921         std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
2922         auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
2923         CALL_LIFECYCLE_LISTENER(AfterBackground, lifecycleListeners);
2924     }
2925     if (needNotifyUiContent) {
2926         CALL_UI_CONTENT(Background);
2927     }
2928     if (vsyncStation_ == nullptr) {
2929         TLOGE(WmsLogTag::WMS_MAIN, "SetFrameRateLinkerEnable false failed, vsyncStation is nullptr");
2930         return;
2931     }
2932     TLOGD(WmsLogTag::WMS_MAIN, "SetFrameRateLinkerEnable: false, linkerId = %{public}" PRIu64,
2933         vsyncStation_->GetFrameRateLinkerId());
2934     vsyncStation_->SetFrameRateLinkerEnable(false);
2935     if (WindowHelper::IsMainWindow(GetType())) {
2936         TLOGD(WmsLogTag::WMS_MAIN, "IsMainWindow: %{public}d, WindowType: %{public}d",
2937             WindowHelper::IsMainWindow(GetType()), GetType());
2938         vsyncStation_->SetDisplaySoloistFrameRateLinkerEnable(false);
2939     }
2940 }
2941 
RequestInputMethodCloseKeyboard(bool isNeedKeyboard,bool keepKeyboardFlag)2942 static void RequestInputMethodCloseKeyboard(bool isNeedKeyboard, bool keepKeyboardFlag)
2943 {
2944     if (!isNeedKeyboard && !keepKeyboardFlag) {
2945 #ifdef IMF_ENABLE
2946         TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify InputMethod framework close keyboard start.");
2947         if (MiscServices::InputMethodController::GetInstance()) {
2948             MiscServices::InputMethodController::GetInstance()->RequestHideInput();
2949             TLOGI(WmsLogTag::WMS_KEYBOARD, "Notify InputMethod framework close keyboard end.");
2950         }
2951 #endif
2952     }
2953 }
2954 
NotifyUIContentFocusStatus()2955 void WindowSessionImpl::NotifyUIContentFocusStatus()
2956 {
2957     if (!isFocused_) {
2958         CALL_UI_CONTENT(UnFocus);
2959         return;
2960     }
2961     CALL_UI_CONTENT(Focus);
2962     auto task = [weak = wptr(this)]() {
2963         auto window = weak.promote();
2964         if (!window) {
2965             return;
2966         }
2967         bool isNeedKeyboard = false;
2968         {
2969             std::shared_ptr<Ace::UIContent> uiContent = window->GetUIContentSharedPtr();
2970             if (uiContent != nullptr) {
2971                 // isNeedKeyboard is set by arkui and indicates whether the window needs a keyboard or not.
2972                 isNeedKeyboard = uiContent->NeedSoftKeyboard();
2973             }
2974         }
2975         // whether keep the keyboard created by other windows, support system window and app subwindow.
2976         bool keepKeyboardFlag = (window->property_) ? window->property_->GetKeepKeyboardFlag() : false;
2977         TLOGI(WmsLogTag::WMS_KEYBOARD, "isNeedKeyboard: %{public}d, keepKeyboardFlag: %{public}d",
2978             isNeedKeyboard, keepKeyboardFlag);
2979         RequestInputMethodCloseKeyboard(isNeedKeyboard, keepKeyboardFlag);
2980     };
2981     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2982     if (uiContent != nullptr) {
2983         uiContent->SetOnWindowFocused(task);
2984     }
2985 }
2986 
NotifyAfterFocused()2987 void WindowSessionImpl::NotifyAfterFocused()
2988 {
2989     NotifyWindowAfterFocused();
2990     if (GetUIContentSharedPtr() != nullptr) {
2991         NotifyUIContentFocusStatus();
2992     } else {
2993         shouldReNotifyFocus_ = true;
2994     }
2995 }
2996 
NotifyAfterUnfocused(bool needNotifyUiContent)2997 void WindowSessionImpl::NotifyAfterUnfocused(bool needNotifyUiContent)
2998 {
2999     NotifyWindowAfterUnfocused();
3000     if (needNotifyUiContent) {
3001         if (GetUIContentSharedPtr() == nullptr) {
3002             shouldReNotifyFocus_ = true;
3003         } else {
3004             CALL_UI_CONTENT(UnFocus);
3005         }
3006     }
3007 }
3008 
NotifyWindowAfterFocused()3009 void WindowSessionImpl::NotifyWindowAfterFocused()
3010 {
3011     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3012     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3013     CALL_LIFECYCLE_LISTENER(AfterFocused, lifecycleListeners);
3014 }
3015 
NotifyWindowAfterUnfocused()3016 void WindowSessionImpl::NotifyWindowAfterUnfocused()
3017 {
3018     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3019     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3020     // use needNotifyUinContent to separate ui content callbacks
3021     CALL_LIFECYCLE_LISTENER(AfterUnfocused, lifecycleListeners);
3022 }
3023 
NotifyBeforeDestroy(std::string windowName)3024 void WindowSessionImpl::NotifyBeforeDestroy(std::string windowName)
3025 {
3026     auto task = [this]() {
3027         {
3028             std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3029             if (uiContent != nullptr) {
3030                 uiContent->Destroy();
3031             }
3032         }
3033         {
3034             std::unique_lock<std::shared_mutex> lock(uiContentMutex_);
3035             if (uiContent_ != nullptr) {
3036                 uiContent_ = nullptr;
3037                 TLOGD(WmsLogTag::WMS_LIFE, "NotifyBeforeDestroy: uiContent destroy success, persistentId:%{public}d",
3038                     GetPersistentId());
3039             }
3040         }
3041     };
3042     if (handler_) {
3043         handler_->PostSyncTask(task, "wms:NotifyBeforeDestroy");
3044     } else {
3045         task();
3046     }
3047     TLOGI(WmsLogTag::WMS_LIFE, "Release uicontent successfully, id: %{public}d.", GetPersistentId());
3048     if (notifyNativeFunc_) {
3049         notifyNativeFunc_(windowName);
3050     }
3051     TLOGI(WmsLogTag::WMS_LIFE, "successed with id: %{public}d.", GetPersistentId());
3052 }
3053 
NotifyAfterDestroy()3054 void WindowSessionImpl::NotifyAfterDestroy()
3055 {
3056     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3057     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3058     CALL_LIFECYCLE_LISTENER(AfterDestroyed, lifecycleListeners);
3059 }
3060 
NotifyAfterActive()3061 void WindowSessionImpl::NotifyAfterActive()
3062 {
3063     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3064     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3065     CALL_LIFECYCLE_LISTENER(AfterActive, lifecycleListeners);
3066 }
3067 
NotifyAfterInactive()3068 void WindowSessionImpl::NotifyAfterInactive()
3069 {
3070     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3071     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3072     CALL_LIFECYCLE_LISTENER(AfterInactive, lifecycleListeners);
3073 }
3074 
NotifyForegroundFailed(WMError ret)3075 void WindowSessionImpl::NotifyForegroundFailed(WMError ret)
3076 {
3077     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3078     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3079     CALL_LIFECYCLE_LISTENER_WITH_PARAM(ForegroundFailed, lifecycleListeners, static_cast<int32_t>(ret));
3080 }
3081 
NotifyBackgroundFailed(WMError ret)3082 void WindowSessionImpl::NotifyBackgroundFailed(WMError ret)
3083 {
3084     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3085     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3086     CALL_LIFECYCLE_LISTENER_WITH_PARAM(BackgroundFailed, lifecycleListeners, static_cast<int32_t>(ret));
3087 }
3088 
NotifyAfterResumed()3089 void WindowSessionImpl::NotifyAfterResumed()
3090 {
3091     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3092     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3093     CALL_LIFECYCLE_LISTENER(AfterResumed, lifecycleListeners);
3094 }
3095 
NotifyAfterPaused()3096 void WindowSessionImpl::NotifyAfterPaused()
3097 {
3098     std::lock_guard<std::recursive_mutex> lockListener(lifeCycleListenerMutex_);
3099     auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3100     CALL_LIFECYCLE_LISTENER(AfterPaused, lifecycleListeners);
3101 }
3102 
MarkProcessed(int32_t eventId)3103 WSError WindowSessionImpl::MarkProcessed(int32_t eventId)
3104 {
3105     if (IsWindowSessionInvalid()) {
3106         WLOGFE("HostSession is invalid");
3107         return WSError::WS_DO_NOTHING;
3108     }
3109     auto hostSession = GetHostSession();
3110     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WSError::WS_DO_NOTHING);
3111     return hostSession->MarkProcessed(eventId);
3112 }
3113 
RegisterDialogDeathRecipientListener(const sptr<IDialogDeathRecipientListener> & listener)3114 void WindowSessionImpl::RegisterDialogDeathRecipientListener(const sptr<IDialogDeathRecipientListener>& listener)
3115 {
3116     TLOGI(WmsLogTag::WMS_DIALOG, "window %{public}s id %{public}d register DialogDeathRecipientListener",
3117         GetWindowName().c_str(), GetPersistentId());
3118     if (listener == nullptr) {
3119         WLOGFE("listener is nullptr");
3120         return;
3121     }
3122     std::lock_guard<std::recursive_mutex> lockListener(dialogDeathRecipientListenerMutex_);
3123     RegisterListener(dialogDeathRecipientListeners_[GetPersistentId()], listener);
3124 }
3125 
UnregisterDialogDeathRecipientListener(const sptr<IDialogDeathRecipientListener> & listener)3126 void WindowSessionImpl::UnregisterDialogDeathRecipientListener(const sptr<IDialogDeathRecipientListener>& listener)
3127 {
3128     TLOGI(WmsLogTag::WMS_DIALOG, "window %{public}s id %{public}d unregister DialogDeathRecipientListener",
3129         GetWindowName().c_str(), GetPersistentId());
3130     std::lock_guard<std::recursive_mutex> lockListener(dialogDeathRecipientListenerMutex_);
3131     UnregisterListener(dialogDeathRecipientListeners_[GetPersistentId()], listener);
3132 }
3133 
RegisterDialogTargetTouchListener(const sptr<IDialogTargetTouchListener> & listener)3134 WMError WindowSessionImpl::RegisterDialogTargetTouchListener(const sptr<IDialogTargetTouchListener>& listener)
3135 {
3136     TLOGI(WmsLogTag::WMS_DIALOG, "window %{public}s id %{public}d register DialogTargetTouchListener",
3137         GetWindowName().c_str(), GetPersistentId());
3138     if (listener == nullptr) {
3139         WLOGFE("listener is nullptr");
3140         return WMError::WM_ERROR_NULLPTR;
3141     }
3142     std::lock_guard<std::recursive_mutex> lockListener(dialogTargetTouchListenerMutex_);
3143     return RegisterListener(dialogTargetTouchListener_[GetPersistentId()], listener);
3144 }
3145 
UnregisterDialogTargetTouchListener(const sptr<IDialogTargetTouchListener> & listener)3146 WMError WindowSessionImpl::UnregisterDialogTargetTouchListener(const sptr<IDialogTargetTouchListener>& listener)
3147 {
3148     TLOGI(WmsLogTag::WMS_DIALOG, "window %{public}s id %{public}d unregister DialogTargetTouchListener",
3149         GetWindowName().c_str(), GetPersistentId());
3150     std::lock_guard<std::recursive_mutex> lockListener(dialogTargetTouchListenerMutex_);
3151     return UnregisterListener(dialogTargetTouchListener_[GetPersistentId()], listener);
3152 }
3153 
RegisterScreenshotListener(const sptr<IScreenshotListener> & listener)3154 WMError WindowSessionImpl::RegisterScreenshotListener(const sptr<IScreenshotListener>& listener)
3155 {
3156     WLOGFD("Start register ScreenshotListener");
3157     std::lock_guard<std::recursive_mutex> lockListener(screenshotListenerMutex_);
3158     return RegisterListener(screenshotListeners_[GetPersistentId()], listener);
3159 }
3160 
UnregisterScreenshotListener(const sptr<IScreenshotListener> & listener)3161 WMError WindowSessionImpl::UnregisterScreenshotListener(const sptr<IScreenshotListener>& listener)
3162 {
3163     WLOGFD("Start unregister ScreenshotListener");
3164     std::lock_guard<std::recursive_mutex> lockListener(screenshotListenerMutex_);
3165     return UnregisterListener(screenshotListeners_[GetPersistentId()], listener);
3166 }
3167 
3168 template<typename T>
3169 EnableIfSame<T, IDialogDeathRecipientListener, std::vector<sptr<IDialogDeathRecipientListener>>> WindowSessionImpl::
GetListeners()3170     GetListeners()
3171 {
3172     std::vector<sptr<IDialogDeathRecipientListener>> dialogDeathRecipientListener;
3173     for (auto& listener : dialogDeathRecipientListeners_[GetPersistentId()]) {
3174         dialogDeathRecipientListener.push_back(listener);
3175     }
3176     return dialogDeathRecipientListener;
3177 }
3178 
3179 template<typename T>
3180 EnableIfSame<T, IDialogTargetTouchListener,
GetListeners()3181     std::vector<sptr<IDialogTargetTouchListener>>> WindowSessionImpl::GetListeners()
3182 {
3183     std::vector<sptr<IDialogTargetTouchListener>> dialogTargetTouchListener;
3184     for (auto& listener : dialogTargetTouchListener_[GetPersistentId()]) {
3185         dialogTargetTouchListener.push_back(listener);
3186     }
3187     return dialogTargetTouchListener;
3188 }
3189 
3190 template<typename T>
GetListeners()3191 EnableIfSame<T, IScreenshotListener, std::vector<sptr<IScreenshotListener>>> WindowSessionImpl::GetListeners()
3192 {
3193     std::vector<sptr<IScreenshotListener>> screenshotListeners;
3194     for (auto& listener : screenshotListeners_[GetPersistentId()]) {
3195         screenshotListeners.push_back(listener);
3196     }
3197     return screenshotListeners;
3198 }
3199 
NotifyDestroy()3200 WSError WindowSessionImpl::NotifyDestroy()
3201 {
3202     if (WindowHelper::IsDialogWindow(property_->GetWindowType())) {
3203         std::lock_guard<std::recursive_mutex> lockListener(dialogDeathRecipientListenerMutex_);
3204         auto dialogDeathRecipientListener = GetListeners<IDialogDeathRecipientListener>();
3205         for (auto& listener : dialogDeathRecipientListener) {
3206             if (listener != nullptr) {
3207                 listener->OnDialogDeathRecipient();
3208             }
3209         }
3210     } else if (WindowHelper::IsSubWindow(property_->GetWindowType())) {
3211         if (property_->GetExtensionFlag() == true && !isUIExtensionAbilityProcess_) {
3212             Destroy();
3213         }
3214     }
3215     return WSError::WS_OK;
3216 }
3217 
3218 template<typename T>
GetListeners()3219 EnableIfSame<T, IDisplayMoveListener, std::vector<sptr<IDisplayMoveListener>>> WindowSessionImpl::GetListeners()
3220 {
3221     std::vector<sptr<IDisplayMoveListener>> displayMoveListeners;
3222     for (auto& listener : displayMoveListeners_[GetPersistentId()]) {
3223         displayMoveListeners.push_back(listener);
3224     }
3225     return displayMoveListeners;
3226 }
3227 
NotifyDisplayMove(DisplayId from,DisplayId to)3228 void WindowSessionImpl::NotifyDisplayMove(DisplayId from, DisplayId to)
3229 {
3230     WLOGFD("Notify display move from %{public}" PRIu64 " to %{public}" PRIu64, from, to);
3231     std::lock_guard<std::mutex> lockListener(displayMoveListenerMutex_);
3232     auto displayMoveListeners = GetListeners<IDisplayMoveListener>();
3233     for (auto& listener : displayMoveListeners) {
3234         if (listener != nullptr) {
3235             listener->OnDisplayMove(from, to);
3236         }
3237     }
3238 }
3239 
NotifyCloseExistPipWindow()3240 WSError WindowSessionImpl::NotifyCloseExistPipWindow()
3241 {
3242     TLOGI(WmsLogTag::WMS_PIP, "WindowSessionImpl::NotifyCloseExistPipWindow");
3243     auto task = []() {
3244         PictureInPictureManager::DoClose(true, true);
3245     };
3246     handler_->PostTask(task, "WMS_WindowSessionImpl_NotifyCloseExistPipWindow");
3247     return WSError::WS_OK;
3248 }
3249 
NotifyTouchDialogTarget(int32_t posX,int32_t posY)3250 void WindowSessionImpl::NotifyTouchDialogTarget(int32_t posX, int32_t posY)
3251 {
3252     TLOGI(WmsLogTag::WMS_DIALOG, "window %{public}s id %{public}d", GetWindowName().c_str(), GetPersistentId());
3253     auto hostSession = GetHostSession();
3254     if (hostSession != nullptr) {
3255         hostSession->ProcessPointDownSession(posX, posY);
3256     }
3257     std::lock_guard<std::recursive_mutex> lockListener(dialogTargetTouchListenerMutex_);
3258     auto dialogTargetTouchListener = GetListeners<IDialogTargetTouchListener>();
3259     for (auto& listener : dialogTargetTouchListener) {
3260         if (listener != nullptr) {
3261             listener->OnDialogTargetTouch();
3262         }
3263     }
3264 }
3265 
NotifyScreenshot()3266 void WindowSessionImpl::NotifyScreenshot()
3267 {
3268     std::lock_guard<std::recursive_mutex> lockListener(screenshotListenerMutex_);
3269     auto screenshotListeners = GetListeners<IScreenshotListener>();
3270     for (auto& listener : screenshotListeners) {
3271         if (listener != nullptr) {
3272             listener->OnScreenshot();
3273         }
3274     }
3275 }
3276 
NotifySizeChange(Rect rect,WindowSizeChangeReason reason)3277 void WindowSessionImpl::NotifySizeChange(Rect rect, WindowSizeChangeReason reason)
3278 {
3279     {
3280         std::lock_guard<std::recursive_mutex> lockListener(windowChangeListenerMutex_);
3281         auto windowChangeListeners = GetListeners<IWindowChangeListener>();
3282         for (auto& listener : windowChangeListeners) {
3283             if (listener != nullptr) {
3284                 listener->OnSizeChange(rect, reason);
3285             }
3286         }
3287     }
3288     {
3289         std::lock_guard<std::mutex> lockRectListener(windowRectChangeListenerMutex_);
3290         auto windowRectChangeListeners = GetListeners<IWindowRectChangeListener>();
3291         for (auto& listener : windowRectChangeListeners) {
3292             if (listener != nullptr) {
3293                 listener->OnRectChange(rect, reason);
3294             }
3295         }
3296     }
3297 }
3298 
NotifySubWindowClose(bool & terminateCloseProcess)3299 void WindowSessionImpl::NotifySubWindowClose(bool& terminateCloseProcess)
3300 {
3301     WLOGFD("WindowSessionImpl::NotifySubWindowClose");
3302     std::lock_guard<std::mutex> lockListener(subWindowCloseListenersMutex_);
3303     auto subWindowCloseListeners = GetListeners<ISubWindowCloseListener>();
3304     if (subWindowCloseListeners != nullptr) {
3305         subWindowCloseListeners->OnSubWindowClose(terminateCloseProcess);
3306     }
3307 }
3308 
NotifyMainWindowClose(bool & terminateCloseProcess)3309 WMError WindowSessionImpl::NotifyMainWindowClose(bool& terminateCloseProcess)
3310 {
3311     std::lock_guard<std::mutex> lockListener(mainWindowCloseListenersMutex_);
3312     auto mainWindowCloseListener = GetListeners<IMainWindowCloseListener>();
3313     if (mainWindowCloseListener != nullptr) {
3314         mainWindowCloseListener->OnMainWindowClose(terminateCloseProcess);
3315         return WMError::WM_OK;
3316     }
3317     return WMError::WM_ERROR_NULLPTR;
3318 }
3319 
NotifyWindowWillClose(sptr<Window> window)3320 WMError WindowSessionImpl::NotifyWindowWillClose(sptr<Window> window)
3321 {
3322     std::lock_guard<std::mutex> lockListener(windowWillCloseListenersMutex_);
3323     const auto& windowWillCloseListeners = GetListeners<IWindowWillCloseListener>();
3324     auto res = WMError::WM_ERROR_NULLPTR;
3325     for (const auto& listener : windowWillCloseListeners) {
3326         if (listener != nullptr) {
3327             listener->OnWindowWillClose(window);
3328             res = WMError::WM_OK;
3329         }
3330     }
3331     return res;
3332 }
3333 
NotifySwitchFreeMultiWindow(bool enable)3334 void WindowSessionImpl::NotifySwitchFreeMultiWindow(bool enable)
3335 {
3336     std::lock_guard<std::mutex> lockListener(switchFreeMultiWindowListenerMutex_);
3337     auto switchFreeMultiWindowListeners = GetListeners<ISwitchFreeMultiWindowListener>();
3338     for (auto& listener : switchFreeMultiWindowListeners) {
3339         if (listener != nullptr) {
3340             listener->OnSwitchFreeMultiWindow(enable);
3341         }
3342     }
3343 }
3344 
RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)3345 WMError WindowSessionImpl::RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
3346 {
3347     bool isUpdate = false;
3348     WMError ret = WMError::WM_OK;
3349     auto persistentId = GetPersistentId();
3350     TLOGI(WmsLogTag::WMS_IMMS, "Start register avoidAreaChange listener, id:%{public}d", persistentId);
3351     if (listener == nullptr) {
3352         TLOGE(WmsLogTag::WMS_IMMS, "listener is nullptr");
3353         return WMError::WM_ERROR_NULLPTR;
3354     }
3355 
3356     {
3357         std::lock_guard<std::recursive_mutex> lockListener(avoidAreaChangeListenerMutex_);
3358         ret = RegisterListener(avoidAreaChangeListeners_[persistentId], listener);
3359         if (ret != WMError::WM_OK) {
3360             return ret;
3361         }
3362         if (avoidAreaChangeListeners_[persistentId].size() == 1) {
3363             isUpdate = true;
3364         }
3365     }
3366     if (isUpdate) {
3367         ret = SingletonContainer::Get<WindowAdapter>().UpdateSessionAvoidAreaListener(persistentId, true);
3368     }
3369     return ret;
3370 }
3371 
UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)3372 WMError WindowSessionImpl::UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
3373 {
3374     bool isUpdate = false;
3375     WMError ret = WMError::WM_OK;
3376     auto persistentId = GetPersistentId();
3377     TLOGI(WmsLogTag::WMS_IMMS, "Start unregister avoidAreaChange listener, id:%{public}d", persistentId);
3378     if (listener == nullptr) {
3379         WLOGFE("listener is nullptr");
3380         return WMError::WM_ERROR_NULLPTR;
3381     }
3382 
3383     {
3384         std::lock_guard<std::recursive_mutex> lockListener(avoidAreaChangeListenerMutex_);
3385         ret = UnregisterListener(avoidAreaChangeListeners_[persistentId], listener);
3386         if (ret != WMError::WM_OK) {
3387             return ret;
3388         }
3389         if (avoidAreaChangeListeners_[persistentId].empty()) {
3390             isUpdate = true;
3391         }
3392     }
3393     if (isUpdate) {
3394         ret = SingletonContainer::Get<WindowAdapter>().UpdateSessionAvoidAreaListener(persistentId, false);
3395     }
3396     return ret;
3397 }
3398 
RegisterExtensionAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)3399 WMError WindowSessionImpl::RegisterExtensionAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
3400 {
3401     auto persistentId = GetPersistentId();
3402     WLOGI("Start register extension avoidAreaChange listener, id:%{public}d", persistentId);
3403     std::lock_guard<std::recursive_mutex> lockListener(avoidAreaChangeListenerMutex_);
3404     return RegisterListener(avoidAreaChangeListeners_[persistentId], listener);
3405 }
3406 
UnregisterExtensionAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)3407 WMError WindowSessionImpl::UnregisterExtensionAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
3408 {
3409     auto persistentId = GetPersistentId();
3410     WLOGI("Start unregister extension avoidAreaChange listener, id:%{public}d", persistentId);
3411     std::lock_guard<std::recursive_mutex> lockListener(avoidAreaChangeListenerMutex_);
3412     return UnregisterListener(avoidAreaChangeListeners_[persistentId], listener);
3413 }
3414 
3415 template<typename T>
3416 EnableIfSame<T, IAvoidAreaChangedListener,
GetListeners()3417     std::vector<sptr<IAvoidAreaChangedListener>>> WindowSessionImpl::GetListeners()
3418 {
3419     std::vector<sptr<IAvoidAreaChangedListener>> windowChangeListeners;
3420     for (auto& listener : avoidAreaChangeListeners_[GetPersistentId()]) {
3421         windowChangeListeners.push_back(listener);
3422     }
3423     return windowChangeListeners;
3424 }
3425 
NotifyAvoidAreaChange(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)3426 void WindowSessionImpl::NotifyAvoidAreaChange(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
3427 {
3428     TLOGI(WmsLogTag::WMS_IMMS,
3429           "window [%{public}d, %{public}s] type %{public}d area %{public}s",
3430           GetPersistentId(), GetWindowName().c_str(), type, avoidArea->ToString().c_str());
3431     std::lock_guard<std::recursive_mutex> lockListener(avoidAreaChangeListenerMutex_);
3432     auto avoidAreaChangeListeners = GetListeners<IAvoidAreaChangedListener>();
3433     for (auto& listener : avoidAreaChangeListeners) {
3434         if (listener != nullptr) {
3435             listener->OnAvoidAreaChanged(*avoidArea, type);
3436         }
3437     }
3438 }
3439 
NotifyTransferComponentData(const AAFwk::WantParams & wantParams)3440 WSError WindowSessionImpl::NotifyTransferComponentData(const AAFwk::WantParams& wantParams)
3441 {
3442     return WSError::WS_OK;
3443 }
3444 
NotifyTransferComponentDataSync(const AAFwk::WantParams & wantParams,AAFwk::WantParams & reWantParams)3445 WSErrorCode WindowSessionImpl::NotifyTransferComponentDataSync(const AAFwk::WantParams& wantParams,
3446     AAFwk::WantParams& reWantParams)
3447 {
3448     return WSErrorCode::WS_OK;
3449 }
3450 
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)3451 WSError WindowSessionImpl::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
3452 {
3453     auto task = [weak = wptr(this), avoidArea, type] {
3454         auto window = weak.promote();
3455         if (!window) {
3456             return;
3457         }
3458         if (window->lastAvoidAreaMap_[type] != *avoidArea) {
3459             window->lastAvoidAreaMap_[type] = *avoidArea;
3460             window->NotifyAvoidAreaChange(avoidArea, type);
3461             window->UpdateViewportConfig(window->GetRect(), WindowSizeChangeReason::AVOID_AREA_CHANGE);
3462         }
3463     };
3464     handler_->PostTask(std::move(task), __func__);
3465     return WSError::WS_OK;
3466 }
3467 
SetPipActionEvent(const std::string & action,int32_t status)3468 WSError WindowSessionImpl::SetPipActionEvent(const std::string& action, int32_t status)
3469 {
3470     TLOGI(WmsLogTag::WMS_PIP, "action: %{public}s, status: %{public}d", action.c_str(), status);
3471     auto task = [action, status]() {
3472         PictureInPictureManager::DoActionEvent(action, status);
3473     };
3474     handler_->PostTask(task, "WMS_WindowSessionImpl_SetPipActionEvent");
3475     return WSError::WS_OK;
3476 }
3477 
SetPiPControlEvent(WsPiPControlType controlType,WsPiPControlStatus status)3478 WSError WindowSessionImpl::SetPiPControlEvent(WsPiPControlType controlType, WsPiPControlStatus status)
3479 {
3480     TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, enabled:%{public}d", controlType, status);
3481     auto task = [controlType, status]() {
3482         PictureInPictureManager::DoControlEvent(static_cast<PiPControlType>(controlType),
3483             static_cast<PiPControlStatus>(status));
3484     };
3485     handler_->PostTask(task, "WMS_WindowSessionImpl_SetPiPControlEvent");
3486     return WSError::WS_OK;
3487 }
3488 
NotifyPipWindowSizeChange(uint32_t width,uint32_t height,double scale)3489 WSError WindowSessionImpl::NotifyPipWindowSizeChange(uint32_t width, uint32_t height, double scale)
3490 {
3491     TLOGI(WmsLogTag::WMS_PIP, "width: %{public}u, height: %{public}u scale: %{public}f", width, height, scale);
3492     auto task = [width, height, scale]() {
3493         PictureInPictureManager::PipSizeChange(width, height, scale);
3494     };
3495     handler_->PostTask(task, "WMS_WindowSessionImpl_NotifyPipWindowSizeChange");
3496     return WSError::WS_OK;
3497 }
3498 
RegisterTouchOutsideListener(const sptr<ITouchOutsideListener> & listener)3499 WMError WindowSessionImpl::RegisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
3500 {
3501     bool isUpdate = false;
3502     WMError ret = WMError::WM_OK;
3503     auto persistentId = GetPersistentId();
3504     TLOGI(WmsLogTag::WMS_EVENT, "Start register touchOutside listener, window: name=%{public}s, id=%{public}u",
3505         GetWindowName().c_str(), GetPersistentId());
3506     if (listener == nullptr) {
3507         TLOGE(WmsLogTag::WMS_EVENT, "listener is nullptr");
3508         return WMError::WM_ERROR_NULLPTR;
3509     }
3510 
3511     {
3512         std::lock_guard<std::recursive_mutex> lockListener(touchOutsideListenerMutex_);
3513         ret = RegisterListener(touchOutsideListeners_[persistentId], listener);
3514         if (ret != WMError::WM_OK) {
3515             TLOGE(WmsLogTag::WMS_EVENT, "Register touchOutside listener fail, ret:%{public}u", ret);
3516             return ret;
3517         }
3518         if (touchOutsideListeners_[persistentId].size() == 1) {
3519             isUpdate = true;
3520         }
3521     }
3522     if (isUpdate) {
3523         ret = SingletonContainer::Get<WindowAdapter>().UpdateSessionTouchOutsideListener(persistentId, true);
3524     }
3525     return ret;
3526 }
3527 
UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener> & listener)3528 WMError WindowSessionImpl::UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
3529 {
3530     bool isUpdate = false;
3531     WMError ret = WMError::WM_OK;
3532     auto persistentId = GetPersistentId();
3533     TLOGI(WmsLogTag::WMS_EVENT, "Start unregister touchOutside listener, window: name=%{public}s, id=%{public}u",
3534         GetWindowName().c_str(), GetPersistentId());
3535     if (listener == nullptr) {
3536         TLOGE(WmsLogTag::WMS_EVENT, "listener is nullptr");
3537         return WMError::WM_ERROR_NULLPTR;
3538     }
3539 
3540     {
3541         std::lock_guard<std::recursive_mutex> lockListener(touchOutsideListenerMutex_);
3542         ret = UnregisterListener(touchOutsideListeners_[persistentId], listener);
3543         if (ret != WMError::WM_OK) {
3544             TLOGE(WmsLogTag::WMS_EVENT, "Unregister touchOutside listener fail, ret:%{public}u", ret);
3545             return ret;
3546         }
3547         if (touchOutsideListeners_[persistentId].empty()) {
3548             isUpdate = true;
3549         }
3550     }
3551     if (isUpdate) {
3552         ret = SingletonContainer::Get<WindowAdapter>().UpdateSessionTouchOutsideListener(persistentId, false);
3553     }
3554     return ret;
3555 }
3556 
3557 template<typename T>
GetListeners()3558 EnableIfSame<T, ITouchOutsideListener, std::vector<sptr<ITouchOutsideListener>>> WindowSessionImpl::GetListeners()
3559 {
3560     std::vector<sptr<ITouchOutsideListener>> windowChangeListeners;
3561     for (auto& listener : touchOutsideListeners_[GetPersistentId()]) {
3562         windowChangeListeners.push_back(listener);
3563     }
3564     return windowChangeListeners;
3565 }
3566 
NotifyTouchOutside()3567 WSError WindowSessionImpl::NotifyTouchOutside()
3568 {
3569     TLOGI(WmsLogTag::WMS_EVENT, "Notify touch outside, window: name=%{public}s, id=%{public}u",
3570         GetWindowName().c_str(), GetPersistentId());
3571     std::lock_guard<std::recursive_mutex> lockListener(touchOutsideListenerMutex_);
3572     auto touchOutsideListeners = GetListeners<ITouchOutsideListener>();
3573     for (auto& listener : touchOutsideListeners) {
3574         if (listener != nullptr) {
3575             listener->OnTouchOutside();
3576         }
3577     }
3578     return WSError::WS_OK;
3579 }
3580 
RegisterWindowVisibilityChangeListener(const IWindowVisibilityListenerSptr & listener)3581 WMError WindowSessionImpl::RegisterWindowVisibilityChangeListener(const IWindowVisibilityListenerSptr& listener)
3582 {
3583     auto persistentId = GetPersistentId();
3584     WLOGFD("Start to register window visibility change listener, persistentId=%{public}d.", persistentId);
3585     WMError ret = WMError::WM_OK;
3586     bool isFirstRegister = false;
3587     {
3588         std::lock_guard<std::recursive_mutex> lockListener(windowVisibilityChangeListenerMutex_);
3589         ret = RegisterListener(windowVisibilityChangeListeners_[persistentId], listener);
3590         if (ret != WMError::WM_OK) {
3591             return ret;
3592         }
3593         isFirstRegister = windowVisibilityChangeListeners_[persistentId].size() == 1;
3594     }
3595 
3596     if (isFirstRegister) {
3597         ret = SingletonContainer::Get<WindowAdapter>().UpdateSessionWindowVisibilityListener(persistentId, true);
3598     }
3599     return ret;
3600 }
3601 
UnregisterWindowVisibilityChangeListener(const IWindowVisibilityListenerSptr & listener)3602 WMError WindowSessionImpl::UnregisterWindowVisibilityChangeListener(const IWindowVisibilityListenerSptr& listener)
3603 {
3604     auto persistentId = GetPersistentId();
3605     WLOGFD("Start to unregister window visibility change listener, persistentId=%{public}d.", persistentId);
3606     WMError ret = WMError::WM_OK;
3607     bool isLastUnregister = false;
3608     {
3609         std::lock_guard<std::recursive_mutex> lockListener(windowVisibilityChangeListenerMutex_);
3610         ret = UnregisterListener(windowVisibilityChangeListeners_[persistentId], listener);
3611         if (ret != WMError::WM_OK) {
3612             return ret;
3613         }
3614         isLastUnregister = windowVisibilityChangeListeners_[persistentId].empty();
3615     }
3616 
3617     if (isLastUnregister) {
3618         ret = SingletonContainer::Get<WindowAdapter>().UpdateSessionWindowVisibilityListener(persistentId, false);
3619     }
3620     return ret;
3621 }
3622 
RegisterDisplayIdChangeListener(const IDisplayIdChangeListenerSptr & listener)3623 WMError WindowSessionImpl::RegisterDisplayIdChangeListener(const IDisplayIdChangeListenerSptr& listener)
3624 {
3625     TLOGD(WmsLogTag::DEFAULT, "name=%{public}s, id=%{public}u", GetWindowName().c_str(), GetPersistentId());
3626     std::lock_guard<std::mutex> lockListener(displayIdChangeListenerMutex_);
3627     return RegisterListener(displayIdChangeListeners_[GetPersistentId()], listener);
3628 }
3629 
UnregisterDisplayIdChangeListener(const IDisplayIdChangeListenerSptr & listener)3630 WMError WindowSessionImpl::UnregisterDisplayIdChangeListener(const IDisplayIdChangeListenerSptr& listener)
3631 {
3632     TLOGD(WmsLogTag::DEFAULT, "name=%{public}s, id=%{public}u", GetWindowName().c_str(), GetPersistentId());
3633     std::lock_guard<std::mutex> lockListener(displayIdChangeListenerMutex_);
3634     return UnregisterListener(displayIdChangeListeners_[GetPersistentId()], listener);
3635 }
3636 
RegisterSystemDensityChangeListener(const ISystemDensityChangeListenerSptr & listener)3637 WMError WindowSessionImpl::RegisterSystemDensityChangeListener(const ISystemDensityChangeListenerSptr& listener)
3638 {
3639     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "name=%{public}s, id=%{public}d", GetWindowName().c_str(), GetPersistentId());
3640     std::lock_guard<std::mutex> lockListener(systemDensityChangeListenerMutex_);
3641     return RegisterListener(systemDensityChangeListeners_[GetPersistentId()], listener);
3642 }
3643 
UnregisterSystemDensityChangeListener(const ISystemDensityChangeListenerSptr & listener)3644 WMError WindowSessionImpl::UnregisterSystemDensityChangeListener(const ISystemDensityChangeListenerSptr& listener)
3645 {
3646     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "name=%{public}s, id=%{public}d", GetWindowName().c_str(), GetPersistentId());
3647     std::lock_guard<std::mutex> lockListener(systemDensityChangeListenerMutex_);
3648     return UnregisterListener(systemDensityChangeListeners_[GetPersistentId()], listener);
3649 }
3650 
RegisterWindowNoInteractionListener(const IWindowNoInteractionListenerSptr & listener)3651 WMError WindowSessionImpl::RegisterWindowNoInteractionListener(const IWindowNoInteractionListenerSptr& listener)
3652 {
3653     WLOGFD("Start to register window no interaction listener.");
3654     std::lock_guard<std::recursive_mutex> lockListener(windowNoInteractionListenerMutex_);
3655     WMError ret = RegisterListener(windowNoInteractionListeners_[GetPersistentId()], listener);
3656     if (ret != WMError::WM_OK) {
3657         WLOGFE("register no interaction listener failed.");
3658     } else {
3659         SubmitNoInteractionMonitorTask(this->lastInteractionEventId_.load(), listener);
3660     }
3661     return ret;
3662 }
3663 
UnregisterWindowNoInteractionListener(const IWindowNoInteractionListenerSptr & listener)3664 WMError WindowSessionImpl::UnregisterWindowNoInteractionListener(const IWindowNoInteractionListenerSptr& listener)
3665 {
3666     WLOGFD("Start to unregister window no interaction listener.");
3667     std::lock_guard<std::recursive_mutex> lockListener(windowNoInteractionListenerMutex_);
3668     WMError ret = UnregisterListener(windowNoInteractionListeners_[GetPersistentId()], listener);
3669     if (windowNoInteractionListeners_[GetPersistentId()].empty()) {
3670         lastInteractionEventId_.store(-1);
3671     }
3672     return ret;
3673 }
3674 
3675 template<typename T>
GetListeners()3676 EnableIfSame<T, IWindowVisibilityChangedListener, std::vector<IWindowVisibilityListenerSptr>> WindowSessionImpl::GetListeners()
3677 {
3678     std::vector<IWindowVisibilityListenerSptr> windowVisibilityChangeListeners;
3679     for (auto& listener : windowVisibilityChangeListeners_[GetPersistentId()]) {
3680         windowVisibilityChangeListeners.push_back(listener);
3681     }
3682     return windowVisibilityChangeListeners;
3683 }
3684 
3685 template<typename T>
3686 EnableIfSame<T, IDisplayIdChangeListener,
GetListeners()3687     std::vector<IDisplayIdChangeListenerSptr>> WindowSessionImpl::GetListeners()
3688 {
3689     return displayIdChangeListeners_[GetPersistentId()];
3690 }
3691 
3692 template<typename T>
3693 EnableIfSame<T, ISystemDensityChangeListener,
GetListeners()3694     std::vector<ISystemDensityChangeListenerSptr>> WindowSessionImpl::GetListeners()
3695 {
3696     return systemDensityChangeListeners_[GetPersistentId()];
3697 }
3698 
3699 template<typename T>
GetListeners()3700 EnableIfSame<T, IWindowNoInteractionListener, std::vector<IWindowNoInteractionListenerSptr>> WindowSessionImpl::GetListeners()
3701 {
3702     std::vector<IWindowNoInteractionListenerSptr> noInteractionListeners;
3703     for (auto& listener : windowNoInteractionListeners_[GetPersistentId()]) {
3704         noInteractionListeners.push_back(listener);
3705     }
3706     return noInteractionListeners;
3707 }
3708 
NotifyDisplayIdChange(DisplayId displayId)3709 WSError WindowSessionImpl::NotifyDisplayIdChange(DisplayId displayId)
3710 {
3711     TLOGD(WmsLogTag::DEFAULT, "id=%{public}u, displayId=%{public}" PRIu64, GetPersistentId(), displayId);
3712     std::lock_guard<std::mutex> lock(displayIdChangeListenerMutex_);
3713     auto displayIdChangeListeners = GetListeners<IDisplayIdChangeListener>();
3714     for (auto& listener : displayIdChangeListeners) {
3715         if (listener != nullptr) {
3716             listener->OnDisplayIdChanged(displayId);
3717         }
3718     }
3719     return WSError::WS_OK;
3720 }
3721 
NotifySystemDensityChange(float density)3722 WSError WindowSessionImpl::NotifySystemDensityChange(float density)
3723 {
3724     std::lock_guard<std::mutex> lock(systemDensityChangeListenerMutex_);
3725     const auto& systemDensityChangeListeners = GetListeners<ISystemDensityChangeListener>();
3726     for (const auto& listener : systemDensityChangeListeners) {
3727         if (listener != nullptr) {
3728             listener->OnSystemDensityChanged(density);
3729         }
3730     }
3731     return WSError::WS_OK;
3732 }
3733 
NotifyWindowVisibility(bool isVisible)3734 WSError WindowSessionImpl::NotifyWindowVisibility(bool isVisible)
3735 {
3736     TLOGD(WmsLogTag::DEFAULT, "window: name=%{public}s, id=%{public}u, isVisible=%{public}d",
3737         GetWindowName().c_str(), GetPersistentId(), isVisible);
3738     std::lock_guard<std::recursive_mutex> lockListener(windowVisibilityChangeListenerMutex_);
3739     auto windowVisibilityListeners = GetListeners<IWindowVisibilityChangedListener>();
3740     for (auto& listener : windowVisibilityListeners) {
3741         if (listener != nullptr) {
3742             listener->OnWindowVisibilityChangedCallback(isVisible);
3743         }
3744     }
3745     return WSError::WS_OK;
3746 }
3747 
NotifyNoInteractionTimeout(const IWindowNoInteractionListenerSptr & listener)3748 WSError WindowSessionImpl::NotifyNoInteractionTimeout(const IWindowNoInteractionListenerSptr& listener)
3749 {
3750     if (listener == nullptr) {
3751         WLOGFE("invalid listener: nullptr");
3752         return WSError::WS_ERROR_NULLPTR;
3753     }
3754     WLOGFD("Notify window no interaction timeout, window: name=%{public}s, id=%{public}u, timeout=%{public}" PRId64,
3755         GetWindowName().c_str(), GetPersistentId(), listener->GetTimeout());
3756 
3757     listener->OnWindowNoInteractionCallback();
3758     return WSError::WS_OK;
3759 }
3760 
NotifyPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3761 void WindowSessionImpl::NotifyPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3762 {
3763     if (!pointerEvent) {
3764         TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "Pointer event is nullptr");
3765         return;
3766     }
3767 
3768     std::shared_ptr<IInputEventConsumer> inputEventConsumer;
3769     {
3770         std::lock_guard<std::recursive_mutex> lock(mutex_);
3771         inputEventConsumer = inputEventConsumer_;
3772     }
3773     if (inputEventConsumer != nullptr) {
3774         WLOGFD("Transfer pointer event to inputEventConsumer");
3775         if (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_MOVE) {
3776             TLOGI(WmsLogTag::WMS_INPUT_KEY_FLOW,
3777                 "Transfer pointer event to inputEventConsumer InputTracking id:%{public}d",
3778                 pointerEvent->GetId());
3779         }
3780         if (!(inputEventConsumer->OnInputEvent(pointerEvent))) {
3781             pointerEvent->MarkProcessed();
3782         }
3783         return;
3784     }
3785     if (FilterPointerEvent(pointerEvent)) {
3786         return;
3787     }
3788 
3789     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3790     if (uiContent != nullptr) {
3791         if (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_MOVE) {
3792             TLOGI(WmsLogTag::WMS_EVENT, "Input id:%{public}d",
3793                 pointerEvent->GetId());
3794         }
3795         TLOGI(WmsLogTag::WMS_EVENT, "Start to process pointerEvent, id: %{public}d", pointerEvent->GetId());
3796         if (!(uiContent->ProcessPointerEvent(pointerEvent))) {
3797             TLOGI(WmsLogTag::WMS_INPUT_KEY_FLOW, "UI content dose not consume this pointer event");
3798             pointerEvent->MarkProcessed();
3799         }
3800     } else {
3801         TLOGW(WmsLogTag::WMS_INPUT_KEY_FLOW, "pointerEvent is not consumed, windowId: %{public}u", GetWindowId());
3802         pointerEvent->MarkProcessed();
3803     }
3804 }
3805 
SetKeyEventFilter(KeyEventFilterFunc filter)3806 WMError WindowSessionImpl::SetKeyEventFilter(KeyEventFilterFunc filter)
3807 {
3808     std::unique_lock<std::mutex> lock(keyEventFilterMutex_);
3809     keyEventFilter_ = std::move(filter);
3810     return WMError::WM_OK;
3811 }
3812 
ClearKeyEventFilter()3813 WMError WindowSessionImpl::ClearKeyEventFilter()
3814 {
3815     std::unique_lock<std::mutex> lock(keyEventFilterMutex_);
3816     keyEventFilter_ = nullptr;
3817     return WMError::WM_OK;
3818 }
3819 
SetMouseEventFilter(MouseEventFilterFunc filter)3820 WMError WindowSessionImpl::SetMouseEventFilter(MouseEventFilterFunc filter)
3821 {
3822     std::unique_lock<std::mutex> lock(mouseEventFilterMutex_);
3823     mouseEventFilter_ = std::move(filter);
3824     return WMError::WM_OK;
3825 }
3826 
ClearMouseEventFilter()3827 WMError WindowSessionImpl::ClearMouseEventFilter()
3828 {
3829     std::unique_lock<std::mutex> lock(mouseEventFilterMutex_);
3830     mouseEventFilter_ = nullptr;
3831     return WMError::WM_OK;
3832 }
3833 
SetTouchEventFilter(TouchEventFilterFunc filter)3834 WMError WindowSessionImpl::SetTouchEventFilter(TouchEventFilterFunc filter)
3835 {
3836     std::unique_lock<std::mutex> lock(touchEventFilterMutex_);
3837     touchEventFilter_ = std::move(filter);
3838     return WMError::WM_OK;
3839 }
3840 
ClearTouchEventFilter()3841 WMError WindowSessionImpl::ClearTouchEventFilter()
3842 {
3843     std::unique_lock<std::mutex> lock(touchEventFilterMutex_);
3844     touchEventFilter_ = nullptr;
3845     return WMError::WM_OK;
3846 }
3847 
FilterKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)3848 bool WindowSessionImpl::FilterKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
3849 {
3850     std::lock_guard<std::mutex> lock(keyEventFilterMutex_);
3851     if (keyEventFilter_ != nullptr) {
3852         bool isFilter = keyEventFilter_(*keyEvent.get());
3853         TLOGE(WmsLogTag::WMS_SYSTEM, "keyCode:%{public}d isFilter:%{public}d",
3854             keyEvent->GetKeyCode(), isFilter);
3855         if (isFilter) {
3856             keyEvent->MarkProcessed();
3857             return true;
3858         }
3859     }
3860     return false;
3861 }
3862 
FilterPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3863 bool WindowSessionImpl::FilterPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3864 {
3865     bool isFiltered = false;
3866     auto sourceType = pointerEvent->GetSourceType();
3867     auto action = pointerEvent->GetPointerAction();
3868     if (sourceType == OHOS::MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
3869         std::lock_guard<std::mutex> lock(touchEventFilterMutex_);
3870         if (touchEventFilter_ == nullptr) {
3871             return false;
3872         }
3873         isFiltered = touchEventFilter_(*pointerEvent.get());
3874     } else if (sourceType == OHOS::MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
3875                (action != OHOS::MMI::PointerEvent::POINTER_ACTION_AXIS_BEGIN &&
3876                 action != OHOS::MMI::PointerEvent::POINTER_ACTION_AXIS_UPDATE &&
3877                 action != OHOS::MMI::PointerEvent::POINTER_ACTION_AXIS_END)) {
3878         std::lock_guard<std::mutex> lock(mouseEventFilterMutex_);
3879         if (mouseEventFilter_ == nullptr) {
3880             return false;
3881         }
3882         isFiltered = mouseEventFilter_(*pointerEvent.get());
3883     }
3884     if (isFiltered) {
3885         pointerEvent->MarkProcessed();
3886     }
3887     return isFiltered;
3888 }
3889 
DispatchKeyEventCallback(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed)3890 void WindowSessionImpl::DispatchKeyEventCallback(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed)
3891 {
3892     std::shared_ptr<IInputEventConsumer> inputEventConsumer;
3893     {
3894         std::lock_guard<std::recursive_mutex> lock(mutex_);
3895         inputEventConsumer = inputEventConsumer_;
3896     }
3897     int32_t keyCode = keyEvent->GetKeyCode();
3898     int32_t keyAction = keyEvent->GetKeyAction();
3899     if (keyCode == MMI::KeyEvent::KEYCODE_BACK && keyAction == MMI::KeyEvent::KEY_ACTION_UP) {
3900         WLOGFI("input event is consumed by back, return");
3901         if (inputEventConsumer != nullptr) {
3902             WLOGFD("Transfer key event to inputEventConsumer");
3903             if (inputEventConsumer->OnInputEvent(keyEvent)) {
3904                 return;
3905             }
3906             PerformBack();
3907             keyEvent->MarkProcessed();
3908             return;
3909         }
3910         HandleBackEvent();
3911         keyEvent->MarkProcessed();
3912         return;
3913     }
3914 
3915     if (inputEventConsumer != nullptr) {
3916         WLOGD("Transfer key event to inputEventConsumer");
3917         if (!(inputEventConsumer->OnInputEvent(keyEvent))) {
3918             keyEvent->MarkProcessed();
3919         }
3920         return;
3921     }
3922 
3923     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3924     if (uiContent) {
3925         if (FilterKeyEvent(keyEvent)) return;
3926         TLOGI(WmsLogTag::WMS_EVENT, "Start to process keyEvent, id: %{public}d", keyEvent->GetId());
3927         isConsumed = uiContent->ProcessKeyEvent(keyEvent);
3928         if (!isConsumed && keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_ESCAPE &&
3929             property_->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
3930             GetImmersiveModeEnabledState() &&
3931             keyAction == MMI::KeyEvent::KEY_ACTION_DOWN && !escKeyEventTriggered_) {
3932             WLOGI("recover from fullscreen cause KEYCODE_ESCAPE");
3933             Recover();
3934         }
3935         if (!isConsumed) {
3936             keyEvent->MarkProcessed();
3937         }
3938         if (keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_ESCAPE) {
3939             escKeyEventTriggered_ = (keyAction == MMI::KeyEvent::KEY_ACTION_UP) ? false : true;
3940         }
3941     }
3942 }
3943 
HandleBackEvent()3944 WSError WindowSessionImpl::HandleBackEvent()
3945 {
3946     TLOGI(WmsLogTag::WMS_EVENT, "called");
3947     bool isConsumed = false;
3948     std::shared_ptr<IInputEventConsumer> inputEventConsumer;
3949     {
3950         std::lock_guard<std::recursive_mutex> lock(mutex_);
3951         inputEventConsumer = inputEventConsumer_;
3952     }
3953     if (inputEventConsumer != nullptr) {
3954         WLOGFD("Transfer back event to inputEventConsumer");
3955         std::shared_ptr<MMI::KeyEvent> backKeyEvent = MMI::KeyEvent::Create();
3956         if (backKeyEvent == nullptr) {
3957             WLOGFE("backKeyEvent is null");
3958             return WSError::WS_ERROR_NULLPTR;
3959         }
3960         backKeyEvent->SetKeyCode(MMI::KeyEvent::KEYCODE_BACK);
3961         backKeyEvent->SetKeyAction(MMI::KeyEvent::KEY_ACTION_UP);
3962         isConsumed = inputEventConsumer->OnInputEvent(backKeyEvent);
3963     } else {
3964         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3965         if (uiContent != nullptr) {
3966             WLOGFD("Transfer back event to uiContent");
3967             isConsumed = uiContent->ProcessBackPressed();
3968         } else {
3969             WLOGFE("There is no back event consumer");
3970         }
3971     }
3972 
3973     if (isConsumed) {
3974         WLOGD("Back key event is consumed");
3975         return WSError::WS_OK;
3976     }
3977     WLOGFD("report Back");
3978     SingletonContainer::Get<WindowInfoReporter>().ReportBackButtonInfoImmediately();
3979     if (handler_ == nullptr) {
3980         WLOGFE("HandleBackEvent handler_ is nullptr!");
3981         return WSError::WS_ERROR_INVALID_PARAM;
3982     }
3983     // notify back event to host session
3984     wptr<WindowSessionImpl> weak = this;
3985     auto task = [weak]() {
3986         auto weakSession = weak.promote();
3987         if (weakSession == nullptr) {
3988             WLOGFE("HandleBackEvent session wptr is nullptr");
3989             return;
3990         }
3991         weakSession->PerformBack();
3992     };
3993     if (!handler_->PostTask(task, "wms:PerformBack")) {
3994         WLOGFE("Failed to post PerformBack");
3995         return WSError::WS_ERROR_INVALID_OPERATION;
3996     }
3997     return WSError::WS_OK;
3998 }
3999 
NotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed,bool notifyInputMethod)4000 void WindowSessionImpl::NotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed,
4001     bool notifyInputMethod)
4002 {
4003     if (keyEvent == nullptr) {
4004         WLOGFE("keyEvent is nullptr");
4005         return;
4006     }
4007 
4008 #ifdef IMF_ENABLE
4009     bool isKeyboardEvent = IsKeyboardEvent(keyEvent);
4010     if (isKeyboardEvent && notifyInputMethod) {
4011         WLOGD("Async dispatch keyEvent to input method");
4012         auto callback = [weakThis = wptr(this)] (std::shared_ptr<MMI::KeyEvent>& keyEvent, bool consumed) {
4013             if (keyEvent == nullptr) {
4014                 WLOGFW("keyEvent is null, consumed:%{public}" PRId32, consumed);
4015                 return;
4016             }
4017 
4018             if (consumed) {
4019                 WLOGD("Input method has processed key event, id:%{public}" PRId32, keyEvent->GetId());
4020                 return;
4021             }
4022 
4023             auto promoteThis = weakThis.promote();
4024             if (promoteThis == nullptr) {
4025                 WLOGFW("promoteThis is nullptr");
4026                 keyEvent->MarkProcessed();
4027                 return;
4028             }
4029             bool isConsumed = false;
4030             promoteThis->DispatchKeyEventCallback(keyEvent, isConsumed);
4031         };
4032         auto ret = MiscServices::InputMethodController::GetInstance()->DispatchKeyEvent(
4033             const_cast<std::shared_ptr<MMI::KeyEvent>&>(keyEvent), callback);
4034         if (ret != 0) {
4035             WLOGFE("DispatchKeyEvent failed, ret:%{public}" PRId32 ", id:%{public}" PRId32, ret, keyEvent->GetId());
4036             DispatchKeyEventCallback(keyEvent, isConsumed);
4037         }
4038         return;
4039     }
4040 #endif // IMF_ENABLE
4041     DispatchKeyEventCallback(keyEvent, isConsumed);
4042 }
4043 
IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent) const4044 bool WindowSessionImpl::IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent) const
4045 {
4046     int32_t keyCode = keyEvent->GetKeyCode();
4047     bool isKeyFN = (keyCode == MMI::KeyEvent::KEYCODE_FN);
4048     bool isKeyBack = (keyCode == MMI::KeyEvent::KEYCODE_BACK);
4049     bool isKeyboard = (keyCode >= MMI::KeyEvent::KEYCODE_0 && keyCode <= MMI::KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN);
4050     bool isKeySound = (keyCode == MMI::KeyEvent::KEYCODE_SOUND);
4051     WLOGD("isKeyFN: %{public}d, isKeyboard: %{public}d", isKeyFN, isKeyboard);
4052     return (isKeyFN || isKeyboard || isKeyBack || isKeySound);
4053 }
4054 
RequestVsync(const std::shared_ptr<VsyncCallback> & vsyncCallback)4055 void WindowSessionImpl::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
4056 {
4057     std::lock_guard<std::recursive_mutex> lock(mutex_);
4058     if (state_ == WindowState::STATE_DESTROYED) {
4059         WLOGFE("Receive vsync request failed, window is destroyed");
4060         return;
4061     }
4062 
4063     if (vsyncStation_ == nullptr) {
4064         TLOGE(WmsLogTag::WMS_MAIN, "Receive vsync request failed, vsyncStation is nullptr");
4065         return;
4066     }
4067     vsyncStation_->RequestVsync(vsyncCallback);
4068 }
4069 
GetVSyncPeriod()4070 int64_t WindowSessionImpl::GetVSyncPeriod()
4071 {
4072     std::lock_guard<std::recursive_mutex> lock(mutex_);
4073     if (vsyncStation_ == nullptr) {
4074         TLOGE(WmsLogTag::WMS_MAIN, "Get vsync period failed, vsyncStation is nullptr");
4075         return 0;
4076     }
4077     return vsyncStation_->GetVSyncPeriod();
4078 }
4079 
FlushFrameRate(uint32_t rate,int32_t animatorExpectedFrameRate,uint32_t rateType)4080 void WindowSessionImpl::FlushFrameRate(uint32_t rate, int32_t animatorExpectedFrameRate, uint32_t rateType)
4081 {
4082     std::lock_guard<std::recursive_mutex> lock(mutex_);
4083     if (vsyncStation_ == nullptr) {
4084         TLOGE(WmsLogTag::WMS_MAIN, "FlushFrameRate failed, vsyncStation is nullptr");
4085         return;
4086     }
4087     vsyncStation_->FlushFrameRate(rate, animatorExpectedFrameRate, rateType);
4088 }
4089 
UpdateProperty(WSPropertyChangeAction action)4090 WMError WindowSessionImpl::UpdateProperty(WSPropertyChangeAction action)
4091 {
4092     TLOGD(WmsLogTag::DEFAULT, "action:%{public}" PRIu64, action);
4093     if (IsWindowSessionInvalid()) {
4094         TLOGE(WmsLogTag::DEFAULT, "session is invalid");
4095         return WMError::WM_ERROR_INVALID_WINDOW;
4096     }
4097     auto hostSession = GetHostSession();
4098     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
4099     return hostSession->UpdateSessionPropertyByAction(property_, action);
4100 }
4101 
Find(const std::string & name)4102 sptr<Window> WindowSessionImpl::Find(const std::string& name)
4103 {
4104     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4105     TLOGI(WmsLogTag::DEFAULT, "Try to find window %{public}s", name.c_str());
4106     auto iter = windowSessionMap_.find(name);
4107     if (iter == windowSessionMap_.end()) {
4108         TLOGE(WmsLogTag::DEFAULT, "Can not find window %{public}s", name.c_str());
4109         return nullptr;
4110     }
4111     return iter->second.second;
4112 }
4113 
SetAceAbilityHandler(const sptr<IAceAbilityHandler> & handler)4114 void WindowSessionImpl::SetAceAbilityHandler(const sptr<IAceAbilityHandler>& handler)
4115 {
4116     if (handler == nullptr) {
4117         WLOGE("ace ability handler is nullptr");
4118     }
4119     std::lock_guard<std::recursive_mutex> lock(mutex_);
4120     aceAbilityHandler_ = handler;
4121 }
4122 
SetBackgroundColor(const std::string & color)4123 WMError WindowSessionImpl::SetBackgroundColor(const std::string& color)
4124 {
4125     if (IsWindowSessionInvalid()) {
4126         TLOGE(WmsLogTag::DEFAULT, "session is invalid");
4127         return WMError::WM_ERROR_INVALID_WINDOW;
4128     }
4129     uint32_t colorValue;
4130     if (ColorParser::Parse(color, colorValue)) {
4131         TLOGD(WmsLogTag::DEFAULT, "SetBackgroundColor: window: %{public}s, value: [%{public}s, %{public}u]",
4132             GetWindowName().c_str(), color.c_str(), colorValue);
4133         return SetBackgroundColor(colorValue);
4134     }
4135     TLOGE(WmsLogTag::DEFAULT, "invalid color string: %{public}s", color.c_str());
4136     return WMError::WM_ERROR_INVALID_PARAM;
4137 }
4138 
SetBackgroundColor(uint32_t color)4139 WMError WindowSessionImpl::SetBackgroundColor(uint32_t color)
4140 {
4141     TLOGI(WmsLogTag::DEFAULT, "window: %{public}s, value:%{public}u", GetWindowName().c_str(), color);
4142 
4143     // 0xff000000: ARGB style, means Opaque color.
4144     const bool isAlphaZero = !(color & 0xff000000);
4145     std::string bundleName;
4146     std::string abilityName;
4147     if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
4148         bundleName = context_->GetBundleName();
4149         abilityName = context_->GetApplicationInfo()->name;
4150     }
4151 
4152     if (isAlphaZero && WindowHelper::IsMainWindow(GetType())) {
4153         auto& reportInstance = SingletonContainer::Get<WindowInfoReporter>();
4154         reportInstance.ReportZeroOpacityInfoImmediately(bundleName, abilityName);
4155     }
4156     {
4157         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
4158         if (uiContent != nullptr) {
4159             uiContent->SetBackgroundColor(color);
4160             return WMError::WM_OK;
4161         }
4162     }
4163     if (aceAbilityHandler_ != nullptr) {
4164         aceAbilityHandler_->SetBackgroundColor(color);
4165         return WMError::WM_OK;
4166     }
4167     TLOGD(WmsLogTag::DEFAULT, "FA mode could not set bg color: %{public}u", GetWindowId());
4168     return WMError::WM_ERROR_INVALID_OPERATION;
4169 }
4170 
FindWindowById(uint32_t winId)4171 sptr<Window> WindowSessionImpl::FindWindowById(uint32_t winId)
4172 {
4173     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4174     if (windowSessionMap_.empty()) {
4175         WLOGFE("Please create mainWindow First!");
4176         return nullptr;
4177     }
4178     for (auto iter = windowSessionMap_.begin(); iter != windowSessionMap_.end(); iter++) {
4179         if (static_cast<int32_t>(winId) == iter->second.first) {
4180             WLOGD("FindWindow id: %{public}u", winId);
4181             return iter->second.second;
4182         }
4183     }
4184     WLOGFE("Cannot find Window, id: %{public}d", winId);
4185     return nullptr;
4186 }
4187 
GetSubWindow(int parentId)4188 std::vector<sptr<Window>> WindowSessionImpl::GetSubWindow(int parentId)
4189 {
4190     auto iter = subWindowSessionMap_.find(parentId);
4191     if (iter == subWindowSessionMap_.end()) {
4192         return std::vector<sptr<Window>>();
4193     }
4194     return std::vector<sptr<Window>>(subWindowSessionMap_[parentId].begin(), subWindowSessionMap_[parentId].end());
4195 }
4196 
GetBackgroundColor() const4197 uint32_t WindowSessionImpl::GetBackgroundColor() const
4198 {
4199     {
4200         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
4201         if (uiContent != nullptr) {
4202             return uiContent->GetBackgroundColor();
4203         }
4204     }
4205     WLOGD("uiContent is nullptr, windowId: %{public}u, use FA mode", GetWindowId());
4206     if (aceAbilityHandler_ != nullptr) {
4207         return aceAbilityHandler_->GetBackgroundColor();
4208     }
4209     WLOGFD("FA mode does not get bg color: %{public}u", GetWindowId());
4210     return 0xffffffff; // means no background color been set, default color is white
4211 }
4212 
SetLayoutFullScreenByApiVersion(bool status)4213 WMError WindowSessionImpl::SetLayoutFullScreenByApiVersion(bool status)
4214 {
4215     return WMError::WM_OK;
4216 }
4217 
SetSystemBarProperty(WindowType type,const SystemBarProperty & property)4218 WMError WindowSessionImpl::SetSystemBarProperty(WindowType type, const SystemBarProperty& property)
4219 {
4220     return WMError::WM_OK;
4221 }
4222 
SetSpecificBarProperty(WindowType type,const SystemBarProperty & property)4223 WMError WindowSessionImpl::SetSpecificBarProperty(WindowType type, const SystemBarProperty& property)
4224 {
4225     return WMError::WM_OK;
4226 }
4227 
NotifyOccupiedAreaChangeInfoInner(sptr<OccupiedAreaChangeInfo> info)4228 void WindowSessionImpl::NotifyOccupiedAreaChangeInfoInner(sptr<OccupiedAreaChangeInfo> info)
4229 {
4230     std::lock_guard<std::recursive_mutex> lockListener(occupiedAreaChangeListenerMutex_);
4231     auto occupiedAreaChangeListeners = GetListeners<IOccupiedAreaChangeListener>();
4232     for (auto& listener : occupiedAreaChangeListeners) {
4233         if (listener != nullptr) {
4234             listener->OnSizeChange(info);
4235         }
4236     }
4237 }
4238 
NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,const std::shared_ptr<RSTransaction> & rsTransaction)4239 void WindowSessionImpl::NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,
4240                                                      const std::shared_ptr<RSTransaction>& rsTransaction)
4241 {
4242     TLOGI(WmsLogTag::WMS_KEYBOARD, "hasRSTransaction: %{public}d, safeHeight: %{public}u"
4243         ", occupied rect: x %{public}u, y %{public}u, w %{public}u, h %{public}u", rsTransaction != nullptr,
4244         info->safeHeight_, info->rect_.posX_, info->rect_.posY_, info->rect_.width_, info->rect_.height_);
4245     if (handler_ == nullptr) {
4246         TLOGE(WmsLogTag::WMS_KEYBOARD, "handler_ is nullptr, notify occupied area change info failed");
4247         return;
4248     }
4249     auto task = [weak = wptr(this), info, rsTransaction]() {
4250         auto window = weak.promote();
4251         if (!window) {
4252             TLOGE(WmsLogTag::WMS_KEYBOARD, "window is nullptr, notify occupied area change info failed");
4253             return;
4254         }
4255         if (rsTransaction) {
4256             RSTransaction::FlushImplicitTransaction();
4257             rsTransaction->Begin();
4258         }
4259         window->NotifyOccupiedAreaChangeInfoInner(info);
4260         if (rsTransaction) {
4261             rsTransaction->Commit();
4262         }
4263     };
4264     handler_->PostTask(task, "WMS_WindowSessionImpl_NotifyOccupiedAreaChangeInfo");
4265 }
4266 
GetKeyboardAnimationConfig()4267 KeyboardAnimationConfig WindowSessionImpl::GetKeyboardAnimationConfig()
4268 {
4269     return { windowSystemConfig_.animationIn_, windowSystemConfig_.animationOut_ };
4270 }
4271 
DumpSessionElementInfo(const std::vector<std::string> & params)4272 void WindowSessionImpl::DumpSessionElementInfo(const std::vector<std::string>& params)
4273 {
4274     WLOGFD("DumpSessionElementInfo");
4275 }
4276 
UpdateMaximizeMode(MaximizeMode mode)4277 WSError WindowSessionImpl::UpdateMaximizeMode(MaximizeMode mode)
4278 {
4279     return WSError::WS_OK;
4280 }
4281 
TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionIdLevel)4282 WMError WindowSessionImpl::TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info,
4283     int64_t uiExtensionIdLevel)
4284 {
4285     return WMError::WM_OK;
4286 }
4287 
NotifySessionForeground(uint32_t reason,bool withAnimation)4288 void WindowSessionImpl::NotifySessionForeground(uint32_t reason, bool withAnimation)
4289 {
4290     WLOGFD("NotifySessionForeground");
4291 }
4292 
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)4293 void WindowSessionImpl::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
4294 {
4295     WLOGFD("NotifySessionBackground");
4296 }
4297 
UpdateTitleInTargetPos(bool isShow,int32_t height)4298 WSError WindowSessionImpl::UpdateTitleInTargetPos(bool isShow, int32_t height)
4299 {
4300     return WSError::WS_OK;
4301 }
4302 
SwitchFreeMultiWindow(bool enable)4303 WSError WindowSessionImpl::SwitchFreeMultiWindow(bool enable)
4304 {
4305     return WSError::WS_OK;
4306 }
4307 
NotifyDialogStateChange(bool isForeground)4308 WSError WindowSessionImpl::NotifyDialogStateChange(bool isForeground)
4309 {
4310     return WSError::WS_OK;
4311 }
4312 
UpdatePiPRect(const Rect & rect,WindowSizeChangeReason reason)4313 void WindowSessionImpl::UpdatePiPRect(const Rect& rect, WindowSizeChangeReason reason)
4314 {
4315     if (IsWindowSessionInvalid()) {
4316         TLOGE(WmsLogTag::WMS_PIP, "HostSession is invalid");
4317         return;
4318     }
4319     auto hostSession = GetHostSession();
4320     CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
4321     hostSession->UpdatePiPRect(rect, static_cast<SizeChangeReason>(reason));
4322 }
4323 
UpdatePiPControlStatus(PiPControlType controlType,PiPControlStatus status)4324 void WindowSessionImpl::UpdatePiPControlStatus(PiPControlType controlType, PiPControlStatus status)
4325 {
4326     TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, status:%{public}d", controlType, status);
4327     if (IsWindowSessionInvalid()) {
4328         TLOGE(WmsLogTag::WMS_PIP, "HostSession is invalid");
4329         return;
4330     }
4331     auto hostSession = GetHostSession();
4332     CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
4333     hostSession->UpdatePiPControlStatus(static_cast<WsPiPControlType>(controlType),
4334         static_cast<WsPiPControlStatus>(status));
4335 }
4336 
SetAutoStartPiP(bool isAutoStart,uint32_t priority)4337 void WindowSessionImpl::SetAutoStartPiP(bool isAutoStart, uint32_t priority)
4338 {
4339     if (IsWindowSessionInvalid()) {
4340         TLOGE(WmsLogTag::WMS_PIP, "session is invalid");
4341         return;
4342     }
4343     if (auto hostSession = GetHostSession()) {
4344         hostSession->SetAutoStartPiP(isAutoStart, priority);
4345     }
4346 }
4347 
GetWindowStatusInner(WindowMode mode)4348 WindowStatus WindowSessionImpl::GetWindowStatusInner(WindowMode mode)
4349 {
4350     auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
4351     if (mode == WindowMode::WINDOW_MODE_FLOATING) {
4352         windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
4353         if (property_->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
4354             windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
4355         }
4356     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
4357         windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
4358     }
4359     if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
4360         if (IsPcOrPadFreeMultiWindowMode() && GetTargetAPIVersion() >= 14) { // 14: isolated version
4361             windowStatus = GetImmersiveModeEnabledState() ? WindowStatus::WINDOW_STATUS_FULLSCREEN :
4362                 WindowStatus::WINDOW_STATUS_MAXIMIZE;
4363         } else {
4364             windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
4365         }
4366     }
4367     if (state_ == WindowState::STATE_HIDDEN) {
4368         windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
4369     }
4370     return windowStatus;
4371 }
4372 
NotifyWindowStatusChange(WindowMode mode)4373 void WindowSessionImpl::NotifyWindowStatusChange(WindowMode mode)
4374 {
4375     auto windowStatus = GetWindowStatusInner(mode);
4376     TLOGD(WmsLogTag::WMS_LAYOUT, "WindowMode: %{public}d, windowStatus: %{public}d", mode, windowStatus);
4377     std::lock_guard<std::recursive_mutex> lockListener(windowStatusChangeListenerMutex_);
4378     auto windowStatusChangeListeners = GetListeners<IWindowStatusChangeListener>();
4379     for (auto& listener : windowStatusChangeListeners) {
4380         if (listener != nullptr) {
4381             listener->OnWindowStatusChange(windowStatus);
4382         }
4383     }
4384 }
4385 
NotifyTransformChange(const Transform & transform)4386 void WindowSessionImpl::NotifyTransformChange(const Transform& transform)
4387 {
4388     WLOGFI("NotifyWindowStatusChange");
4389     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
4390     if (uiContent != nullptr) {
4391         uiContent->UpdateTransform(transform);
4392         SetLayoutTransform(transform);
4393     }
4394 }
4395 
NotifySingleHandTransformChange(const SingleHandTransform & singleHandTransform)4396 void WindowSessionImpl::NotifySingleHandTransformChange(const SingleHandTransform& singleHandTransform)
4397 {
4398     singleHandTransform_ = singleHandTransform;
4399     if (auto uiContent = GetUIContentSharedPtr()) {
4400         TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, posX:%{public}d, posY:%{public}d, "
4401               "scaleX:%{public}f, scaleY:%{public}f", GetPersistentId(),
4402               singleHandTransform.posX, singleHandTransform.posY,
4403               singleHandTransform.scaleX, singleHandTransform.scaleY);
4404         uiContent->UpdateSingleHandTransform(singleHandTransform);
4405     } else {
4406         TLOGW(WmsLogTag::WMS_LAYOUT, "id:%{public}d, uiContent is nullptr", GetPersistentId());
4407     }
4408 }
4409 
SubmitNoInteractionMonitorTask(int32_t eventId,const IWindowNoInteractionListenerSptr & listener)4410 void WindowSessionImpl::SubmitNoInteractionMonitorTask(int32_t eventId,
4411     const IWindowNoInteractionListenerSptr& listener)
4412 {
4413     auto task = [sessionWptr = wptr(this), eventId, listenerWptr = wptr(listener)]() {
4414         auto session = sessionWptr.promote();
4415         if (session == nullptr) {
4416             WLOGFE("windowInteractionMonitor task running failed, window session is null");
4417             return;
4418         }
4419         if (eventId != session->lastInteractionEventId_.load()) {
4420             WLOGFD("event id of windowInteractionMonitor has been changed, need not notify!");
4421             return;
4422         }
4423         if (session->state_ != WindowState::STATE_SHOWN) {
4424             WLOGFD("window state is not show, need not notify!");
4425             return;
4426         }
4427         session->NotifyNoInteractionTimeout(listenerWptr.promote());
4428     };
4429     handler_->PostTask(task, listener->GetTimeout());
4430 }
4431 
RefreshNoInteractionTimeoutMonitor()4432 void WindowSessionImpl::RefreshNoInteractionTimeoutMonitor()
4433 {
4434     std::lock_guard<std::recursive_mutex> lockListener(windowNoInteractionListenerMutex_);
4435     if (windowNoInteractionListeners_[GetPersistentId()].empty()) {
4436         return;
4437     }
4438     this->lastInteractionEventId_.fetch_add(1);
4439     int32_t eventId = lastInteractionEventId_.load();
4440     auto noInteractionListeners = GetListeners<IWindowNoInteractionListener>();
4441     for (const auto& listenerItem : noInteractionListeners) {
4442         SubmitNoInteractionMonitorTask(eventId, listenerItem);
4443     }
4444 }
4445 
IsUserOrientation(Orientation orientation) const4446 bool WindowSessionImpl::IsUserOrientation(Orientation orientation) const
4447 {
4448     if (orientation == Orientation::USER_ROTATION_PORTRAIT ||
4449         orientation == Orientation::USER_ROTATION_LANDSCAPE ||
4450         orientation == Orientation::USER_ROTATION_PORTRAIT_INVERTED ||
4451         orientation == Orientation::USER_ROTATION_LANDSCAPE_INVERTED) {
4452         return true;
4453     }
4454     return false;
4455 }
4456 
GetCallingWindowWindowStatus(WindowStatus & windowStatus) const4457 WMError WindowSessionImpl::GetCallingWindowWindowStatus(WindowStatus& windowStatus) const
4458 {
4459     TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d", GetPersistentId());
4460     if (IsWindowSessionInvalid()) {
4461         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is invalid");
4462         return WMError::WM_ERROR_INVALID_WINDOW;
4463     }
4464     return SingletonContainer::Get<WindowAdapter>().GetCallingWindowWindowStatus(GetPersistentId(), windowStatus);
4465 }
4466 
GetCallingWindowRect(Rect & rect) const4467 WMError WindowSessionImpl::GetCallingWindowRect(Rect& rect) const
4468 {
4469     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get CallingWindow Rect");
4470     if (IsWindowSessionInvalid()) {
4471         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is invalid");
4472         return WMError::WM_ERROR_INVALID_WINDOW;
4473     }
4474     return SingletonContainer::Get<WindowAdapter>().GetCallingWindowRect(GetPersistentId(), rect);
4475 }
4476 
SetUiDvsyncSwitch(bool dvsyncSwitch)4477 void WindowSessionImpl::SetUiDvsyncSwitch(bool dvsyncSwitch)
4478 {
4479     std::lock_guard<std::recursive_mutex> lock(mutex_);
4480     if (vsyncStation_ == nullptr) {
4481         TLOGE(WmsLogTag::WMS_MAIN, "vsyncStation is nullptr");
4482         return;
4483     }
4484     vsyncStation_->SetUiDvsyncSwitch(dvsyncSwitch);
4485 }
4486 
GetAppForceLandscapeConfig(AppForceLandscapeConfig & config)4487 WMError WindowSessionImpl::GetAppForceLandscapeConfig(AppForceLandscapeConfig& config)
4488 {
4489     if (IsWindowSessionInvalid()) {
4490         TLOGE(WmsLogTag::DEFAULT, "HostSession is invalid");
4491         return WMError::WM_ERROR_INVALID_WINDOW;
4492     }
4493     auto hostSession = GetHostSession();
4494     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
4495     return hostSession->GetAppForceLandscapeConfig(config);
4496 }
4497 
SetForceSplitEnable(bool isForceSplit,const std::string & homePage)4498 void WindowSessionImpl::SetForceSplitEnable(bool isForceSplit, const std::string& homePage)
4499 {
4500     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
4501     if (uiContent == nullptr) {
4502         TLOGE(WmsLogTag::DEFAULT, "uiContent is null!");
4503         return;
4504     }
4505     TLOGI(WmsLogTag::DEFAULT, "isForceSplit: %{public}u, homePage: %{public}s",
4506         isForceSplit, homePage.c_str());
4507     uiContent->SetForceSplitEnable(isForceSplit, homePage);
4508 }
4509 
SetFrameLayoutCallbackEnable(bool enable)4510 void WindowSessionImpl::SetFrameLayoutCallbackEnable(bool enable)
4511 {
4512     enableFrameLayoutFinishCb_ = enable;
4513 }
4514 
UpdateFrameLayoutCallbackIfNeeded(WindowSizeChangeReason wmReason)4515 void WindowSessionImpl::UpdateFrameLayoutCallbackIfNeeded(WindowSizeChangeReason wmReason)
4516 {
4517     bool isDragInPcmode = IsFreeMultiWindowMode() && (wmReason == WindowSizeChangeReason::DRAG_END);
4518     if (wmReason == WindowSizeChangeReason::FULL_TO_SPLIT || wmReason == WindowSizeChangeReason::SPLIT_TO_FULL ||
4519         wmReason == WindowSizeChangeReason::FULL_TO_FLOATING || wmReason == WindowSizeChangeReason::FLOATING_TO_FULL ||
4520         isDragInPcmode) {
4521         TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "enable framelayoutfinish callback reason:%{public}u", wmReason);
4522         SetFrameLayoutCallbackEnable(true);
4523     }
4524 }
4525 
SetContinueState(int32_t continueState)4526 WMError WindowSessionImpl::SetContinueState(int32_t continueState)
4527 {
4528     if (continueState > ContinueState::CONTINUESTATE_MAX || continueState < ContinueState::CONTINUESTATE_UNKNOWN) {
4529         TLOGE(WmsLogTag::WMS_MAIN, "continueState is invalid: %{public}d", continueState);
4530         return WMError::WM_ERROR_INVALID_PARAM;
4531     }
4532     property_->EditSessionInfo().continueState = static_cast<ContinueState>(continueState);
4533     return WMError::WM_OK;
4534 }
4535 
SetUIContentComplete()4536 void WindowSessionImpl::SetUIContentComplete()
4537 {
4538     bool setUIContentCompleted = false;
4539     if (setUIContentCompleted_.compare_exchange_strong(setUIContentCompleted, true)) {
4540         TLOGI(WmsLogTag::WMS_LIFE, "persistentId=%{public}d", GetPersistentId());
4541         handler_->RemoveTask(SET_UICONTENT_TIMEOUT_LISTENER_TASK_NAME + std::to_string(GetPersistentId()));
4542     } else {
4543         TLOGI(WmsLogTag::WMS_LIFE, "already SetUIContent, persistentId=%{public}d", GetPersistentId());
4544     }
4545 }
4546 
AddSetUIContentTimeoutCheck()4547 void WindowSessionImpl::AddSetUIContentTimeoutCheck()
4548 {
4549     const auto checkBeginTime =
4550         std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now())
4551             .time_since_epoch().count();
4552     auto task = [weakThis = wptr(this), checkBeginTime] {
4553         auto window = weakThis.promote();
4554         if (window == nullptr) {
4555             TLOGNI(WmsLogTag::WMS_LIFE, "window is nullptr");
4556             return;
4557         }
4558         if (window->setUIContentCompleted_.load()) {
4559             TLOGNI(WmsLogTag::WMS_LIFE, "already SetUIContent, persistentId=%{public}d", window->GetPersistentId());
4560             return;
4561         }
4562 
4563         const auto checkEndTime =
4564             std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now())
4565                 .time_since_epoch().count();
4566         if (checkEndTime - checkBeginTime > SET_UICONTENT_TIMEOUT_TIME_AFTER_FREEZE_MS) {
4567             TLOGNI(WmsLogTag::WMS_LIFE, "will start re-check after freeze, persistentId=%{public}d",
4568                 window->GetPersistentId());
4569             window->AddSetUIContentTimeoutCheck();
4570             return;
4571         }
4572 
4573         TLOGNI(WmsLogTag::WMS_LIFE, "SetUIContent timeout, persistentId=%{public}d", window->GetPersistentId());
4574         std::ostringstream oss;
4575         oss << "SetUIContent timeout uid: " << getuid();
4576         oss << ", windowName: " << window->GetWindowName();
4577         if (window->context_) {
4578             oss << ", bundleName: " << window->context_->GetBundleName();
4579             if (window->context_->GetApplicationInfo()) {
4580                 oss << ", abilityName: " << window->context_->GetApplicationInfo()->name;
4581             }
4582         }
4583         SingletonContainer::Get<WindowInfoReporter>().ReportWindowException(
4584             static_cast<int32_t>(WindowDFXHelperType::WINDOW_TRANSPARENT_CHECK), getpid(), oss.str());
4585 
4586         if (WindowHelper::IsUIExtensionWindow(window->GetType())) {
4587             window->NotifyExtensionTimeout(TimeoutErrorCode::SET_UICONTENT_TIMEOUT);
4588         }
4589     };
4590     handler_->PostTask(task, SET_UICONTENT_TIMEOUT_LISTENER_TASK_NAME + std::to_string(GetPersistentId()),
4591         SET_UICONTENT_TIMEOUT_TIME_MS, AppExecFwk::EventQueue::Priority::HIGH);
4592 }
4593 
NotifySetUIContentComplete()4594 void WindowSessionImpl::NotifySetUIContentComplete()
4595 {
4596     if (WindowHelper::IsSubWindow(GetType()) || WindowHelper::IsSystemWindow(GetType())) {
4597         // created by UIExtension
4598         auto extWindow = FindExtensionWindowWithContext();
4599         if (extWindow != nullptr) {
4600             extWindow->SetUIContentComplete();
4601         }
4602     }
4603     SetUIContentComplete();
4604 }
4605 
SetUIExtensionDestroyComplete()4606 void WindowSessionImpl::SetUIExtensionDestroyComplete()
4607 {
4608     bool setUIExtensionDestroyCompleted = false;
4609     if (setUIExtensionDestroyCompleted_.compare_exchange_strong(setUIExtensionDestroyCompleted, true)) {
4610         TLOGI(WmsLogTag::WMS_LIFE, "persistentId=%{public}d", GetPersistentId());
4611         handler_->RemoveTask(SET_UIEXTENSION_DESTROY_TIMEOUT_LISTENER_TASK_NAME + std::to_string(GetPersistentId()));
4612     } else {
4613         TLOGI(WmsLogTag::WMS_LIFE, "already, persistentId=%{public}d", GetPersistentId());
4614     }
4615 }
4616 
SetUIExtensionDestroyCompleteInSubWindow()4617 void WindowSessionImpl::SetUIExtensionDestroyCompleteInSubWindow()
4618 {
4619     if (WindowHelper::IsSubWindow(GetType()) || WindowHelper::IsSystemWindow(GetType())) {
4620         bool startUIExtensionDestroyTimer = true;
4621         auto extensionWindow = FindExtensionWindowWithContext();
4622         if (extensionWindow != nullptr && extensionWindow->startUIExtensionDestroyTimer_.compare_exchange_strong(
4623             startUIExtensionDestroyTimer, false)) {
4624             TLOGI(WmsLogTag::WMS_LIFE, "called");
4625             extensionWindow->SetUIExtensionDestroyComplete();
4626             extensionWindow->setUIExtensionDestroyCompleted_.store(false);
4627         }
4628     }
4629 }
4630 
AddSetUIExtensionDestroyTimeoutCheck()4631 void WindowSessionImpl::AddSetUIExtensionDestroyTimeoutCheck()
4632 {
4633     const char* const where = __func__;
4634     auto task = [weakThis = wptr(this), where] {
4635         auto window = weakThis.promote();
4636         if (window == nullptr) {
4637             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s: window is nullptr", where);
4638             return;
4639         }
4640         if (window->setUIExtensionDestroyCompleted_.load()) {
4641             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: already, persistentId=%{public}d", where,
4642                 window->GetPersistentId());
4643             return;
4644         }
4645 
4646         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: timeout, persistentId=%{public}d", where, window->GetPersistentId());
4647         std::ostringstream oss;
4648         oss << "SetUIExtDestroy timeout uid: " << getuid();
4649         oss << ", windowName: " << window->GetWindowName();
4650         if (window->context_) {
4651             oss << ", bundleName: " << window->context_->GetBundleName();
4652             if (window->context_->GetApplicationInfo()) {
4653                 oss << ", abilityName: " << window->context_->GetApplicationInfo()->name;
4654             }
4655         }
4656         SingletonContainer::Get<WindowInfoReporter>().ReportWindowException(
4657             static_cast<int32_t>(WindowDFXHelperType::WINDOW_TRANSPARENT_CHECK), getpid(), oss.str());
4658 
4659         if (WindowHelper::IsUIExtensionWindow(window->GetType())) {
4660             window->NotifyExtensionTimeout(TimeoutErrorCode::SET_UIEXTENSION_DESTROY_TIMEOUT);
4661         }
4662     };
4663     handler_->PostTask(task, SET_UIEXTENSION_DESTROY_TIMEOUT_LISTENER_TASK_NAME + std::to_string(GetPersistentId()),
4664         SET_UIEXTENSION_DESTROY_TIMEOUT_TIME_MS, AppExecFwk::EventQueue::Priority::HIGH);
4665     startUIExtensionDestroyTimer_.store(true);
4666 }
4667 
SetEnableDragBySystem(bool enableDrag)4668 WSError WindowSessionImpl::SetEnableDragBySystem(bool enableDrag)
4669 {
4670     TLOGI(WmsLogTag::WMS_LAYOUT, "enableDrag:%{publlic}d", enableDrag);
4671     property_->SetDragEnabled(enableDrag);
4672     return WSError::WS_OK;
4673 }
4674 
SetDragActivated(bool dragActivated)4675 WSError WindowSessionImpl::SetDragActivated(bool dragActivated)
4676 {
4677     dragActivated_ = dragActivated;
4678     return WSError::WS_OK;
4679 }
4680 
IsWindowDraggable()4681 bool WindowSessionImpl::IsWindowDraggable()
4682 {
4683     bool isDragEnabled = GetProperty()->GetDragEnabled();
4684     TLOGD(WmsLogTag::WMS_LAYOUT, "PersistentId: %{public}d, dragEnabled: %{public}d, dragActivate: %{public}d",
4685         GetPersistentId(), isDragEnabled, dragActivated_.load());
4686     return isDragEnabled && dragActivated_.load();
4687 }
4688 
SetTargetAPIVersion(uint32_t targetAPIVersion)4689 void WindowSessionImpl::SetTargetAPIVersion(uint32_t targetAPIVersion)
4690 {
4691     targetAPIVersion_ = targetAPIVersion;
4692 }
4693 
GetTargetAPIVersion() const4694 uint32_t WindowSessionImpl::GetTargetAPIVersion() const
4695 {
4696     return targetAPIVersion_;
4697 }
4698 
SetLayoutTransform(const Transform & transform)4699 void WindowSessionImpl::SetLayoutTransform(const Transform& transform)
4700 {
4701     std::lock_guard<std::recursive_mutex> lock(transformMutex_);
4702     layoutTransform_ = transform;
4703 }
4704 
GetLayoutTransform() const4705 Transform WindowSessionImpl::GetLayoutTransform() const
4706 {
4707     std::lock_guard<std::recursive_mutex> lock(transformMutex_);
4708     return layoutTransform_;
4709 }
4710 } // namespace Rosen
4711 } // namespace OHOS
4712