• 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_scene_session_impl.h"
17 
18 #include <chrono>
19 #include <limits>
20 #include <ability_manager_client.h>
21 #include <parameters.h>
22 #include <sstream>
23 #include <string>
24 #include <transaction/rs_transaction.h>
25 #include <hitrace_meter.h>
26 #include <hisysevent.h>
27 
28 #include <application_context.h>
29 #include "color_parser.h"
30 #include "common/include/fold_screen_state_internel.h"
31 #include "common/include/fold_screen_common.h"
32 #include "configuration.h"
33 #include "display_manager.h"
34 #include "display_manager_adapter.h"
35 #include "dm_common.h"
36 #include "extension/extension_business_info.h"
37 #include "fold_screen_controller/super_fold_state_manager.h"
38 #include "input_transfer_station.h"
39 #include "perform_reporter.h"
40 #include "rs_adapter.h"
41 #include "session_helper.h"
42 #include "session_permission.h"
43 #include "session/container/include/window_event_channel.h"
44 #include "session_manager/include/session_manager.h"
45 #include "singleton_container.h"
46 #include "sys_cap_util.h"
47 #include "window_adapter.h"
48 #include "window_helper.h"
49 #include "window_inspector.h"
50 #include "window_manager_hilog.h"
51 #include "window_prepare_terminate.h"
52 #include "wm_common.h"
53 #include "wm_common_inner.h"
54 #include "wm_math.h"
55 #include "session_manager_agent_controller.h"
56 #include <transaction/rs_interfaces.h>
57 #include "surface_capture_future.h"
58 #include "pattern_detach_callback.h"
59 #include "picture_in_picture_manager.h"
60 #include "window_session_impl.h"
61 #include "sys_cap_util.h"
62 
63 namespace OHOS {
64 namespace Rosen {
65 union WSColorParam {
66 #if defined(BIG_ENDIANNESS) && BIG_ENDIANNESS
67     struct {
68         uint8_t alpha;
69         uint8_t red;
70         uint8_t green;
71         uint8_t blue;
72     } argb;
73 #else
74     struct {
75         uint8_t blue;
76         uint8_t green;
77         uint8_t red;
78         uint8_t alpha;
79     } argb;
80 #endif
81     uint32_t value;
82 };
83 
84 #define CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession)                         \
85     do {                                                                       \
86         if ((hostSession) == nullptr) {                                        \
87             TLOGE(WmsLogTag::DEFAULT, "hostSession is null");                  \
88             return;                                                            \
89         }                                                                      \
90     } while (false)
91 
92 #define CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, ret)              \
93     do {                                                                       \
94         if ((hostSession) == nullptr) {                                        \
95             TLOGE(WmsLogTag::DEFAULT, "hostSession is null");                  \
96             return ret;                                                        \
97         }                                                                      \
98     } while (false)
99 
100 namespace {
101 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowSceneSessionImpl"};
102 constexpr int32_t WINDOW_DETACH_TIMEOUT = 300;
103 constexpr int32_t WINDOW_LAYOUT_TIMEOUT = 30;
104 constexpr int32_t WINDOW_PAGE_ROTATION_TIMEOUT = 2000;
105 const std::string PARAM_DUMP_HELP = "-h";
106 constexpr float MIN_GRAY_SCALE = 0.0f;
107 constexpr float MAX_GRAY_SCALE = 1.0f;
108 constexpr int32_t DISPLAY_ID_C = 999;
109 constexpr int32_t MAX_POINTERS = 16;
110 constexpr int32_t TOUCH_SLOP_RATIO = 25;
111 const std::string BACK_WINDOW_EVENT = "scb_back_window_event";
112 const std::string COMPATIBLE_MAX_WINDOW_EVENT = "win_compatible_max_event";
113 const std::string COMPATIBLE_RECOVER_WINDOW_EVENT = "win_compatible_recover_event";
114 const std::unordered_set<WindowType> INVALID_SYSTEM_WINDOW_TYPE = {
115     WindowType::WINDOW_TYPE_NEGATIVE_SCREEN,
116     WindowType::WINDOW_TYPE_THEME_EDITOR,
117     WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR,
118     WindowType::WINDOW_TYPE_SCENE_BOARD,
119     WindowType::WINDOW_TYPE_KEYBOARD_PANEL,
120     WindowType::WINDOW_TYPE_APP_LAUNCHING,
121     WindowType::WINDOW_TYPE_INCOMING_CALL,
122     WindowType::WINDOW_TYPE_BOOT_ANIMATION,
123     WindowType::WINDOW_TYPE_FREEZE_DISPLAY,
124     WindowType::WINDOW_TYPE_PLACEHOLDER
125 };
126 const std::unordered_set<WindowType> INVALID_SCB_WINDOW_TYPE = {
127     WindowType::WINDOW_TYPE_WALLPAPER,
128     WindowType::WINDOW_TYPE_DESKTOP,
129     WindowType::WINDOW_TYPE_DOCK_SLICE,
130     WindowType::WINDOW_TYPE_STATUS_BAR,
131     WindowType::WINDOW_TYPE_KEYGUARD,
132     WindowType::WINDOW_TYPE_NAVIGATION_BAR,
133     WindowType::WINDOW_TYPE_LAUNCHER_RECENT,
134     WindowType::WINDOW_TYPE_LAUNCHER_DOCK
135 };
136 constexpr uint32_t MAX_SUB_WINDOW_LEVEL = 10;
137 constexpr float INVALID_DEFAULT_DENSITY = 1.0f;
138 constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_WIDTH = 40;
139 constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_HEIGHT = 40;
140 constexpr int32_t API_VERSION_18 = 18;
141 constexpr uint32_t SNAPSHOT_TIMEOUT = 2000; // MS
142 constexpr uint32_t REASON_MAXIMIZE_MODE_CHANGE = 1;
143 }
144 std::mutex WindowSceneSessionImpl::keyboardPanelInfoChangeListenerMutex_;
145 using WindowSessionImplMap = std::map<std::string, std::pair<int32_t, sptr<WindowSessionImpl>>>;
146 std::mutex WindowSceneSessionImpl::windowAttachStateChangeListenerMutex_;
147 
WindowSceneSessionImpl(const sptr<WindowOption> & option)148 WindowSceneSessionImpl::WindowSceneSessionImpl(const sptr<WindowOption>& option) : WindowSessionImpl(option)
149 {
150     WLOGFI("[WMSCom] Constructor %{public}s", GetWindowName().c_str());
151 }
152 
~WindowSceneSessionImpl()153 WindowSceneSessionImpl::~WindowSceneSessionImpl()
154 {
155     WLOGFI("[WMSCom] Destructor %{public}d, %{public}s", GetPersistentId(), GetWindowName().c_str());
156 }
157 
IsValidSystemWindowType(const WindowType & type)158 bool WindowSceneSessionImpl::IsValidSystemWindowType(const WindowType& type)
159 {
160     if (INVALID_SYSTEM_WINDOW_TYPE.find(type) != INVALID_SYSTEM_WINDOW_TYPE.end()) {
161         TLOGI(WmsLogTag::WMS_SYSTEM, "Invalid type: %{public}u", type);
162         return false;
163     }
164     TLOGI(WmsLogTag::WMS_SYSTEM, "Valid type: %{public}u", type);
165     return true;
166 }
167 
FindParentSessionByParentId(uint32_t parentId)168 sptr<WindowSessionImpl> WindowSceneSessionImpl::FindParentSessionByParentId(uint32_t parentId)
169 {
170     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
171     for (const auto& [_, pair] : windowSessionMap_) {
172         auto& window = pair.second;
173         if (window && window->GetWindowId() == parentId) {
174             if (WindowHelper::IsMainWindow(window->GetType()) || WindowHelper::IsSystemWindow(window->GetType())) {
175                 TLOGD(WmsLogTag::WMS_SUB, "Find parent window [%{public}s, %{public}u, %{public}d]",
176                     window->GetProperty()->GetWindowName().c_str(), parentId,
177                     window->GetProperty()->GetPersistentId());
178                 return window;
179             } else if (WindowHelper::IsSubWindow(window->GetType()) &&
180                        (IsSessionMainWindow(window->GetParentId()) ||
181                         window->GetProperty()->GetIsUIExtFirstSubWindow() ||
182                         window->GetProperty()->GetSubWindowLevel() < MAX_SUB_WINDOW_LEVEL)) {
183                 // subwindow's grandparent is mainwindow or subwindow's parent is an extension subwindow
184                 TLOGD(WmsLogTag::WMS_SUB, "Find parent window [%{public}s, %{public}u, %{public}d]",
185                     window->GetProperty()->GetWindowName().c_str(), parentId,
186                     window->GetProperty()->GetPersistentId());
187                 return window;
188             }
189         }
190     }
191     TLOGD(WmsLogTag::WMS_SUB, "Can not find parent window, id: %{public}d", parentId);
192     return nullptr;
193 }
194 
FindParentMainSession(uint32_t parentId,const SessionMap & sessionMap)195 sptr<WindowSessionImpl> WindowSceneSessionImpl::FindParentMainSession(uint32_t parentId, const SessionMap& sessionMap)
196 {
197     if (parentId == INVALID_SESSION_ID) {
198         TLOGW(WmsLogTag::WMS_SUB, "invalid parent id");
199         return nullptr;
200     }
201     for (const auto& [_, pair] : sessionMap) {
202         auto& window = pair.second;
203         if (window && window->GetWindowId() == parentId) {
204             if (WindowHelper::IsMainWindow(window->GetType()) ||
205                 (WindowHelper::IsSystemWindow(window->GetType()) && window->GetParentId() == INVALID_SESSION_ID)) {
206                 TLOGD(WmsLogTag::WMS_SUB, "find main session, id:%{public}u", window->GetWindowId());
207                 return window;
208             }
209             return FindParentMainSession(window->GetParentId(), sessionMap);
210         }
211     }
212     TLOGW(WmsLogTag::WMS_SUB, "don't find main session, parentId:%{public}u", parentId);
213     return nullptr;
214 }
215 
IsSessionMainWindow(uint32_t parentId)216 bool WindowSceneSessionImpl::IsSessionMainWindow(uint32_t parentId)
217 {
218     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
219     for (const auto& [_, pair] : windowSessionMap_) {
220         auto& window = pair.second;
221         if (window && window->GetWindowId() == parentId && WindowHelper::IsMainWindow(window->GetType())) {
222             return true;
223         }
224     }
225     return false;
226 }
227 
AddSubWindowMapForExtensionWindow()228 void WindowSceneSessionImpl::AddSubWindowMapForExtensionWindow()
229 {
230     // update subWindowSessionMap_
231     auto extensionWindow = FindExtensionWindowWithContext();
232     if (extensionWindow != nullptr) {
233         auto parentWindowId = extensionWindow->GetPersistentId();
234         std::lock_guard<std::recursive_mutex> lock(subWindowSessionMutex_);
235         subWindowSessionMap_[parentWindowId].push_back(this);
236     } else {
237         TLOGE(WmsLogTag::WMS_SUB, "name: %{public}s not found parent extension window",
238             property_->GetWindowName().c_str());
239     }
240 }
241 
GetParentSessionAndVerify(bool isToast,sptr<WindowSessionImpl> & parentSession)242 WMError WindowSceneSessionImpl::GetParentSessionAndVerify(bool isToast, sptr<WindowSessionImpl>& parentSession)
243 {
244     if (isToast) {
245         std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
246         parentSession = FindParentMainSession(property_->GetParentId(), windowSessionMap_);
247     } else {
248         parentSession = FindParentSessionByParentId(property_->GetParentId());
249     }
250     if (parentSession == nullptr) {
251         TLOGE(WmsLogTag::WMS_LIFE, "parent of sub window is nullptr, name: %{public}s, type: %{public}d",
252             property_->GetWindowName().c_str(), GetType());
253         return WMError::WM_ERROR_NULLPTR;
254     }
255     return WindowSceneSessionImpl::VerifySubWindowLevel(false, parentSession);
256 }
257 
VerifySubWindowLevel(bool isToast,const sptr<WindowSessionImpl> & parentSession)258 WMError WindowSceneSessionImpl::VerifySubWindowLevel(bool isToast, const sptr<WindowSessionImpl>& parentSession)
259 {
260     if (parentSession == nullptr) {
261         TLOGE(WmsLogTag::WMS_SUB, "parent of sub window is nullptr");
262         return WMError::WM_ERROR_NULLPTR;
263     }
264     if (!isToast && !parentSession->GetIsUIExtFirstSubWindow() &&
265         parentSession->GetProperty()->GetSubWindowLevel() >= 1 &&
266         !parentSession->IsPcOrFreeMultiWindowCapabilityEnabled()) {
267         TLOGE(WmsLogTag::WMS_SUB, "device not support");
268         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
269     }
270     return WMError::WM_OK;
271 }
272 
AdjustPropertySessionInfo(const std::shared_ptr<AbilityRuntime::Context> & context,SessionInfo & info)273 static void AdjustPropertySessionInfo(const std::shared_ptr<AbilityRuntime::Context>& context, SessionInfo& info)
274 {
275     if (!context) {
276         TLOGE(WmsLogTag::WMS_LIFE, "context is null");
277         return;
278     }
279     info.moduleName_ = context->GetHapModuleInfo() ? context->GetHapModuleInfo()->moduleName : "";
280     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
281     if (abilityContext && abilityContext->GetAbilityInfo()) {
282         info.abilityName_ = abilityContext->GetAbilityInfo()->name;
283         info.bundleName_ = abilityContext->GetAbilityInfo()->bundleName;
284     } else {
285         info.bundleName_ = context->GetBundleName();
286     }
287 }
288 
CreateAndConnectSpecificSession()289 WMError WindowSceneSessionImpl::CreateAndConnectSpecificSession()
290 {
291     sptr<ISessionStage> iSessionStage(this);
292     sptr<IWindowEventChannel> eventChannel = sptr<WindowEventChannel>::MakeSptr(iSessionStage);
293     auto persistentId = INVALID_SESSION_ID;
294     sptr<Rosen::ISession> session;
295     auto context = GetContext();
296     sptr<IRemoteObject> token = context ? context->GetToken() : nullptr;
297     if (token) {
298         property_->SetTokenState(true);
299     }
300     AdjustPropertySessionInfo(context, property_->EditSessionInfo());
301 
302     const WindowType type = GetType();
303     bool hasToastFlag = property_->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST);
304     if (WindowHelper::IsSubWindow(type) && (property_->GetIsUIExtFirstSubWindow() ||
305                                             (property_->GetIsUIExtAnySubWindow() && hasToastFlag))) {
306         property_->SetParentPersistentId(property_->GetParentId());
307         SetDefaultDisplayIdIfNeed();
308         property_->SetIsUIExtensionAbilityProcess(isUIExtensionAbilityProcess_);
309         // create sub session by parent session
310         SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
311             surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
312         if (!hasToastFlag) {
313             AddSubWindowMapForExtensionWindow();
314         }
315     } else if (WindowHelper::IsSubWindow(type)) {
316         sptr<WindowSessionImpl> parentSession = nullptr;
317         auto ret = WindowSceneSessionImpl::VerifySubWindowLevel(hasToastFlag, parentSession);
318         if (ret != WMError::WM_OK) {
319             return ret;
320         }
321         property_->SetDisplayId(parentSession->GetDisplayId());
322         // set parent persistentId
323         auto parentWindowId = parentSession->GetPersistentId();
324         property_->SetParentPersistentId(parentWindowId);
325         property_->SetIsPcAppInPad(parentSession->GetProperty()->GetIsPcAppInPad());
326         property_->SetPcAppInpadCompatibleMode(parentSession->GetProperty()->GetPcAppInpadCompatibleMode());
327         // creat sub session by parent session
328         SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
329             surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
330         {
331             std::lock_guard<std::recursive_mutex> lock(subWindowSessionMutex_);
332             // update subWindowSessionMap_
333             subWindowSessionMap_[parentWindowId].push_back(this);
334         }
335         SetTargetAPIVersion(parentSession->GetTargetAPIVersion());
336     } else { // system window
337         WMError createSystemWindowRet = CreateSystemWindow(type);
338         if (createSystemWindowRet != WMError::WM_OK) {
339             return createSystemWindowRet;
340         }
341         auto parentSession = FindParentSessionByParentId(property_->GetParentPersistentId());
342         if (parentSession != nullptr) {
343             property_->SetIsPcAppInPad(parentSession->GetProperty()->GetIsPcAppInPad());
344         }
345         PreProcessCreate();
346         SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
347             surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
348     }
349     property_->SetPersistentId(persistentId);
350     if (session == nullptr) {
351         TLOGI(WmsLogTag::WMS_LIFE, "create specific failed, session is nullptr, name: %{public}s",
352             property_->GetWindowName().c_str());
353         return WMError::WM_ERROR_NULLPTR;
354     }
355     {
356         std::lock_guard<std::mutex> lock(hostSessionMutex_);
357         hostSession_ = session;
358     }
359     TLOGI(WmsLogTag::WMS_LIFE, "name:%{public}s,id:%{public}d,parentId:%{public}d,type:%{public}u,"
360         "touchable:%{public}d,displayId:%{public}" PRIu64, property_->GetWindowName().c_str(),
361         property_->GetPersistentId(), property_->GetParentPersistentId(), GetType(),
362         property_->GetTouchable(), property_->GetDisplayId());
363     return WMError::WM_OK;
364 }
365 
CreateSystemWindow(WindowType type)366 WMError WindowSceneSessionImpl::CreateSystemWindow(WindowType type)
367 {
368     if (WindowHelper::IsAppFloatingWindow(type) || WindowHelper::IsPipWindow(type) ||
369         type == WindowType::WINDOW_TYPE_TOAST || WindowHelper::IsFbWindow(type)) {
370         property_->SetParentPersistentId(GetFloatingWindowParentId());
371         TLOGI(WmsLogTag::WMS_SYSTEM, "parentId: %{public}d, type: %{public}d",
372             property_->GetParentPersistentId(), type);
373         auto mainWindow = FindMainWindowWithContext();
374         property_->SetFloatingWindowAppType(mainWindow != nullptr ? true : false);
375         if (mainWindow != nullptr) {
376             if (property_->GetDisplayId() == DISPLAY_ID_INVALID) {
377                 property_->SetDisplayId(mainWindow->GetDisplayId());
378             }
379         }
380     } else if (type == WindowType::WINDOW_TYPE_DIALOG) {
381         if (auto mainWindow = FindMainWindowWithContext()) {
382             property_->SetParentPersistentId(mainWindow->GetPersistentId());
383             property_->SetDisplayId(mainWindow->GetDisplayId());
384             TLOGI(WmsLogTag::WMS_DIALOG, "The parentId: %{public}d", mainWindow->GetPersistentId());
385         }
386     } else if (WindowHelper::IsSystemSubWindow(type)) {
387         auto parentSession = FindParentSessionByParentId(property_->GetParentId());
388         if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
389             TLOGE(WmsLogTag::WMS_LIFE, "parent of system sub window, name: %{public}s, type: %{public}d",
390                 property_->GetWindowName().c_str(), type);
391             return WMError::WM_ERROR_NULLPTR;
392         }
393         if (WindowHelper::IsSystemSubWindow(parentSession->GetType())) {
394             TLOGE(WmsLogTag::WMS_LIFE, "parent is system sub window, name: %{public}s, type: %{public}d",
395                 property_->GetWindowName().c_str(), type);
396             return WMError::WM_ERROR_INVALID_TYPE;
397         }
398         // set parent persistentId
399         property_->SetParentPersistentId(parentSession->GetPersistentId());
400         property_->SetDisplayId(parentSession->GetDisplayId());
401     }
402     return WMError::WM_OK;
403 }
404 
RecoverAndConnectSpecificSession()405 WMError WindowSceneSessionImpl::RecoverAndConnectSpecificSession()
406 {
407     TLOGI(WmsLogTag::WMS_RECOVER, "windowName=%{public}s, windowMode=%{public}u, windowType=%{public}u, "
408         "persistentId=%{public}d, windowState=%{public}d, requestWindowState=%{public}d, parentId=%{public}d",
409         GetWindowName().c_str(), property_->GetWindowMode(), property_->GetWindowType(), GetPersistentId(), state_,
410         requestState_, property_->GetParentId());
411 
412     const WindowType type = GetType();
413     if (WindowHelper::IsSubWindow(type) && !property_->GetIsUIExtFirstSubWindow()) { // sub window
414         TLOGD(WmsLogTag::WMS_RECOVER, "SubWindow");
415         auto parentSession = FindParentSessionByParentId(property_->GetParentId());
416         if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
417             TLOGE(WmsLogTag::WMS_RECOVER, "parentSession is null");
418             return WMError::WM_ERROR_NULLPTR;
419         }
420     }
421     if (WindowHelper::IsPipWindow(type)) {
422         TLOGI(WmsLogTag::WMS_RECOVER, "pipWindow");
423         PictureInPictureManager::DoClose(true, true);
424         return WMError::WM_OK;
425     }
426     windowRecoverStateChangeFunc_(true, WindowRecoverState::WINDOW_START_RECONNECT);
427     sptr<ISessionStage> iSessionStage(this);
428     sptr<IWindowEventChannel> eventChannel = sptr<WindowEventChannel>::MakeSptr(iSessionStage);
429     sptr<Rosen::ISession> session = nullptr;
430     auto context = GetContext();
431     sptr<IRemoteObject> token = context ? context->GetToken() : nullptr;
432     windowRecoverStateChangeFunc_(true, WindowRecoverState::WINDOW_DOING_RECONNECT);
433     SingletonContainer::Get<WindowAdapter>().RecoverAndConnectSpecificSession(
434         iSessionStage, eventChannel, surfaceNode_, property_, session, token);
435 
436     if (session == nullptr) {
437         TLOGE(WmsLogTag::WMS_RECOVER, "Recover failed, session is nullptr");
438         windowRecoverStateChangeFunc_(true, WindowRecoverState::WINDOW_NOT_RECONNECT);
439         return WMError::WM_ERROR_NULLPTR;
440     }
441     {
442         std::lock_guard<std::mutex> lock(hostSessionMutex_);
443         hostSession_ = session;
444     }
445     windowRecoverStateChangeFunc_(true, WindowRecoverState::WINDOW_FINISH_RECONNECT);
446     TLOGI(WmsLogTag::WMS_RECOVER,
447         "over, windowName=%{public}s, persistentId=%{public}d",
448         GetWindowName().c_str(), GetPersistentId());
449     return WMError::WM_OK;
450 }
451 
RecoverAndReconnectSceneSession()452 WMError WindowSceneSessionImpl::RecoverAndReconnectSceneSession()
453 {
454     TLOGI(WmsLogTag::WMS_RECOVER, "windowName=%{public}s, windowMode=%{public}u, windowType=%{public}u, "
455         "persistentId=%{public}d, windowState=%{public}d, requestWindowState=%{public}d", GetWindowName().c_str(),
456         property_->GetWindowMode(), property_->GetWindowType(), GetPersistentId(), state_, requestState_);
457 
458     if (isFocused_) {
459         UpdateFocus(false);
460     }
461     auto context = GetContext();
462     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
463     if (context && context->GetHapModuleInfo() && abilityContext && abilityContext->GetAbilityInfo()) {
464         if (!abilityContext->IsHook() || (abilityContext->IsHook() && abilityContext->GetHookOff())) {
465             property_->EditSessionInfo().abilityName_ = abilityContext->GetAbilityInfo()->name;
466             property_->EditSessionInfo().moduleName_ = context->GetHapModuleInfo()->moduleName;
467         }
468     } else {
469         TLOGE(WmsLogTag::WMS_RECOVER, "context or abilityContext is null, recovered session failed");
470         return WMError::WM_ERROR_NULLPTR;
471     }
472     auto& info = property_->EditSessionInfo();
473     if (auto want = abilityContext->GetWant()) {
474         info.want = want;
475     } else {
476         TLOGE(WmsLogTag::WMS_RECOVER, "want is nullptr!");
477     }
478     windowRecoverStateChangeFunc_(false, WindowRecoverState::WINDOW_START_RECONNECT);
479     sptr<ISessionStage> iSessionStage(this);
480     sptr<IWindowEventChannel> iWindowEventChannel = sptr<WindowEventChannel>::MakeSptr(iSessionStage);
481     sptr<IRemoteObject> token = context ? context->GetToken() : nullptr;
482     sptr<Rosen::ISession> session = nullptr;
483     windowRecoverStateChangeFunc_(false, WindowRecoverState::WINDOW_DOING_RECONNECT);
484     auto ret = SingletonContainer::Get<WindowAdapter>().RecoverAndReconnectSceneSession(
485         iSessionStage, iWindowEventChannel, surfaceNode_, session, property_, token);
486     if (session == nullptr) {
487         TLOGE(WmsLogTag::WMS_RECOVER, "session is null, recovered session failed");
488         windowRecoverStateChangeFunc_(false, WindowRecoverState::WINDOW_NOT_RECONNECT);
489         return WMError::WM_ERROR_NULLPTR;
490     }
491     {
492         std::lock_guard<std::mutex> lock(hostSessionMutex_);
493         hostSession_ = session;
494     }
495     windowRecoverStateChangeFunc_(false, WindowRecoverState::WINDOW_FINISH_RECONNECT);
496     TLOGI(WmsLogTag::WMS_RECOVER, "Successful, persistentId=%{public}d", GetPersistentId());
497     return static_cast<WMError>(ret);
498 }
499 
TransferLifeCycleEventToString(LifeCycleEvent type) const500 std::string WindowSceneSessionImpl::TransferLifeCycleEventToString(LifeCycleEvent type) const
501 {
502     std::string event;
503     switch (type) {
504         case LifeCycleEvent::CREATE_EVENT:
505             event = "CREATE";
506             break;
507         case LifeCycleEvent::SHOW_EVENT:
508             event = "SHOW";
509             break;
510         case LifeCycleEvent::HIDE_EVENT:
511             event = "HIDE";
512             break;
513         case LifeCycleEvent::DESTROY_EVENT:
514             event = "DESTROY";
515             break;
516         default:
517             event = "UNDEFINE";
518             break;
519     }
520     return event;
521 }
522 
RecordLifeCycleExceptionEvent(LifeCycleEvent event,WMError errCode) const523 void WindowSceneSessionImpl::RecordLifeCycleExceptionEvent(LifeCycleEvent event, WMError errCode) const
524 {
525     if (!(errCode > WMError::WM_ERROR_NEED_REPORT_BASE && errCode < WMError::WM_ERROR_PIP_REPEAT_OPERATION)) {
526         return;
527     }
528     std::ostringstream oss;
529     oss << "life cycle is abnormal: " << "window_name: " << GetWindowName().c_str()
530         << ", id:" << GetWindowId() << ", event: " << TransferLifeCycleEventToString(event)
531         << ", errCode: " << static_cast<int32_t>(errCode) << ";";
532     std::string info = oss.str();
533     TLOGI(WmsLogTag::WMS_LIFE, "window life cycle exception: %{public}s", info.c_str());
534     int32_t ret = HiSysEventWrite(
535         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
536         "WINDOW_LIFE_CYCLE_EXCEPTION",
537         OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
538         "PID", getpid(),
539         "UID", getuid(),
540         "MSG", info);
541     if (ret != 0) {
542         TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret:%{public}d", ret);
543     }
544 }
545 
UpdateWindowState()546 void WindowSceneSessionImpl::UpdateWindowState()
547 {
548     {
549         std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
550         windowSessionMap_.insert(std::make_pair(property_->GetWindowName(),
551         std::pair<uint64_t, sptr<WindowSessionImpl>>(property_->GetPersistentId(), this)));
552     }
553     state_ = WindowState::STATE_CREATED;
554     requestState_ = WindowState::STATE_CREATED;
555     WindowType windowType = GetType();
556     if (WindowHelper::IsMainWindow(windowType)) {
557         if (property_->GetIsNeedUpdateWindowMode()) {
558             WLOGFI("UpdateWindowMode %{public}u mode %{public}u",
559                 GetWindowId(), static_cast<uint32_t>(property_->GetWindowMode()));
560             UpdateWindowModeImmediately(property_->GetWindowMode());
561             property_->SetIsNeedUpdateWindowMode(false);
562         } else {
563             SetWindowMode(windowSystemConfig_.defaultWindowMode_);
564         }
565         NotifyWindowNeedAvoid(
566             (property_->GetWindowFlags()) & (static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
567         GetConfigurationFromAbilityInfo();
568     } else {
569         bool isSubWindow = WindowHelper::IsSubWindow(windowType);
570         bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
571         bool isSysytemWindow = WindowHelper::IsSystemWindow(windowType);
572         UpdateWindowSizeLimits();
573         if ((isSubWindow || isDialogWindow || isSysytemWindow) && IsWindowDraggable()) {
574             WLOGFD("sync window limits to server side to make size limits work while resizing");
575             UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
576         }
577     }
578 }
579 
Create(const std::shared_ptr<AbilityRuntime::Context> & context,const sptr<Rosen::ISession> & iSession,const std::string & identityToken,bool isModuleAbilityHookEnd)580 WMError WindowSceneSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
581     const sptr<Rosen::ISession>& iSession, const std::string& identityToken, bool isModuleAbilityHookEnd)
582 {
583     TLOGI(WmsLogTag::WMS_LIFE, "Window Create name:%{public}s, state:%{public}u, mode:%{public}u",
584         property_->GetWindowName().c_str(), state_, GetWindowMode());
585     // allow iSession is nullptr when create window by innerkits
586     if (!context) {
587         TLOGW(WmsLogTag::WMS_LIFE, "context is nullptr");
588     }
589     WMError ret = WindowSessionCreateCheck();
590     if (ret != WMError::WM_OK) {
591         return ret;
592     }
593     // Since here is init of this window, no other threads will rw it.
594     hostSession_ = iSession;
595     SetContext(context);
596     identityToken_ = identityToken;
597     property_->SetIsAbilityHookOff(isModuleAbilityHookEnd);
598     TLOGI(WmsLogTag::WMS_LIFE, "SetIsAbilityHookOff %{public}d", isModuleAbilityHookEnd);
599     AdjustWindowAnimationFlag();
600     if (context && context->GetApplicationInfo() &&
601         context->GetApplicationInfo()->apiCompatibleVersion >= 9 && // 9: api version
602         !SessionPermission::IsSystemCalling()) {
603         WLOGI("Remove window flag WINDOW_FLAG_SHOW_WHEN_LOCKED");
604         property_->SetWindowFlags(property_->GetWindowFlags() &
605             (~(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))));
606     }
607     int32_t zLevel = GetSubWindowZLevelByFlags(GetType(), GetWindowFlags(), IsTopmost());
608     if (zLevel != NORMAL_SUB_WINDOW_Z_LEVEL) {
609         property_->SetSubWindowZLevel(zLevel);
610     }
611 
612     bool isSpecificSession = false;
613     const auto& initRect = GetRequestRect();
614     if (GetHostSession()) { // main window
615         SetDefaultDisplayIdIfNeed();
616         ret = Connect();
617         SetTargetAPIVersion(SysCapUtil::GetApiCompatibleVersion());
618         TLOGD(WmsLogTag::WMS_PC, "targeAPItVersion: %{public}d", GetTargetAPIVersion());
619     } else { // system or sub window
620         TLOGI(WmsLogTag::WMS_LIFE, "Create system or sub window with type=%{public}d", GetType());
621         isSpecificSession = true;
622         const auto& type = GetType();
623         if (WindowHelper::IsSystemWindow(type)) {
624             // Not valid system window type for session should return WMError::WM_OK;
625             if (!IsValidSystemWindowType(type)) {
626                 return WMError::WM_ERROR_INVALID_CALLING;
627             }
628             if (INVALID_SCB_WINDOW_TYPE.find(type) != INVALID_SCB_WINDOW_TYPE.end()) {
629                 TLOGI(WmsLogTag::WMS_SYSTEM, "Invalid SCB type: %{public}u", type);
630                 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
631             }
632             InitSystemSessionDragEnable();
633         } else if (!WindowHelper::IsSubWindow(type)) {
634             TLOGI(WmsLogTag::WMS_LIFE, "create failed not system or sub type, type: %{public}d", type);
635             return WMError::WM_ERROR_INVALID_CALLING;
636         }
637         isEnableDefaultDensityWhenCreate_ = windowOption_->IsDefaultDensityEnabled();
638         ret = CreateAndConnectSpecificSession();
639     }
640 
641     RecordLifeCycleExceptionEvent(LifeCycleEvent::CREATE_EVENT, ret);
642     if (ret == WMError::WM_OK) {
643         MakeSubOrDialogWindowDragableAndMoveble();
644         UpdateWindowState();
645         RegisterWindowRecoverStateChangeListener();
646         RegisterSessionRecoverListener(isSpecificSession);
647         UpdateDefaultStatusBarColor();
648         AddSetUIContentTimeoutCheck();
649         SetUIExtensionDestroyCompleteInSubWindow();
650         SetSubWindowZLevelToProperty();
651         InputTransferStation::GetInstance().AddInputWindow(this);
652         if (WindowHelper::IsSubWindow(GetType()) && !initRect.IsUninitializedRect()) {
653             auto hostSession = GetHostSession();
654             if (IsFullScreenSizeWindow(initRect.width_, initRect.height_) && (hostSession != nullptr)) {
655                 // Full screen size sub window don't need to resize when dpi change
656                 TLOGI(WmsLogTag::WMS_LIFE, "Full screen size sub window set isDefaultDensityEnabled true");
657                 hostSession->OnDefaultDensityEnabled(true);
658             }
659             Resize(initRect.width_, initRect.height_);
660         }
661         RegisterWindowInspectorCallback();
662         SetPcAppInpadSpecificSystemBarInvisible();
663         SetPcAppInpadOrientationLandscape();
664     }
665     TLOGD(WmsLogTag::WMS_LIFE, "Window Create success [name:%{public}s, id:%{public}d], state:%{public}u, "
666         "mode:%{public}u, enableDefaultDensity:%{public}d, displayId:%{public}" PRIu64,
667         property_->GetWindowName().c_str(), property_->GetPersistentId(), state_, GetWindowMode(),
668         isEnableDefaultDensityWhenCreate_, property_->GetDisplayId());
669     return ret;
670 }
671 
SetPcAppInpadSpecificSystemBarInvisible()672 WMError WindowSceneSessionImpl::SetPcAppInpadSpecificSystemBarInvisible()
673 {
674     TLOGI(WmsLogTag::WMS_COMPAT, "isPcAppInpadSpecificSystemBarInvisible: %{public}d",
675         property_->GetPcAppInpadSpecificSystemBarInvisible());
676     if (WindowHelper::IsMainWindow(GetType()) && IsPadAndNotFreeMutiWindowCompatibleMode() &&
677         property_->GetPcAppInpadSpecificSystemBarInvisible()) {
678         SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
679         UpdateSpecificSystemBarEnabled(false, false, statusProperty);
680         SetSpecificBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
681 
682         SystemBarProperty NavigationIndicatorPorperty =
683             GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR);
684         UpdateSpecificSystemBarEnabled(false, false, NavigationIndicatorPorperty);
685         SetSpecificBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, NavigationIndicatorPorperty);
686         return WMError::WM_OK;
687     }
688     return WMError::WM_ERROR_INVALID_CALLING;
689 }
690 
SetPcAppInpadOrientationLandscape()691 WMError WindowSceneSessionImpl::SetPcAppInpadOrientationLandscape()
692 {
693     TLOGI(WmsLogTag::WMS_COMPAT, "isPcAppInpadOrientationLandscape: %{public}d",
694         property_->GetPcAppInpadOrientationLandscape());
695     if (WindowHelper::IsMainWindow(GetType()) && IsPadAndNotFreeMutiWindowCompatibleMode() &&
696         property_->GetPcAppInpadOrientationLandscape()) {
697         SetRequestedOrientation(Orientation::HORIZONTAL, false);
698         return WMError::WM_OK;
699     }
700     return WMError::WM_ERROR_INVALID_CALLING;
701 }
702 
IsFullScreenSizeWindow(uint32_t width,uint32_t height)703 bool WindowSceneSessionImpl::IsFullScreenSizeWindow(uint32_t width, uint32_t height)
704 {
705     DisplayId displayId = property_->GetDisplayId();
706     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
707     if (display == nullptr) {
708         TLOGE(WmsLogTag::WMS_LAYOUT, "display is null");
709         return false;
710     }
711     auto displayInfo = display->GetDisplayInfo();
712     if (displayInfo == nullptr) {
713         TLOGE(WmsLogTag::WMS_LAYOUT, "displayInfo is null");
714         return false;
715     }
716     uint32_t displayWidth = static_cast<uint32_t>(displayInfo->GetWidth());
717     uint32_t displayHeight = static_cast<uint32_t>(displayInfo->GetHeight());
718     if (displayWidth == width && displayHeight == height) {
719         return true;
720     }
721     if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice() ||
722         DisplayManager::GetInstance().GetFoldStatus() != FoldStatus::HALF_FOLD) {
723         return false;
724     }
725     // if is super fold device and in half fold state, check virtual screen
726     auto virtualDisplay = SingletonContainer::Get<DisplayManager>().GetDisplayById(DISPLAY_ID_C);
727     if (virtualDisplay == nullptr) {
728         TLOGE(WmsLogTag::WMS_LAYOUT, "virtual display is null");
729         return false;
730     }
731     auto virtualDisplayInfo = virtualDisplay->GetDisplayInfo();
732     if (virtualDisplayInfo == nullptr) {
733         TLOGE(WmsLogTag::WMS_LAYOUT, "virtual displayInfo is null");
734         return false;
735     }
736     displayWidth = static_cast<uint32_t>(virtualDisplayInfo->GetWidth());
737     displayHeight = static_cast<uint32_t>(virtualDisplayInfo->GetHeight());
738     if (displayWidth == width && displayHeight == height) {
739         return true;
740     }
741     return false;
742 }
743 
SetParentWindowInner(int32_t oldParentWindowId,const sptr<WindowSessionImpl> & newParentWindow)744 WMError WindowSceneSessionImpl::SetParentWindowInner(int32_t oldParentWindowId,
745     const sptr<WindowSessionImpl>& newParentWindow)
746 {
747     auto newParentWindowId = newParentWindow->GetPersistentId();
748     auto subWindowId = GetPersistentId();
749     TLOGI(WmsLogTag::WMS_SUB, "subWindowId: %{public}d, oldParentWindowId: %{public}d, "
750         "newParentWindowId: %{public}d", subWindowId, oldParentWindowId, newParentWindowId);
751     WMError ret = SingletonContainer::Get<WindowAdapter>().SetParentWindow(subWindowId, newParentWindowId);
752     if (ret != WMError::WM_OK) {
753         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d set parent window failed errCode: %{public}d",
754             subWindowId, static_cast<int32_t>(ret));
755         return ret;
756     }
757     RemoveSubWindow(oldParentWindowId);
758     {
759         std::lock_guard<std::recursive_mutex> lock(subWindowSessionMutex_);
760         subWindowSessionMap_[newParentWindowId].push_back(this);
761     }
762     property_->SetParentPersistentId(newParentWindowId);
763     UpdateSubWindowInfo(newParentWindow->GetProperty()->GetSubWindowLevel() + 1,
764         newParentWindow->GetContext());
765     if (state_ == WindowState::STATE_SHOWN &&
766         newParentWindow->GetWindowState() == WindowState::STATE_HIDDEN) {
767         UpdateSubWindowStateAndNotify(newParentWindowId, WindowState::STATE_HIDDEN);
768     }
769     return WMError::WM_OK;
770 }
771 
SetParentWindow(int32_t newParentWindowId)772 WMError WindowSceneSessionImpl::SetParentWindow(int32_t newParentWindowId)
773 {
774     auto subWindowId = GetPersistentId();
775     if (property_->GetPcAppInpadCompatibleMode()) {
776         TLOGE(WmsLogTag::WMS_SUB, "This is PcAppInPad, not Supported");
777         return WMError::WM_OK;
778     }
779     if (!IsPcWindow()) {
780         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d device not support", subWindowId);
781         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
782     }
783     if (IsWindowSessionInvalid()) {
784         return WMError::WM_ERROR_INVALID_WINDOW;
785     }
786     if (!WindowHelper::IsSubWindow(GetType())) {
787         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d called by invalid window type %{public}d",
788             subWindowId, GetType());
789         return WMError::WM_ERROR_INVALID_CALLING;
790     }
791     auto oldParentWindowId = property_->GetParentPersistentId();
792     if (oldParentWindowId == newParentWindowId || subWindowId == newParentWindowId) {
793         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d newParentWindowId is the same as "
794             "oldParentWindowId or subWindowId", subWindowId);
795         return WMError::WM_ERROR_INVALID_PARENT;
796     }
797     auto oldParentWindow = GetWindowWithId(oldParentWindowId);
798     if (oldParentWindow == nullptr) {
799         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d find not old parent window By Id: %{public}d",
800             subWindowId, oldParentWindowId);
801         return WMError::WM_ERROR_INVALID_PARENT;
802     }
803     auto oldWindowType = oldParentWindow->GetType();
804     if (!WindowHelper::IsMainWindow(oldWindowType) && !WindowHelper::IsFloatOrSubWindow(oldWindowType)) {
805         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d old parent window type invalid", subWindowId);
806         return WMError::WM_ERROR_INVALID_PARENT;
807     }
808     auto newParentWindow = GetWindowWithId(newParentWindowId);
809     if (newParentWindow == nullptr) {
810         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d find not new parent window By Id: %{public}d",
811             subWindowId, newParentWindowId);
812         return WMError::WM_ERROR_INVALID_PARENT;
813     }
814     auto newWindowType = newParentWindow->GetType();
815     if (!WindowHelper::IsMainWindow(newWindowType) && !WindowHelper::IsFloatOrSubWindow(newWindowType)) {
816         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d new parent window type invalid", subWindowId);
817         return WMError::WM_ERROR_INVALID_PARENT;
818     }
819     return SetParentWindowInner(oldParentWindowId, newParentWindow);
820 }
821 
GetParentWindow(sptr<Window> & parentWindow)822 WMError WindowSceneSessionImpl::GetParentWindow(sptr<Window>& parentWindow)
823 {
824     if (property_->GetPcAppInpadCompatibleMode()) {
825         TLOGE(WmsLogTag::WMS_SUB, "This is PcAppInPad, not Supported");
826         return WMError::WM_OK;
827     }
828     if (!IsPcWindow()) {
829         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d device not support", GetPersistentId());
830         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
831     }
832     if (IsWindowSessionInvalid()) {
833         return WMError::WM_ERROR_INVALID_WINDOW;
834     }
835     if (!WindowHelper::IsSubWindow(GetType())) {
836         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d called by invalid window type %{public}d",
837             GetPersistentId(), GetType());
838         return WMError::WM_ERROR_INVALID_CALLING;
839     }
840     if (property_->GetIsUIExtFirstSubWindow()) {
841         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d UIExtension sub window not get parent window",
842             GetPersistentId());
843         return WMError::WM_ERROR_INVALID_CALLING;
844     }
845     parentWindow = FindWindowById(property_->GetParentPersistentId());
846     if (parentWindow == nullptr) {
847         TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d parentWindow is nullptr", GetPersistentId());
848         return WMError::WM_ERROR_INVALID_PARENT;
849     }
850     return WMError::WM_OK;
851 }
852 
InitSystemSessionDragEnable()853 void WindowSceneSessionImpl::InitSystemSessionDragEnable()
854 {
855     if (WindowHelper::IsDialogWindow(GetType())) {
856         TLOGI(WmsLogTag::WMS_LAYOUT, "dialogWindow default draggable, should not init false, id: %{public}d",
857             GetPersistentId());
858         return;
859     }
860     TLOGI(WmsLogTag::WMS_LAYOUT, "windId: %{public}d init dragEnable false",
861         GetPersistentId());
862     property_->SetDragEnabled(false);
863 }
864 
UpdateDefaultStatusBarColor()865 void WindowSceneSessionImpl::UpdateDefaultStatusBarColor()
866 {
867     SystemBarProperty statusBarProp = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
868     if (static_cast<SystemBarSettingFlag>(static_cast<uint32_t>(statusBarProp.settingFlag_) &
869         static_cast<uint32_t>(SystemBarSettingFlag::COLOR_SETTING)) == SystemBarSettingFlag::COLOR_SETTING) {
870         TLOGD(WmsLogTag::WMS_IMMS, "user has set color");
871         return;
872     }
873     if (!WindowHelper::IsMainWindow(GetType())) {
874         TLOGD(WmsLogTag::WMS_IMMS, "not main window");
875         return;
876     }
877     uint32_t contentColor;
878     constexpr uint32_t BLACK = 0xFF000000;
879     constexpr uint32_t WHITE = 0xFFFFFFFF;
880     bool isColorModeSetByApp = !specifiedColorMode_.empty();
881     std::string colorMode = specifiedColorMode_;
882     if (isColorModeSetByApp) {
883         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u type %{public}u colorMode %{public}s",
884             GetPersistentId(), GetType(), colorMode.c_str());
885         contentColor = colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT ? BLACK : WHITE;
886     } else {
887         auto appContext = AbilityRuntime::Context::GetApplicationContext();
888         if (appContext == nullptr) {
889             TLOGE(WmsLogTag::WMS_IMMS, "app context is nullptr");
890             return;
891         }
892         std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
893         if (config == nullptr) {
894             TLOGE(WmsLogTag::WMS_IMMS, "config is null, winId: %{public}d", GetPersistentId());
895             return;
896         }
897         colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
898         isColorModeSetByApp = !config->GetItem(AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_APP).empty();
899         if (isColorModeSetByApp) {
900             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "win=%{public}u, appColor=%{public}s", GetWindowId(), colorMode.c_str());
901             contentColor = colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT ? BLACK : WHITE;
902         } else {
903             bool hasDarkRes = false;
904             appContext->AppHasDarkRes(hasDarkRes);
905             TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u type %{public}u hasDarkRes %{public}u colorMode %{public}s",
906                 GetPersistentId(), GetType(), hasDarkRes, colorMode.c_str());
907             contentColor = colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT ? BLACK :
908                 (hasDarkRes ? WHITE : BLACK);
909         }
910     }
911     statusBarProp.contentColor_ = contentColor;
912     statusBarProp.settingFlag_ = static_cast<SystemBarSettingFlag>(
913         static_cast<uint32_t>(statusBarProp.settingFlag_) |
914         static_cast<uint32_t>(SystemBarSettingFlag::FOLLOW_SETTING));
915     SetSpecificBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusBarProp);
916 }
917 
RegisterSessionRecoverListener(bool isSpecificSession)918 void WindowSceneSessionImpl::RegisterSessionRecoverListener(bool isSpecificSession)
919 {
920     TLOGD(WmsLogTag::WMS_RECOVER, "Id=%{public}d, isSpecificSession=%{public}s",
921         GetPersistentId(), isSpecificSession ? "true" : "false");
922 
923     if (GetType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
924         TLOGI(WmsLogTag::WMS_RECOVER, "input method window does not need to recover");
925         return;
926     }
927     if (property_->GetCollaboratorType() != CollaboratorType::DEFAULT_TYPE) {
928         TLOGI(WmsLogTag::WMS_RECOVER, "collaboratorType is %{public}" PRId32 ", not need to recover",
929             property_->GetCollaboratorType());
930         return;
931     }
932 
933     wptr<WindowSceneSessionImpl> weakThis = this;
934     auto callbackFunc = [weakThis, isSpecificSession] {
935         auto promoteThis = weakThis.promote();
936         if (promoteThis == nullptr) {
937             TLOGW(WmsLogTag::WMS_RECOVER, "promoteThis is nullptr");
938             return WMError::WM_ERROR_NULLPTR;
939         }
940         if (promoteThis->state_ == WindowState::STATE_DESTROYED) {
941             TLOGW(WmsLogTag::WMS_RECOVER, "windowState is STATE_DESTROYED, no need to recover");
942             return WMError::WM_ERROR_DESTROYED_OBJECT;
943         }
944         if (promoteThis->windowRecoverStateChangeFunc_ == nullptr) {
945             TLOGW(WmsLogTag::WMS_RECOVER, "windowRecoverStateChangeFunc_ is nullptr");
946             return WMError::WM_ERROR_NULLPTR;
947         }
948 
949         auto ret = isSpecificSession ? promoteThis->RecoverAndConnectSpecificSession() :
950 			promoteThis->RecoverAndReconnectSceneSession();
951 
952         TLOGD(WmsLogTag::WMS_RECOVER, "Recover session over, ret=%{public}d", ret);
953         return ret;
954     };
955     SingletonContainer::Get<WindowAdapter>().RegisterSessionRecoverCallbackFunc(GetPersistentId(), callbackFunc);
956 }
957 
RegisterWindowRecoverStateChangeListener()958 void WindowSceneSessionImpl::RegisterWindowRecoverStateChangeListener()
959 {
960     windowRecoverStateChangeFunc_ = [weakThis = wptr(this)](bool isSpecificSession,
961         const WindowRecoverState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
962         auto window = weakThis.promote();
963         if (window == nullptr) {
964             TLOGNE(WmsLogTag::WMS_RECOVER, "window is null");
965             return;
966         }
967         window->OnWindowRecoverStateChange(isSpecificSession, state);
968     };
969 }
970 
OnWindowRecoverStateChange(bool isSpecificSession,const WindowRecoverState & state)971 void WindowSceneSessionImpl::OnWindowRecoverStateChange(bool isSpecificSession, const WindowRecoverState& state)
972 {
973     TLOGI(WmsLogTag::WMS_RECOVER, "id: %{public}d, state:%{public}u", GetPersistentId(), state);
974     switch (state) {
975         case WindowRecoverState::WINDOW_START_RECONNECT:
976             UpdateStartRecoverProperty(isSpecificSession);
977             break;
978         case WindowRecoverState::WINDOW_FINISH_RECONNECT:
979             UpdateFinishRecoverProperty(isSpecificSession);
980             RecoverSessionListener();
981             break;
982         default:
983             break;
984     }
985 }
986 
UpdateStartRecoverProperty(bool isSpecificSession)987 void WindowSceneSessionImpl::UpdateStartRecoverProperty(bool isSpecificSession)
988 {
989     if (isSpecificSession) {
990         property_->SetWindowState(requestState_);
991         if (GetContext() && GetContext()->GetToken()) {
992             property_->SetTokenState(true);
993         }
994     } else {
995         property_->SetWindowState(state_);
996         property_->SetIsFullScreenWaterfallMode(isFullScreenWaterfallMode_.load());
997     }
998 }
999 
UpdateFinishRecoverProperty(bool isSpecificSession)1000 void WindowSceneSessionImpl::UpdateFinishRecoverProperty(bool isSpecificSession)
1001 {
1002     property_->SetWindowState(state_);
1003 }
1004 
HandlePointDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const MMI::PointerEvent::PointerItem & pointerItem)1005 bool WindowSceneSessionImpl::HandlePointDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1006     const MMI::PointerEvent::PointerItem& pointerItem)
1007 {
1008     bool needNotifyEvent = true;
1009     WindowType windowType = property_->GetWindowType();
1010     AreaType dragType = GetDragAreaByDownEvent(pointerEvent, pointerItem);
1011     TLOGD(WmsLogTag::WMS_EVENT, "dragType: %{public}d", dragType);
1012     bool isDecorDialog = windowType == WindowType::WINDOW_TYPE_DIALOG && property_->IsDecorEnable();
1013     bool isFixedSubWin = WindowHelper::IsSubWindow(windowType) && !IsWindowDraggable();
1014     bool isFixedSystemWin = WindowHelper::IsSystemWindow(windowType) && !IsWindowDraggable();
1015     auto hostSession = GetHostSession();
1016     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, needNotifyEvent);
1017     TLOGD(WmsLogTag::WMS_EVENT, "isFixedSystemWin %{public}d, isFixedSubWin %{public}d, isDecorDialog %{public}d",
1018         isFixedSystemWin, isFixedSubWin, isDecorDialog);
1019     if ((isFixedSystemWin || isFixedSubWin) && !isDecorDialog) {
1020         hostSession->SendPointEventForMoveDrag(pointerEvent, isExecuteDelayRaise_);
1021     } else {
1022         if (dragType != AreaType::UNDEFINED) {
1023             hostSession->SendPointEventForMoveDrag(pointerEvent, isExecuteDelayRaise_);
1024             needNotifyEvent = false;
1025         } else if (WindowHelper::IsMainWindow(windowType) ||
1026                    WindowHelper::IsSubWindow(windowType) ||
1027                    WindowHelper::IsSystemWindow(windowType)) {
1028             hostSession->SendPointEventForMoveDrag(pointerEvent, isExecuteDelayRaise_);
1029         } else {
1030             hostSession->ProcessPointDownSession(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
1031         }
1032     }
1033     return needNotifyEvent;
1034 }
1035 
GetDragAreaByDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const MMI::PointerEvent::PointerItem & pointerItem)1036 AreaType WindowSceneSessionImpl::GetDragAreaByDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1037     const MMI::PointerEvent::PointerItem& pointerItem)
1038 {
1039     AreaType dragType = AreaType::UNDEFINED;
1040     float vpr = WindowSessionImpl::GetVirtualPixelRatio();
1041     if (MathHelper::NearZero(vpr)) {
1042         return dragType;
1043     }
1044     const auto& sourceType = pointerEvent->GetSourceType();
1045     int outside = (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) ? static_cast<int>(HOTZONE_POINTER * vpr) :
1046         static_cast<int>(HOTZONE_TOUCH * vpr);
1047     int32_t winX = pointerItem.GetWindowX();
1048     int32_t winY = pointerItem.GetWindowY();
1049     WindowType windowType = property_->GetWindowType();
1050     bool isSystemDraggableType = WindowHelper::IsSystemWindow(windowType) && IsWindowDraggable();
1051     const auto& rect = SessionHelper::TransferToWSRect(GetRect());
1052     if (property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING || isSystemDraggableType) {
1053         dragType = SessionHelper::GetAreaType(winX, winY, sourceType, outside, vpr, rect);
1054     }
1055     return dragType;
1056 }
1057 
ResetSuperFoldDisplayY(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1058 void WindowSceneSessionImpl::ResetSuperFoldDisplayY(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1059 {
1060     if (superFoldOffsetY_ == -1) {
1061         auto foldCreaseRegion = DisplayManager::GetInstance().GetCurrentFoldCreaseRegion();
1062         if (foldCreaseRegion == nullptr) {
1063             TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "foldCreaseRegion is nullptr");
1064             return;
1065         }
1066         const auto& creaseRects = foldCreaseRegion->GetCreaseRects();
1067         if (creaseRects.empty()) {
1068             TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "creaseRects is empty");
1069             return;
1070         }
1071         const auto& rect = creaseRects.front();
1072         superFoldOffsetY_ = rect.height_ + rect.posY_;
1073         TLOGI(WmsLogTag::WMS_EVENT, "height: %{public}d, posY: %{public}d", rect.height_, rect.posY_);
1074     }
1075     std::vector<int32_t> pointerIds = pointerEvent->GetPointerIds();
1076     for (int32_t pointerId : pointerIds) {
1077         MMI::PointerEvent::PointerItem pointerItem;
1078         if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
1079             TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "Get pointerItem failed");
1080             return;
1081         }
1082         if (auto displayYPos = pointerItem.GetDisplayYPos();
1083             !MathHelper::LessNotEqual(displayYPos, superFoldOffsetY_)) {
1084             pointerItem.SetDisplayYPos(displayYPos - superFoldOffsetY_);
1085             pointerEvent->UpdatePointerItem(pointerId, pointerItem);
1086             pointerEvent->SetTargetDisplayId(DISPLAY_ID_C);
1087             TLOGD(WmsLogTag::WMS_EVENT, "Calculated superFoldOffsetY:%{public}d,displayId:%{public}d,"
1088                 "InputId:%{public}d,pointerId:%{public}d,displayXPos:%{private}f,displayYPos:%{private}f,",
1089                 superFoldOffsetY_, pointerEvent->GetTargetDisplayId(), pointerEvent->GetId(),
1090                 pointerId, pointerItem.GetDisplayXPos(), pointerItem.GetDisplayYPos());
1091         }
1092     }
1093 }
1094 
ConsumePointerEventInner(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem,bool isHitTargetDraggable)1095 void WindowSceneSessionImpl::ConsumePointerEventInner(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1096     MMI::PointerEvent::PointerItem& pointerItem, bool isHitTargetDraggable)
1097 {
1098     const int32_t& action = pointerEvent->GetPointerAction();
1099     const auto& sourceType = pointerEvent->GetSourceType();
1100     const auto& rect = SessionHelper::TransferToWSRect(GetRect());
1101     bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
1102         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
1103     bool needNotifyEvent = true;
1104     if (property_->IsAdaptToEventMapping()) {
1105         HandleEventForCompatibleMode(pointerEvent, pointerItem);
1106     }
1107     lastPointerEvent_ = pointerEvent;
1108     if (isPointDown) {
1109         float vpr = WindowSessionImpl::GetVirtualPixelRatio();
1110         if (MathHelper::NearZero(vpr)) {
1111             WLOGFW("vpr is zero");
1112             pointerEvent->MarkProcessed();
1113             return;
1114         }
1115         if (IsWindowDelayRaiseEnabled() && isHitTargetDraggable) {
1116             isExecuteDelayRaise_ = true;
1117         }
1118         needNotifyEvent = HandlePointDownEvent(pointerEvent, pointerItem);
1119         RefreshNoInteractionTimeoutMonitor();
1120     }
1121     bool isPointUp = (action == MMI::PointerEvent::POINTER_ACTION_UP ||
1122         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
1123         action == MMI::PointerEvent::POINTER_ACTION_CANCEL);
1124     if (isPointUp) {
1125         if (auto hostSession = GetHostSession()) {
1126             hostSession->SendPointEventForMoveDrag(pointerEvent, isExecuteDelayRaise_);
1127         }
1128     }
1129 
1130     bool isPointPullUp = action == MMI::PointerEvent::POINTER_ACTION_PULL_UP;
1131     if (isExecuteDelayRaise_ && (isPointUp || isPointPullUp)) {
1132         isExecuteDelayRaise_ = false;
1133     }
1134     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
1135         property_->GetDisplayId() == DISPLAY_ID_C &&
1136         DisplayManager::GetInstance().GetFoldStatus() == FoldStatus::HALF_FOLD) {
1137         ResetSuperFoldDisplayY(pointerEvent);
1138     }
1139     if (needNotifyEvent) {
1140         NotifyPointerEvent(pointerEvent);
1141     } else {
1142         pointerEvent->MarkProcessed();
1143     }
1144     if (isPointDown || isPointUp) {
1145         TLOGNI(WmsLogTag::WMS_INPUT_KEY_FLOW, "Consume:id:%{public}d,wid:%{public}u,pointId:%{public}d"
1146             ",srcType:%{public}d,rect:[%{public}d,%{public}d,%{public}u,%{public}u],notify:%{public}d",
1147             pointerEvent->GetId(), GetWindowId(), pointerEvent->GetPointerId(),
1148             sourceType, rect.posX_, rect.posY_, rect.width_, rect.height_, needNotifyEvent);
1149     }
1150 }
1151 
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1152 void WindowSceneSessionImpl::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1153 {
1154     if (pointerEvent == nullptr) {
1155         WLOGFE("PointerEvent is nullptr, windowId: %{public}d", GetWindowId());
1156         return;
1157     }
1158 
1159     if (GetHostSession() == nullptr) {
1160         TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "hostSession is nullptr, windowId: %{public}d", GetWindowId());
1161         pointerEvent->MarkProcessed();
1162         return;
1163     }
1164     MMI::PointerEvent::PointerItem pointerItem;
1165     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
1166         TLOGW(WmsLogTag::WMS_INPUT_KEY_FLOW, "invalid pointerEvent, windowId: %{public}d", GetWindowId());
1167         pointerEvent->MarkProcessed();
1168         return;
1169     }
1170 
1171     bool isPointDown = pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN ||
1172         pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN;
1173     AreaType dragType = AreaType::UNDEFINED;
1174     if (isPointDown) {
1175         dragType = GetDragAreaByDownEvent(pointerEvent, pointerItem);
1176     }
1177     if (!IsWindowDelayRaiseEnabled() || dragType != AreaType::UNDEFINED) {
1178         ConsumePointerEventInner(pointerEvent, pointerItem, false);
1179         return;
1180     }
1181     if (auto uiContent = GetUIContentSharedPtr()) {
1182         uiContent->ProcessPointerEvent(pointerEvent,
1183             [weakThis = wptr(this), pointerEvent, pointerItem](bool isHitTargetDraggable) mutable {
1184                 auto window = weakThis.promote();
1185                 if (window == nullptr) {
1186                     TLOGNE(WmsLogTag::WMS_FOCUS, "window is null");
1187                     return;
1188                 }
1189                 window->ConsumePointerEventInner(pointerEvent, pointerItem, isHitTargetDraggable);
1190             });
1191     } else {
1192         TLOGE(WmsLogTag::WMS_FOCUS, "uiContent is nullptr, windowId: %{public}u", GetWindowId());
1193         pointerEvent->MarkProcessed();
1194     }
1195 }
1196 
PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)1197 bool WindowSceneSessionImpl::PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
1198 {
1199     bool isConsumed = false;
1200     if (auto uiContent = GetUIContentSharedPtr()) {
1201         isConsumed = uiContent->ProcessKeyEvent(keyEvent, true);
1202     }
1203     RefreshNoInteractionTimeoutMonitor();
1204     if ((keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_TAB ||
1205          keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_ENTER) && isConsumed &&
1206         keyEvent->GetKeyAction() == MMI::KeyEvent::KEY_ACTION_DOWN) {
1207         TLOGD(WmsLogTag::WMS_EVENT, "wid:%{public}d, keyCode:%{public}d, isConsumed:%{public}d",
1208             GetWindowId(), keyEvent->GetKeyCode(), isConsumed);
1209         NotifyWatchGestureConsumeResult(keyEvent->GetKeyCode(), isConsumed);
1210     }
1211     SetWatchGestureConsumed(isConsumed);
1212     return isConsumed;
1213 }
1214 
GetWindowSizeLimits(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo,WindowSizeLimits & windowSizeLimits)1215 static void GetWindowSizeLimits(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo,
1216     WindowSizeLimits& windowSizeLimits)
1217 {
1218     windowSizeLimits.maxWindowWidth = windowSizeLimits.maxWindowWidth > 0 ?
1219         windowSizeLimits.maxWindowWidth : abilityInfo->maxWindowWidth;
1220     windowSizeLimits.maxWindowHeight = windowSizeLimits.maxWindowHeight > 0 ?
1221         windowSizeLimits.maxWindowHeight : abilityInfo->maxWindowHeight;
1222     windowSizeLimits.minWindowWidth = windowSizeLimits.minWindowWidth > 0 ?
1223         windowSizeLimits.minWindowWidth : abilityInfo->minWindowWidth;
1224     windowSizeLimits.minWindowHeight = windowSizeLimits.minWindowHeight > 0 ?
1225         windowSizeLimits.minWindowHeight : abilityInfo->minWindowHeight;
1226 }
1227 
HandleWindowLimitsInCompatibleMode(WindowSizeLimits & windowSizeLimits)1228 void WindowSceneSessionImpl::HandleWindowLimitsInCompatibleMode(WindowSizeLimits& windowSizeLimits)
1229 {
1230     if (!property_->IsWindowLimitDisabled()) {
1231         return;
1232     }
1233     windowSizeLimits.maxWindowWidth = windowSystemConfig_.maxFloatingWindowSize_;
1234     windowSizeLimits.maxWindowHeight = windowSystemConfig_.maxFloatingWindowSize_;
1235     if (WindowHelper::IsMainWindow(GetType())) {
1236         windowSizeLimits.minWindowWidth = windowSystemConfig_.miniWidthOfMainWindow_;
1237         windowSizeLimits.minWindowHeight = windowSystemConfig_.miniHeightOfMainWindow_;
1238     } else if (WindowHelper::IsSubWindow(GetType())) {
1239         windowSizeLimits.minWindowWidth = windowSystemConfig_.miniWidthOfSubWindow_;
1240         windowSizeLimits.minWindowHeight = windowSystemConfig_.miniHeightOfSubWindow_;
1241     } else if (WindowHelper::IsDialogWindow(GetType())) {
1242         windowSizeLimits.minWindowWidth = windowSystemConfig_.miniWidthOfDialogWindow_;
1243         windowSizeLimits.minWindowHeight = windowSystemConfig_.miniHeightOfDialogWindow_;
1244     } else {
1245         windowSizeLimits.minWindowWidth = MIN_FLOATING_WIDTH;
1246         windowSizeLimits.minWindowHeight = MIN_FLOATING_HEIGHT;
1247     }
1248     TLOGI(WmsLogTag::WMS_COMPAT, "maxWidth: %{public}u, minWidth: %{public}u, maxHeight: %{public}u, "
1249         "minHeight: %{public}u", windowSizeLimits.maxWindowWidth, windowSizeLimits.minWindowWidth,
1250         windowSizeLimits.maxWindowHeight, windowSizeLimits.minWindowHeight);
1251 }
1252 
ExtractSupportWindowModeFromMetaData(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)1253 std::vector<AppExecFwk::SupportWindowMode> WindowSceneSessionImpl::ExtractSupportWindowModeFromMetaData(
1254     const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
1255 {
1256     std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
1257     if (windowSystemConfig_.IsPcWindow() || IsFreeMultiWindowMode()) {
1258         auto metadata = abilityInfo->metadata;
1259         for (auto item : metadata) {
1260             if (item.name == "ohos.ability.window.supportWindowModeInFreeMultiWindow") {
1261                 updateWindowModes = ParseWindowModeFromMetaData(item.value);
1262             }
1263         }
1264     }
1265     if (updateWindowModes.empty()) {
1266         updateWindowModes = abilityInfo->windowModes;
1267     }
1268     return updateWindowModes;
1269 }
1270 
ParseWindowModeFromMetaData(const std::string & supportModesInFreeMultiWindow)1271 std::vector<AppExecFwk::SupportWindowMode> WindowSceneSessionImpl::ParseWindowModeFromMetaData(
1272     const std::string& supportModesInFreeMultiWindow)
1273 {
1274     std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
1275     std::stringstream supportModes(supportModesInFreeMultiWindow);
1276     std::string supportWindowMode;
1277     while (getline(supportModes, supportWindowMode, ',')) {
1278         if (supportWindowMode == "fullscreen") {
1279             updateWindowModes.push_back(AppExecFwk::SupportWindowMode::FULLSCREEN);
1280         } else if (supportWindowMode == "split") {
1281             updateWindowModes.push_back(AppExecFwk::SupportWindowMode::SPLIT);
1282         } else if (supportWindowMode == "floating") {
1283             updateWindowModes.push_back(AppExecFwk::SupportWindowMode::FLOATING);
1284         }
1285     }
1286     return updateWindowModes;
1287 }
1288 
GetConfigurationFromAbilityInfo()1289 void WindowSceneSessionImpl::GetConfigurationFromAbilityInfo()
1290 {
1291     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(GetContext());
1292     if (abilityContext == nullptr) {
1293         WLOGFE("abilityContext is nullptr");
1294         return;
1295     }
1296     auto abilityInfo = abilityContext->GetAbilityInfo();
1297     if (abilityInfo != nullptr) {
1298         WindowSizeLimits windowSizeLimits = property_->GetWindowSizeLimits();
1299         GetWindowSizeLimits(abilityInfo, windowSizeLimits);
1300         if (property_->IsWindowLimitDisabled()) {
1301             HandleWindowLimitsInCompatibleMode(windowSizeLimits);
1302         }
1303         property_->SetConfigWindowLimitsVP({
1304             windowSizeLimits.maxWindowWidth, windowSizeLimits.maxWindowHeight,
1305             windowSizeLimits.minWindowWidth, windowSizeLimits.minWindowHeight,
1306             static_cast<float>(abilityInfo->maxWindowRatio), static_cast<float>(abilityInfo->minWindowRatio)
1307         });
1308         UpdateWindowSizeLimits();
1309         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
1310         // get support modes configuration
1311         uint32_t windowModeSupportType = 0;
1312         std::vector<AppExecFwk::SupportWindowMode> supportedWindowModes;
1313         property_->GetSupportedWindowModes(supportedWindowModes);
1314         auto size = supportedWindowModes.size();
1315         if (size > 0 && size <= WINDOW_SUPPORT_MODE_MAX_SIZE) {
1316             windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(supportedWindowModes);
1317         } else {
1318             std::vector<AppExecFwk::SupportWindowMode> updateWindowModes =
1319                 ExtractSupportWindowModeFromMetaData(abilityInfo);
1320             if (auto hostSession = GetHostSession()) {
1321                 hostSession->NotifySupportWindowModesChange(updateWindowModes);
1322             };
1323             windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(updateWindowModes);
1324         }
1325         if (windowModeSupportType == 0) {
1326             TLOGI(WmsLogTag::WMS_LAYOUT_PC, "mode config param is 0, all modes is supported");
1327             windowModeSupportType = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
1328         } else {
1329             TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId: %{public}u, windowModeSupportType: %{public}u",
1330                 GetWindowId(), windowModeSupportType);
1331         }
1332         if (property_->IsSupportRotateFullScreen()) {
1333             windowModeSupportType = (WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN |
1334                                      WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING);
1335         }
1336         property_->SetWindowModeSupportType(windowModeSupportType);
1337         // update windowModeSupportType to server
1338         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
1339         bool isWindowModeSupportFullscreen = GetTargetAPIVersion() < 15 ? // 15: isolated version
1340             (windowModeSupportType == WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN) :
1341             (WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
1342             !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING));
1343         auto mainWindow = FindMainWindowWithContext();
1344         bool isAnco = mainWindow != nullptr && mainWindow->IsAnco();
1345         bool onlySupportFullScreen = (isWindowModeSupportFullscreen || isAnco) &&
1346             ((!windowSystemConfig_.IsPhoneWindow() && !windowSystemConfig_.IsPadWindow()) || IsFreeMultiWindowMode());
1347         bool compatibleDisableFullScreen = property_->IsFullScreenDisabled();
1348         if ((onlySupportFullScreen || property_->GetFullScreenStart()) && !compatibleDisableFullScreen) {
1349             TLOGI(WmsLogTag::WMS_LAYOUT_PC, "onlySupportFullScreen:%{public}d fullScreenStart:%{public}d",
1350                 onlySupportFullScreen, property_->GetFullScreenStart());
1351             Maximize(MaximizePresentation::ENTER_IMMERSIVE);
1352         }
1353     }
1354 }
1355 
UpdateConfigVal(uint32_t minVal,uint32_t maxVal,uint32_t configVal,uint32_t defaultVal,float vpr)1356 uint32_t WindowSceneSessionImpl::UpdateConfigVal(uint32_t minVal, uint32_t maxVal, uint32_t configVal,
1357                                                  uint32_t defaultVal, float vpr)
1358 {
1359     bool validConfig = minVal < (configVal * vpr) && (configVal * vpr) < maxVal;
1360     return validConfig ? static_cast<uint32_t>(configVal * vpr) : static_cast<uint32_t>(defaultVal * vpr);
1361 }
1362 
GetSystemSizeLimits(uint32_t displayWidth,uint32_t displayHeight,float vpr)1363 WindowLimits WindowSceneSessionImpl::GetSystemSizeLimits(uint32_t displayWidth,
1364     uint32_t displayHeight, float vpr)
1365 {
1366     WindowLimits systemLimits;
1367     systemLimits.maxWidth_ = static_cast<uint32_t>(windowSystemConfig_.maxFloatingWindowSize_ * vpr);
1368     systemLimits.maxHeight_ = static_cast<uint32_t>(windowSystemConfig_.maxFloatingWindowSize_ * vpr);
1369 
1370     if (WindowHelper::IsMainWindow(GetType())) {
1371         systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfMainWindow_,
1372                                                  MIN_FLOATING_WIDTH, vpr);
1373         systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfMainWindow_,
1374                                                   MIN_FLOATING_HEIGHT, vpr);
1375     } else if (WindowHelper::IsSubWindow(GetType())) {
1376         systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfSubWindow_,
1377                                                  MIN_FLOATING_WIDTH, vpr);
1378         systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfSubWindow_,
1379                                                   MIN_FLOATING_HEIGHT, vpr);
1380     } else if (WindowHelper::IsDialogWindow(GetType())) {
1381         systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfDialogWindow_,
1382                                                  MIN_FLOATING_WIDTH, vpr);
1383         systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfDialogWindow_,
1384                                                   MIN_FLOATING_HEIGHT, vpr);
1385     } else if (WindowHelper::IsSystemWindow(GetType())) {
1386         systemLimits.minWidth_ = 0;
1387         systemLimits.minHeight_ = 0;
1388     } else {
1389         systemLimits.minWidth_ = static_cast<uint32_t>(MIN_FLOATING_WIDTH * vpr);
1390         systemLimits.minHeight_ = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * vpr);
1391     }
1392     TLOGI(WmsLogTag::WMS_LAYOUT, "maxWidth: %{public}u, minWidth: %{public}u, maxHeight: %{public}u, "
1393         "minHeight: %{public}u, maxFloatingWindowSize: %{public}u, vpr: %{public}f", systemLimits.maxWidth_,
1394         systemLimits.minWidth_, systemLimits.maxHeight_, systemLimits.minHeight_,
1395         windowSystemConfig_.maxFloatingWindowSize_, vpr);
1396     return systemLimits;
1397 }
1398 
1399 /** @note @window.layout */
CalculateNewLimitsByLimits(WindowLimits & newLimits,WindowLimits & customizedLimits,float & virtualPixelRatio)1400 void WindowSceneSessionImpl::CalculateNewLimitsByLimits(
1401     WindowLimits& newLimits, WindowLimits& customizedLimits, float& virtualPixelRatio)
1402 {
1403     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
1404     if (display == nullptr) {
1405         TLOGE(WmsLogTag::WMS_LAYOUT, "display is null");
1406         return;
1407     }
1408     auto displayInfo = display->GetDisplayInfo();
1409     if (displayInfo == nullptr) {
1410         TLOGE(WmsLogTag::WMS_LAYOUT, "displayInfo is null");
1411         return;
1412     }
1413     uint32_t displayWidth = static_cast<uint32_t>(displayInfo->GetWidth());
1414     uint32_t displayHeight = static_cast<uint32_t>(displayInfo->GetHeight());
1415     if (displayWidth == 0 || displayHeight == 0) {
1416         return;
1417     }
1418     virtualPixelRatio = GetVirtualPixelRatio(displayInfo);
1419     const auto& systemLimits = GetSystemSizeLimits(displayWidth, displayHeight, virtualPixelRatio);
1420     if (userLimitsSet_) {
1421         customizedLimits = property_->GetUserWindowLimits();
1422     } else {
1423         customizedLimits = property_->GetConfigWindowLimitsVP();
1424         customizedLimits.maxWidth_ = static_cast<uint32_t>(customizedLimits.maxWidth_ * virtualPixelRatio);
1425         customizedLimits.maxHeight_ = static_cast<uint32_t>(customizedLimits.maxHeight_ * virtualPixelRatio);
1426         customizedLimits.minWidth_ = static_cast<uint32_t>(customizedLimits.minWidth_ * virtualPixelRatio);
1427         customizedLimits.minHeight_ = static_cast<uint32_t>(customizedLimits.minHeight_ * virtualPixelRatio);
1428     }
1429     newLimits = systemLimits;
1430     uint32_t limitMinWidth = systemLimits.minWidth_;
1431     uint32_t limitMinHeight = systemLimits.minHeight_;
1432     if (forceLimits_ && IsPcOrFreeMultiWindowCapabilityEnabled()) {
1433         uint32_t forceLimitMinWidth = static_cast<uint32_t>(FORCE_LIMIT_MIN_FLOATING_WIDTH * virtualPixelRatio);
1434         uint32_t forceLimitMinHeight = static_cast<uint32_t>(FORCE_LIMIT_MIN_FLOATING_HEIGHT * virtualPixelRatio);
1435         limitMinWidth = std::min(forceLimitMinWidth, limitMinWidth);
1436         limitMinHeight = std::min(forceLimitMinHeight, limitMinHeight);
1437         newLimits.minWidth_ = limitMinWidth;
1438         newLimits.minHeight_ = limitMinHeight;
1439     }
1440     // calculate new limit size
1441     if (limitMinWidth <= customizedLimits.maxWidth_ &&
1442         customizedLimits.maxWidth_ <= systemLimits.maxWidth_) {
1443         newLimits.maxWidth_ = customizedLimits.maxWidth_;
1444     }
1445     if (limitMinHeight <= customizedLimits.maxHeight_ &&
1446         customizedLimits.maxHeight_ <= systemLimits.maxHeight_) {
1447         newLimits.maxHeight_ = customizedLimits.maxHeight_;
1448     }
1449     if (limitMinWidth <= customizedLimits.minWidth_ &&
1450         customizedLimits.minWidth_ <= newLimits.maxWidth_) {
1451         newLimits.minWidth_ = customizedLimits.minWidth_;
1452     }
1453     if (limitMinHeight <= customizedLimits.minHeight_ &&
1454         customizedLimits.minHeight_ <= newLimits.maxHeight_) {
1455         newLimits.minHeight_ = customizedLimits.minHeight_;
1456     }
1457 }
1458 
1459 /** @note @window.layout */
CalculateNewLimitsByRatio(WindowLimits & newLimits,WindowLimits & customizedLimits)1460 void WindowSceneSessionImpl::CalculateNewLimitsByRatio(WindowLimits& newLimits, WindowLimits& customizedLimits)
1461 {
1462     newLimits.maxRatio_ = customizedLimits.maxRatio_;
1463     newLimits.minRatio_ = customizedLimits.minRatio_;
1464 
1465     // calculate new limit ratio
1466     double maxRatio = FLT_MAX;
1467     double minRatio = 0.0f;
1468     if (newLimits.minHeight_ != 0) {
1469         maxRatio = static_cast<double>(newLimits.maxWidth_) / static_cast<double>(newLimits.minHeight_);
1470     }
1471     if (newLimits.maxHeight_ != 0) {
1472         minRatio = static_cast<double>(newLimits.minWidth_) / static_cast<double>(newLimits.maxHeight_);
1473     }
1474     if (!MathHelper::GreatNotEqual(minRatio, customizedLimits.maxRatio_) &&
1475         !MathHelper::GreatNotEqual(customizedLimits.maxRatio_, maxRatio)) {
1476         maxRatio = customizedLimits.maxRatio_;
1477     }
1478     if (!MathHelper::GreatNotEqual(minRatio, customizedLimits.minRatio_) &&
1479         !MathHelper::GreatNotEqual(customizedLimits.minRatio_, maxRatio)) {
1480         minRatio = customizedLimits.minRatio_;
1481     }
1482 
1483     // recalculate limit size by new ratio
1484     double newMaxWidthFloat = static_cast<double>(newLimits.maxHeight_) * maxRatio;
1485     uint32_t newMaxWidth = (newMaxWidthFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1486         std::round(newMaxWidthFloat);
1487     newLimits.maxWidth_ = std::min(newMaxWidth, newLimits.maxWidth_);
1488 
1489     double newMinWidthFloat = static_cast<double>(newLimits.minHeight_) * minRatio;
1490     uint32_t newMinWidth = (newMinWidthFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1491         std::round(newMinWidthFloat);
1492     newLimits.minWidth_ = std::max(newMinWidth, newLimits.minWidth_);
1493 
1494     double newMaxHeightFloat = MathHelper::NearZero(minRatio) ? UINT32_MAX :
1495         static_cast<double>(newLimits.maxWidth_) / minRatio;
1496     uint32_t newMaxHeight = (newMaxHeightFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1497         std::round(newMaxHeightFloat);
1498     newLimits.maxHeight_ = std::min(newMaxHeight, newLimits.maxHeight_);
1499 
1500     double newMinHeightFloat = MathHelper::NearZero(maxRatio) ? UINT32_MAX :
1501         static_cast<double>(newLimits.minWidth_) / maxRatio;
1502     uint32_t newMinHeight = (newMinHeightFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1503         std::round(newMinHeightFloat);
1504     newLimits.minHeight_ = std::max(newMinHeight, newLimits.minHeight_);
1505 }
1506 
1507 /** @note @window.layout */
UpdateWindowSizeLimits()1508 void WindowSceneSessionImpl::UpdateWindowSizeLimits()
1509 {
1510     WindowLimits customizedLimits;
1511     WindowLimits newLimits;
1512     float virtualPixelRatio = 0.0f;
1513 
1514     CalculateNewLimitsByLimits(newLimits, customizedLimits, virtualPixelRatio);
1515     if (MathHelper::NearZero(virtualPixelRatio)) {
1516         return;
1517     }
1518     newLimits.vpRatio_ = virtualPixelRatio;
1519     CalculateNewLimitsByRatio(newLimits, customizedLimits);
1520 
1521     property_->SetWindowLimits(newLimits);
1522     property_->SetLastLimitsVpr(virtualPixelRatio);
1523 }
1524 
PreLayoutOnShow(WindowType type,const sptr<DisplayInfo> & info)1525 void WindowSceneSessionImpl::PreLayoutOnShow(WindowType type, const sptr<DisplayInfo>& info)
1526 {
1527     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1528     if (uiContent == nullptr) {
1529         TLOGW(WmsLogTag::WMS_LIFE, "uiContent is null");
1530         return;
1531     }
1532     const auto& requestRect = GetRequestRect();
1533     TLOGI(WmsLogTag::WMS_LIFE, "name: %{public}s, id: %{public}d, type: %{public}u, requestRect:%{public}s",
1534         property_->GetWindowName().c_str(), GetPersistentId(), type, requestRect.ToString().c_str());
1535     if (requestRect.width_ != 0 && requestRect.height_ != 0) {
1536         UpdateViewportConfig(requestRect, WindowSizeChangeReason::RESIZE, nullptr, info);
1537         if (auto hostSession = GetHostSession()) {
1538             WSRect wsRect = { requestRect.posX_, requestRect.posY_, requestRect.width_, requestRect.height_ };
1539             if (type != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1540                 SetNotifySizeChangeFlag(true);
1541                 property_->SetWindowRect(requestRect);
1542             }
1543             hostSession->UpdateClientRect(wsRect);
1544         } else {
1545             TLOGE(WmsLogTag::WMS_LAYOUT, "hostSession is null");
1546         }
1547     }
1548     uiContent->PreLayout();
1549 }
1550 
Show(uint32_t reason,bool withAnimation,bool withFocus)1551 WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus)
1552 {
1553     return Show(reason, withAnimation, withFocus, false);
1554 }
1555 
Show(uint32_t reason,bool withAnimation,bool withFocus,bool waitAttach)1556 WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus, bool waitAttach)
1557 {
1558     if (reason == static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH)) {
1559         TLOGI(WmsLogTag::WMS_MULTI_USER, "Switch to current user, NotifyAfterForeground");
1560         NotifyAfterForeground(true, false);
1561         NotifyAfterDidForeground(reason);
1562         return WMError::WM_OK;
1563     }
1564     const auto type = GetType();
1565     if (IsWindowSessionInvalid()) {
1566         TLOGI(WmsLogTag::WMS_LIFE, "Window show failed, session is invalid, name: %{public}s, id: %{public}d",
1567             property_->GetWindowName().c_str(), GetPersistentId());
1568         return WMError::WM_ERROR_INVALID_WINDOW;
1569     }
1570     auto hostSession = GetHostSession();
1571     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1572 
1573     TLOGI(WmsLogTag::WMS_LIFE, "Window show [name: %{public}s, id: %{public}d, type: %{public}u], reason: %{public}u,"
1574         " state:%{public}u, requestState:%{public}u", property_->GetWindowName().c_str(),
1575         property_->GetPersistentId(), type, reason, state_, requestState_);
1576     auto isDecorEnable = IsDecorEnable();
1577     UpdateDecorEnableToAce(isDecorEnable);
1578     property_->SetDecorEnable(isDecorEnable);
1579 
1580     if (state_ == WindowState::STATE_SHOWN) {
1581         TLOGI(WmsLogTag::WMS_LIFE, "window is already shown [name:%{public}s, id:%{public}d, type: %{public}u]",
1582             property_->GetWindowName().c_str(), property_->GetPersistentId(), type);
1583         if (WindowHelper::IsMainWindow(type)) {
1584             hostSession->RaiseAppMainWindowToTop();
1585         }
1586         NotifyAfterForeground(true, false);
1587         NotifyAfterDidForeground(reason);
1588         RefreshNoInteractionTimeoutMonitor();
1589         return WMError::WM_OK;
1590     }
1591     auto displayInfo = GetDisplayInfo();
1592     if (displayInfo == nullptr) {
1593         TLOGE(WmsLogTag::WMS_LIFE, "Window show failed, displayInfo is null, name: %{public}s, id: %{public}d",
1594             property_->GetWindowName().c_str(), GetPersistentId());
1595         return WMError::WM_ERROR_NULLPTR;
1596     }
1597     float density = GetVirtualPixelRatio(displayInfo);
1598     if (!MathHelper::NearZero(virtualPixelRatio_ - density) ||
1599         !MathHelper::NearZero(property_->GetLastLimitsVpr() - density)) {
1600         UpdateDensityInner(displayInfo);
1601     }
1602 
1603     WMError ret = UpdateAnimationFlagProperty(withAnimation);
1604     if (ret != WMError::WM_OK) {
1605         TLOGE(WmsLogTag::WMS_LIFE, "Window show failed, UpdateProperty failed, ret: %{public}d, name: %{public}s"
1606             ", id: %{public}d", static_cast<int32_t>(ret), property_->GetWindowName().c_str(), GetPersistentId());
1607         return ret;
1608     }
1609     UpdateTitleButtonVisibility();
1610     property_->SetFocusableOnShow(withFocus);
1611     if (WindowHelper::IsMainWindow(type)) {
1612         ret = static_cast<WMError>(hostSession->Foreground(property_, true, identityToken_));
1613     } else if (WindowHelper::IsSystemOrSubWindow(type)) {
1614         if (waitAttach && !lifecycleCallback_ && !WindowHelper::IsKeyboardWindow(type) &&
1615             SysCapUtil::GetBundleName() != AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
1616             lifecycleCallback_ = sptr<LifecycleFutureCallback>::MakeSptr();
1617             TLOGI(WmsLogTag::WMS_LIFE, "init lifecycleCallback, id:%{public}d", GetPersistentId());
1618         }
1619         if (waitAttach && lifecycleCallback_) {
1620             lifecycleCallback_->ResetAttachLock();
1621         }
1622         PreLayoutOnShow(type, displayInfo);
1623         // Add maintenance logs before the IPC process.
1624         TLOGD(WmsLogTag::WMS_LIFE, "Show session [name: %{public}s, id: %{public}d]",
1625             property_->GetWindowName().c_str(), GetPersistentId());
1626         ret = static_cast<WMError>(hostSession->Show(property_));
1627     } else {
1628         ret = WMError::WM_ERROR_INVALID_WINDOW;
1629     }
1630     RecordLifeCycleExceptionEvent(LifeCycleEvent::SHOW_EVENT, ret);
1631     if (ret == WMError::WM_OK) {
1632         // update sub window state
1633         UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_SHOWN);
1634         state_ = WindowState::STATE_SHOWN;
1635         requestState_ = WindowState::STATE_SHOWN;
1636         NotifyAfterForeground(true, true, waitAttach);
1637         NotifyAfterDidForeground(reason);
1638         NotifyFreeMultiWindowModeResume();
1639         RefreshNoInteractionTimeoutMonitor();
1640         TLOGI(WmsLogTag::WMS_LIFE, "Window show success [name:%{public}s, id:%{public}d, type:%{public}u]",
1641             property_->GetWindowName().c_str(), GetPersistentId(), type);
1642     } else {
1643         NotifyForegroundFailed(ret);
1644         TLOGI(WmsLogTag::WMS_LIFE, "Window show failed with errcode: %{public}d, name:%{public}s, id:%{public}d",
1645             static_cast<int32_t>(ret), property_->GetWindowName().c_str(), GetPersistentId());
1646     }
1647     NotifyWindowStatusChange(GetWindowMode());
1648     NotifyWindowStatusDidChange(GetWindowMode());
1649     NotifyDisplayInfoChange(displayInfo);
1650     return ret;
1651 }
1652 
GetDisplayInfo() const1653 sptr<DisplayInfo> WindowSceneSessionImpl::GetDisplayInfo() const
1654 {
1655     const auto type = GetType();
1656     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
1657     if (display == nullptr && (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
1658         type == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || WindowHelper::IsSubWindow(type))) {
1659         display = SingletonContainer::Get<DisplayManager>().GetDefaultDisplay();
1660         if (display != nullptr) {
1661             property_->SetDisplayId(display->GetId());
1662             TLOGI(WmsLogTag::WMS_KEYBOARD, "use default display id: %{public}" PRIu64, display->GetId());
1663         }
1664     }
1665     if (display == nullptr) {
1666         TLOGE(WmsLogTag::WMS_LIFE, "failed, display is null, name: %{public}s, id: %{public}d",
1667             property_->GetWindowName().c_str(), GetPersistentId());
1668         return nullptr;
1669     }
1670     return display->GetDisplayInfo();
1671 }
1672 
ShowKeyboard(KeyboardEffectOption effectOption)1673 WMError WindowSceneSessionImpl::ShowKeyboard(KeyboardEffectOption effectOption)
1674 {
1675     TLOGI(WmsLogTag::WMS_KEYBOARD, "Effect option: %{public}s", effectOption.ToString().c_str());
1676     if (effectOption.viewMode_ >= KeyboardViewMode::VIEW_MODE_END) {
1677         TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid view mode: %{public}u. Use default mode",
1678             static_cast<uint32_t>(effectOption.viewMode_));
1679         effectOption.viewMode_ = KeyboardViewMode::NON_IMMERSIVE_MODE;
1680     }
1681     if (effectOption.flowLightMode_ >= KeyboardFlowLightMode::END) {
1682         TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid flow light mode: %{public}u. Use default mode",
1683             static_cast<uint32_t>(effectOption.flowLightMode_));
1684         effectOption.flowLightMode_ = KeyboardFlowLightMode::NONE;
1685     }
1686     if (effectOption.gradientMode_ >= KeyboardGradientMode::END) {
1687         TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid gradient mode: %{public}u. Use default mode",
1688             static_cast<uint32_t>(effectOption.gradientMode_));
1689         effectOption.gradientMode_ = KeyboardGradientMode::NONE;
1690     }
1691     property_->SetKeyboardEffectOption(effectOption);
1692     return Show();
1693 }
1694 
NotifyFreeMultiWindowModeResume()1695 void WindowSceneSessionImpl::NotifyFreeMultiWindowModeResume()
1696 {
1697     TLOGI(WmsLogTag::WMS_MAIN, "IsPcMode %{public}d, isColdStart %{public}d", IsPcOrFreeMultiWindowCapabilityEnabled(),
1698         isColdStart_);
1699     if (IsPcOrFreeMultiWindowCapabilityEnabled() && !isColdStart_) {
1700         isDidForeground_ = true;
1701         NotifyAfterLifecycleResumed();
1702     }
1703 }
1704 
Resume()1705 void WindowSceneSessionImpl::Resume()
1706 {
1707     TLOGI(WmsLogTag::WMS_LIFE, "in, isColdStart: %{public}d, isDidForeground: %{public}d",
1708         isColdStart_, isDidForeground_);
1709     isDidForeground_ = true;
1710     isColdStart_ = false;
1711     NotifyAfterLifecycleResumed();
1712 }
1713 
Pause()1714 void WindowSceneSessionImpl::Pause()
1715 {
1716     TLOGI(WmsLogTag::WMS_LIFE, "in, isColdStart: %{public}d", isColdStart_);
1717     isColdStart_ = false;
1718     NotifyAfterLifecyclePaused();
1719 }
1720 
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)1721 WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
1722 {
1723     return Hide(reason, withAnimation, isFromInnerkits, false);
1724 }
1725 
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits,bool waitDetach)1726 WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits, bool waitDetach)
1727 {
1728     if (reason == static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH)) {
1729         TLOGI(WmsLogTag::WMS_MULTI_USER, "Switch to another user, NotifyAfterBackground");
1730         NotifyAfterBackground(true, false);
1731         NotifyAfterDidBackground(reason);
1732         return WMError::WM_OK;
1733     }
1734 
1735     const auto type = GetType();
1736     TLOGI(WmsLogTag::WMS_LIFE, "Window hide [id:%{public}d, type: %{public}d, reason:%{public}u, state:%{public}u, "
1737         "requestState:%{public}u", GetPersistentId(), type, reason, state_, requestState_);
1738     if (IsWindowSessionInvalid()) {
1739         TLOGI(WmsLogTag::WMS_LIFE, "session is invalid, id:%{public}d", GetPersistentId());
1740         return WMError::WM_ERROR_INVALID_WINDOW;
1741     }
1742     auto hostSession = GetHostSession();
1743     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1744 
1745     WindowState validState = state_;
1746     if (WindowHelper::IsSubWindow(type) || WindowHelper::IsDialogWindow(type)) {
1747         validState = requestState_;
1748     }
1749     if (validState == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
1750         TLOGD(WmsLogTag::WMS_LIFE, "window is alreay hidden, id:%{public}d", property_->GetPersistentId());
1751         NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
1752         return WMError::WM_OK;
1753     }
1754 
1755     WMError res = UpdateAnimationFlagProperty(withAnimation);
1756     if (res != WMError::WM_OK) {
1757         TLOGE(WmsLogTag::WMS_LIFE, "UpdateProperty failed with errCode:%{public}d", static_cast<int32_t>(res));
1758         return res;
1759     }
1760 
1761     /*
1762      * main window no need to notify host, since host knows hide first
1763      * main window notify host temporarily, since host background may failed
1764      * need to SetActive(false) for host session before background
1765      */
1766 
1767     if (WindowHelper::IsMainWindow(type)) {
1768         res = static_cast<WMError>(SetActive(false));
1769         if (res != WMError::WM_OK) {
1770             return res;
1771         }
1772         res = static_cast<WMError>(hostSession->Background(true, identityToken_));
1773     } else if (WindowHelper::IsSystemOrSubWindow(type)) {
1774         if (waitDetach && !lifecycleCallback_ && !WindowHelper::IsKeyboardWindow(type) &&
1775             SysCapUtil::GetBundleName() != AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
1776             lifecycleCallback_ = sptr<LifecycleFutureCallback>::MakeSptr();
1777             TLOGI(WmsLogTag::WMS_LIFE, "init lifecycleCallback, id:%{public}d", GetPersistentId());
1778         }
1779         if (waitDetach && lifecycleCallback_) {
1780             lifecycleCallback_->ResetDetachLock();
1781         }
1782         res = static_cast<WMError>(hostSession->Hide());
1783     } else {
1784         res = WMError::WM_ERROR_INVALID_WINDOW;
1785     }
1786 
1787     RecordLifeCycleExceptionEvent(LifeCycleEvent::HIDE_EVENT, res);
1788     if (res == WMError::WM_OK) {
1789         // update sub window state if this is main window
1790         UpdateSubWindowState(type, waitDetach);
1791         NotifyAfterDidBackground(reason);
1792         state_ = WindowState::STATE_HIDDEN;
1793         requestState_ = WindowState::STATE_HIDDEN;
1794         isDidForeground_ = false;
1795         if (!interactive_) {
1796             hasFirstNotifyInteractive_ = false;
1797         }
1798     }
1799     uint32_t animationFlag = property_->GetAnimationFlag();
1800     if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
1801         animationTransitionController_->AnimationForHidden();
1802         RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
1803     }
1804     NotifyWindowStatusChange(GetWindowMode());
1805     NotifyWindowStatusDidChange(GetWindowMode());
1806     escKeyEventTriggered_ = false;
1807     TLOGI(WmsLogTag::WMS_LIFE, "Window hide success [id:%{public}d, type: %{public}d",
1808         property_->GetPersistentId(), type);
1809     return res;
1810 }
1811 
NotifyDrawingCompleted()1812 WMError WindowSceneSessionImpl::NotifyDrawingCompleted()
1813 {
1814     if (IsWindowSessionInvalid()) {
1815         TLOGE(WmsLogTag::WMS_LIFE, "session is invalid, id:%{public}d", GetPersistentId());
1816         return WMError::WM_ERROR_INVALID_WINDOW;
1817     }
1818     auto hostSession = GetHostSession();
1819     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1820     WMError res = WindowHelper::IsMainWindow(GetType()) ?
1821                   static_cast<WMError>(hostSession->DrawingCompleted()) :
1822                   WMError::WM_ERROR_INVALID_WINDOW;
1823     if (res == WMError::WM_OK) {
1824         TLOGI(WmsLogTag::WMS_LIFE, "success id:%{public}d", GetPersistentId());
1825     }
1826     return res;
1827 }
1828 
NotifyRemoveStartingWindow()1829 WMError WindowSceneSessionImpl::NotifyRemoveStartingWindow()
1830 {
1831     if (IsWindowSessionInvalid()) {
1832         TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "session is invalid, id:%{public}d", GetPersistentId());
1833         return WMError::WM_ERROR_INVALID_WINDOW;
1834     }
1835     auto hostSession = GetHostSession();
1836     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1837     WMError res = WindowHelper::IsMainWindow(GetType()) ?
1838                   static_cast<WMError>(hostSession->RemoveStartingWindow()) :
1839                   WMError::WM_ERROR_INVALID_WINDOW;
1840     if (res == WMError::WM_OK) {
1841         TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "success id:%{public}d", GetPersistentId());
1842     }
1843     return res;
1844 }
1845 
UpdateSubWindowState(const WindowType & type,bool waitDetach)1846 void WindowSceneSessionImpl::UpdateSubWindowState(const WindowType& type, bool waitDetach)
1847 {
1848     UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_HIDDEN);
1849     if (WindowHelper::IsSubWindow(type)) {
1850         if (state_ == WindowState::STATE_SHOWN) {
1851             NotifyAfterBackground(true, true, waitDetach);
1852         }
1853     } else {
1854         NotifyAfterBackground(true, true, waitDetach);
1855     }
1856 }
1857 
PreProcessCreate()1858 void WindowSceneSessionImpl::PreProcessCreate()
1859 {
1860     SetDefaultProperty();
1861 }
1862 
SetDefaultProperty()1863 void WindowSceneSessionImpl::SetDefaultProperty()
1864 {
1865     switch (property_->GetWindowType()) {
1866         case WindowType::WINDOW_TYPE_TOAST:
1867         case WindowType::WINDOW_TYPE_FLOAT:
1868         case WindowType::WINDOW_TYPE_SYSTEM_FLOAT:
1869         case WindowType::WINDOW_TYPE_FLOAT_CAMERA:
1870         case WindowType::WINDOW_TYPE_VOICE_INTERACTION:
1871         case WindowType::WINDOW_TYPE_SEARCHING_BAR:
1872         case WindowType::WINDOW_TYPE_SCREENSHOT:
1873         case WindowType::WINDOW_TYPE_GLOBAL_SEARCH:
1874         case WindowType::WINDOW_TYPE_DIALOG:
1875         case WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW:
1876         case WindowType::WINDOW_TYPE_PANEL:
1877         case WindowType::WINDOW_TYPE_LAUNCHER_DOCK:
1878         case WindowType::WINDOW_TYPE_WALLET_SWIPE_CARD:
1879         case WindowType::WINDOW_TYPE_MUTISCREEN_COLLABORATION:
1880         case WindowType::WINDOW_TYPE_MAGNIFICATION:
1881         case WindowType::WINDOW_TYPE_MAGNIFICATION_MENU:
1882         case WindowType::WINDOW_TYPE_SELECTION:
1883         case WindowType::WINDOW_TYPE_DYNAMIC: {
1884             property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1885             break;
1886         }
1887         case WindowType::WINDOW_TYPE_VOLUME_OVERLAY:
1888         case WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT:
1889         case WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR:
1890         case WindowType::WINDOW_TYPE_DOCK_SLICE:
1891         case WindowType::WINDOW_TYPE_STATUS_BAR:
1892         case WindowType::WINDOW_TYPE_NAVIGATION_BAR:
1893         case WindowType::WINDOW_TYPE_FLOAT_NAVIGATION: {
1894             property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1895             property_->SetFocusable(false);
1896             break;
1897         }
1898         case WindowType::WINDOW_TYPE_SYSTEM_TOAST: {
1899             property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1900             property_->SetTouchable(false);
1901             property_->SetFocusable(false);
1902             break;
1903         }
1904         case WindowType::WINDOW_TYPE_POINTER: {
1905             property_->SetFocusable(false);
1906             break;
1907         }
1908         case WindowType::WINDOW_TYPE_SCREEN_CONTROL: {
1909             property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1910             property_->SetTouchable(false);
1911             property_->SetFocusable(false);
1912             SetAlpha(0);
1913             break;
1914         }
1915         default:
1916             break;
1917     }
1918 }
1919 
DestroyInner(bool needNotifyServer)1920 WMError WindowSceneSessionImpl::DestroyInner(bool needNotifyServer)
1921 {
1922     WMError ret = WMError::WM_OK;
1923     if (!WindowHelper::IsMainWindow(GetType()) && needNotifyServer) {
1924         if (WindowHelper::IsSystemWindow(GetType())) {
1925             // main window no need to notify host, since host knows hide first
1926             ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1927         } else if (WindowHelper::IsSubWindow(GetType()) && !property_->GetIsUIExtFirstSubWindow()) {
1928             auto parentSession = FindParentSessionByParentId(GetParentId());
1929             if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
1930                 return WMError::WM_ERROR_NULLPTR;
1931             }
1932             ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1933         } else if (property_->GetIsUIExtFirstSubWindow()) {
1934             ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1935         }
1936     }
1937     if (ret != WMError::WM_OK) {
1938         TLOGE(WmsLogTag::WMS_LIFE, "DestroyInner fail, ret:%{public}d", ret);
1939         return ret;
1940     }
1941 
1942     if (WindowHelper::IsMainWindow(GetType())) {
1943         if (auto hostSession = GetHostSession()) {
1944             ret = static_cast<WMError>(hostSession->Disconnect(true, identityToken_));
1945         }
1946     }
1947     return ret;
1948 }
1949 
SyncDestroyAndDisconnectSpecificSession(int32_t persistentId)1950 WMError WindowSceneSessionImpl::SyncDestroyAndDisconnectSpecificSession(int32_t persistentId)
1951 {
1952     WMError ret = WMError::WM_OK;
1953     if (SysCapUtil::GetBundleName() == AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
1954         TLOGI(WmsLogTag::WMS_LIFE, "Destroy window is scb window");
1955         ret = SingletonContainer::Get<WindowAdapter>().DestroyAndDisconnectSpecificSession(persistentId);
1956         return ret;
1957     }
1958     sptr<PatternDetachCallback> callback = sptr<PatternDetachCallback>::MakeSptr();
1959     ret = SingletonContainer::Get<WindowAdapter>().DestroyAndDisconnectSpecificSessionWithDetachCallback(persistentId,
1960         callback->AsObject());
1961     if (ret != WMError::WM_OK) {
1962         return ret;
1963     }
1964     auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1965         std::chrono::system_clock::now().time_since_epoch()).count();
1966     callback->GetResult(WINDOW_DETACH_TIMEOUT);
1967     auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1968         std::chrono::system_clock::now().time_since_epoch()).count();
1969     auto waitTime = endTime - startTime;
1970     if (waitTime >= WINDOW_DETACH_TIMEOUT) {
1971         TLOGW(WmsLogTag::WMS_LIFE, "Destroy window timeout, persistentId:%{public}d", persistentId);
1972         callback->GetResult(std::numeric_limits<int>::max());
1973     }
1974     TLOGI(WmsLogTag::WMS_LIFE, "Destroy window persistentId:%{public}d waitTime:%{public}lld", persistentId, waitTime);
1975     return ret;
1976 }
1977 
DestroyHookWindow()1978 WMError WindowSceneSessionImpl::DestroyHookWindow()
1979 {
1980     TLOGI(WmsLogTag::WMS_LIFE, "in");
1981     InputTransferStation::GetInstance().RemoveInputWindow(GetPersistentId());
1982     if (IsWindowSessionInvalid()) {
1983         TLOGE(WmsLogTag::WMS_LIFE, "session invalid, id: %{public}d", GetPersistentId());
1984         return WMError::WM_ERROR_INVALID_WINDOW;
1985     }
1986     {
1987         std::lock_guard<std::recursive_mutex> lock(mutex_);
1988         state_ = WindowState::STATE_DESTROYED;
1989         requestState_ = WindowState::STATE_DESTROYED;
1990     }
1991 
1992     DestroySubWindow();
1993     {
1994         std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
1995         windowSessionMap_.erase(property_->GetWindowName());
1996     }
1997     {
1998         std::lock_guard<std::mutex> lock(hostSessionMutex_);
1999         hostSession_ = nullptr;
2000     }
2001     NotifyAfterDestroy();
2002     ClearListenersById(GetPersistentId());
2003     ClearVsyncStation();
2004     SetUIContentComplete();
2005     TLOGI(WmsLogTag::WMS_LIFE, "Destroy hook window success, id: %{public}d", property_->GetPersistentId());
2006     return WMError::WM_OK;
2007 }
2008 
GetWindowLifecycleInfo() const2009 WindowLifeCycleInfo WindowSceneSessionImpl::GetWindowLifecycleInfo() const
2010 {
2011     WindowLifeCycleInfo lifeCycleInfo;
2012     lifeCycleInfo.windowId = GetPersistentId();
2013     lifeCycleInfo.windowType = GetType();
2014     lifeCycleInfo.windowName = GetWindowName();
2015     return lifeCycleInfo;
2016 }
2017 
Destroy(bool needNotifyServer,bool needClearListener,uint32_t reason)2018 WMError WindowSceneSessionImpl::Destroy(bool needNotifyServer, bool needClearListener, uint32_t reason)
2019 {
2020     TLOGI(WmsLogTag::WMS_LIFE, "Destroy start, id:%{public}d, state:%{public}u, needNotifyServer:%{public}d, "
2021         "needClearListener:%{public}d, reason:%{public}u", GetPersistentId(), state_, needNotifyServer,
2022         needClearListener, reason);
2023     if (reason == static_cast<uint32_t>(WindowStateChangeReason::ABILITY_HOOK)) {
2024         return DestroyHookWindow();
2025     }
2026     InputTransferStation::GetInstance().RemoveInputWindow(GetPersistentId());
2027     if (IsWindowSessionInvalid()) {
2028         TLOGE(WmsLogTag::WMS_LIFE, "session invalid, id: %{public}d", GetPersistentId());
2029         return WMError::WM_ERROR_INVALID_WINDOW;
2030     }
2031     WindowInspector::GetInstance().UnregisterGetWMSWindowListCallback(GetWindowId());
2032     SingletonContainer::Get<WindowAdapter>().UnregisterSessionRecoverCallbackFunc(property_->GetPersistentId());
2033 
2034     auto ret = DestroyInner(needNotifyServer);
2035     RecordLifeCycleExceptionEvent(LifeCycleEvent::DESTROY_EVENT, ret);
2036     if (ret != WMError::WM_OK && ret != WMError::WM_ERROR_NULLPTR) { // nullptr means no session in server
2037         WLOGFW("Destroy window failed, id: %{public}d", GetPersistentId());
2038         return ret;
2039     }
2040     WindowLifeCycleInfo windowLifeCycleInfo = GetWindowLifecycleInfo();
2041     SingletonContainer::Get<WindowManager>().NotifyWMSWindowDestroyed(windowLifeCycleInfo);
2042 
2043     // delete after replace WSError with WMError
2044     NotifyBeforeDestroy(GetWindowName());
2045     {
2046         std::lock_guard<std::recursive_mutex> lock(mutex_);
2047         state_ = WindowState::STATE_DESTROYED;
2048         requestState_ = WindowState::STATE_DESTROYED;
2049     }
2050 
2051     DestroySubWindow();
2052 	{
2053         std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
2054         windowSessionMap_.erase(property_->GetWindowName());
2055 	}
2056     {
2057         std::lock_guard<std::mutex> lock(hostSessionMutex_);
2058         hostSession_ = nullptr;
2059     }
2060     NotifyAfterDestroy();
2061     if (needClearListener) {
2062         ClearListenersById(GetPersistentId());
2063     }
2064     auto context = GetContext();
2065     if (context) {
2066         context.reset();
2067     }
2068     ClearVsyncStation();
2069     SetUIContentComplete();
2070     surfaceNode_ = nullptr;
2071     TLOGI(WmsLogTag::WMS_LIFE, "Destroy success, id: %{public}d", property_->GetPersistentId());
2072     return WMError::WM_OK;
2073 }
2074 
2075 /** @note @window.layout */
CheckMoveConfiguration(MoveConfiguration & moveConfiguration)2076 void WindowSceneSessionImpl::CheckMoveConfiguration(MoveConfiguration& moveConfiguration)
2077 {
2078     std::vector<DisplayId> displayIds = SingletonContainer::Get<DisplayManagerAdapter>().GetAllDisplayIds();
2079     if (std::find(displayIds.begin(), displayIds.end(), moveConfiguration.displayId) ==
2080         displayIds.end()) { // need to be found in displayIds, otherwise the value is DISPLAY_ID_INVALID
2081         TLOGD(WmsLogTag::WMS_LAYOUT, "Id:%{public}d not find displayId moveConfiguration %{public}s",
2082             property_->GetPersistentId(), moveConfiguration.ToString().c_str());
2083         moveConfiguration.displayId = DISPLAY_ID_INVALID;
2084     }
2085 }
2086 
2087 /** @note @window.layout */
MoveTo(int32_t x,int32_t y,bool isMoveToGlobal,MoveConfiguration moveConfiguration)2088 WMError WindowSceneSessionImpl::MoveTo(int32_t x, int32_t y, bool isMoveToGlobal, MoveConfiguration moveConfiguration)
2089 {
2090     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d MoveTo %{public}d %{public}d isMoveToGlobal %{public}d "
2091         "moveConfiguration %{public}s", property_->GetPersistentId(), x, y, isMoveToGlobal,
2092         moveConfiguration.ToString().c_str());
2093     if (IsWindowSessionInvalid()) {
2094         return WMError::WM_ERROR_INVALID_WINDOW;
2095     }
2096     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2097         TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
2098         return WMError::WM_ERROR_INVALID_OPERATION;
2099     }
2100     const auto& windowRect = GetRect();
2101     const auto& requestRect = GetRequestRect();
2102     if (WindowHelper::IsSubWindow(GetType())) {
2103         auto mainWindow = FindMainWindowWithContext();
2104         if (mainWindow != nullptr && (mainWindow->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
2105                                       mainWindow->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
2106             if (requestRect.posX_ == x && requestRect.posY_ == y) {
2107                 TLOGW(WmsLogTag::WMS_LAYOUT, "Request same position in multiWindow will not update");
2108                 return WMError::WM_OK;
2109             }
2110         }
2111     }
2112     Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
2113     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
2114         "%{public}s, windowRect: %{public}s, newRect: %{public}s",
2115         property_->GetPersistentId(), state_, GetType(), GetWindowMode(), requestRect.ToString().c_str(),
2116         windowRect.ToString().c_str(), newRect.ToString().c_str());
2117 
2118     property_->SetRequestRect(newRect);
2119 
2120     CheckMoveConfiguration(moveConfiguration);
2121     WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
2122     auto hostSession = GetHostSession();
2123     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2124     auto ret = hostSession->UpdateSessionRect(wsRect, SizeChangeReason::MOVE, isMoveToGlobal, false, moveConfiguration);
2125     return static_cast<WMError>(ret);
2126 }
2127 
MoveWindowToGlobal(int32_t x,int32_t y,MoveConfiguration moveConfiguration)2128 WMError WindowSceneSessionImpl::MoveWindowToGlobal(int32_t x, int32_t y, MoveConfiguration moveConfiguration)
2129 {
2130     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
2131     if (IsWindowSessionInvalid()) {
2132         return WMError::WM_ERROR_INVALID_WINDOW;
2133     }
2134 
2135     if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
2136         TLOGW(WmsLogTag::WMS_LAYOUT, "window should not move, winId:%{public}u, mode:%{public}u",
2137             GetWindowId(), GetWindowMode());
2138         return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
2139     }
2140 
2141     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2142         TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
2143         return WMError::WM_ERROR_INVALID_OPERATION;
2144     }
2145     const auto& windowRect = GetRect();
2146     const auto& requestRect = GetRequestRect();
2147     Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
2148     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
2149         "%{public}s, windowRect: %{public}s, newRect: %{public}s",
2150         property_->GetPersistentId(), state_, GetType(), GetWindowMode(), requestRect.ToString().c_str(),
2151         windowRect.ToString().c_str(), newRect.ToString().c_str());
2152 
2153     property_->SetRequestRect(newRect);
2154 
2155     CheckMoveConfiguration(moveConfiguration);
2156     WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
2157     auto hostSession = GetHostSession();
2158     RectAnimationConfig rectAnimationConfig = moveConfiguration.rectAnimationConfig;
2159     SizeChangeReason reason = rectAnimationConfig.duration > 0 ? SizeChangeReason::MOVE_WITH_ANIMATION :
2160         SizeChangeReason::MOVE;
2161     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2162     auto ret = hostSession->UpdateSessionRect(wsRect, reason, false, true, moveConfiguration, rectAnimationConfig);
2163     if (state_ == WindowState::STATE_SHOWN) {
2164         layoutCallback_->ResetMoveToLock();
2165         auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2166             std::chrono::system_clock::now().time_since_epoch()).count();
2167         layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2168         auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2169             std::chrono::system_clock::now().time_since_epoch()).count();
2170         auto waitTime = endTime - startTime;
2171         if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
2172             TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
2173             layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2174         }
2175     }
2176     return static_cast<WMError>(ret);
2177 }
2178 
MoveToAsync(int32_t x,int32_t y,MoveConfiguration moveConfiguration)2179 WMError WindowSceneSessionImpl::MoveToAsync(int32_t x, int32_t y, MoveConfiguration moveConfiguration)
2180 {
2181     if (IsWindowSessionInvalid()) {
2182         TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
2183         return WMError::WM_ERROR_INVALID_WINDOW;
2184     }
2185 
2186     if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
2187         TLOGW(WmsLogTag::WMS_LAYOUT, "window should not move, winId:%{public}u, mode:%{public}u",
2188             GetWindowId(), GetWindowMode());
2189         return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
2190     }
2191     auto ret = MoveTo(x, y, false, moveConfiguration);
2192     if (state_ == WindowState::STATE_SHOWN) {
2193         layoutCallback_->ResetMoveToLock();
2194         auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2195             std::chrono::system_clock::now().time_since_epoch()).count();
2196         layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2197         auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2198             std::chrono::system_clock::now().time_since_epoch()).count();
2199         auto waitTime = endTime - startTime;
2200         if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
2201             TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
2202             layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2203         }
2204     }
2205     return static_cast<WMError>(ret);
2206 }
2207 
2208 /** @note @window.layout */
MoveWindowToGlobalDisplay(int32_t x,int32_t y,MoveConfiguration)2209 WMError WindowSceneSessionImpl::MoveWindowToGlobalDisplay(
2210     int32_t x, int32_t y, MoveConfiguration /*moveConfiguration*/)
2211 {
2212     if (IsWindowSessionInvalid()) {
2213         TLOGE(WmsLogTag::WMS_LAYOUT, "Invalid session");
2214         return WMError::WM_ERROR_INVALID_WINDOW;
2215     }
2216     auto mode = GetWindowMode();
2217     if (mode != WindowMode::WINDOW_MODE_FLOATING) {
2218         TLOGW(WmsLogTag::WMS_LAYOUT, "window should not move, windowId: %{public}u, mode: %{public}u",
2219             GetWindowId(), mode);
2220         return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
2221     }
2222     auto winId = GetPersistentId();
2223     const auto curGlobalDisplayRect = GetGlobalDisplayRect();
2224     if (curGlobalDisplayRect.IsSamePosition(x, y)) {
2225         TLOGW(WmsLogTag::WMS_LAYOUT, "windowId: %{public}u, request same position: [%{public}d, %{public}d]",
2226             winId, x, y);
2227         return WMError::WM_OK;
2228     }
2229     // Use RequestRect to quickly get width and height from Resize method.
2230     const auto requestRect = GetRequestRect();
2231     if (!Rect::IsRightBottomValid(x, y, requestRect.width_, requestRect.height_)) {
2232         TLOGE(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, illegal position: [%{public}d, %{public}d]", winId, x, y);
2233         return WMError::WM_ERROR_ILLEGAL_PARAM;
2234     }
2235     WSRect newGlobalDisplayRect = { x, y, requestRect.width_, requestRect.height_ };
2236     TLOGI(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, newGlobalDisplayRect: %{public}s",
2237         winId, newGlobalDisplayRect.ToString().c_str());
2238     auto hostSession = GetHostSession();
2239     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2240     auto ret = hostSession->UpdateGlobalDisplayRectFromClient(newGlobalDisplayRect, SizeChangeReason::MOVE);
2241     // If the window is shown, wait for the layout result from the server, so that the
2242     // caller can directly obtain the updated globalDisplayRect from the window properties.
2243     if (state_ == WindowState::STATE_SHOWN) {
2244         layoutCallback_->ResetMoveWindowToGlobalDisplayLock();
2245         const auto now = [] {
2246             return std::chrono::duration_cast<std::chrono::milliseconds>(
2247                 std::chrono::system_clock::now().time_since_epoch()).count();
2248         };
2249         const auto startTime = now();
2250         layoutCallback_->GetMoveWindowToGlobalDisplayAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2251         const auto waitDuration = now() - startTime;
2252         if (waitDuration >= WINDOW_LAYOUT_TIMEOUT) {
2253             TLOGW(WmsLogTag::WMS_LAYOUT, "Window layout timeout, windowId: %{public}d", winId);
2254             layoutCallback_->GetMoveWindowToGlobalDisplayAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2255         }
2256     }
2257     return static_cast<WMError>(ret);
2258 }
2259 
GetGlobalScaledRect(Rect & globalScaledRect)2260 WMError WindowSceneSessionImpl::GetGlobalScaledRect(Rect& globalScaledRect)
2261 {
2262     if (IsWindowSessionInvalid()) {
2263         TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
2264         return WMError::WM_ERROR_INVALID_WINDOW;
2265     }
2266     auto hostSession = GetHostSession();
2267     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2268     auto ret = hostSession->GetGlobalScaledRect(globalScaledRect);
2269     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, globalScaledRect:%{public}s, ret:%{public}d",
2270         GetPersistentId(), globalScaledRect.ToString().c_str(), ret);
2271     if (WMError::WM_OK == static_cast<WMError>(ret)) {
2272         HookWindowSizeByHookWindowInfo(globalScaledRect);
2273     }
2274     return static_cast<WMError>(ret);
2275 }
2276 
LimitCameraFloatWindowMininumSize(uint32_t & width,uint32_t & height,float & vpr)2277 void WindowSceneSessionImpl::LimitCameraFloatWindowMininumSize(uint32_t& width, uint32_t& height, float& vpr)
2278 {
2279     // Float camera window has a special limit:
2280     // if display sw <= 600dp, portrait: min width = display sw * 30%, landscape: min width = sw * 50%
2281     // if display sw > 600dp, portrait: min width = display sw * 12%, landscape: min width = sw * 30%
2282     if (GetType() != WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2283         return;
2284     }
2285 
2286     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2287     if (display == nullptr) {
2288         WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2289         return;
2290     }
2291     auto displayInfo = display->GetDisplayInfo();
2292     if (displayInfo == nullptr) {
2293         WLOGFE("get displayInfo failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2294         return;
2295     }
2296     uint32_t displayWidth = static_cast<uint32_t>(display->GetWidth());
2297     uint32_t displayHeight = static_cast<uint32_t>(display->GetHeight());
2298     if (displayWidth == 0 || displayHeight == 0) {
2299         return;
2300     }
2301     vpr = GetVirtualPixelRatio(displayInfo);
2302     uint32_t smallWidth = displayHeight <= displayWidth ? displayHeight : displayWidth;
2303     float hwRatio = static_cast<float>(displayHeight) / static_cast<float>(displayWidth);
2304     uint32_t minWidth;
2305     if (smallWidth <= static_cast<uint32_t>(600 * vpr)) { // sw <= 600dp
2306         if (displayWidth <= displayHeight) {
2307             minWidth = static_cast<uint32_t>(smallWidth * 0.3); // ratio : 0.3
2308         } else {
2309             minWidth = static_cast<uint32_t>(smallWidth * 0.5); // ratio : 0.5
2310         }
2311     } else {
2312         if (displayWidth <= displayHeight) {
2313             minWidth = static_cast<uint32_t>(smallWidth * 0.12); // ratio : 0.12
2314         } else {
2315             minWidth = static_cast<uint32_t>(smallWidth * 0.3); // ratio : 0.3
2316         }
2317     }
2318     width = (width < minWidth) ? minWidth : width;
2319     height = static_cast<uint32_t>(width * hwRatio);
2320 }
2321 
2322 /** @note @window.layout */
UpdateFloatingWindowSizeBySizeLimits(uint32_t & width,uint32_t & height) const2323 void WindowSceneSessionImpl::UpdateFloatingWindowSizeBySizeLimits(uint32_t& width, uint32_t& height) const
2324 {
2325     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2326         TLOGD(WmsLogTag::WMS_LAYOUT, "float camera type window");
2327         return;
2328     }
2329     // get new limit config with the settings of system and app
2330     const auto& sizeLimits = property_->GetWindowLimits();
2331     // limit minimum size of floating (not system type) window
2332     if (!WindowHelper::IsSystemWindow(property_->GetWindowType()) ||
2333         property_->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
2334         width = std::max(sizeLimits.minWidth_, width);
2335         height = std::max(sizeLimits.minHeight_, height);
2336     }
2337     width = std::min(sizeLimits.maxWidth_, width);
2338     height = std::min(sizeLimits.maxHeight_, height);
2339     if (height == 0) {
2340         return;
2341     }
2342     float curRatio = static_cast<float>(width) / static_cast<float>(height);
2343     // there is no need to fix size by ratio if this is not main floating window
2344     if (!WindowHelper::IsMainFloatingWindow(property_->GetWindowType(), GetWindowMode()) ||
2345         (!MathHelper::GreatNotEqual(sizeLimits.minRatio_, curRatio) &&
2346          !MathHelper::GreatNotEqual(curRatio, sizeLimits.maxRatio_))) {
2347         return;
2348     }
2349 
2350     float newRatio = curRatio < sizeLimits.minRatio_ ? sizeLimits.minRatio_ : sizeLimits.maxRatio_;
2351     if (MathHelper::NearZero(newRatio)) {
2352         return;
2353     }
2354     if (sizeLimits.maxWidth_ == sizeLimits.minWidth_) {
2355         height = static_cast<uint32_t>(static_cast<float>(width) / newRatio);
2356         return;
2357     }
2358     if (sizeLimits.maxHeight_ == sizeLimits.minHeight_) {
2359         width = static_cast<uint32_t>(static_cast<float>(height) * newRatio);
2360         return;
2361     }
2362     WLOGFD("After limit by customize config: %{public}u %{public}u", width, height);
2363 }
2364 
2365 /** @note @window.layout */
LimitWindowSize(uint32_t & width,uint32_t & height)2366 void WindowSceneSessionImpl::LimitWindowSize(uint32_t& width, uint32_t& height)
2367 {
2368     float vpr = 0.0f;
2369 
2370     // Float camera window has special limits
2371     LimitCameraFloatWindowMininumSize(width, height, vpr);
2372 
2373     if (!MathHelper::NearZero(vpr) || !MathHelper::NearZero(property_->GetLastLimitsVpr() - vpr)) {
2374         UpdateWindowSizeLimits();
2375     }
2376     UpdateFloatingWindowSizeBySizeLimits(width, height);
2377 }
2378 
CheckAndModifyWindowRect(uint32_t & width,uint32_t & height)2379 WMError WindowSceneSessionImpl::CheckAndModifyWindowRect(uint32_t& width, uint32_t& height)
2380 {
2381     if (width == 0 || height == 0) {
2382         TLOGE(WmsLogTag::WMS_LAYOUT, "width or height should greater than 0!");
2383         return WMError::WM_ERROR_INVALID_PARAM;
2384     }
2385     if (IsWindowSessionInvalid()) {
2386         return WMError::WM_ERROR_INVALID_WINDOW;
2387     }
2388     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2389         TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
2390         return WMError::WM_ERROR_INVALID_OPERATION;
2391     }
2392     if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING && !IsFullScreenPcAppInPadMode()) {
2393         TLOGW(WmsLogTag::WMS_LAYOUT, "Fullscreen window could not resize, winId: %{public}u", GetWindowId());
2394         return WMError::WM_ERROR_INVALID_OPERATION;
2395     }
2396     if (IsFullScreenPcAppInPadMode() && IsFullScreenEnable()) {
2397         NotifyClientWindowSize();
2398         return WMError::WM_ERROR_INVALID_OPERATION;
2399     }
2400 
2401     LimitWindowSize(width, height);
2402     return WMError::WM_OK;
2403 }
2404 
2405 /** @note @window.layout */
Resize(uint32_t width,uint32_t height,const RectAnimationConfig & rectAnimationConfig)2406 WMError WindowSceneSessionImpl::Resize(uint32_t width, uint32_t height, const RectAnimationConfig& rectAnimationConfig)
2407 {
2408     auto reason = SizeChangeReason::RESIZE;
2409     if (isResizedByLimit_) {
2410         reason = SizeChangeReason::RESIZE_BY_LIMIT;
2411         isResizedByLimit_ = false;
2412     }
2413     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d resize %{public}u %{public}u",
2414         property_->GetPersistentId(), width, height);
2415 
2416     if (CheckAndModifyWindowRect(width, height) != WMError::WM_OK) {
2417         return WMError::WM_ERROR_INVALID_OPERATION;
2418     }
2419     const auto& windowRect = GetRect();
2420     const auto& requestRect = GetRequestRect();
2421 
2422     if (WindowHelper::IsSubWindow(GetType())) {
2423         auto mainWindow = FindMainWindowWithContext();
2424         if (mainWindow != nullptr && (mainWindow->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
2425                                       mainWindow->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
2426             if (width == requestRect.width_ && height == requestRect.height_) {
2427                 TLOGW(WmsLogTag::WMS_LAYOUT, "Request same size in multiWindow will not update, return");
2428                 return WMError::WM_OK;
2429             }
2430         }
2431     }
2432 
2433     Rect newRect = { requestRect.posX_, requestRect.posY_, width, height }; // must keep w/h
2434     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
2435         "%{public}s, windowRect: %{public}s, newRect: %{public}s",
2436         property_->GetPersistentId(), state_, GetType(), GetWindowMode(), requestRect.ToString().c_str(),
2437         windowRect.ToString().c_str(), newRect.ToString().c_str());
2438 
2439     property_->SetRequestRect(newRect);
2440     property_->SetRectAnimationConfig(rectAnimationConfig);
2441 
2442     WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
2443     auto hostSession = GetHostSession();
2444     if (rectAnimationConfig.duration > 0 && reason == SizeChangeReason::RESIZE) {
2445         reason = SizeChangeReason::RESIZE_WITH_ANIMATION;
2446     }
2447 
2448     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2449     auto ret = hostSession->UpdateSessionRect(wsRect, reason, false, false, {}, rectAnimationConfig);
2450     return static_cast<WMError>(ret);
2451 }
2452 
ResizeAsync(uint32_t width,uint32_t height,const RectAnimationConfig & rectAnimationConfig)2453 WMError WindowSceneSessionImpl::ResizeAsync(uint32_t width, uint32_t height,
2454     const RectAnimationConfig& rectAnimationConfig)
2455 {
2456     if (IsWindowSessionInvalid()) {
2457         TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
2458         return WMError::WM_ERROR_INVALID_WINDOW;
2459     }
2460 
2461     if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING && !property_->GetIsPcAppInPad()) {
2462         TLOGW(WmsLogTag::WMS_LAYOUT, "window should not resize, winId:%{public}u, mode:%{public}u",
2463             GetWindowId(), GetWindowMode());
2464         return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
2465     }
2466     auto ret = Resize(width, height, rectAnimationConfig);
2467     if (state_ == WindowState::STATE_SHOWN) {
2468         layoutCallback_->ResetResizeLock();
2469         auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2470             std::chrono::system_clock::now().time_since_epoch()).count();
2471         layoutCallback_->GetResizeAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2472         auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2473             std::chrono::system_clock::now().time_since_epoch()).count();
2474         auto waitTime = endTime - startTime;
2475         if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
2476             TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
2477             layoutCallback_->GetResizeAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2478         }
2479     }
2480     return static_cast<WMError>(ret);
2481 }
2482 
SetFrameRectForPartialZoomIn(const Rect & frameRect)2483 WMError WindowSceneSessionImpl::SetFrameRectForPartialZoomIn(const Rect& frameRect)
2484 {
2485     TLOGI(WmsLogTag::WMS_ANIMATION, "set frame rect start, rect: %{public}s", frameRect.ToString().c_str());
2486     if (GetType() != WindowType::WINDOW_TYPE_MAGNIFICATION) {
2487         TLOGE(WmsLogTag::WMS_ANIMATION, "window type is invalid");
2488         return WMError::WM_ERROR_INVALID_WINDOW;
2489     }
2490 
2491     if (IsWindowSessionInvalid()) {
2492         return WMError::WM_ERROR_INVALID_WINDOW;
2493     }
2494     auto hostSession = GetHostSession();
2495     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2496     return static_cast<WMError>(hostSession->SetFrameRectForPartialZoomIn(frameRect));
2497 }
2498 
UpdateWindowModeForUITest(int32_t updateMode)2499 WMError WindowSceneSessionImpl::UpdateWindowModeForUITest(int32_t updateMode)
2500 {
2501     TLOGI(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, updateMode: %{public}d", GetPersistentId(), updateMode);
2502     switch (updateMode) {
2503         case static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN):
2504             return Maximize();
2505         case static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING):
2506             return Recover();
2507         case static_cast<int32_t>(WindowMode::WINDOW_MODE_SPLIT_PRIMARY):
2508             return SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
2509         case static_cast<int32_t>(WindowMode::WINDOW_MODE_SPLIT_SECONDARY):
2510             return SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_SECONDARY);
2511         default:
2512             break;
2513     }
2514     return WMError::WM_DO_NOTHING;
2515 }
2516 
GetTargetOrientationConfigInfo(Orientation targetOrientation,const std::map<WindowType,SystemBarProperty> & properties,Ace::ViewportConfig & config,std::map<AvoidAreaType,AvoidArea> & avoidAreas)2517 WMError WindowSceneSessionImpl::GetTargetOrientationConfigInfo(Orientation targetOrientation,
2518     const std::map<WindowType, SystemBarProperty>& properties, Ace::ViewportConfig& config,
2519     std::map<AvoidAreaType, AvoidArea>& avoidAreas)
2520 {
2521     if (IsWindowSessionInvalid()) {
2522         TLOGE(WmsLogTag::WMS_ROTATION, "Session is invalid");
2523         return WMError::WM_ERROR_INVALID_WINDOW;
2524     }
2525     std::map<WindowType, SystemBarProperty> pageProperties;
2526     GetSystemBarPropertyForPage(properties, pageProperties);
2527     auto hostSession = GetHostSession();
2528     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2529 
2530     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2531     if (display == nullptr) {
2532         TLOGE(WmsLogTag::WMS_ROTATION, "display is null, winId=%{public}u", GetWindowId());
2533         return WMError::WM_ERROR_NULLPTR;
2534     }
2535     sptr<DisplayInfo> displayInfo = display ? display->GetDisplayInfo() : nullptr;
2536     if (displayInfo == nullptr) {
2537         TLOGE(WmsLogTag::WMS_ROTATION, "displayInfo is null!");
2538         return WMError::WM_ERROR_NULLPTR;
2539     }
2540     WSError ret;
2541     if (targetOrientation == Orientation::INVALID) {
2542         Orientation requestedOrientation = ConvertInvalidOrientation();
2543         ret = hostSession->GetTargetOrientationConfigInfo(requestedOrientation, pageProperties);
2544     } else {
2545         ret = hostSession->GetTargetOrientationConfigInfo(targetOrientation, pageProperties);
2546     }
2547     getTargetInfoCallback_->ResetGetTargetRotationLock();
2548     OrientationInfo info = getTargetInfoCallback_->GetTargetOrientationResult(WINDOW_PAGE_ROTATION_TIMEOUT);
2549     avoidAreas = info.avoidAreas;
2550     config = FillTargetOrientationConfig(info, displayInfo, GetDisplayId());
2551     TLOGI(WmsLogTag::WMS_ROTATION,
2552         "win:%{public}u, rotate:%{public}d, rect:%{public}s, avoidAreas:%{public}s,%{public}s,%{public}s,%{public}s",
2553         GetWindowId(), info.rotation, info.rect.ToString().c_str(),
2554         avoidAreas[AvoidAreaType::TYPE_SYSTEM].ToString().c_str(),
2555         avoidAreas[AvoidAreaType::TYPE_CUTOUT].ToString().c_str(),
2556         avoidAreas[AvoidAreaType::TYPE_KEYBOARD].ToString().c_str(),
2557         avoidAreas[AvoidAreaType::TYPE_NAVIGATION_INDICATOR].ToString().c_str());
2558     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
2559         "GetTargetOrientationConfigInfo: targetOrientation:%u, rotation:%d, rect:%s",
2560         static_cast<uint32_t>(targetOrientation), info.rotation, info.rect.ToString().c_str());
2561 
2562     return static_cast<WMError>(ret);
2563 }
2564 
FillTargetOrientationConfig(const OrientationInfo & info,const sptr<DisplayInfo> & displayInfo,uint64_t displayId)2565 Ace::ViewportConfig WindowSceneSessionImpl::FillTargetOrientationConfig(
2566     const OrientationInfo& info, const sptr<DisplayInfo>& displayInfo, uint64_t displayId)
2567 {
2568     Ace::ViewportConfig config;
2569     Rect targetRect = info.rect;
2570     uint32_t targetRotation = info.rotation;
2571     if (displayInfo == nullptr) {
2572         TLOGE(WmsLogTag::WMS_ROTATION, "displayInfo is null!");
2573         return config;
2574     }
2575     auto deviceRotation = static_cast<uint32_t>(displayInfo->GetDefaultDeviceRotationOffset());
2576     uint32_t transformHint = (targetRotation + deviceRotation) % FULL_CIRCLE_DEGREE;
2577     float density = GetVirtualPixelRatio(displayInfo);
2578     int32_t orientation = static_cast<int32_t>(targetRotation) / ONE_FOURTH_FULL_CIRCLE_DEGREE;
2579     virtualPixelRatio_ = density;
2580     config.SetSize(targetRect.width_, targetRect.height_);
2581     config.SetPosition(targetRect.posX_, targetRect.posY_);
2582     config.SetDensity(density);
2583     config.SetOrientation(orientation);
2584     config.SetTransformHint(transformHint);
2585     config.SetDisplayId(displayId);
2586     return config;
2587 }
2588 
NotifyTargetRotationInfo(OrientationInfo & info)2589 WSError WindowSceneSessionImpl::NotifyTargetRotationInfo(OrientationInfo& info)
2590 {
2591     WSError ret = WSError::WS_OK;
2592     if (getTargetInfoCallback_) {
2593         ret = getTargetInfoCallback_->OnUpdateTargetOrientationInfo(info);
2594     }
2595     return ret;
2596 }
2597 
SetAspectRatio(float ratio)2598 WMError WindowSceneSessionImpl::SetAspectRatio(float ratio)
2599 {
2600     if (IsWindowSessionInvalid()) {
2601         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
2602         return WMError::WM_ERROR_INVALID_WINDOW;
2603     }
2604 
2605     auto hostSession = GetHostSession();
2606     if (hostSession == nullptr) {
2607         WLOGFE("failed, because of nullptr");
2608         return WMError::WM_ERROR_NULLPTR;
2609     }
2610     if (ratio == MathHelper::INF || ratio == MathHelper::NAG_INF || std::isnan(ratio) || MathHelper::NearZero(ratio)) {
2611         WLOGFE("failed, because of wrong value: %{public}f", ratio);
2612         return WMError::WM_ERROR_INVALID_PARAM;
2613     }
2614     if (hostSession->SetAspectRatio(ratio) != WSError::WS_OK) {
2615         return WMError::WM_ERROR_INVALID_PARAM;
2616     }
2617     return WMError::WM_OK;
2618 }
2619 
ResetAspectRatio()2620 WMError WindowSceneSessionImpl::ResetAspectRatio()
2621 {
2622     auto hostSession = GetHostSession();
2623     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2624     return static_cast<WMError>(hostSession->SetAspectRatio(0.0f));
2625 }
2626 
2627 /** @note @window.hierarchy */
RaiseToAppTop()2628 WMError WindowSceneSessionImpl::RaiseToAppTop()
2629 {
2630     if (IsWindowSessionInvalid()) {
2631         TLOGE(WmsLogTag::WMS_HIERARCHY, "Session is invalid");
2632         return WMError::WM_ERROR_INVALID_WINDOW;
2633     }
2634 
2635     WLOGFI("id: %{public}d", GetPersistentId());
2636     auto parentId = GetParentId();
2637     if (parentId == INVALID_SESSION_ID) {
2638         WLOGFE("Only the children of the main window can be raised!");
2639         return WMError::WM_ERROR_INVALID_PARENT;
2640     }
2641 
2642     if (!WindowHelper::IsSubWindow(GetType())) {
2643         WLOGFE("Must be app sub window window!");
2644         return WMError::WM_ERROR_INVALID_CALLING;
2645     }
2646 
2647     if (state_ != WindowState::STATE_SHOWN) {
2648         WLOGFE("The sub window must be shown!");
2649         return WMError::WM_DO_NOTHING;
2650     }
2651     auto hostSession = GetHostSession();
2652     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2653     WSError ret = hostSession->RaiseToAppTop();
2654     return static_cast<WMError>(ret);
2655 }
2656 
2657 /** @note @window.hierarchy */
RaiseAboveTarget(int32_t subWindowId)2658 WMError WindowSceneSessionImpl::RaiseAboveTarget(int32_t subWindowId)
2659 {
2660     if (IsWindowSessionInvalid()) {
2661         TLOGE(WmsLogTag::WMS_HIERARCHY, "Session is invalid");
2662         return WMError::WM_ERROR_INVALID_WINDOW;
2663     }
2664 
2665     auto parentId = GetParentId();
2666     auto currentWindowId = GetWindowId();
2667 
2668     if (parentId == INVALID_SESSION_ID) {
2669         WLOGFE("Only the children of the main window can be raised!");
2670         return WMError::WM_ERROR_INVALID_PARENT;
2671     }
2672 
2673     auto subWindows = Window::GetSubWindow(parentId);
2674     auto targetWindow = find_if(subWindows.begin(), subWindows.end(), [subWindowId](sptr<Window>& window) {
2675         return static_cast<uint32_t>(subWindowId) == window->GetWindowId();
2676     });
2677     if (targetWindow == subWindows.end()) {
2678         return WMError::WM_ERROR_INVALID_PARAM;
2679     }
2680 
2681     if (!WindowHelper::IsSubWindow(GetType())) {
2682         WLOGFE("Must be app sub window window!");
2683         return WMError::WM_ERROR_INVALID_CALLING;
2684     }
2685 
2686     if ((state_ != WindowState::STATE_SHOWN) ||
2687         ((*targetWindow)->GetWindowState() != WindowState::STATE_SHOWN)) {
2688         WLOGFE("The sub window must be shown!");
2689         return WMError::WM_DO_NOTHING;
2690     }
2691     if (currentWindowId == static_cast<uint32_t>(subWindowId)) {
2692         return WMError::WM_OK;
2693     }
2694     auto hostSession = GetHostSession();
2695     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2696     WSError ret = hostSession->RaiseAboveTarget(subWindowId);
2697     return static_cast<WMError>(ret);
2698 }
2699 
2700 /** @note @window.hierarchy */
RaiseMainWindowAboveTarget(int32_t targetId)2701 WMError WindowSceneSessionImpl::RaiseMainWindowAboveTarget(int32_t targetId)
2702 {
2703     TLOGI(WmsLogTag::WMS_HIERARCHY, "source id: %{public}u, target id: %{public}u", GetWindowId(), targetId);
2704     if (!IsPcOrPadFreeMultiWindowMode()) {
2705         TLOGE(WmsLogTag::WMS_HIERARCHY, "device type not supported");
2706         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2707     }
2708     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
2709     auto targetIter = std::find_if(windowSessionMap_.begin(), windowSessionMap_.end(),
2710         [targetId](const auto& windowInfoPair) {return windowInfoPair.second.first == targetId;});
2711     if (targetIter == windowSessionMap_.end()) {
2712         TLOGE(WmsLogTag::WMS_HIERARCHY, "target id invalid or pid inconsistent with source window pid");
2713         return WMError::WM_ERROR_INVALID_WINDOW;
2714     }
2715     auto targetSessionImpl = targetIter->second.second;
2716     if (IsWindowSessionInvalid() || targetSessionImpl == nullptr || targetSessionImpl->GetHostSession() == nullptr ||
2717         targetSessionImpl->state_ == WindowState::STATE_DESTROYED) {
2718         TLOGE(WmsLogTag::WMS_HIERARCHY, "source window or target window is null or destroyed");
2719         return WMError::WM_ERROR_INVALID_WINDOW;
2720     }
2721     if (state_ != WindowState::STATE_SHOWN || targetSessionImpl->state_ != WindowState::STATE_SHOWN) {
2722         TLOGE(WmsLogTag::WMS_HIERARCHY, "both source window and target window must be shown");
2723         return WMError::WM_ERROR_INVALID_WINDOW;
2724     }
2725     if (!WindowHelper::IsMainWindow(GetType()) || !WindowHelper::IsMainWindow(targetSessionImpl->GetType())) {
2726         TLOGE(WmsLogTag::WMS_HIERARCHY, "window type not supported");
2727         return WMError::WM_ERROR_INVALID_CALLING;
2728     }
2729     if (WindowHelper::IsModalMainWindow(GetType(), GetWindowFlags()) ||
2730         WindowHelper::IsModalMainWindow(targetSessionImpl->GetType(), targetSessionImpl->GetWindowFlags())) {
2731         TLOGE(WmsLogTag::WMS_HIERARCHY, "both source window and target window must be not modal");
2732         return WMError::WM_ERROR_INVALID_CALLING;
2733     }
2734     if (IsApplicationModalSubWindowShowing(GetWindowId()) || IsApplicationModalSubWindowShowing(targetId)) {
2735         TLOGE(WmsLogTag::WMS_HIERARCHY, "application sub window is not allowed");
2736         return WMError::WM_ERROR_INVALID_CALLING;
2737     }
2738     if (IsMainWindowTopmost() || targetSessionImpl->IsMainWindowTopmost() || IsTopmost() ||
2739         targetSessionImpl->IsTopmost()) {
2740         TLOGE(WmsLogTag::WMS_HIERARCHY, "both source window and target window must be not topmost");
2741         return WMError::WM_ERROR_INVALID_CALLING;
2742     }
2743     auto hostSession = GetHostSession();
2744     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2745     WSError ret = hostSession->RaiseMainWindowAboveTarget(targetId);
2746     return static_cast<WMError>(ret);
2747 }
2748 
2749 /** @note @window.hierarchy */
SetSubWindowZLevel(int32_t zLevel)2750 WMError WindowSceneSessionImpl::SetSubWindowZLevel(int32_t zLevel)
2751 {
2752     TLOGD(WmsLogTag::WMS_HIERARCHY, "%{public}d", zLevel);
2753     if (IsWindowSessionInvalid()) {
2754         TLOGE(WmsLogTag::WMS_HIERARCHY, "session is invalid");
2755         return WMError::WM_ERROR_INVALID_WINDOW;
2756     }
2757 
2758     if (!windowSystemConfig_.supportZLevel_) {
2759         TLOGE(WmsLogTag::WMS_HIERARCHY, "The device is not supported");
2760         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2761     }
2762 
2763     if (!WindowHelper::IsNormalSubWindow(GetType(), property_->GetWindowFlags())) {
2764         TLOGE(WmsLogTag::WMS_HIERARCHY, "must be normal app sub window");
2765         return WMError::WM_ERROR_INVALID_CALLING;
2766     }
2767     if (GetParentId() == INVALID_SESSION_ID) {
2768         TLOGE(WmsLogTag::WMS_HIERARCHY, "only the children of the main window can be raised");
2769         return WMError::WM_ERROR_INVALID_PARENT;
2770     }
2771     if (zLevel > MAXIMUM_Z_LEVEL || zLevel < MINIMUM_Z_LEVEL) {
2772         TLOGE(WmsLogTag::WMS_HIERARCHY, "zLevel value %{public}d exceeds valid range [-10000, 10000]!", zLevel);
2773         return WMError::WM_ERROR_INVALID_PARAM;
2774     }
2775 
2776     auto currentZLevel = property_->GetSubWindowZLevel();
2777     if (currentZLevel == static_cast<int32_t>(zLevel)) {
2778         return WMError::WM_OK;
2779     }
2780     property_->SetSubWindowZLevel(zLevel);
2781     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SUB_WINDOW_Z_LEVEL);
2782 }
2783 
2784 /** @note @window.hierarchy */
GetSubWindowZLevel(int32_t & zLevel)2785 WMError WindowSceneSessionImpl::GetSubWindowZLevel(int32_t& zLevel)
2786 {
2787     if (IsWindowSessionInvalid()) {
2788         TLOGE(WmsLogTag::WMS_HIERARCHY, "session is invalid");
2789         return WMError::WM_ERROR_INVALID_WINDOW;
2790     }
2791 
2792     if (!windowSystemConfig_.supportZLevel_) {
2793         TLOGE(WmsLogTag::WMS_HIERARCHY, "The device is not supported");
2794         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2795     }
2796 
2797     if (!WindowHelper::IsSubWindow(GetType()) || !WindowHelper::IsDialogWindow(GetType())) {
2798         TLOGE(WmsLogTag::WMS_HIERARCHY, "must be app sub window!");
2799         return WMError::WM_ERROR_INVALID_CALLING;
2800     }
2801     zLevel = property_->GetSubWindowZLevel();
2802     TLOGI(WmsLogTag::WMS_HIERARCHY, "Id:%{public}u, zLevel:%{public}d", GetWindowId(), zLevel);
2803     return WMError::WM_OK;
2804 }
2805 
GetAvoidAreaByType(AvoidAreaType type,AvoidArea & avoidArea,const Rect & rect,int32_t apiVersion)2806 WMError WindowSceneSessionImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea,
2807     const Rect& rect, int32_t apiVersion)
2808 {
2809     uint32_t currentApiVersion = GetTargetAPIVersionByApplicationInfo();
2810     apiVersion = (apiVersion == API_VERSION_INVALID) ? static_cast<int32_t>(currentApiVersion) : apiVersion;
2811     if (apiVersion < API_VERSION_18 && WindowHelper::IsSystemWindow(property_->GetWindowType())) {
2812         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u type %{public}d api %{public}u not supported",
2813             GetWindowId(), type, apiVersion);
2814         return WMError::WM_OK;
2815     }
2816     if (IsWindowSessionInvalid()) {
2817         return WMError::WM_ERROR_INVALID_WINDOW;
2818     }
2819     auto hostSession = GetHostSession();
2820     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2821     WSRect sessionRect = {
2822         rect.posX_, rect.posY_, static_cast<int32_t>(rect.width_), static_cast<int32_t>(rect.height_)
2823     };
2824     avoidArea = hostSession->GetAvoidAreaByType(type, sessionRect, apiVersion);
2825     getAvoidAreaCnt_++;
2826     TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] type %{public}d times %{public}u area %{public}s",
2827           GetWindowId(), GetWindowName().c_str(), type, getAvoidAreaCnt_.load(), avoidArea.ToString().c_str());
2828     return WMError::WM_OK;
2829 }
2830 
NotifyWindowNeedAvoid(bool status)2831 WMError WindowSceneSessionImpl::NotifyWindowNeedAvoid(bool status)
2832 {
2833     TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u status %{public}d",
2834         GetWindowId(), static_cast<int32_t>(status));
2835     if (IsWindowSessionInvalid()) {
2836         TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
2837         return WMError::WM_ERROR_INVALID_WINDOW;
2838     }
2839     auto hostSession = GetHostSession();
2840     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2841     hostSession->OnNeedAvoid(status);
2842     return WMError::WM_OK;
2843 }
2844 
SetIgnoreSafeArea(bool isIgnoreSafeArea)2845 WMError WindowSceneSessionImpl::SetIgnoreSafeArea(bool isIgnoreSafeArea)
2846 {
2847     return SetLayoutFullScreenByApiVersion(isIgnoreSafeArea);
2848 }
2849 
SetLayoutFullScreenByApiVersion(bool status)2850 WMError WindowSceneSessionImpl::SetLayoutFullScreenByApiVersion(bool status)
2851 {
2852     if (IsWindowSessionInvalid()) {
2853         TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
2854         return WMError::WM_ERROR_INVALID_WINDOW;
2855     }
2856     uint32_t version = 0;
2857     auto context = GetContext();
2858     if ((context != nullptr) && (context->GetApplicationInfo() != nullptr)) {
2859         version = context->GetApplicationInfo()->apiCompatibleVersion;
2860     }
2861     isIgnoreSafeArea_ = status;
2862     isIgnoreSafeAreaNeedNotify_ = true;
2863     // 10 ArkUI new framework support after API10
2864     if (version >= 10) {
2865         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u status %{public}d",
2866             GetWindowId(), static_cast<int32_t>(status));
2867         if (auto uiContent = GetUIContentSharedPtr()) {
2868             uiContent->SetIgnoreViewSafeArea(status);
2869         }
2870     } else {
2871         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u status %{public}d",
2872             GetWindowId(), static_cast<int32_t>(status));
2873         WMError ret = WMError::WM_OK;
2874         if (status) {
2875             ret = RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
2876             if (ret != WMError::WM_OK) {
2877                 TLOGE(WmsLogTag::WMS_IMMS, "remove window flag, win %{public}u errCode %{public}d",
2878                     GetWindowId(), static_cast<int32_t>(ret));
2879                 return ret;
2880             }
2881         } else {
2882             ret = AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
2883             if (ret != WMError::WM_OK) {
2884                 TLOGE(WmsLogTag::WMS_IMMS, "add window flag, win %{public}u errCode %{public}d",
2885                     GetWindowId(), static_cast<int32_t>(ret));
2886                 return ret;
2887             }
2888         }
2889         ret = NotifyWindowNeedAvoid(!status);
2890         if (ret != WMError::WM_OK) {
2891             TLOGE(WmsLogTag::WMS_IMMS, "notify window need avoid, win %{public}u errCode %{public}d",
2892                 GetWindowId(), static_cast<int32_t>(ret));
2893             return ret;
2894         }
2895     }
2896     return WMError::WM_OK;
2897 }
2898 
SetLayoutFullScreen(bool status)2899 WMError WindowSceneSessionImpl::SetLayoutFullScreen(bool status)
2900 {
2901     TLOGD(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] status %{public}d",
2902         GetWindowId(), GetWindowName().c_str(), static_cast<int32_t>(status));
2903     if (IsWindowSessionInvalid()) {
2904         return WMError::WM_ERROR_INVALID_WINDOW;
2905     }
2906     if (WindowHelper::IsSystemWindow(GetType())) {
2907         TLOGI(WmsLogTag::WMS_IMMS, "system window not supported");
2908         return WMError::WM_OK;
2909     }
2910 
2911     if (IsPcOrPadFreeMultiWindowMode() && property_->IsAdaptToImmersive()) {
2912         SetLayoutFullScreenByApiVersion(status);
2913         // compatibleMode app may set statusBarColor before ignoreSafeArea
2914         auto systemBarProperties = property_->GetSystemBarProperty();
2915         if (status && systemBarProperties.find(WindowType::WINDOW_TYPE_STATUS_BAR) != systemBarProperties.end()) {
2916             auto statusBarProperty = systemBarProperties[WindowType::WINDOW_TYPE_STATUS_BAR];
2917             HookDecorButtonStyleInCompatibleMode(statusBarProperty.contentColor_);
2918         }
2919         return WMError::WM_OK;
2920     }
2921 
2922     bool preStatus = property_->IsLayoutFullScreen();
2923     property_->SetIsLayoutFullScreen(status);
2924     auto hostSession = GetHostSession();
2925     if (hostSession != nullptr) {
2926         hostSession->OnLayoutFullScreenChange(status);
2927     }
2928 
2929     if (WindowHelper::IsMainWindow(GetType()) && !windowSystemConfig_.IsPhoneWindow() &&
2930         !windowSystemConfig_.IsPadWindow()) {
2931         if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
2932             WindowMode::WINDOW_MODE_FULLSCREEN)) {
2933             TLOGE(WmsLogTag::WMS_IMMS, "fullscreen window mode not supported");
2934             return WMError::WM_ERROR_INVALID_WINDOW;
2935         }
2936         CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2937         auto event = SessionEvent::EVENT_MAXIMIZE;
2938         if (isFullScreenWaterfallMode_.load()) {
2939             event = SessionEvent::EVENT_MAXIMIZE_WATERFALL;
2940         } else if (isWaterfallToMaximize_.load()) {
2941             event = SessionEvent::EVENT_WATERFALL_TO_MAXIMIZE;
2942             isWaterfallToMaximize_.store(false);
2943         }
2944         hostSession->OnSessionEvent(event);
2945         SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
2946     }
2947 
2948     WMError ret = SetLayoutFullScreenByApiVersion(status);
2949     if (ret != WMError::WM_OK) {
2950         property_->SetIsLayoutFullScreen(preStatus);
2951         TLOGE(WmsLogTag::WMS_IMMS, "failed, win %{public}u errCode %{public}d",
2952             GetWindowId(), static_cast<int32_t>(ret));
2953     }
2954     enableImmersiveMode_ = status;
2955     return ret;
2956 }
2957 
SetTitleAndDockHoverShown(bool isTitleHoverShown,bool isDockHoverShown)2958 WMError WindowSceneSessionImpl::SetTitleAndDockHoverShown(
2959     bool isTitleHoverShown, bool isDockHoverShown)
2960 {
2961     if (IsWindowSessionInvalid()) {
2962         return WMError::WM_ERROR_INVALID_WINDOW;
2963     }
2964     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId:%{public}u %{public}s isTitleHoverShown:%{public}d, "
2965         "isDockHoverShown:%{public}d", GetWindowId(), GetWindowName().c_str(), isTitleHoverShown, isDockHoverShown);
2966     if (!WindowHelper::IsMainWindow(GetType())) {
2967         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "window is not main window");
2968         return WMError::WM_ERROR_INVALID_CALLING;
2969     }
2970     if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
2971         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is PcAppInPad, not supported");
2972         return WMError::WM_OK;
2973     }
2974     if (!IsPcOrPadFreeMultiWindowMode()) {
2975         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
2976         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2977     }
2978     titleHoverShowEnabled_ = isTitleHoverShown;
2979     dockHoverShowEnabled_ = isDockHoverShown;
2980     if (auto hostSession = GetHostSession()) {
2981         hostSession->OnTitleAndDockHoverShowChange(isTitleHoverShown, isDockHoverShown);
2982     }
2983     return WMError::WM_OK;
2984 }
2985 
IsLayoutFullScreen() const2986 bool WindowSceneSessionImpl::IsLayoutFullScreen() const
2987 {
2988     if (IsWindowSessionInvalid()) {
2989         return false;
2990     }
2991     WindowType winType = property_->GetWindowType();
2992     if (WindowHelper::IsMainWindow(winType)) {
2993         return (GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && isIgnoreSafeArea_);
2994     }
2995     if (WindowHelper::IsSubWindow(winType)) {
2996         return (isIgnoreSafeAreaNeedNotify_ && isIgnoreSafeArea_);
2997     }
2998     return false;
2999 }
3000 
GetSystemBarPropertyByType(WindowType type) const3001 SystemBarProperty WindowSceneSessionImpl::GetSystemBarPropertyByType(WindowType type) const
3002 {
3003     auto curProperties = property_->GetSystemBarProperty();
3004     return curProperties[type];
3005 }
3006 
NotifyWindowSessionProperty()3007 WMError WindowSceneSessionImpl::NotifyWindowSessionProperty()
3008 {
3009     TLOGD(WmsLogTag::WMS_IMMS, "windowId:%{public}u", GetWindowId());
3010     if (IsWindowSessionInvalid()) {
3011         TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
3012         return WMError::WM_ERROR_INVALID_WINDOW;
3013     }
3014     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS);
3015     return WMError::WM_OK;
3016 }
3017 
NotifySpecificWindowSessionProperty(WindowType type,const SystemBarProperty & property)3018 WMError WindowSceneSessionImpl::NotifySpecificWindowSessionProperty(WindowType type, const SystemBarProperty& property)
3019 {
3020     TLOGD(WmsLogTag::WMS_IMMS, "windowId:%{public}u", GetWindowId());
3021     if (IsWindowSessionInvalid()) {
3022         TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
3023         return WMError::WM_ERROR_INVALID_WINDOW;
3024     }
3025     if (type == WindowType::WINDOW_TYPE_STATUS_BAR) {
3026         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS);
3027         if (auto uiContent = GetUIContentSharedPtr()) {
3028             uiContent->SetStatusBarItemColor(property.contentColor_);
3029             AAFwk::Want want;
3030             want.SetParam(Extension::HOST_STATUS_BAR_CONTENT_COLOR, static_cast<int32_t>(property.contentColor_));
3031             uiContent->SendUIExtProprty(
3032                 static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_STATUS_BAR_CONTENT_COLOR), want,
3033                 static_cast<uint8_t>(SubSystemId::WM_UIEXT));
3034         }
3035         if (property_->IsAdaptToImmersive() && isIgnoreSafeArea_) {
3036             HookDecorButtonStyleInCompatibleMode(property.contentColor_);
3037         }
3038     } else if (type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
3039         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS);
3040     } else if (type == WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR) {
3041         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS);
3042     }
3043     return WMError::WM_OK;
3044 }
3045 
HookDecorButtonStyleInCompatibleMode(uint32_t color)3046 void WindowSceneSessionImpl::HookDecorButtonStyleInCompatibleMode(uint32_t color)
3047 {
3048     if (!property_->IsAdaptToImmersive()) {
3049         return;
3050     }
3051     // alpha Color Channel
3052     auto alpha = (color >> 24) & 0xFF;
3053     // R Color Channel
3054     auto red = (color >> 16) & 0xFF;
3055     // G Color Channel
3056     auto green = (color >> 8) & 0xFF;
3057     // B Color Channel
3058     auto blue = color & 0xFF;
3059     // calculate luminance, Identify whether a color is more black or more white.
3060     double luminance = 0.299 * red + 0.587 * green + 0.114 * blue;
3061     DecorButtonStyle style;
3062     style.colorMode = ((luminance > (0xFF>>1)) || (alpha == 0x00)) ? LIGHT_COLOR_MODE : DARK_COLOR_MODE;
3063     TLOGI(WmsLogTag::WMS_DECOR, "contentColor:%{public}d luminance:%{public}f colorMode:%{public}d",
3064         color, luminance, style.colorMode);
3065     SetDecorButtonStyle(style);
3066 }
3067 
SetSpecificBarProperty(WindowType type,const SystemBarProperty & property)3068 WMError WindowSceneSessionImpl::SetSpecificBarProperty(WindowType type, const SystemBarProperty& property)
3069 {
3070     if (IsWindowSessionInvalid()) {
3071         return WMError::WM_ERROR_INVALID_WINDOW;
3072     }
3073     if (!WindowHelper::IsMainWindow(GetType())) {
3074         TLOGI(WmsLogTag::WMS_IMMS, "only main window support");
3075         return WMError::WM_OK;
3076     }
3077     if (!(state_ > WindowState::STATE_INITIAL && state_ < WindowState::STATE_BOTTOM)) {
3078         TLOGE(WmsLogTag::WMS_IMMS, "win %{public}u invalid state", GetWindowId());
3079         return WMError::WM_ERROR_INVALID_WINDOW;
3080     } else if (GetSystemBarPropertyByType(type) == property &&
3081         property.settingFlag_ == SystemBarSettingFlag::DEFAULT_SETTING) {
3082         setSameSystembarPropertyCnt_++;
3083         TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] set "
3084             "%{public}u %{public}u %{public}x %{public}x %{public}u, for %{public}u times",
3085             GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type), property.enable_,
3086             property.backgroundColor_, property.contentColor_, property.enableAnimation_,
3087             setSameSystembarPropertyCnt_);
3088         return WMError::WM_OK;
3089     }
3090     setSameSystembarPropertyCnt_ = 0;
3091     TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] type %{public}u "
3092         "%{public}u %{public}x %{public}x %{public}u %{public}u",
3093         GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type), property.enable_,
3094         property.backgroundColor_, property.contentColor_, property.enableAnimation_, property.settingFlag_);
3095 
3096     isSystembarPropertiesSet_ = true;
3097     property_->SetSystemBarProperty(type, property);
3098     WMError ret = NotifySpecificWindowSessionProperty(type, property);
3099     if (ret != WMError::WM_OK) {
3100         TLOGE(WmsLogTag::WMS_IMMS, "win %{public}u errCode %{public}d",
3101             GetWindowId(), static_cast<int32_t>(ret));
3102     }
3103     return ret;
3104 }
3105 
UpdateSystemBarProperties(const std::unordered_map<WindowType,SystemBarProperty> & systemBarProperties,const std::unordered_map<WindowType,SystemBarPropertyFlag> & systemBarPropertyFlags)3106 WMError WindowSceneSessionImpl::UpdateSystemBarProperties(
3107     const std::unordered_map<WindowType, SystemBarProperty>& systemBarProperties,
3108     const std::unordered_map<WindowType, SystemBarPropertyFlag>& systemBarPropertyFlags)
3109 {
3110     for (auto [systemBarType, systemBarPropertyFlag] : systemBarPropertyFlags) {
3111         if (systemBarProperties.find(systemBarType) == systemBarProperties.end()) {
3112             TLOGE(WmsLogTag::WMS_IMMS, "system bar type is invalid");
3113             return WMError::WM_DO_NOTHING;
3114         }
3115         auto property = GetSystemBarPropertyByType(systemBarType);
3116         property.enable_ = systemBarPropertyFlag.enableFlag ?
3117             systemBarProperties.at(systemBarType).enable_ : property.enable_;
3118         property.backgroundColor_ = systemBarPropertyFlag.backgroundColorFlag ?
3119             systemBarProperties.at(systemBarType).backgroundColor_ : property.backgroundColor_;
3120         property.contentColor_ = systemBarPropertyFlag.contentColorFlag ?
3121             systemBarProperties.at(systemBarType).contentColor_ : property.contentColor_;
3122         property.enableAnimation_ = systemBarPropertyFlag.enableAnimationFlag ?
3123             systemBarProperties.at(systemBarType).enableAnimation_ : property.enableAnimation_;
3124 
3125         if (systemBarPropertyFlag.enableFlag) {
3126             property.settingFlag_ |= SystemBarSettingFlag::ENABLE_SETTING;
3127         }
3128         if (systemBarPropertyFlag.backgroundColorFlag || systemBarPropertyFlag.contentColorFlag) {
3129             property.settingFlag_ |= SystemBarSettingFlag::COLOR_SETTING;
3130         }
3131         if (systemBarPropertyFlag.enableFlag || systemBarPropertyFlag.backgroundColorFlag ||
3132             systemBarPropertyFlag.contentColorFlag || systemBarPropertyFlag.enableAnimationFlag) {
3133             auto err = SetSystemBarProperty(systemBarType, property);
3134             if (err != WMError::WM_OK) {
3135                 return err;
3136             }
3137         }
3138     }
3139     return WMError::WM_OK;
3140 }
3141 
SetSystemBarProperty(WindowType type,const SystemBarProperty & property)3142 WMError WindowSceneSessionImpl::SetSystemBarProperty(WindowType type, const SystemBarProperty& property)
3143 {
3144     return SetSpecificBarProperty(type, property);
3145 }
3146 
SetSystemBarProperties(const std::map<WindowType,SystemBarProperty> & properties,const std::map<WindowType,SystemBarPropertyFlag> & propertyFlags)3147 WMError WindowSceneSessionImpl::SetSystemBarProperties(const std::map<WindowType, SystemBarProperty>& properties,
3148     const std::map<WindowType, SystemBarPropertyFlag>& propertyFlags)
3149 {
3150     SystemBarProperty current = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
3151     auto flagIter = propertyFlags.find(WindowType::WINDOW_TYPE_STATUS_BAR);
3152     auto propertyIter = properties.find(WindowType::WINDOW_TYPE_STATUS_BAR);
3153     if ((flagIter != propertyFlags.end() && flagIter->second.contentColorFlag) &&
3154         (propertyIter != properties.end() && current.contentColor_ != propertyIter->second.contentColor_)) {
3155         current.contentColor_ = propertyIter->second.contentColor_;
3156         current.settingFlag_ = static_cast<SystemBarSettingFlag>(
3157             static_cast<uint32_t>(propertyIter->second.settingFlag_) |
3158             static_cast<uint32_t>(SystemBarSettingFlag::COLOR_SETTING));
3159         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u set status bar content color %{public}u",
3160             GetWindowId(), current.contentColor_);
3161         return SetSpecificBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, current);
3162     }
3163     return WMError::WM_OK;
3164 }
3165 
GetSystemBarProperties(std::map<WindowType,SystemBarProperty> & properties)3166 WMError WindowSceneSessionImpl::GetSystemBarProperties(std::map<WindowType, SystemBarProperty>& properties)
3167 {
3168     auto currProperties = property_->GetSystemBarProperty();
3169     properties[WindowType::WINDOW_TYPE_STATUS_BAR] = currProperties[WindowType::WINDOW_TYPE_STATUS_BAR];
3170     return WMError::WM_OK;
3171 }
3172 
SetSystemBarPropertyForPage(WindowType type,std::optional<SystemBarProperty> property)3173 WMError WindowSceneSessionImpl::SetSystemBarPropertyForPage(WindowType type, std::optional<SystemBarProperty> property)
3174 {
3175     if (IsWindowSessionInvalid()) {
3176         TLOGE(WmsLogTag::WMS_IMMS, "win %{public}u invalid state", GetWindowId());
3177         return WMError::WM_ERROR_INVALID_WINDOW;
3178     }
3179     if (!WindowHelper::IsMainWindow(GetType())) {
3180         TLOGI(WmsLogTag::WMS_IMMS, "only main window support, win %{public}u", GetWindowId());
3181         return WMError::WM_DO_NOTHING;
3182     }
3183     if (property == std::nullopt) {
3184         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u property is nullptr use main window prop", GetWindowId());
3185         return NotifySpecificWindowSessionProperty(type, GetSystemBarPropertyByType(type));
3186     }
3187     TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] type %{public}u "
3188         "%{public}u %{public}x %{public}x %{public}u %{public}u",
3189         GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type),
3190         property->enable_, property->backgroundColor_,
3191         property->contentColor_, property->enableAnimation_, property->settingFlag_);
3192     auto lastProperty = GetSystemBarPropertyByType(type);
3193     property_->SetSystemBarProperty(type, property.value());
3194     auto ret = NotifySpecificWindowSessionProperty(type, property.value());
3195     property_->SetSystemBarProperty(type, lastProperty);
3196     if (ret != WMError::WM_OK) {
3197         TLOGE(WmsLogTag::WMS_IMMS, "set prop fail, ret %{public}u", ret);
3198         return ret;
3199     }
3200     return WMError::WM_OK;
3201 }
3202 
GetSystemBarPropertyForPage(const std::map<WindowType,SystemBarProperty> & properties,std::map<WindowType,SystemBarProperty> & pageProperties)3203 void WindowSceneSessionImpl::GetSystemBarPropertyForPage(const std::map<WindowType, SystemBarProperty>& properties,
3204     std::map<WindowType, SystemBarProperty>& pageProperties)
3205 {
3206     for (auto type : { WindowType::WINDOW_TYPE_STATUS_BAR, WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR }) {
3207         if (properties.find(type) != properties.end()) {
3208             pageProperties[type] = properties.at(type);
3209         } else {
3210             pageProperties[type] = GetSystemBarPropertyByType(type);
3211         }
3212         TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] type %{public}u "
3213             "%{public}u %{public}x %{public}x %{public}u %{public}u",
3214             GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type),
3215             pageProperties[type].enable_, pageProperties[type].backgroundColor_,
3216             pageProperties[type].contentColor_, pageProperties[type].enableAnimation_,
3217             pageProperties[type].settingFlag_);
3218     }
3219 }
3220 
SetFullScreen(bool status)3221 WMError WindowSceneSessionImpl::SetFullScreen(bool status)
3222 {
3223     TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] status %{public}d",
3224         GetWindowId(), GetWindowName().c_str(), static_cast<int32_t>(status));
3225     if (IsWindowSessionInvalid()) {
3226         return WMError::WM_ERROR_INVALID_WINDOW;
3227     }
3228     if (WindowHelper::IsSystemWindow(GetType())) {
3229         TLOGI(WmsLogTag::WMS_IMMS, "system window not supported");
3230         return WMError::WM_OK;
3231     }
3232 
3233     if (WindowHelper::IsMainWindow(GetType()) && IsPcOrPadFreeMultiWindowMode()) {
3234         if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
3235             WindowMode::WINDOW_MODE_FULLSCREEN)) {
3236             TLOGE(WmsLogTag::WMS_IMMS, "fullscreen window not supported");
3237             return WMError::WM_ERROR_INVALID_WINDOW;
3238         }
3239         auto hostSession = GetHostSession();
3240         CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
3241         hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
3242         SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
3243     };
3244 
3245     WMError ret = SetLayoutFullScreenByApiVersion(status);
3246     if (ret != WMError::WM_OK) {
3247         TLOGE(WmsLogTag::WMS_IMMS, "failed, win %{public}u errCode %{public}d",
3248             GetWindowId(), static_cast<int32_t>(ret));
3249     }
3250 
3251     UpdateDecorEnable(true);
3252     SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
3253     statusProperty.enable_ = !status;
3254     ret = SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
3255     if (ret != WMError::WM_OK) {
3256         TLOGE(WmsLogTag::WMS_IMMS, "SetSystemBarProperty win %{public}u errCode %{public}d",
3257             GetWindowId(), static_cast<int32_t>(ret));
3258     }
3259 
3260     return ret;
3261 }
3262 
IsFullScreen() const3263 bool WindowSceneSessionImpl::IsFullScreen() const
3264 {
3265     SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
3266     return (IsLayoutFullScreen() && !statusProperty.enable_);
3267 }
3268 
IsDecorEnable() const3269 bool WindowSceneSessionImpl::IsDecorEnable() const
3270 {
3271     WindowType windowType = GetType();
3272     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
3273     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
3274     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
3275     bool isValidWindow = isMainWindow ||
3276         ((isSubWindow || isDialogWindow) && property_->IsDecorEnable());
3277     bool isWindowModeSupported = WindowHelper::IsWindowModeSupported(
3278         windowSystemConfig_.decorWindowModeSupportType_, GetWindowMode());
3279     if (windowSystemConfig_.freeMultiWindowSupport_) {
3280         return isValidWindow && windowSystemConfig_.isSystemDecorEnable_;
3281     }
3282     bool enable = isValidWindow && windowSystemConfig_.isSystemDecorEnable_ &&
3283         isWindowModeSupported;
3284     if ((isSubWindow || isDialogWindow) && property_->GetIsPcAppInPad() && property_->IsDecorEnable()) {
3285         enable = true;
3286     }
3287     TLOGD(WmsLogTag::WMS_DECOR, "get decor enable %{public}d", enable);
3288     return enable;
3289 }
3290 
SetWindowTitle(const std::string & title)3291 WMError WindowSceneSessionImpl::SetWindowTitle(const std::string& title)
3292 {
3293     if (IsWindowSessionInvalid()) {
3294         TLOGE(WmsLogTag::WMS_DECOR, "Session is invalid");
3295         return WMError::WM_ERROR_INVALID_WINDOW;
3296     }
3297     if (property_->GetPcAppInpadCompatibleMode() && !IsDecorEnable()) {
3298         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is PcAppInPad, not supported");
3299         return WMError::WM_OK;
3300     }
3301     if (!(windowSystemConfig_.IsPcWindow() || windowSystemConfig_.IsPadWindow() ||
3302           IsDeviceFeatureCapableForFreeMultiWindow())) {
3303         TLOGE(WmsLogTag::WMS_DECOR, "device not support");
3304         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3305     }
3306     if (!IsDecorEnable()) {
3307         TLOGE(WmsLogTag::WMS_DECOR, "DecorEnable is false");
3308         return WMError::WM_ERROR_INVALID_WINDOW;
3309     }
3310     if (WindowHelper::IsMainWindow(GetType())) {
3311         auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(GetContext());
3312         if (abilityContext == nullptr) {
3313             return WMError::WM_ERROR_NULLPTR;
3314         }
3315         abilityContext->SetMissionLabel(title);
3316     } else {
3317         return SetAPPWindowLabel(title);
3318     }
3319     return WMError::WM_OK;
3320 }
3321 
Minimize()3322 WMError WindowSceneSessionImpl::Minimize()
3323 {
3324     WLOGFI("id: %{public}d", GetPersistentId());
3325     if (IsWindowSessionInvalid()) {
3326         WLOGFE("session is invalid");
3327         return WMError::WM_ERROR_INVALID_WINDOW;
3328     }
3329     auto hostSession = GetHostSession();
3330     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3331     if (WindowHelper::IsMainWindow(GetType())) {
3332         hostSession->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
3333     } else {
3334         WLOGFE("This window state is abnormal.");
3335         return WMError::WM_DO_NOTHING;
3336     }
3337     return WMError::WM_OK;
3338 }
3339 
MaximizeForCompatibleMode()3340 WMError WindowSceneSessionImpl::MaximizeForCompatibleMode()
3341 {
3342     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3343     if (IsWindowSessionInvalid()) {
3344         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3345         return WMError::WM_ERROR_INVALID_WINDOW;
3346     }
3347     if (!WindowHelper::IsMainWindow(GetType())) {
3348         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "maximize fail, not main");
3349         return WMError::WM_ERROR_INVALID_CALLING;
3350     }
3351     auto hostSession = GetHostSession();
3352     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
3353     hostSession->OnSessionEvent(SessionEvent::EVENT_COMPATIBLE_TO_MAXIMIZE);
3354     return WMError::WM_OK;
3355 }
3356 
RecoverForCompatibleMode()3357 WMError WindowSceneSessionImpl::RecoverForCompatibleMode()
3358 {
3359     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3360     if (IsWindowSessionInvalid()) {
3361         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3362         return WMError::WM_ERROR_INVALID_WINDOW;
3363     }
3364     if (!WindowHelper::IsMainWindow(GetType())) {
3365         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "recover fail, not main");
3366         return WMError::WM_ERROR_INVALID_CALLING;
3367     }
3368     auto hostSession = GetHostSession();
3369     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
3370     hostSession->OnSessionEvent(SessionEvent::EVENT_COMPATIBLE_TO_RECOVER);
3371     return WMError::WM_OK;
3372 }
3373 
Maximize()3374 WMError WindowSceneSessionImpl::Maximize()
3375 {
3376     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3377     if (IsWindowSessionInvalid()) {
3378         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3379         return WMError::WM_ERROR_INVALID_WINDOW;
3380     }
3381     if (WindowHelper::IsMainWindow(GetType())) {
3382         SetLayoutFullScreen(enableImmersiveMode_);
3383     }
3384     return WMError::WM_OK;
3385 }
3386 
Maximize(MaximizePresentation presentation)3387 WMError WindowSceneSessionImpl::Maximize(MaximizePresentation presentation)
3388 {
3389     if (IsWindowSessionInvalid()) {
3390         return WMError::WM_ERROR_INVALID_WINDOW;
3391     }
3392     if (!WindowHelper::IsMainWindow(GetType())) {
3393         if (IsSubWindowMaximizeSupported()) {
3394             return MaximizeFloating();
3395         }
3396         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "maximize fail, not main or sub window");
3397         return WMError::WM_ERROR_INVALID_CALLING;
3398     }
3399     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
3400         WindowMode::WINDOW_MODE_FULLSCREEN)) {
3401         return WMError::WM_ERROR_INVALID_WINDOW;
3402     }
3403     // The device is not supported
3404     if (!IsPcOrPadFreeMultiWindowMode() || property_->IsFullScreenDisabled()) {
3405         TLOGW(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3406         return WMError::WM_OK;
3407     }
3408     titleHoverShowEnabled_ = true;
3409     dockHoverShowEnabled_ = true;
3410     switch (presentation) {
3411         case MaximizePresentation::ENTER_IMMERSIVE:
3412             enableImmersiveMode_ = true;
3413             break;
3414         case MaximizePresentation::EXIT_IMMERSIVE:
3415             enableImmersiveMode_ = false;
3416             break;
3417         case MaximizePresentation::ENTER_IMMERSIVE_DISABLE_TITLE_AND_DOCK_HOVER:
3418             enableImmersiveMode_ = true;
3419             titleHoverShowEnabled_ = false;
3420             dockHoverShowEnabled_ = false;
3421             break;
3422         case MaximizePresentation::FOLLOW_APP_IMMERSIVE_SETTING:
3423             break;
3424     }
3425     property_->SetIsLayoutFullScreen(enableImmersiveMode_);
3426     auto hostSession = GetHostSession();
3427     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
3428     hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
3429     hostSession->OnTitleAndDockHoverShowChange(titleHoverShowEnabled_, dockHoverShowEnabled_);
3430     SetLayoutFullScreenByApiVersion(enableImmersiveMode_);
3431     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "present: %{public}d, enableImmersiveMode_:%{public}d!",
3432         presentation, enableImmersiveMode_.load());
3433     hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
3434     return SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
3435 }
3436 
MaximizeFloating()3437 WMError WindowSceneSessionImpl::MaximizeFloating()
3438 {
3439     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3440     if (IsWindowSessionInvalid()) {
3441         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3442         return WMError::WM_ERROR_INVALID_WINDOW;
3443     }
3444     auto hostSession = GetHostSession();
3445     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3446     if (!WindowHelper::IsMainWindow(property_->GetWindowType()) && !IsSubWindowMaximizeSupported()) {
3447         TLOGW(WmsLogTag::WMS_LAYOUT_PC,
3448               "SetGlobalMaximizeMode fail, not main or sub window, id %{public}d",
3449               GetPersistentId());
3450         return WMError::WM_ERROR_INVALID_WINDOW;
3451     }
3452     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
3453         WindowMode::WINDOW_MODE_FULLSCREEN)) {
3454         return WMError::WM_ERROR_INVALID_WINDOW;
3455     }
3456     if (property_->IsFullScreenDisabled()) {
3457         TLOGW(WmsLogTag::WMS_COMPAT, "diable fullScreen in compatibleMode window ,id:%{public}d", GetPersistentId());
3458         return WMError::WM_ERROR_INVALID_WINDOW;
3459     }
3460     if (GetGlobalMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
3461         hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
3462         SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
3463         UpdateDecorEnable(true);
3464         property_->SetMaximizeMode(MaximizeMode::MODE_FULL_FILL);
3465     } else {
3466         hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE_FLOATING);
3467         SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3468         property_->SetMaximizeMode(MaximizeMode::MODE_AVOID_SYSTEM_BAR);
3469         UpdateDecorEnable(true);
3470         NotifyWindowStatusChange(GetWindowMode());
3471     }
3472     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
3473 
3474     return WMError::WM_OK;
3475 }
3476 
Recover()3477 WMError WindowSceneSessionImpl::Recover()
3478 {
3479     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3480     if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && isFullScreenWaterfallMode_.load() &&
3481         lastWindowModeBeforeWaterfall_.load() == WindowMode::WINDOW_MODE_FULLSCREEN) {
3482         isWaterfallToMaximize_.store(true);
3483         SetFullScreenWaterfallMode(false);
3484         WMError ret = Maximize();
3485         if (ret != WMError::WM_OK) {
3486             TLOGE(WmsLogTag::WMS_LAYOUT_PC, "recover to fullscreen failed");
3487             isWaterfallToMaximize_.store(false);
3488             SetFullScreenWaterfallMode(true);
3489         }
3490         return ret;
3491     }
3492     if (IsWindowSessionInvalid()) {
3493         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3494         return WMError::WM_ERROR_INVALID_WINDOW;
3495     }
3496     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING)) {
3497         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "not support floating, can not Recover");
3498         return WMError::WM_ERROR_INVALID_OPERATION;
3499     }
3500     auto hostSession = GetHostSession();
3501     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3502     if (WindowHelper::IsMainWindow(GetType()) || IsSubWindowMaximizeSupported()) {
3503         if (property_->GetMaximizeMode() == MaximizeMode::MODE_RECOVER &&
3504             property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
3505             TLOGW(WmsLogTag::WMS_LAYOUT_PC, "Recover fail, already MODE_RECOVER");
3506             return WMError::WM_ERROR_REPEAT_OPERATION;
3507         }
3508         if (enableImmersiveMode_) {
3509             enableImmersiveMode_ = false;
3510             property_->SetIsLayoutFullScreen(enableImmersiveMode_);
3511             hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
3512         }
3513         hostSession->OnSessionEvent(SessionEvent::EVENT_RECOVER);
3514         SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3515         property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
3516         UpdateDecorEnable(true);
3517         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
3518         NotifyWindowStatusChange(GetWindowMode());
3519     } else {
3520         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "recovery is invalid, window id: %{public}d", GetPersistentId());
3521         return WMError::WM_ERROR_INVALID_OPERATION;
3522     }
3523     return WMError::WM_OK;
3524 }
3525 
Restore()3526 WMError WindowSceneSessionImpl::Restore()
3527 {
3528     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3529     if (IsWindowSessionInvalid()) {
3530         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3531         return WMError::WM_ERROR_INVALID_WINDOW;
3532     }
3533     if (!WindowHelper::IsMainWindow(GetType())) {
3534         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "Restore fail, not main window");
3535         return WMError::WM_ERROR_INVALID_CALLING;
3536     }
3537     if (!(windowSystemConfig_.IsPcWindow() || property_->GetIsPcAppInPad())) {
3538         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is not PC or PcAppInPad, not supported");
3539         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3540     }
3541     if (property_->GetIsAppSupportPhoneInPc()) {
3542         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is PhoneAppSupportOnPc, not supported");
3543         return WMError::WM_ERROR_INVALID_CALLING;
3544     }
3545     auto hostSession = GetHostSession();
3546     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
3547     hostSession->OnRestoreMainWindow();
3548     return WMError::WM_OK;
3549 }
3550 
Recover(uint32_t reason)3551 WMError WindowSceneSessionImpl::Recover(uint32_t reason)
3552 {
3553     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d, reason: %{public}u", GetPersistentId(), reason);
3554     if (IsWindowSessionInvalid()) {
3555         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3556         return WMError::WM_ERROR_INVALID_WINDOW;
3557     }
3558     if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
3559         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3560         return WMError::WM_OK;
3561     }
3562     if (!IsPcOrPadFreeMultiWindowMode()) {
3563         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3564         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3565     }
3566     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING)) {
3567         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "not support floating, can not Recover");
3568         return WMError::WM_ERROR_INVALID_OPERATION;
3569     }
3570     auto hostSession = GetHostSession();
3571     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3572     if (WindowHelper::IsMainWindow(GetType()) || IsSubWindowMaximizeSupported()) {
3573         if (property_->GetMaximizeMode() == MaximizeMode::MODE_RECOVER &&
3574             property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
3575             TLOGW(WmsLogTag::WMS_LAYOUT_PC, "Recover fail, already MODE_RECOVER");
3576             return WMError::WM_ERROR_REPEAT_OPERATION;
3577         }
3578         if (enableImmersiveMode_) {
3579             enableImmersiveMode_ = false;
3580             property_->SetIsLayoutFullScreen(enableImmersiveMode_);
3581             hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
3582         }
3583         hostSession->OnSessionEvent(SessionEvent::EVENT_RECOVER);
3584         // need notify arkui maximize mode change
3585         if (reason == REASON_MAXIMIZE_MODE_CHANGE &&
3586             property_->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
3587             UpdateMaximizeMode(MaximizeMode::MODE_RECOVER);
3588         }
3589         SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3590         property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
3591         UpdateDecorEnable(true);
3592         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
3593         NotifyWindowStatusChange(GetWindowMode());
3594     } else {
3595         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "recovery is invalid on sub window");
3596         return WMError::WM_ERROR_INVALID_OPERATION;
3597     }
3598     return WMError::WM_OK;
3599 }
3600 
SetWindowRectAutoSave(bool enabled,bool isSaveBySpecifiedFlag)3601 WMError WindowSceneSessionImpl::SetWindowRectAutoSave(bool enabled, bool isSaveBySpecifiedFlag)
3602 {
3603     TLOGI(WmsLogTag::WMS_MAIN, "id: %{public}d", GetPersistentId());
3604     if (IsWindowSessionInvalid()) {
3605         TLOGE(WmsLogTag::WMS_MAIN, "session is invalid");
3606         return WMError::WM_ERROR_INVALID_WINDOW;
3607     }
3608 
3609     if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
3610         TLOGE(WmsLogTag::WMS_MAIN, "This is PcAppInPad, not supported");
3611         return WMError::WM_OK;
3612     }
3613 
3614     if (!IsPcOrPadFreeMultiWindowMode()) {
3615         TLOGE(WmsLogTag::WMS_MAIN, "This is not PC mode or free multi window mode, not supported");
3616         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3617     }
3618 
3619     if (!WindowHelper::IsMainWindow(GetType())) {
3620         TLOGE(WmsLogTag::WMS_MAIN, "This is not main window, not supported");
3621         return WMError::WM_ERROR_INVALID_CALLING;
3622     }
3623 
3624     auto hostSession = GetHostSession();
3625     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
3626     hostSession->OnSetWindowRectAutoSave(enabled, isSaveBySpecifiedFlag);
3627     return WMError::WM_OK;
3628 }
3629 
IsWindowRectAutoSave(bool & enabled)3630 WMError WindowSceneSessionImpl::IsWindowRectAutoSave(bool& enabled)
3631 {
3632     if (IsWindowSessionInvalid()) {
3633         TLOGE(WmsLogTag::WMS_MAIN, "session is invalid");
3634         return WMError::WM_ERROR_INVALID_WINDOW;
3635     }
3636 
3637     if (property_->GetPcAppInpadCompatibleMode()) {
3638         TLOGE(WmsLogTag::WMS_MAIN, "This is PcAppInPad, not supported");
3639         return WMError::WM_OK;
3640     }
3641 
3642     if (!windowSystemConfig_.IsPcWindow()) {
3643         TLOGE(WmsLogTag::WMS_MAIN, "This is not PC, not supported");
3644         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3645     }
3646 
3647     if (!WindowHelper::IsMainWindow(GetType())) {
3648         TLOGE(WmsLogTag::WMS_MAIN, "This is not main window, not supported");
3649         return WMError::WM_ERROR_INVALID_CALLING;
3650     }
3651     auto context = GetContext();
3652     if (context == nullptr) {
3653         TLOGE(WmsLogTag::WMS_MAIN, "context is nullptr");
3654         return WMError::WM_ERROR_NULLPTR;
3655     }
3656     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
3657     std::string bundleName = property_->GetSessionInfo().bundleName_;
3658     std::string moduleName = property_->GetSessionInfo().moduleName_;
3659     std::string abilityName = property_->GetSessionInfo().abilityName_;
3660     if (abilityContext && abilityContext->GetAbilityInfo()) {
3661         abilityName = abilityContext->GetAbilityInfo()->name;
3662         moduleName = context->GetHapModuleInfo() ? context->GetHapModuleInfo()->moduleName : "";
3663         bundleName = abilityContext->GetAbilityInfo()->bundleName;
3664     } else if (context) {
3665         moduleName = context->GetHapModuleInfo() ? context->GetHapModuleInfo()->moduleName : "";
3666         bundleName = context->GetBundleName();
3667     }
3668     std::string key = bundleName + moduleName + abilityName;
3669     int persistentId = GetPersistentId();
3670     auto ret = SingletonContainer::Get<WindowAdapter>().IsWindowRectAutoSave(key, enabled, persistentId);
3671     return ret;
3672 }
3673 
SetSupportedWindowModes(const std::vector<AppExecFwk::SupportWindowMode> & supportedWindowModes,bool grayOutMaximizeButton)3674 WMError WindowSceneSessionImpl::SetSupportedWindowModes(
3675     const std::vector<AppExecFwk::SupportWindowMode>& supportedWindowModes, bool grayOutMaximizeButton)
3676 {
3677     if (IsWindowSessionInvalid()) {
3678         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3679         return WMError::WM_ERROR_INVALID_WINDOW;
3680     }
3681 
3682     if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
3683         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is PcAppInpad, not supported");
3684         return WMError::WM_OK;
3685     }
3686 
3687     if (!(windowSystemConfig_.IsPcWindow() || windowSystemConfig_.freeMultiWindowSupport_)) {
3688         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "Neither is Pc nor support free multi window, invalid calling");
3689         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3690     }
3691 
3692     if (!WindowHelper::IsMainWindow(GetType())) {
3693         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is not main window, not supported");
3694         return WMError::WM_ERROR_INVALID_CALLING;
3695     }
3696 
3697     if (grayOutMaximizeButton) {
3698         size_t size = supportedWindowModes.size();
3699         if (size == 0 || size > WINDOW_SUPPORT_MODE_MAX_SIZE) {
3700             TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is invalid");
3701             return WMError::WM_ERROR_ILLEGAL_PARAM;
3702         }
3703         if (std::find(supportedWindowModes.begin(), supportedWindowModes.end(),
3704             AppExecFwk::SupportWindowMode::FULLSCREEN) != supportedWindowModes.end()) {
3705             TLOGE(WmsLogTag::WMS_LAYOUT_PC, "Supports full screen cannot be grayed out");
3706             return WMError::WM_ERROR_ILLEGAL_PARAM;
3707         }
3708         GrayOutMaximizeButton(true);
3709     } else if (grayOutMaximizeButton_) {
3710         GrayOutMaximizeButton(false);
3711     }
3712 
3713     return SetSupportedWindowModesInner(supportedWindowModes);
3714 }
3715 
GrayOutMaximizeButton(bool isGrayOut)3716 WMError WindowSceneSessionImpl::GrayOutMaximizeButton(bool isGrayOut)
3717 {
3718     if (grayOutMaximizeButton_ == isGrayOut) {
3719         TLOGW(WmsLogTag::WMS_LAYOUT_PC, "Duplicate settings are gray out: %{public}d", isGrayOut);
3720         return WMError::WM_DO_NOTHING;
3721     }
3722     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3723     if (uiContent == nullptr) {
3724         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "uicontent is empty");
3725         return WMError::WM_ERROR_NULLPTR;
3726     }
3727     grayOutMaximizeButton_ = isGrayOut;
3728     uiContent->OnContainerModalEvent(WINDOW_GRAY_OUT_MAXIMIZE_EVENT, isGrayOut ? "true" : "false");
3729     return WMError::WM_OK;
3730 }
3731 
UpdateWindowModeWhenSupportTypeChange(uint32_t windowModeSupportType)3732 void WindowSceneSessionImpl::UpdateWindowModeWhenSupportTypeChange(uint32_t windowModeSupportType)
3733 {
3734     bool onlySupportFullScreen =
3735         WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
3736         !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING);
3737     bool disableFullScreen = property_->IsFullScreenDisabled();
3738     if (onlySupportFullScreen && !property_->IsLayoutFullScreen() && !disableFullScreen) {
3739         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "onlySupportFullScreen:%{public}d IsLayoutFullScreen:%{public}d",
3740             onlySupportFullScreen, property_->IsLayoutFullScreen());
3741         Maximize(MaximizePresentation::ENTER_IMMERSIVE);
3742         return;
3743     }
3744 
3745     bool onlySupportFloating =
3746         !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
3747         WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING);
3748     if (onlySupportFloating) {
3749         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "onlySupportFloating:%{public}d", onlySupportFloating);
3750         Recover(REASON_MAXIMIZE_MODE_CHANGE);
3751     }
3752 }
3753 
SetSupportedWindowModesInner(const std::vector<AppExecFwk::SupportWindowMode> & supportedWindowModes)3754 WMError WindowSceneSessionImpl::SetSupportedWindowModesInner(
3755     const std::vector<AppExecFwk::SupportWindowMode>& supportedWindowModes)
3756 {
3757     auto size = supportedWindowModes.size();
3758     if (size <= 0 || size > WINDOW_SUPPORT_MODE_MAX_SIZE) {
3759         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is invalid");
3760         return WMError::WM_ERROR_INVALID_PARAM;
3761     }
3762 
3763     uint32_t windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(supportedWindowModes);
3764     if (windowModeSupportType == 0) {
3765         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is 0");
3766         return WMError::WM_ERROR_INVALID_PARAM;
3767     }
3768     bool onlySupportSplit = (windowModeSupportType ==
3769                             (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
3770                              WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY));
3771     if (onlySupportSplit) {
3772         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is only support split");
3773         return WMError::WM_ERROR_INVALID_PARAM;
3774     }
3775     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId: %{public}u, windowModeSupportType: %{public}u",
3776         GetWindowId(), windowModeSupportType);
3777 
3778     // update windowModeSupportType to server
3779     auto hostSession = GetHostSession();
3780     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
3781     hostSession->NotifySupportWindowModesChange(supportedWindowModes);
3782     if (!IsPcOrPadFreeMultiWindowMode()) {
3783         pendingWindowModeSupportType_ = windowModeSupportType;
3784         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "pending update, winId: %{public}u, windowModeSupportType: %{public}u",
3785             GetWindowId(), windowModeSupportType);
3786         return WMError::WM_OK;
3787     }
3788 
3789     haveSetSupportedWindowModes_ = true;
3790     property_->SetWindowModeSupportType(windowModeSupportType);
3791     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
3792     UpdateTitleButtonVisibility();
3793     UpdateWindowModeWhenSupportTypeChange(windowModeSupportType);
3794     return WMError::WM_OK;
3795 }
3796 
SetImageForRecent(uint32_t imgResourceId,ImageFit imageFit)3797 WMError WindowSceneSessionImpl::SetImageForRecent(uint32_t imgResourceId, ImageFit imageFit)
3798 {
3799     int32_t persistentId = GetPersistentId();
3800     return SingletonContainer::Get<WindowAdapter>().SetImageForRecent(imgResourceId, imageFit, persistentId);
3801 }
3802 
3803 /** @note @window.drag */
StartMove()3804 void WindowSceneSessionImpl::StartMove()
3805 {
3806     WLOGFI("id: %{public}d", GetPersistentId());
3807     if (IsWindowSessionInvalid()) {
3808         WLOGFE("session is invalid");
3809         return;
3810     }
3811     WindowType windowType = GetType();
3812     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
3813     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
3814     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
3815     bool isDecorDialog = isDialogWindow && property_->IsDecorEnable();
3816     bool isValidWindow = isMainWindow || (IsPcOrFreeMultiWindowCapabilityEnabled() && (isSubWindow || isDecorDialog));
3817     auto hostSession = GetHostSession();
3818     if (isValidWindow && hostSession) {
3819         hostSession->OnSessionEvent(SessionEvent::EVENT_START_MOVE);
3820     }
3821 }
3822 
IsStartMoving()3823 bool WindowSceneSessionImpl::IsStartMoving()
3824 {
3825     bool isMoving = false;
3826     if (auto hostSession = GetHostSession()) {
3827         isMoving = hostSession->IsStartMoving();
3828     }
3829     TLOGI(WmsLogTag::WMS_LAYOUT, "id: %{public}d, isMoving: %{public}d", GetPersistentId(), isMoving);
3830     return isMoving;
3831 }
3832 
CalcWindowShouldMove()3833 bool WindowSceneSessionImpl::CalcWindowShouldMove()
3834 {
3835     if ((windowSystemConfig_.IsPhoneWindow() ||
3836         (windowSystemConfig_.IsPadWindow() && !IsFreeMultiWindowMode())) &&
3837         GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
3838             return true;
3839     }
3840 
3841     if (IsPcOrFreeMultiWindowCapabilityEnabled()) {
3842         return true;
3843     }
3844     return false;
3845 }
3846 
CheckCanMoveWindowType()3847 bool WindowSceneSessionImpl::CheckCanMoveWindowType()
3848 {
3849     WindowType windowType = GetType();
3850     if (!WindowHelper::IsSystemWindow(windowType) &&
3851         !WindowHelper::IsMainWindow(windowType) &&
3852         !WindowHelper::IsSubWindow(windowType)) {
3853         return false;
3854     }
3855     return true;
3856 }
3857 
CheckCanMoveWindowTypeByDevice()3858 bool WindowSceneSessionImpl::CheckCanMoveWindowTypeByDevice()
3859 {
3860     WindowType windowType = GetType();
3861     bool isPcOrFreeMultiWindowCanMove = IsPcOrFreeMultiWindowCapabilityEnabled() &&
3862         (WindowHelper::IsSystemWindow(windowType) ||
3863          WindowHelper::IsMainWindow(windowType) ||
3864          WindowHelper::IsSubWindow(windowType));
3865     bool isPhoneWindowCanMove = (windowSystemConfig_.IsPhoneWindow() ||
3866         (windowSystemConfig_.IsPadWindow() && !IsFreeMultiWindowMode())) &&
3867         (WindowHelper::IsSystemWindow(windowType) || WindowHelper::IsSubWindow(windowType));
3868     if (isPcOrFreeMultiWindowCanMove || isPhoneWindowCanMove) {
3869         return true;
3870     }
3871     return false;
3872 }
3873 
CheckIsPcAppInPadFullScreenOnMobileWindowMode()3874 bool WindowSceneSessionImpl::CheckIsPcAppInPadFullScreenOnMobileWindowMode()
3875 {
3876     if (property_->GetIsPcAppInPad() &&
3877         property_->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
3878         !IsFreeMultiWindowMode()) {
3879         return true;
3880     }
3881     return false;
3882 }
3883 
StartMoveWindow()3884 WmErrorCode WindowSceneSessionImpl::StartMoveWindow()
3885 {
3886     if (!CheckCanMoveWindowTypeByDevice()) {
3887         TLOGE(WmsLogTag::WMS_LAYOUT, "invalid window type:%{public}u", GetType());
3888         return WmErrorCode::WM_ERROR_INVALID_CALLING;
3889     }
3890     if (!CalcWindowShouldMove()) {
3891         TLOGE(WmsLogTag::WMS_LAYOUT, "The device is not supported");
3892         return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
3893     }
3894     if (CheckIsPcAppInPadFullScreenOnMobileWindowMode()) {
3895         return WmErrorCode::WM_OK;
3896     }
3897     if (auto hostSession = GetHostSession()) {
3898         WSError errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_START_MOVE);
3899         TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, errorCode:%{public}d",
3900             GetPersistentId(), static_cast<int>(errorCode));
3901         switch (errorCode) {
3902             case WSError::WS_ERROR_REPEAT_OPERATION: {
3903                 return WmErrorCode::WM_ERROR_REPEAT_OPERATION;
3904             }
3905             case WSError::WS_ERROR_NULLPTR: {
3906                 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3907             }
3908             default: {
3909                 return WmErrorCode::WM_OK;
3910             }
3911         }
3912     } else {
3913         TLOGE(WmsLogTag::WMS_LAYOUT, "hostSession is nullptr");
3914         return WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY;
3915     }
3916 }
3917 
StartMoveWindowWithCoordinate(int32_t offsetX,int32_t offsetY)3918 WmErrorCode WindowSceneSessionImpl::StartMoveWindowWithCoordinate(int32_t offsetX, int32_t offsetY)
3919 {
3920     if (!CheckCanMoveWindowType()) {
3921         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "invalid window type:%{public}u", GetType());
3922         return WmErrorCode::WM_ERROR_INVALID_CALLING;
3923     }
3924     if (!IsPcOrFreeMultiWindowCapabilityEnabled()) {
3925         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3926         return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
3927     }
3928     if (CheckIsPcAppInPadFullScreenOnMobileWindowMode()) {
3929         return WmErrorCode::WM_OK;
3930     }
3931     if (IsWindowSessionInvalid()) {
3932         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3933         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3934     }
3935     const auto& windowRect = GetRect();
3936     if (offsetX < 0 || offsetX > static_cast<int32_t>(windowRect.width_) ||
3937         offsetY < 0 || offsetY > static_cast<int32_t>(windowRect.height_)) {
3938         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "offset not in window");
3939         return WmErrorCode::WM_ERROR_INVALID_PARAM;
3940     }
3941     auto hostSession = GetHostSession();
3942     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY);
3943     WSError errorCode;
3944     MMI::PointerEvent::PointerItem pointerItem;
3945     if (lastPointerEvent_ != nullptr &&
3946         lastPointerEvent_->GetPointerItem(lastPointerEvent_->GetPointerId(), pointerItem)) {
3947         int32_t lastDisplayX = pointerItem.GetDisplayX();
3948         int32_t lastDisplayY = pointerItem.GetDisplayY();
3949         int32_t lastDisplayId = lastPointerEvent_->GetTargetDisplayId();
3950         TLOGD(WmsLogTag::WMS_LAYOUT_PC, "offset:[%{public}d,%{public}d] lastEvent:[%{private}d,%{private}d]"
3951             " lastDisplayId:%{public}d", offsetX, offsetY, lastDisplayX, lastDisplayY, lastDisplayId);
3952         errorCode = hostSession->StartMovingWithCoordinate(offsetX, offsetY, lastDisplayX, lastDisplayY, lastDisplayId);
3953     } else {
3954         errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_START_MOVE);
3955     }
3956     TLOGD(WmsLogTag::WMS_LAYOUT_PC, "id:%{public}d, errorCode:%{public}d",
3957           GetPersistentId(), static_cast<int>(errorCode));
3958     switch (errorCode) {
3959         case WSError::WS_ERROR_REPEAT_OPERATION: {
3960             return WmErrorCode::WM_ERROR_REPEAT_OPERATION;
3961         }
3962         case WSError::WS_ERROR_NULLPTR: {
3963             return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3964         }
3965         default: {
3966             return WmErrorCode::WM_OK;
3967         }
3968     }
3969 }
3970 
StopMoveWindow()3971 WmErrorCode WindowSceneSessionImpl::StopMoveWindow()
3972 {
3973     if (!CheckCanMoveWindowType()) {
3974         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "invalid window type:%{public}u", GetType());
3975         return WmErrorCode::WM_ERROR_INVALID_CALLING;
3976     }
3977     if (!IsPcOrFreeMultiWindowCapabilityEnabled()) {
3978         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3979         return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
3980     }
3981     if (IsWindowSessionInvalid()) {
3982         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3983         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3984     }
3985     auto hostSession = GetHostSession();
3986     if (!hostSession) {
3987         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "hostSession is nullptr");
3988         return WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY;
3989     }
3990     WSError errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_END_MOVE);
3991     TLOGD(WmsLogTag::WMS_LAYOUT_PC, "id:%{public}d, errorCode:%{public}d",
3992           GetPersistentId(), static_cast<int>(errorCode));
3993     return errorCode == WSError::WS_ERROR_NULLPTR ? WmErrorCode::WM_ERROR_STATE_ABNORMALLY : WmErrorCode::WM_OK;
3994 }
3995 
MainWindowCloseInner()3996 WMError WindowSceneSessionImpl::MainWindowCloseInner()
3997 {
3998     auto hostSession = GetHostSession();
3999     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
4000     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(GetContext());
4001     if (!abilityContext) {
4002         return Destroy(true);
4003     }
4004     bool terminateCloseProcess = false;
4005     WMError res = NotifyMainWindowClose(terminateCloseProcess);
4006     if (res == WMError::WM_OK) {
4007         TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d, not close: %{public}d", GetPersistentId(),
4008             terminateCloseProcess);
4009         if (!terminateCloseProcess) {
4010             hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
4011         }
4012         return res;
4013     }
4014     auto handler = sptr<WindowPrepareTerminateHandler>::MakeSptr();
4015     PrepareTerminateFunc func = [hostSessionWptr = wptr<ISession>(hostSession)] {
4016         auto hostSession = hostSessionWptr.promote();
4017         if (hostSession == nullptr) {
4018             TLOGNE(WmsLogTag::WMS_LIFE, "this session is nullptr");
4019             return;
4020         }
4021         hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
4022     };
4023     handler->SetPrepareTerminateFun(func);
4024     if (AAFwk::AbilityManagerClient::GetInstance()->PrepareTerminateAbility(abilityContext->GetToken(),
4025         handler) != ERR_OK) {
4026         TLOGE(WmsLogTag::WMS_LIFE, "PrepareTerminateAbility failed, do close window");
4027         hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
4028     }
4029     return WMError::WM_OK;
4030 }
4031 
Close()4032 WMError WindowSceneSessionImpl::Close()
4033 {
4034     TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d", GetPersistentId());
4035     if (IsWindowSessionInvalid()) {
4036         TLOGE(WmsLogTag::WMS_DECOR, "session is invalid");
4037         return WMError::WM_ERROR_INVALID_WINDOW;
4038     }
4039     WindowType windowType = GetType();
4040     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
4041     bool isSystemSubWindow = WindowHelper::IsSystemSubWindow(windowType);
4042     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
4043     if (WindowHelper::IsMainWindow(windowType) || isSubWindow) {
4044         WMError res = NotifyWindowWillClose(this);
4045         if (res == WMError::WM_OK) {
4046             TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d will close", GetPersistentId());
4047             return res;
4048         }
4049     }
4050     if (WindowHelper::IsMainWindow(windowType)) {
4051         return MainWindowCloseInner();
4052     } else if (isSubWindow || isSystemSubWindow || isDialogWindow) {
4053         TLOGI(WmsLogTag::WMS_DECOR, "subwindow or dialog");
4054         bool terminateCloseProcess = false;
4055         NotifySubWindowClose(terminateCloseProcess);
4056         if (!terminateCloseProcess || isDialogWindow) {
4057             return Destroy(true);
4058         }
4059     }
4060     return WMError::WM_OK;
4061 }
4062 
CloseDirectly()4063 WMError WindowSceneSessionImpl::CloseDirectly()
4064 {
4065     if (IsWindowSessionInvalid()) {
4066         TLOGE(WmsLogTag::WMS_DECOR, "session is invalid");
4067         return WMError::WM_ERROR_INVALID_WINDOW;
4068     }
4069     TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d", GetPersistentId());
4070     if (WindowHelper::IsMainWindow(GetType())) {
4071         auto hostSession = GetHostSession();
4072         CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
4073         hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
4074         return WMError::WM_OK;
4075     }
4076     return Destroy(true);
4077 }
4078 
DisableAppWindowDecor()4079 WMError WindowSceneSessionImpl::DisableAppWindowDecor()
4080 {
4081     if (IsWindowSessionInvalid()) {
4082         return WMError::WM_ERROR_INVALID_WINDOW;
4083     }
4084     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4085         TLOGE(WmsLogTag::WMS_DECOR, "disable app window decor permission denied!");
4086         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4087     }
4088     if (!WindowHelper::IsMainWindow(GetType())) {
4089         TLOGE(WmsLogTag::WMS_DECOR, "window decoration is invalid on sub window");
4090         return WMError::WM_ERROR_INVALID_OPERATION;
4091     }
4092     TLOGI(WmsLogTag::WMS_DECOR, "disable app window decoration.");
4093     windowSystemConfig_.isSystemDecorEnable_ = false;
4094     UpdateDecorEnable(true);
4095     return WMError::WM_OK;
4096 }
4097 
PerformBack()4098 void WindowSceneSessionImpl::PerformBack()
4099 {
4100     if (!WindowHelper::IsMainWindow(GetType())) {
4101         WLOGFI("PerformBack is not MainWindow, return");
4102         return;
4103     }
4104     if (auto hostSession = GetHostSession()) {
4105         bool needMoveToBackground = false;
4106         auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(GetContext());
4107         if (abilityContext != nullptr) {
4108             abilityContext->OnBackPressedCallBack(needMoveToBackground);
4109         }
4110         TLOGI(WmsLogTag::DEFAULT, "%{public}d", needMoveToBackground);
4111         hostSession->RequestSessionBack(needMoveToBackground);
4112     }
4113 }
4114 
SetGlobalMaximizeMode(MaximizeMode mode)4115 WMError WindowSceneSessionImpl::SetGlobalMaximizeMode(MaximizeMode mode)
4116 {
4117     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "mode %{public}u", static_cast<uint32_t>(mode));
4118     if (IsWindowSessionInvalid()) {
4119         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
4120         return WMError::WM_ERROR_INVALID_WINDOW;
4121     }
4122     auto hostSession = GetHostSession();
4123     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
4124     if (WindowHelper::IsMainWindow(GetType())) {
4125         hostSession->SetGlobalMaximizeMode(mode);
4126         return WMError::WM_OK;
4127     } else {
4128         TLOGW(WmsLogTag::WMS_LAYOUT_PC, "fail, not main window");
4129         return WMError::WM_ERROR_INVALID_PARAM;
4130     }
4131 }
4132 
GetGlobalMaximizeMode() const4133 MaximizeMode WindowSceneSessionImpl::GetGlobalMaximizeMode() const
4134 {
4135     TLOGD(WmsLogTag::WMS_LAYOUT_PC, "in");
4136     MaximizeMode mode = MaximizeMode::MODE_RECOVER;
4137     if (auto hostSession = GetHostSession()) {
4138         hostSession->GetGlobalMaximizeMode(mode);
4139     }
4140     return mode;
4141 }
4142 
SetWindowMode(WindowMode mode)4143 WMError WindowSceneSessionImpl::SetWindowMode(WindowMode mode)
4144 {
4145     TLOGD(WmsLogTag::WMS_LAYOUT, "%{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
4146     if (IsWindowSessionInvalid()) {
4147         TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
4148         return WMError::WM_ERROR_INVALID_WINDOW;
4149     }
4150     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), mode)) {
4151         TLOGE(WmsLogTag::WMS_LAYOUT, "window %{public}u do not support mode: %{public}u",
4152             GetWindowId(), static_cast<uint32_t>(mode));
4153         return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
4154     }
4155     WMError ret = UpdateWindowModeImmediately(mode);
4156     if (ret != WMError::WM_OK) {
4157         TLOGE(WmsLogTag::WMS_LAYOUT, "Update window mode fail, ret:%{public}u", ret);
4158         return ret;
4159     }
4160     auto hostSession = GetHostSession();
4161     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
4162     if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
4163         hostSession->OnSessionEvent(SessionEvent::EVENT_SPLIT_PRIMARY);
4164     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
4165         hostSession->OnSessionEvent(SessionEvent::EVENT_SPLIT_SECONDARY);
4166     }
4167     return WMError::WM_OK;
4168 }
4169 
SetGrayScale(float grayScale)4170 WMError WindowSceneSessionImpl::SetGrayScale(float grayScale)
4171 {
4172     if (IsWindowSessionInvalid()) {
4173         WLOGFE("session is invalid");
4174         return WMError::WM_ERROR_INVALID_WINDOW;
4175     }
4176     constexpr float eps = 1e-6f;
4177     if (grayScale < (MIN_GRAY_SCALE - eps) || grayScale > (MAX_GRAY_SCALE + eps)) {
4178         WLOGFE("invalid grayScale value: %{public}f", grayScale);
4179         return WMError::WM_ERROR_INVALID_PARAM;
4180     }
4181     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
4182     if (uiContent == nullptr) {
4183         WLOGFE("uicontent is empty");
4184         return WMError::WM_ERROR_NULLPTR;
4185     }
4186     uiContent->SetContentNodeGrayScale(grayScale);
4187     WLOGI("Set window gray scale success, grayScale: %{public}f", grayScale);
4188     return WMError::WM_OK;
4189 }
4190 
GetWindowMode() const4191 WindowMode WindowSceneSessionImpl::GetWindowMode() const
4192 {
4193     return property_->GetWindowMode();
4194 }
4195 
IsTransparent() const4196 bool WindowSceneSessionImpl::IsTransparent() const
4197 {
4198     if (IsWindowSessionInvalid()) {
4199         return false;
4200     }
4201     WSColorParam backgroundColor;
4202     backgroundColor.value = GetBackgroundColor();
4203     WLOGFD("color: %{public}u, alpha: %{public}u", backgroundColor.value, backgroundColor.argb.alpha);
4204     return backgroundColor.argb.alpha == 0x00; // 0x00: completely transparent
4205 }
4206 
SetTransparent(bool isTransparent)4207 WMError WindowSceneSessionImpl::SetTransparent(bool isTransparent)
4208 {
4209     if (IsWindowSessionInvalid()) {
4210         WLOGFE("session is invalid");
4211         return WMError::WM_ERROR_INVALID_WINDOW;
4212     }
4213     WSColorParam backgroundColor;
4214     backgroundColor.value = GetBackgroundColor();
4215     if (isTransparent) {
4216         backgroundColor.argb.alpha = 0x00; // 0x00: completely transparent
4217         return SetBackgroundColor(backgroundColor.value);
4218     } else {
4219         backgroundColor.value = GetBackgroundColor();
4220         if (backgroundColor.argb.alpha == 0x00) {
4221             backgroundColor.argb.alpha = 0xff; // 0xff: completely opaque
4222             return SetBackgroundColor(backgroundColor.value);
4223         }
4224     }
4225     return WMError::WM_OK;
4226 }
4227 
AddWindowFlag(WindowFlag flag)4228 WMError WindowSceneSessionImpl::AddWindowFlag(WindowFlag flag)
4229 {
4230     if (IsWindowSessionInvalid()) {
4231         return WMError::WM_ERROR_INVALID_WINDOW;
4232     }
4233     auto context = GetContext();
4234     if (flag == WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED && context && context->GetApplicationInfo() &&
4235         context->GetApplicationInfo()->apiCompatibleVersion >= 9 && // 9: api version
4236         !SessionPermission::IsSystemCalling()) {
4237         TLOGI(WmsLogTag::DEFAULT, "Can not set show when locked, PersistentId: %{public}u", GetPersistentId());
4238         return WMError::WM_ERROR_INVALID_PERMISSION;
4239     }
4240     if (flag == WindowFlag::WINDOW_FLAG_HANDWRITING && !SessionPermission::IsSystemCalling()) {
4241         TLOGI(WmsLogTag::DEFAULT, "Can not set handwritting, PersistentId: %{public}u", GetPersistentId());
4242         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4243     }
4244     if (flag == WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE && !SessionPermission::IsSystemCalling()) {
4245         TLOGI(WmsLogTag::DEFAULT, "Can not set forbid split move, PersistentId: %{public}u", GetPersistentId());
4246         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4247     }
4248     uint32_t updateFlags = property_->GetWindowFlags() | (static_cast<uint32_t>(flag));
4249     return SetWindowFlags(updateFlags);
4250 }
4251 
RemoveWindowFlag(WindowFlag flag)4252 WMError WindowSceneSessionImpl::RemoveWindowFlag(WindowFlag flag)
4253 {
4254     if (IsWindowSessionInvalid()) {
4255         return WMError::WM_ERROR_INVALID_WINDOW;
4256     }
4257     uint32_t updateFlags = property_->GetWindowFlags() & (~(static_cast<uint32_t>(flag)));
4258     return SetWindowFlags(updateFlags);
4259 }
4260 
SetWindowFlags(uint32_t flags)4261 WMError WindowSceneSessionImpl::SetWindowFlags(uint32_t flags)
4262 {
4263     TLOGI(WmsLogTag::DEFAULT, "Session %{public}u flags %{public}u", GetWindowId(), flags);
4264     if (IsWindowSessionInvalid()) {
4265         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
4266         return WMError::WM_ERROR_INVALID_WINDOW;
4267     }
4268     if (property_->GetWindowFlags() == flags) {
4269         TLOGI(WmsLogTag::DEFAULT, "Session %{public}u set same flags %{public}u", GetWindowId(), flags);
4270         return WMError::WM_OK;
4271     }
4272     auto oriFlags = property_->GetWindowFlags();
4273     property_->SetWindowFlags(flags);
4274     WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_FLAGS);
4275     if (ret != WMError::WM_OK) {
4276         TLOGE(WmsLogTag::DEFAULT, "SetWindowFlags errCode:%{public}d winId:%{public}u",
4277             static_cast<int32_t>(ret), GetWindowId());
4278         property_->SetWindowFlags(oriFlags);
4279     }
4280     return ret;
4281 }
4282 
GetWindowFlags() const4283 uint32_t WindowSceneSessionImpl::GetWindowFlags() const
4284 {
4285     return property_->GetWindowFlags();
4286 }
4287 
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)4288 void WindowSceneSessionImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
4289 {
4290     if (auto uiContent = GetUIContentSharedPtr()) {
4291         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace scene win=%{public}u, display=%{public}" PRIu64,
4292             GetWindowId(), GetDisplayId());
4293         uiContent->UpdateConfiguration(configuration);
4294     } else {
4295         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, scene win=%{public}u, display=%{public}" PRIu64,
4296             GetWindowId(), GetDisplayId());
4297     }
4298     UpdateDefaultStatusBarColor();
4299     std::vector<sptr<WindowSessionImpl>> subWindows;
4300     GetSubWindows(GetPersistentId(), subWindows);
4301     for (auto& subWindowSession : subWindows) {
4302         if (subWindowSession != nullptr) {
4303             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene subWin=%{public}u, display=%{public}" PRIu64,
4304                 subWindowSession->GetWindowId(), subWindowSession->GetDisplayId());
4305             subWindowSession->UpdateConfiguration(configuration);
4306         }
4307     }
4308 }
4309 
UpdateConfigurationForSpecified(const std::shared_ptr<AppExecFwk::Configuration> & configuration,const std::shared_ptr<Global::Resource::ResourceManager> & resourceManager)4310 void WindowSceneSessionImpl::UpdateConfigurationForSpecified(
4311     const std::shared_ptr<AppExecFwk::Configuration>& configuration,
4312     const std::shared_ptr<Global::Resource::ResourceManager>& resourceManager)
4313 {
4314     if (auto uiContent = GetUIContentSharedPtr()) {
4315         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace scene win=%{public}u, display=%{public}" PRIu64,
4316             GetWindowId(), GetDisplayId());
4317         uiContent->UpdateConfiguration(configuration, resourceManager);
4318     } else {
4319         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, scene win=%{public}u, display=%{public}" PRIu64,
4320             GetWindowId(), GetDisplayId());
4321     }
4322     if (configuration != nullptr) {
4323         specifiedColorMode_ = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
4324         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "scene win=%{public}u, colorMode=%{public}s, display=%{public}" PRIu64,
4325             GetWindowId(), specifiedColorMode_.c_str(), GetDisplayId());
4326     }
4327     UpdateDefaultStatusBarColor();
4328     std::vector<sptr<WindowSessionImpl>> subWindows;
4329     GetSubWindows(GetPersistentId(), subWindows);
4330     if (subWindows.empty()) {
4331         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "no subSession, scene win=%{public}u, display=%{public}" PRIu64,
4332             GetWindowId(), GetDisplayId());
4333         return;
4334     }
4335     for (auto& subWindowSession : subWindows) {
4336         if (subWindowSession != nullptr) {
4337             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene subWin=%{public}u, display=%{public}" PRIu64,
4338                 subWindowSession->GetWindowId(), subWindowSession->GetDisplayId());
4339             subWindowSession->UpdateConfigurationForSpecified(configuration, resourceManager);
4340         }
4341     }
4342 }
4343 
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration,const std::vector<std::shared_ptr<AbilityRuntime::Context>> & ignoreWindowContexts)4344 void WindowSceneSessionImpl::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration,
4345     const std::vector<std::shared_ptr<AbilityRuntime::Context>>& ignoreWindowContexts)
4346 {
4347     std::unordered_set<std::shared_ptr<AbilityRuntime::Context>> ignoreWindowCtxSet(
4348         ignoreWindowContexts.begin(), ignoreWindowContexts.end());
4349     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene map size: %{public}u", static_cast<uint32_t>(windowSessionMap_.size()));
4350     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4351     for (const auto& winPair : windowSessionMap_) {
4352         auto window = winPair.second.second;
4353         if (window == nullptr) {
4354             TLOGE(WmsLogTag::WMS_ATTRIBUTE, "scene window is null");
4355             continue;
4356         }
4357         if (ignoreWindowCtxSet.count(window->GetContext()) == 0) {
4358             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene win=%{public}u, display=%{public}" PRIu64,
4359                 window->GetWindowId(), window->GetDisplayId());
4360             window->UpdateConfiguration(configuration);
4361         } else {
4362             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "skip scene win=%{public}u, display=%{public}" PRIu64,
4363                 window->GetWindowId(), window->GetDisplayId());
4364         }
4365     }
4366 }
4367 
UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration> & configuration)4368 void WindowSceneSessionImpl::UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
4369 {
4370     if (auto uiContent = GetUIContentSharedPtr()) {
4371         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace scene win=%{public}u, display=%{public}" PRIu64,
4372             GetWindowId(), GetDisplayId());
4373         uiContent->UpdateConfigurationSyncForAll(configuration);
4374     } else {
4375         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, scene win=%{public}u, display=%{public}" PRIu64,
4376             GetWindowId(), GetDisplayId());
4377     }
4378     std::vector<sptr<WindowSessionImpl>> subWindows;
4379     GetSubWindows(GetPersistentId(), subWindows);
4380     if (subWindows.empty()) {
4381         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "no subSession, scene win=%{public}u, display=%{public}" PRIu64,
4382             GetWindowId(), GetDisplayId());
4383         return;
4384     }
4385     for (auto& subWindowSession : subWindows) {
4386         if (subWindowSession != nullptr) {
4387             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene subWin=%{public}u, display=%{public}" PRIu64,
4388                 subWindowSession->GetWindowId(), subWindowSession->GetDisplayId());
4389             subWindowSession->UpdateConfigurationSync(configuration);
4390         }
4391     }
4392 }
4393 
UpdateConfigurationSyncForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)4394 void WindowSceneSessionImpl::UpdateConfigurationSyncForAll(
4395     const std::shared_ptr<AppExecFwk::Configuration>& configuration)
4396 {
4397     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4398     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene map size: %{public}u", static_cast<uint32_t>(windowSessionMap_.size()));
4399     for (const auto& winPair : windowSessionMap_) {
4400         if (auto window = winPair.second.second) {
4401             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene win=%{public}u, display=%{public}" PRIu64,
4402                 window->GetWindowId(), window->GetDisplayId());
4403             window->UpdateConfigurationSync(configuration);
4404         }
4405     }
4406 }
4407 
4408 /** @note @window.hierarchy */
GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context> & context)4409 sptr<Window> WindowSceneSessionImpl::GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context>& context)
4410 {
4411     uint32_t mainWinId = INVALID_WINDOW_ID;
4412     {
4413         std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4414         if (windowSessionMap_.empty()) {
4415             TLOGE(WmsLogTag::WMS_HIERARCHY, "Please create mainWindow First!");
4416             return nullptr;
4417         }
4418         for (const auto& winPair : windowSessionMap_) {
4419             auto win = winPair.second.second;
4420             if (win && WindowHelper::IsMainWindow(win->GetType()) && context.get() == win->GetContext().get()) {
4421                 mainWinId = win->GetWindowId();
4422                 TLOGD(WmsLogTag::WMS_HIERARCHY, "Find MainWinId:%{public}u.", mainWinId);
4423                 break;
4424             }
4425         }
4426     }
4427     TLOGI(WmsLogTag::WMS_HIERARCHY, "mainId:%{public}u!", mainWinId);
4428     if (mainWinId == INVALID_WINDOW_ID) {
4429         TLOGE(WmsLogTag::WMS_HIERARCHY, "Cannot find topWindow!");
4430         return nullptr;
4431     }
4432     uint32_t topWinId = INVALID_WINDOW_ID;
4433     WMError ret = SingletonContainer::Get<WindowAdapter>().GetTopWindowId(mainWinId, topWinId);
4434     if (ret != WMError::WM_OK) {
4435         TLOGE(WmsLogTag::WMS_HIERARCHY, "failed with errCode:%{public}d", static_cast<int32_t>(ret));
4436         return nullptr;
4437     }
4438     return FindWindowById(topWinId);
4439 }
4440 
4441 /** @note @window.hierarchy */
GetTopWindowWithId(uint32_t mainWinId)4442 sptr<Window> WindowSceneSessionImpl::GetTopWindowWithId(uint32_t mainWinId)
4443 {
4444     TLOGI(WmsLogTag::WMS_HIERARCHY, "mainId:%{public}u", mainWinId);
4445     uint32_t topWinId = INVALID_WINDOW_ID;
4446     WMError ret = SingletonContainer::Get<WindowAdapter>().GetTopWindowId(mainWinId, topWinId);
4447     if (ret != WMError::WM_OK) {
4448         WLOGFE("[GetTopWin] failed with errCode:%{public}d", static_cast<int32_t>(ret));
4449         return nullptr;
4450     }
4451     return FindWindowById(topWinId);
4452 }
4453 
GetMainWindowWithContext(const std::shared_ptr<AbilityRuntime::Context> & context)4454 sptr<Window> WindowSceneSessionImpl::GetMainWindowWithContext(const std::shared_ptr<AbilityRuntime::Context>& context)
4455 {
4456     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4457     if (windowSessionMap_.empty()) {
4458         TLOGE(WmsLogTag::WMS_MAIN, "Please create mainWindow First!");
4459         return nullptr;
4460     }
4461     for (const auto& winPair : windowSessionMap_) {
4462         auto win = winPair.second.second;
4463         if (win && WindowHelper::IsMainWindow(win->GetType()) && context.get() == win->GetContext().get()) {
4464             TLOGI(WmsLogTag::WMS_MAIN, "Find MainWinId:%{public}u.", win->GetWindowId());
4465             return win;
4466         }
4467     }
4468     TLOGE(WmsLogTag::WMS_MAIN, "Cannot find Window!");
4469     return nullptr;
4470 }
4471 
GetMainWindowWithId(uint32_t mainWinId)4472 sptr<WindowSessionImpl> WindowSceneSessionImpl::GetMainWindowWithId(uint32_t mainWinId)
4473 {
4474     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4475     if (windowSessionMap_.empty()) {
4476         WLOGFE("Please create mainWindow First!");
4477         return nullptr;
4478     }
4479     for (const auto& winPair : windowSessionMap_) {
4480         auto win = winPair.second.second;
4481         if (win && WindowHelper::IsMainWindow(win->GetType()) && mainWinId == win->GetWindowId()) {
4482             WLOGI("GetTopWindow Find MainWinId:%{public}u.", mainWinId);
4483             return win;
4484         }
4485     }
4486     WLOGFE("Cannot find Window!");
4487     return nullptr;
4488 }
4489 
GetParentMainWindowIdInner(WindowSessionImplMap & sessionMap,int32_t windowId,int32_t & mainWindowId)4490 static WMError GetParentMainWindowIdInner(WindowSessionImplMap& sessionMap, int32_t windowId, int32_t& mainWindowId)
4491 {
4492     for (const auto& [_, pair] : sessionMap) {
4493         const auto& window = pair.second;
4494         if (window == nullptr) {
4495             return WMError::WM_ERROR_NULLPTR;
4496         }
4497         if (window->GetPersistentId() != windowId) {
4498             continue;
4499         }
4500 
4501         if (WindowHelper::IsMainWindow(window->GetType())) {
4502             TLOGI(WmsLogTag::WMS_SUB, "find main window, id:%{public}u", window->GetPersistentId());
4503             mainWindowId = window->GetPersistentId();
4504             return WMError::WM_OK;
4505         }
4506         if (WindowHelper::IsSubWindow(window->GetType()) || WindowHelper::IsDialogWindow(window->GetType())) {
4507             return GetParentMainWindowIdInner(sessionMap, window->GetParentId(), mainWindowId);
4508         }
4509         // not main window, sub window, dialog, set invalid id
4510         mainWindowId = INVALID_SESSION_ID;
4511         return WMError::WM_OK;
4512     }
4513     return WMError::WM_ERROR_INVALID_PARENT;
4514 }
4515 
GetParentMainWindowId(int32_t windowId)4516 int32_t WindowSceneSessionImpl::GetParentMainWindowId(int32_t windowId)
4517 {
4518     if (windowId == INVALID_SESSION_ID) {
4519         TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
4520         return INVALID_SESSION_ID;
4521     }
4522     int32_t mainWindowId = INVALID_SESSION_ID;
4523     {
4524         std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4525         WMError findRet = GetParentMainWindowIdInner(windowSessionMap_, windowId, mainWindowId);
4526         if (findRet == WMError::WM_OK) {
4527             return mainWindowId;
4528         }
4529     }
4530     // can't find in client, need to find in server find
4531     WMError ret = SingletonContainer::Get<WindowAdapter>().GetParentMainWindowId(windowId, mainWindowId);
4532     if (ret != WMError::WM_OK) {
4533         TLOGE(WmsLogTag::WMS_SUB, "cant't find main window id, err:%{public}d", static_cast<uint32_t>(ret));
4534         return INVALID_SESSION_ID;
4535     }
4536     return mainWindowId;
4537 }
4538 
GetAndVerifyWindowTypeForArkUI(uint32_t parentId,const std::string & windowName,WindowType parentWindowType,WindowType & windowType)4539 WMError WindowSceneSessionImpl::GetAndVerifyWindowTypeForArkUI(uint32_t parentId, const std::string& windowName,
4540     WindowType parentWindowType, WindowType& windowType)
4541 {
4542     auto window = WindowSceneSessionImpl::Find(windowName);
4543     if (window != nullptr) {
4544         TLOGE(WmsLogTag::WMS_SUB, "WindowName(%{public}s) already exists.", windowName.c_str());
4545         return WMError::WM_ERROR_REPEAT_OPERATION;
4546     }
4547     TLOGI(WmsLogTag::WMS_SUB, "parentWindowId:%{public}d, parentWindowType:%{public}d", parentId, parentWindowType);
4548     if (parentWindowType == WindowType::WINDOW_TYPE_SCENE_BOARD ||
4549         parentWindowType == WindowType::WINDOW_TYPE_DESKTOP) {
4550         windowType = WindowType::WINDOW_TYPE_SYSTEM_FLOAT;
4551     } else if (WindowHelper::IsUIExtensionWindow(parentWindowType)) {
4552         windowType = WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
4553     } else if (WindowHelper::IsSystemSubWindow(parentWindowType)) {
4554         TLOGE(WmsLogTag::WMS_SUB, "parent is system sub window, id: %{public}d, type: %{public}d",
4555             parentId, parentWindowType);
4556         return WMError::WM_ERROR_INVALID_TYPE;
4557     } else if (WindowHelper::IsSystemWindow(parentWindowType)) {
4558         windowType = WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW;
4559     } else {
4560         auto parentWindow = WindowSceneSessionImpl::GetWindowWithId(parentId);
4561         if (parentWindow == nullptr) {
4562             TLOGE(WmsLogTag::WMS_SUB, "parentWindow is null, windowId:%{public}d", parentId);
4563             return WMError::WM_ERROR_INVALID_WINDOW;
4564         }
4565         if (parentWindowType != parentWindow->GetType()) {
4566             TLOGE(WmsLogTag::WMS_SUB, "parentWindow does match type");
4567             return WMError::WM_ERROR_INVALID_WINDOW;
4568         }
4569         auto ret = WindowSceneSessionImpl::VerifySubWindowLevel(false, parentWindow);
4570         if (ret != WMError::WM_OK) {
4571             return ret;
4572         }
4573         windowType = WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
4574     }
4575     return WMError::WM_OK;
4576 }
4577 
SetNeedDefaultAnimation(bool needDefaultAnimation)4578 void WindowSceneSessionImpl::SetNeedDefaultAnimation(bool needDefaultAnimation)
4579 {
4580     enableDefaultAnimation_= needDefaultAnimation;
4581     auto hostSession = GetHostSession();
4582     CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
4583     hostSession->UpdateWindowAnimationFlag(needDefaultAnimation);
4584 }
4585 
ConvertRadiusToSigma(float radius)4586 static float ConvertRadiusToSigma(float radius)
4587 {
4588     return radius > 0.0f ? 0.57735f * radius + SK_ScalarHalf : 0.0f; // 0.57735f is blur sigma scale
4589 }
4590 
CheckParmAndPermission()4591 WMError WindowSceneSessionImpl::CheckParmAndPermission()
4592 {
4593     if (surfaceNode_ == nullptr) {
4594         WLOGFE("RSSurface node is null");
4595         return WMError::WM_ERROR_NULLPTR;
4596     }
4597 
4598     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4599         WLOGFE("Check failed, permission denied");
4600         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4601     }
4602 
4603     return WMError::WM_OK;
4604 }
4605 
SetCornerRadius(float cornerRadius)4606 WMError WindowSceneSessionImpl::SetCornerRadius(float cornerRadius)
4607 {
4608     if (surfaceNode_ == nullptr) {
4609         WLOGFE("RSSurface node is null");
4610         return WMError::WM_ERROR_NULLPTR;
4611     }
4612 
4613     WLOGFI("Set window %{public}s corner radius %{public}f", GetWindowName().c_str(), cornerRadius);
4614     surfaceNode_->SetCornerRadius(cornerRadius);
4615     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4616     return WMError::WM_OK;
4617 }
4618 
SetWindowCornerRadius(float cornerRadius)4619 WMError WindowSceneSessionImpl::SetWindowCornerRadius(float cornerRadius)
4620 {
4621     if (IsWindowSessionInvalid()) {
4622         return WMError::WM_ERROR_INVALID_WINDOW;
4623     }
4624     if (!windowSystemConfig_.IsPcWindow() && !windowSystemConfig_.IsPadWindow() &&
4625         !windowSystemConfig_.IsPhoneWindow()) {
4626         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not pc, pad or phone, not supported.");
4627         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
4628     }
4629     if (!WindowHelper::IsFloatOrSubWindow(GetType())) {
4630         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not sub window or float window.");
4631         return WMError::WM_ERROR_INVALID_CALLING;
4632     }
4633 
4634     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Set id %{public}u corner radius %{public}f.", GetWindowId(), cornerRadius);
4635     if (MathHelper::LessNotEqual(cornerRadius, 0.0f)) {
4636         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The corner radius is less than zero.");
4637         return WMError::WM_ERROR_INVALID_PARAM;
4638     }
4639 
4640     property_->SetWindowCornerRadius(cornerRadius);
4641 
4642     auto hostSession = GetHostSession();
4643     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
4644     hostSession->SetWindowCornerRadius(cornerRadius);
4645     return WMError::WM_OK;
4646 }
4647 
GetWindowCornerRadius(float & cornerRadius)4648 WMError WindowSceneSessionImpl::GetWindowCornerRadius(float& cornerRadius)
4649 {
4650     if (IsWindowSessionInvalid()) {
4651         return WMError::WM_ERROR_INVALID_WINDOW;
4652     }
4653     if (!IsPcOrFreeMultiWindowCapabilityEnabled()) {
4654         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not PC or Pad, not supported.");
4655         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
4656     }
4657     if (!WindowHelper::IsFloatOrSubWindow(GetType())) {
4658         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not sub window or float window.");
4659         return WMError::WM_ERROR_INVALID_CALLING;
4660     }
4661 
4662     cornerRadius = property_->GetWindowCornerRadius();
4663     if (MathHelper::LessNotEqual(cornerRadius, 0.0f)) {
4664         // Invalid corner radius means app has not set corner radius of the window, return the default corner radius
4665         TLOGI(WmsLogTag::WMS_ANIMATION, "System config radius: %{public}f, property radius: %{public}f, id: %{public}d",
4666               windowSystemConfig_.defaultCornerRadius_, cornerRadius, GetPersistentId());
4667         cornerRadius = MathHelper::LessNotEqual(windowSystemConfig_.defaultCornerRadius_, 0.0f) ?
4668             0.0f : windowSystemConfig_.defaultCornerRadius_;
4669     }
4670     return WMError::WM_OK;
4671 }
4672 
SetShadowRadius(float radius)4673 WMError WindowSceneSessionImpl::SetShadowRadius(float radius)
4674 {
4675     WMError ret = CheckParmAndPermission();
4676     if (ret != WMError::WM_OK) {
4677         return ret;
4678     }
4679 
4680     WLOGFI("Set window %{public}s shadow radius %{public}f", GetWindowName().c_str(), radius);
4681     if (MathHelper::LessNotEqual(radius, 0.0)) {
4682         return WMError::WM_ERROR_INVALID_PARAM;
4683     }
4684 
4685     surfaceNode_->SetShadowRadius(ConvertRadiusToSigma(radius));
4686     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4687     return WMError::WM_OK;
4688 }
4689 
SyncShadowsToComponent(const ShadowsInfo & shadowsInfo)4690 WMError WindowSceneSessionImpl::SyncShadowsToComponent(const ShadowsInfo& shadowsInfo)
4691 {
4692     if (IsWindowSessionInvalid()) {
4693         return WMError::WM_ERROR_INVALID_WINDOW;
4694     }
4695 
4696     TLOGI(WmsLogTag::WMS_ANIMATION, "Sync Shadows To Component %{public}s shadow radius: %{public}f,"
4697         " color: %{public}s, offsetX: %{public}f, offsetY: %{public}f", GetWindowName().c_str(),
4698         shadowsInfo.radius_, shadowsInfo.color_.c_str(), shadowsInfo.offsetX_, shadowsInfo.offsetY_);
4699     if (MathHelper::LessNotEqual(shadowsInfo.radius_, 0.0)) {
4700         return WMError::WM_ERROR_INVALID_PARAM;
4701     }
4702 
4703     property_->SetWindowShadows(shadowsInfo);
4704     auto hostSession = GetHostSession();
4705 
4706     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
4707     hostSession->SetWindowShadows(shadowsInfo);
4708     return WMError::WM_OK;
4709 }
4710 
SetWindowShadowRadius(float radius)4711 WMError WindowSceneSessionImpl::SetWindowShadowRadius(float radius)
4712 {
4713     if (IsWindowSessionInvalid()) {
4714         return WMError::WM_ERROR_INVALID_WINDOW;
4715     }
4716     if (!windowSystemConfig_.IsPcWindow() && !windowSystemConfig_.IsPadWindow() &&
4717         !IsDeviceFeatureCapableForFreeMultiWindow()) {
4718         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not PC or Pad, not supported.");
4719         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
4720     }
4721     if (!WindowHelper::IsFloatOrSubWindow(GetType())) {
4722         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not sub window or float window.");
4723         return WMError::WM_ERROR_INVALID_CALLING;
4724     }
4725 
4726     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Set id %{public}u shadow radius %{public}f.", GetWindowId(), radius);
4727     if (MathHelper::LessNotEqual(radius, 0.0f)) {
4728         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The shadow radius is less than zero.");
4729         return WMError::WM_ERROR_INVALID_PARAM;
4730     }
4731 
4732     if (surfaceNode_ == nullptr) {
4733         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "RSSurface node is nullptr.");
4734         return WMError::WM_ERROR_NULLPTR;
4735     }
4736     surfaceNode_->SetShadowRadius(ConvertRadiusToSigma(radius));
4737     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4738     return WMError::WM_OK;
4739 }
4740 
SetShadowColor(std::string color)4741 WMError WindowSceneSessionImpl::SetShadowColor(std::string color)
4742 {
4743     WMError ret = CheckParmAndPermission();
4744     if (ret != WMError::WM_OK) {
4745         return ret;
4746     }
4747 
4748     WLOGFI("Set window %{public}s shadow color %{public}s", GetWindowName().c_str(), color.c_str());
4749     uint32_t colorValue = 0;
4750     if (!ColorParser::Parse(color, colorValue)) {
4751         return WMError::WM_ERROR_INVALID_PARAM;
4752     }
4753 
4754     surfaceNode_->SetShadowColor(colorValue);
4755     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4756     return WMError::WM_OK;
4757 }
4758 
SetShadowOffsetX(float offsetX)4759 WMError WindowSceneSessionImpl::SetShadowOffsetX(float offsetX)
4760 {
4761     WMError ret = CheckParmAndPermission();
4762     if (ret != WMError::WM_OK) {
4763         return ret;
4764     }
4765 
4766     WLOGFI("Set window %{public}s shadow offsetX %{public}f", GetWindowName().c_str(), offsetX);
4767     surfaceNode_->SetShadowOffsetX(offsetX);
4768     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4769     return WMError::WM_OK;
4770 }
4771 
SetShadowOffsetY(float offsetY)4772 WMError WindowSceneSessionImpl::SetShadowOffsetY(float offsetY)
4773 {
4774     WMError ret = CheckParmAndPermission();
4775     if (ret != WMError::WM_OK) {
4776         return ret;
4777     }
4778 
4779     WLOGFI("Set window %{public}s shadow offsetY %{public}f", GetWindowName().c_str(), offsetY);
4780     surfaceNode_->SetShadowOffsetY(offsetY);
4781     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4782     return WMError::WM_OK;
4783 }
4784 
SetBlur(float radius)4785 WMError WindowSceneSessionImpl::SetBlur(float radius)
4786 {
4787     WMError ret = CheckParmAndPermission();
4788     if (ret != WMError::WM_OK) {
4789         return ret;
4790     }
4791 
4792     WLOGFI("Set window %{public}s blur radius %{public}f", GetWindowName().c_str(), radius);
4793     if (MathHelper::LessNotEqual(radius, 0.0)) {
4794         return WMError::WM_ERROR_INVALID_PARAM;
4795     }
4796 
4797     radius = ConvertRadiusToSigma(radius);
4798     WLOGFI("Set window %{public}s blur radius after conversion %{public}f", GetWindowName().c_str(), radius);
4799     surfaceNode_->SetFilter(RSFilter::CreateBlurFilter(radius, radius));
4800     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4801     return WMError::WM_OK;
4802 }
4803 
SetBackdropBlur(float radius)4804 WMError WindowSceneSessionImpl::SetBackdropBlur(float radius)
4805 {
4806     WMError ret = CheckParmAndPermission();
4807     if (ret != WMError::WM_OK) {
4808         return ret;
4809     }
4810 
4811     WLOGFI("Set window %{public}s backdrop blur radius %{public}f", GetWindowName().c_str(), radius);
4812     if (MathHelper::LessNotEqual(radius, 0.0)) {
4813         return WMError::WM_ERROR_INVALID_PARAM;
4814     }
4815 
4816     radius = ConvertRadiusToSigma(radius);
4817     WLOGFI("Set window %{public}s backdrop blur radius after conversion %{public}f", GetWindowName().c_str(), radius);
4818     surfaceNode_->SetBackgroundFilter(RSFilter::CreateBlurFilter(radius, radius));
4819     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4820     return WMError::WM_OK;
4821 }
4822 
SetBackdropBlurStyle(WindowBlurStyle blurStyle)4823 WMError WindowSceneSessionImpl::SetBackdropBlurStyle(WindowBlurStyle blurStyle)
4824 {
4825     WMError ret = CheckParmAndPermission();
4826     if (ret != WMError::WM_OK) {
4827         return ret;
4828     }
4829 
4830     WLOGFI("Set window %{public}s backdrop blur style %{public}u", GetWindowName().c_str(), blurStyle);
4831     if (blurStyle < WindowBlurStyle::WINDOW_BLUR_OFF || blurStyle > WindowBlurStyle::WINDOW_BLUR_THICK) {
4832         return WMError::WM_ERROR_INVALID_PARAM;
4833     }
4834 
4835     if (blurStyle == WindowBlurStyle::WINDOW_BLUR_OFF) {
4836         surfaceNode_->SetBackgroundFilter(nullptr);
4837     } else {
4838         auto display = SingletonContainer::IsDestroyed() ? nullptr :
4839             SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
4840         if (display == nullptr) {
4841             WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
4842             return WMError::WM_ERROR_INVALID_PARAM;
4843         }
4844         auto displayInfo = display->GetDisplayInfo();
4845         if (displayInfo == nullptr) {
4846             WLOGFE("get displayInfo failed displayId:%{public}" PRIu64, property_->GetDisplayId());
4847             return WMError::WM_ERROR_INVALID_PARAM;
4848         }
4849         surfaceNode_->SetBackgroundFilter(RSFilter::CreateMaterialFilter(
4850             static_cast<int>(blurStyle), GetVirtualPixelRatio(displayInfo)));
4851     }
4852 
4853     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4854     return WMError::WM_OK;
4855 }
4856 
SetPrivacyMode(bool isPrivacyMode)4857 WMError WindowSceneSessionImpl::SetPrivacyMode(bool isPrivacyMode)
4858 {
4859     if (IsWindowSessionInvalid()) {
4860         return WMError::WM_ERROR_INVALID_WINDOW;
4861     }
4862     WLOGFD("id : %{public}u, %{public}u", GetWindowId(), isPrivacyMode);
4863     property_->SetPrivacyMode(isPrivacyMode);
4864     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE);
4865 }
4866 
IsPrivacyMode() const4867 bool WindowSceneSessionImpl::IsPrivacyMode() const
4868 {
4869     if (IsWindowSessionInvalid()) {
4870         return false;
4871     }
4872     return property_->GetPrivacyMode();
4873 }
4874 
SetSystemPrivacyMode(bool isSystemPrivacyMode)4875 void WindowSceneSessionImpl::SetSystemPrivacyMode(bool isSystemPrivacyMode)
4876 {
4877     WLOGFD("id : %{public}u, %{public}u", GetWindowId(), isSystemPrivacyMode);
4878     property_->SetSystemPrivacyMode(isSystemPrivacyMode);
4879     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE);
4880 }
4881 
SetSnapshotSkip(bool isSkip)4882 WMError WindowSceneSessionImpl::SetSnapshotSkip(bool isSkip)
4883 {
4884     if (IsWindowSessionInvalid()) {
4885         return WMError::WM_ERROR_INVALID_WINDOW;
4886     }
4887     bool oldSkipValue = property_->GetSnapshotSkip();
4888     property_->SetSnapshotSkip(isSkip);
4889     auto resError = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP);
4890     if (resError != WMError::WM_OK) {
4891         property_->SetSnapshotSkip(oldSkipValue);
4892     }
4893     return resError;
4894 }
4895 
Snapshot()4896 std::shared_ptr<Media::PixelMap> WindowSceneSessionImpl::Snapshot()
4897 {
4898     if (IsWindowSessionInvalid()) {
4899         return nullptr;
4900     }
4901     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
4902     auto isSucceeded = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
4903     if (!isSucceeded) {
4904         WLOGFE("Failed to TakeSurfaceCapture!");
4905         return nullptr;
4906     }
4907     std::shared_ptr<Media::PixelMap> pixelMap = callback->GetResult(SNAPSHOT_TIMEOUT);
4908     if (pixelMap != nullptr) {
4909         WLOGFD("Snapshot succeed, save WxH=%{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
4910     } else {
4911         WLOGFE("Failed to get pixelmap, return nullptr!");
4912     }
4913     return pixelMap;
4914 }
4915 
Snapshot(std::shared_ptr<Media::PixelMap> & pixelMap)4916 WMError WindowSceneSessionImpl::Snapshot(std::shared_ptr<Media::PixelMap>& pixelMap)
4917 {
4918     if (IsWindowSessionInvalid()) {
4919         return WMError::WM_ERROR_INVALID_WINDOW;
4920     }
4921     if (state_ < WindowState::STATE_SHOWN) {
4922         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d bounds not init, state: %{public}u",
4923             GetPersistentId(), state_);
4924         return WMError::WM_ERROR_INVALID_WINDOW;
4925     }
4926     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
4927     auto isSucceeded = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
4928     if (!isSucceeded) {
4929         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, Failed to TakeSurfaceCapture", GetPersistentId());
4930         return WMError::WM_ERROR_INVALID_OPERATION;
4931     }
4932     pixelMap = callback->GetResult(SNAPSHOT_TIMEOUT);
4933     if (pixelMap == nullptr) {
4934         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, Failed to get pixelmap", GetPersistentId());
4935         return WMError::WM_ERROR_TIMEOUT;
4936     }
4937     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d snapshot end, WxH=%{public}dx%{public}d",
4938         GetPersistentId(), pixelMap->GetWidth(), pixelMap->GetHeight());
4939     return WMError::WM_OK;
4940 }
4941 
SnapshotIgnorePrivacy(std::shared_ptr<Media::PixelMap> & pixelMap)4942 WMError WindowSceneSessionImpl::SnapshotIgnorePrivacy(std::shared_ptr<Media::PixelMap>& pixelMap)
4943 {
4944     if (IsWindowSessionInvalid()) {
4945         return WMError::WM_ERROR_INVALID_WINDOW;
4946     }
4947     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
4948     auto isSucceeded = RSInterfaces::GetInstance().TakeSelfSurfaceCapture(surfaceNode_, callback);
4949     if (!isSucceeded) {
4950         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "windowId:%{public}u, Failed to TakeSelfSurfaceCapture!", GetWindowId());
4951         return WMError::WM_ERROR_INVALID_OPERATION;
4952     }
4953     pixelMap = callback->GetResult(SNAPSHOT_TIMEOUT);
4954     if (pixelMap == nullptr) {
4955         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Failed to get pixelmap, windowId:%{public}u", GetWindowId());
4956         return WMError::WM_ERROR_NULLPTR;
4957     }
4958     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "succeed, windowId:%{public}u, WxH=%{public}dx%{public}d",
4959         GetWindowId(), pixelMap->GetWidth(), pixelMap->GetHeight());
4960     return WMError::WM_OK;
4961 }
4962 
NotifyMemoryLevel(int32_t level)4963 WMError WindowSceneSessionImpl::NotifyMemoryLevel(int32_t level)
4964 {
4965     TLOGI(WmsLogTag::DEFAULT, "id: %{public}u, level: %{public}d", GetWindowId(), level);
4966     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
4967     if (uiContent == nullptr) {
4968         WLOGFE("Window %{public}s notify failed, uiContent is null.", GetWindowName().c_str());
4969         return WMError::WM_ERROR_NULLPTR;
4970     }
4971     // notify memory level
4972     uiContent->NotifyMemoryLevel(level);
4973     WLOGFD("End!");
4974     return WMError::WM_OK;
4975 }
4976 
SetTurnScreenOn(bool turnScreenOn)4977 WMError WindowSceneSessionImpl::SetTurnScreenOn(bool turnScreenOn)
4978 {
4979     if (IsWindowSessionInvalid()) {
4980         return WMError::WM_ERROR_INVALID_WINDOW;
4981     }
4982     property_->SetTurnScreenOn(turnScreenOn);
4983     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON);
4984 }
4985 
IsTurnScreenOn() const4986 bool WindowSceneSessionImpl::IsTurnScreenOn() const
4987 {
4988     return property_->IsTurnScreenOn();
4989 }
4990 
SetKeepScreenOn(bool keepScreenOn)4991 WMError WindowSceneSessionImpl::SetKeepScreenOn(bool keepScreenOn)
4992 {
4993     if (IsWindowSessionInvalid()) {
4994         WLOGFE("session is invalid");
4995         return WMError::WM_ERROR_INVALID_WINDOW;
4996     }
4997     property_->SetKeepScreenOn(keepScreenOn);
4998     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON);
4999 }
5000 
IsKeepScreenOn() const5001 bool WindowSceneSessionImpl::IsKeepScreenOn() const
5002 {
5003     return property_->IsKeepScreenOn();
5004 }
5005 
SetViewKeepScreenOn(bool keepScreenOn)5006 WMError WindowSceneSessionImpl::SetViewKeepScreenOn(bool keepScreenOn)
5007 {
5008     if (IsWindowSessionInvalid()) {
5009         return WMError::WM_ERROR_INVALID_WINDOW;
5010     }
5011     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, enabled: %{public}u", GetPersistentId(), keepScreenOn);
5012     property_->SetViewKeepScreenOn(keepScreenOn);
5013     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_VIEW_KEEP_SCREEN_ON);
5014 }
5015 
IsViewKeepScreenOn() const5016 bool WindowSceneSessionImpl::IsViewKeepScreenOn() const
5017 {
5018     return property_->IsViewKeepScreenOn();
5019 }
5020 
SetWindowShadowEnabled(bool isEnabled)5021 WMError WindowSceneSessionImpl::SetWindowShadowEnabled(bool isEnabled)
5022 {
5023     if (property_->GetPcAppInpadCompatibleMode()) {
5024         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is PcAppInPad, not supported");
5025         return WMError::WM_OK;
5026     }
5027     if (!windowSystemConfig_.IsPcWindow()) {
5028         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
5029     }
5030     if (IsWindowSessionInvalid()) {
5031         return WMError::WM_ERROR_INVALID_WINDOW;
5032     }
5033     property_->SetWindowShadowEnabled(isEnabled);
5034     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_SHADOW_ENABLED);
5035 }
5036 
GetWindowShadowEnabled() const5037 bool WindowSceneSessionImpl::GetWindowShadowEnabled() const
5038 {
5039     return property_->GetWindowShadowEnabled();
5040 }
5041 
SetTransform(const Transform & trans)5042 WMError WindowSceneSessionImpl::SetTransform(const Transform& trans)
5043 {
5044     TLOGI(WmsLogTag::DEFAULT, "Id: %{public}d", property_->GetPersistentId());
5045     if (IsWindowSessionInvalid()) {
5046         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
5047         return WMError::WM_ERROR_INVALID_WINDOW;
5048     }
5049     Transform oriTrans = property_->GetTransform();
5050     property_->SetTransform(trans);
5051     TransformSurfaceNode(trans);
5052     return WMError::WM_OK;
5053 }
5054 
GetTransform() const5055 const Transform& WindowSceneSessionImpl::GetTransform() const
5056 {
5057     return property_->GetTransform();
5058 }
5059 
TransformSurfaceNode(const Transform & trans)5060 void WindowSceneSessionImpl::TransformSurfaceNode(const Transform& trans)
5061 {
5062     if (surfaceNode_ == nullptr) {
5063         return;
5064     }
5065     surfaceNode_->SetPivotX(trans.pivotX_);
5066     surfaceNode_->SetPivotY(trans.pivotY_);
5067     surfaceNode_->SetScaleX(trans.scaleX_);
5068     surfaceNode_->SetScaleY(trans.scaleY_);
5069     surfaceNode_->SetTranslateX(trans.translateX_);
5070     surfaceNode_->SetTranslateY(trans.translateY_);
5071     surfaceNode_->SetTranslateZ(trans.translateZ_);
5072     surfaceNode_->SetRotationX(trans.rotationX_);
5073     surfaceNode_->SetRotationY(trans.rotationY_);
5074     surfaceNode_->SetRotation(trans.rotationZ_);
5075     uint32_t animationFlag = property_->GetAnimationFlag();
5076     if (animationFlag != static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
5077         RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
5078     }
5079 }
5080 
RegisterAnimationTransitionController(const sptr<IAnimationTransitionController> & listener)5081 WMError WindowSceneSessionImpl::RegisterAnimationTransitionController(
5082     const sptr<IAnimationTransitionController>& listener)
5083 {
5084     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5085         TLOGE(WmsLogTag::WMS_SYSTEM, "permission denied!");
5086         return WMError::WM_ERROR_NOT_SYSTEM_APP;
5087     }
5088     if (listener == nullptr) {
5089         TLOGE(WmsLogTag::WMS_SYSTEM, "listener is nullptr");
5090         return WMError::WM_ERROR_NULLPTR;
5091     }
5092     animationTransitionController_ = listener;
5093     wptr<WindowSessionProperty> propertyWeak(property_);
5094     wptr<IAnimationTransitionController> animationTransitionControllerWeak(animationTransitionController_);
5095 
5096     if (auto uiContent = GetUIContentSharedPtr()) {
5097         uiContent->SetNextFrameLayoutCallback([propertyWeak, animationTransitionControllerWeak]() {
5098             auto property = propertyWeak.promote();
5099             auto animationTransitionController = animationTransitionControllerWeak.promote();
5100             if (!property || !animationTransitionController) {
5101                 TLOGE(WmsLogTag::WMS_SYSTEM, "property or animation transition controller is nullptr");
5102                 return;
5103             }
5104             uint32_t animationFlag = property->GetAnimationFlag();
5105             if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
5106                 // CustomAnimation is enabled when animationTransitionController_ exists
5107                 animationTransitionController->AnimationForShown();
5108             }
5109             TLOGI(WmsLogTag::WMS_SYSTEM, "AnimationForShown excute sucess %{public}d!", property->GetPersistentId());
5110         });
5111     }
5112     TLOGI(WmsLogTag::WMS_SYSTEM, "%{public}d!", property_->GetPersistentId());
5113     return WMError::WM_OK;
5114 }
5115 
UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)5116 WMError WindowSceneSessionImpl::UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)
5117 {
5118     TLOGI(WmsLogTag::WMS_SYSTEM, "id:%{public}d, isAdd:%{public}u", property_->GetPersistentId(), isAdd);
5119     if (IsWindowSessionInvalid()) {
5120         return WMError::WM_ERROR_INVALID_WINDOW;
5121     }
5122     if (!WindowHelper::IsSystemWindow(property_->GetWindowType())) {
5123         TLOGE(WmsLogTag::WMS_SYSTEM, "only system window can set");
5124         return WMError::WM_ERROR_INVALID_OPERATION;
5125     }
5126     // set no custom after customAnimation
5127     WMError ret = UpdateAnimationFlagProperty(false);
5128     if (ret != WMError::WM_OK) {
5129         TLOGE(WmsLogTag::WMS_SYSTEM, "UpdateAnimationFlagProperty failed!");
5130         return ret;
5131     }
5132     auto hostSession = GetHostSession();
5133     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5134     ret = static_cast<WMError>(hostSession->UpdateWindowSceneAfterCustomAnimation(isAdd));
5135     return ret;
5136 }
5137 
AdjustWindowAnimationFlag(bool withAnimation)5138 void WindowSceneSessionImpl::AdjustWindowAnimationFlag(bool withAnimation)
5139 {
5140     if (IsWindowSessionInvalid()) {
5141         WLOGFW("session invalid!");
5142         return;
5143     }
5144     // when show/hide with animation
5145     // use custom animation when transitionController exists; else use default animation
5146     WindowType winType = property_->GetWindowType();
5147     bool isAppWindow = WindowHelper::IsAppWindow(winType);
5148     if (withAnimation && !isAppWindow && animationTransitionController_) {
5149         // use custom animation
5150         property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
5151     } else if ((isAppWindow && enableDefaultAnimation_) || (withAnimation && !animationTransitionController_)) {
5152         // use default animation
5153         property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::DEFAULT));
5154     } else {
5155         // with no animation
5156         property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
5157     }
5158 }
5159 
UpdateAnimationFlagProperty(bool withAnimation)5160 WMError WindowSceneSessionImpl::UpdateAnimationFlagProperty(bool withAnimation)
5161 {
5162     if (!WindowHelper::IsSystemWindow(GetType())) {
5163         return WMError::WM_OK;
5164     }
5165     AdjustWindowAnimationFlag(withAnimation);
5166     // when show(true) with default, hide() with None, to adjust animationFlag to disabled default animation
5167     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG);
5168 }
5169 
SetAlpha(float alpha)5170 WMError WindowSceneSessionImpl::SetAlpha(float alpha)
5171 {
5172     WLOGFI("%{public}d alpha %{public}f", property_->GetPersistentId(), alpha);
5173     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5174         WLOGFE("permission denied!");
5175         return WMError::WM_ERROR_NOT_SYSTEM_APP;
5176     }
5177     if (IsWindowSessionInvalid()) {
5178         return WMError::WM_ERROR_INVALID_WINDOW;
5179     }
5180     surfaceNode_->SetAlpha(alpha);
5181     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
5182     return WMError::WM_OK;
5183 }
5184 
BindDialogTarget(sptr<IRemoteObject> targetToken)5185 WMError WindowSceneSessionImpl::BindDialogTarget(sptr<IRemoteObject> targetToken)
5186 {
5187     if (IsWindowSessionInvalid()) {
5188         TLOGE(WmsLogTag::WMS_DIALOG, "session is invalid");
5189         return WMError::WM_ERROR_INVALID_WINDOW;
5190     }
5191     auto persistentId = property_->GetPersistentId();
5192     TLOGI(WmsLogTag::WMS_DIALOG, "id: %{public}d", persistentId);
5193     WMError ret = SingletonContainer::Get<WindowAdapter>().BindDialogSessionTarget(persistentId, targetToken);
5194     if (ret != WMError::WM_OK) {
5195         TLOGE(WmsLogTag::WMS_DIALOG, "bind window failed with errCode:%{public}d", static_cast<int32_t>(ret));
5196     }
5197     return ret;
5198 }
5199 
SetDialogBackGestureEnabled(bool isEnabled)5200 WMError WindowSceneSessionImpl::SetDialogBackGestureEnabled(bool isEnabled)
5201 {
5202     WindowType windowType = GetType();
5203     if (windowType != WindowType::WINDOW_TYPE_DIALOG) {
5204         TLOGE(WmsLogTag::WMS_DIALOG, "windowType not support. WinId:%{public}u, WindowType:%{public}u",
5205             GetWindowId(), static_cast<uint32_t>(windowType));
5206         return WMError::WM_ERROR_INVALID_CALLING;
5207     }
5208     auto hostSession = GetHostSession();
5209     if (hostSession == nullptr) {
5210         TLOGE(WmsLogTag::WMS_DIALOG, "set window failed because of nullptr");
5211         return WMError::WM_ERROR_NULLPTR;
5212     }
5213     WMError ret = static_cast<WMError>(hostSession->SetDialogSessionBackGestureEnabled(isEnabled));
5214     dialogSessionBackGestureEnabled_ = isEnabled;
5215     if (ret != WMError::WM_OK) {
5216         TLOGE(WmsLogTag::WMS_DIALOG, "set window failed with errCode:%{public}d", static_cast<int32_t>(ret));
5217     }
5218     return ret;
5219 }
5220 
SetTouchHotAreas(const std::vector<Rect> & rects)5221 WMError WindowSceneSessionImpl::SetTouchHotAreas(const std::vector<Rect>& rects)
5222 {
5223     std::vector<Rect> lastTouchHotAreas;
5224     property_->GetTouchHotAreas(lastTouchHotAreas);
5225     property_->SetTouchHotAreas(rects);
5226     WMError result = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA);
5227     if (result != WMError::WM_OK) {
5228         property_->SetTouchHotAreas(lastTouchHotAreas);
5229         WLOGFE("errCode:%{public}d", static_cast<int32_t>(result));
5230         return result;
5231     }
5232     for (uint32_t i = 0; i < rects.size(); i++) {
5233         TLOGD(WmsLogTag::WMS_EVENT, "id:%{public}u xywh:[%{public}d %{public}d %{public}u %{public}u]",
5234             i, rects[i].posX_, rects[i].posY_, rects[i].width_, rects[i].height_);
5235     }
5236     return result;
5237 }
5238 
SetKeyboardTouchHotAreas(const KeyboardTouchHotAreas & hotAreas)5239 WMError WindowSceneSessionImpl::SetKeyboardTouchHotAreas(const KeyboardTouchHotAreas& hotAreas)
5240 {
5241     if (GetType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
5242         return WMError::WM_ERROR_INVALID_TYPE;
5243     }
5244     KeyboardTouchHotAreas lastKeyboardTouchHotAreas = property_->GetKeyboardTouchHotAreas();
5245     property_->SetKeyboardTouchHotAreas(hotAreas);
5246     WMError result = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_KEYBOARD_TOUCH_HOT_AREA);
5247     if (result != WMError::WM_OK) {
5248         property_->SetKeyboardTouchHotAreas(lastKeyboardTouchHotAreas);
5249         TLOGE(WmsLogTag::WMS_EVENT, "errCode:%{public}d", static_cast<int32_t>(result));
5250     }
5251     return result;
5252 }
5253 
KeepKeyboardOnFocus(bool keepKeyboardFlag)5254 WmErrorCode WindowSceneSessionImpl::KeepKeyboardOnFocus(bool keepKeyboardFlag)
5255 {
5256     property_->KeepKeyboardOnFocus(keepKeyboardFlag);
5257     return WmErrorCode::WM_OK;
5258 }
5259 
SetCallingWindow(uint32_t callingSessionId)5260 WMError WindowSceneSessionImpl::SetCallingWindow(uint32_t callingSessionId)
5261 {
5262     if (IsWindowSessionInvalid()) {
5263         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is invalid!");
5264         return WMError::WM_ERROR_INVALID_WINDOW;
5265     }
5266     if (callingSessionId != property_->GetCallingSessionId()) {
5267         TLOGI(WmsLogTag::WMS_KEYBOARD, "from %{public}d to: %{public}d",
5268             property_->GetCallingSessionId(), callingSessionId);
5269     }
5270     if (auto hostSession = GetHostSession()) {
5271         hostSession->SetCallingSessionId(callingSessionId);
5272     }
5273     property_->SetCallingSessionId(callingSessionId);
5274     return WMError::WM_OK;
5275 }
5276 
ChangeKeyboardEffectOption(KeyboardEffectOption effectOption)5277 WMError WindowSceneSessionImpl::ChangeKeyboardEffectOption(KeyboardEffectOption effectOption)
5278 {
5279     TLOGI(WmsLogTag::WMS_KEYBOARD, "effect option: %{public}s",
5280         effectOption.ToString().c_str());
5281     if (effectOption.viewMode_ >= KeyboardViewMode::VIEW_MODE_END ||
5282         effectOption.flowLightMode_ >= KeyboardFlowLightMode::END ||
5283         effectOption.gradientMode_ >= KeyboardGradientMode::END) {
5284         TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid view or effect mode! effectOption: %{public}s",
5285             effectOption.ToString().c_str());
5286         return WMError::WM_ERROR_INVALID_PARAM;
5287     }
5288 
5289     auto lastOption = property_->GetKeyboardEffectOption();
5290     if (effectOption == lastOption) {
5291         TLOGI(WmsLogTag::WMS_KEYBOARD, "Is same option: %{public}s", lastOption.ToString().c_str());
5292         return WMError::WM_DO_NOTHING;
5293     }
5294 
5295     if (IsWindowSessionInvalid()) {
5296         TLOGE(WmsLogTag::WMS_KEYBOARD, "Session is invalid!");
5297         return WMError::WM_ERROR_INVALID_WINDOW;
5298     }
5299 
5300     if (state_ != WindowState::STATE_SHOWN) {
5301         TLOGE(WmsLogTag::WMS_KEYBOARD, "The keyboard is not show status.");
5302         return WMError::WM_ERROR_INVALID_WINDOW;
5303     }
5304 
5305     property_->SetKeyboardEffectOption(effectOption);
5306     auto hostSession = GetHostSession();
5307     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5308     return static_cast<WMError>(hostSession->ChangeKeyboardEffectOption(effectOption));
5309 }
5310 
DumpSessionElementInfo(const std::vector<std::string> & params)5311 void WindowSceneSessionImpl::DumpSessionElementInfo(const std::vector<std::string>& params)
5312 {
5313     WLOGFD("in");
5314     std::vector<std::string> info;
5315     if (params.size() == 1 && params[0] == PARAM_DUMP_HELP) { // 1: params num
5316         WLOGFD("Dump ArkUI help Info");
5317         Ace::UIContent::ShowDumpHelp(info);
5318         SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
5319         return;
5320     }
5321 
5322     WLOGFD("ArkUI:DumpInfo");
5323     if (auto uiContent = GetUIContentSharedPtr()) {
5324         uiContent->DumpInfo(params, info);
5325     }
5326 
5327     for (auto iter = info.begin(); iter != info.end();) {
5328         if ((*iter).size() == 0) {
5329             iter = info.erase(iter);
5330             continue;
5331         }
5332         WLOGFD("ElementInfo size: %{public}u", static_cast<uint32_t>((*iter).size()));
5333         iter++;
5334     }
5335     if (info.size() == 0) {
5336         WLOGFD("ElementInfo is empty");
5337         return;
5338     }
5339     SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
5340 }
5341 
NotifyLayoutFinishAfterWindowModeChange(WindowMode mode)5342 WSError WindowSceneSessionImpl::NotifyLayoutFinishAfterWindowModeChange(WindowMode mode)
5343 {
5344     NotifyWindowStatusDidChange(mode);
5345     return WSError::WS_OK;
5346 }
5347 
UpdateWindowMode(WindowMode mode)5348 WSError WindowSceneSessionImpl::UpdateWindowMode(WindowMode mode)
5349 {
5350     WLOGFI("%{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
5351     if (IsWindowSessionInvalid()) {
5352         return WSError::WS_ERROR_INVALID_WINDOW;
5353     }
5354     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), mode)) {
5355         WLOGFE("%{public}u do not support mode: %{public}u",
5356             GetWindowId(), static_cast<uint32_t>(mode));
5357         return WSError::WS_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
5358     }
5359     WMError ret = UpdateWindowModeImmediately(mode);
5360 
5361     if (windowSystemConfig_.IsPcWindow()) {
5362         if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
5363             ret = SetLayoutFullScreenByApiVersion(true);
5364             if (ret != WMError::WM_OK) {
5365                 TLOGE(WmsLogTag::WMS_IMMS, "SetLayoutFullScreenByApiVersion errCode:%{public}d winId:%{public}u",
5366                     static_cast<int32_t>(ret), GetWindowId());
5367             }
5368             SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
5369             statusProperty.enable_ = false;
5370             ret = SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
5371             if (ret != WMError::WM_OK) {
5372                 WLOGFE("SetSystemBarProperty errCode:%{public}d winId:%{public}u",
5373                     static_cast<int32_t>(ret), GetWindowId());
5374             }
5375         }
5376     }
5377     return static_cast<WSError>(ret);
5378 }
5379 
GetTopNavDestinationName(std::string & topNavDestName)5380 WSError WindowSceneSessionImpl::GetTopNavDestinationName(std::string& topNavDestName)
5381 {
5382     auto uiContent = GetUIContentSharedPtr();
5383     if (uiContent == nullptr) {
5384         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent is null: winId=%{public}u", GetWindowId());
5385         return WSError::WS_DO_NOTHING;
5386     }
5387     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "call uicontent: winId=%{public}u", GetWindowId());
5388     std::string navDestInfoJsonStr = uiContent->GetTopNavDestinationInfo(false, false);
5389     if (navDestInfoJsonStr.empty()) {
5390         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, empty navDestInfoJsonStr", GetWindowId());
5391         return WSError::WS_OK;
5392     }
5393     nlohmann::json navDestInfoJson = nlohmann::json::parse(navDestInfoJsonStr, nullptr, false);
5394     if (navDestInfoJson.is_discarded()) {
5395         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "parse json error: winId=%{public}u, navDestInfoJsonStr=%{public}s",
5396             GetWindowId(), navDestInfoJsonStr.c_str());
5397         return WSError::WS_DO_NOTHING;
5398     }
5399     if (navDestInfoJson.contains("name")) {
5400         navDestInfoJson["name"].get_to(topNavDestName);
5401     }
5402     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, navDestInfoJsonStr=%{public}s, topNavDestName=%{public}s",
5403         GetWindowId(), navDestInfoJsonStr.c_str(), topNavDestName.c_str());
5404     return WSError::WS_OK;
5405 }
5406 
UpdateWindowModeImmediately(WindowMode mode)5407 WMError WindowSceneSessionImpl::UpdateWindowModeImmediately(WindowMode mode)
5408 {
5409     if (state_ == WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
5410         property_->SetWindowMode(mode);
5411         UpdateTitleButtonVisibility();
5412         UpdateDecorEnable(true);
5413     } else if (state_ == WindowState::STATE_SHOWN) {
5414         // set client window mode if success.
5415         property_->SetWindowMode(mode);
5416         UpdateTitleButtonVisibility();
5417         UpdateDecorEnable(true, mode);
5418         if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
5419             property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
5420         }
5421     }
5422     NotifyWindowStatusChange(mode);
5423     return WMError::WM_OK;
5424 }
5425 
UpdateMaximizeMode(MaximizeMode mode)5426 WSError WindowSceneSessionImpl::UpdateMaximizeMode(MaximizeMode mode)
5427 {
5428     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "%{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
5429     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
5430     if (uiContent == nullptr) {
5431         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "uiContent is null");
5432         return WSError::WS_ERROR_INVALID_PARAM;
5433     }
5434     uiContent->UpdateMaximizeMode(mode);
5435     property_->SetMaximizeMode(mode);
5436     if (mode == MaximizeMode::MODE_RECOVER && enableImmersiveMode_.load()) {
5437         enableImmersiveMode_.store(false);
5438         property_->SetIsLayoutFullScreen(false);
5439         if (auto hostSession = GetHostSession()) {
5440             hostSession->OnLayoutFullScreenChange(false);
5441         }
5442     }
5443     return WSError::WS_OK;
5444 }
5445 
NotifySessionFullScreen(bool fullScreen)5446 void WindowSceneSessionImpl::NotifySessionFullScreen(bool fullScreen)
5447 {
5448     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId: %{public}u", GetWindowId());
5449     Maximize(fullScreen ? MaximizePresentation::ENTER_IMMERSIVE : MaximizePresentation::EXIT_IMMERSIVE);
5450 }
5451 
UpdateTitleInTargetPos(bool isShow,int32_t height)5452 WSError WindowSceneSessionImpl::UpdateTitleInTargetPos(bool isShow, int32_t height)
5453 {
5454     TLOGI(WmsLogTag::WMS_DECOR, "%{public}u isShow %{public}u, height %{public}u", GetWindowId(), isShow, height);
5455     if (IsWindowSessionInvalid()) {
5456         return WSError::WS_ERROR_INVALID_WINDOW;
5457     }
5458     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
5459     if (uiContent == nullptr) {
5460         TLOGE(WmsLogTag::WMS_DECOR, "uiContent is null");
5461         return WSError::WS_ERROR_INVALID_PARAM;
5462     }
5463     uiContent->UpdateTitleInTargetPos(isShow, height);
5464     return WSError::WS_OK;
5465 }
5466 
UpdateSupportWindowModesWhenSwitchFreeMultiWindow()5467 void WindowSceneSessionImpl::UpdateSupportWindowModesWhenSwitchFreeMultiWindow()
5468 {
5469     if (haveSetSupportedWindowModes_) {
5470         TLOGI(WmsLogTag::WMS_LAYOUT, "SupportedWindowMode is already set, id: %{public}d", GetPersistentId());
5471         return;
5472     }
5473     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
5474     if (abilityContext == nullptr) {
5475         TLOGE(WmsLogTag::WMS_LAYOUT, "abilityContext is nullptr");
5476         return;
5477     }
5478     auto abilityInfo = abilityContext->GetAbilityInfo();
5479     std::vector<AppExecFwk::SupportWindowMode> updateWindowModes =
5480         ExtractSupportWindowModeFromMetaData(abilityInfo);
5481     if (auto hostSession = GetHostSession()) {
5482         hostSession->NotifySupportWindowModesChange(updateWindowModes);
5483     };
5484     auto windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(updateWindowModes);
5485     property_->SetWindowModeSupportType(windowModeSupportType);
5486     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
5487 }
5488 
SwitchFreeMultiWindow(bool enable)5489 WSError WindowSceneSessionImpl::SwitchFreeMultiWindow(bool enable)
5490 {
5491     if (IsWindowSessionInvalid()) {
5492         return WSError::WS_ERROR_INVALID_WINDOW;
5493     }
5494     if (windowSystemConfig_.freeMultiWindowEnable_ == enable) {
5495         UpdateSupportWindowModesWhenSwitchFreeMultiWindow();
5496         return WSError::WS_ERROR_REPEAT_OPERATION;
5497     }
5498     NotifySwitchFreeMultiWindow(enable);
5499     // Switch process finish, update system config
5500     SetFreeMultiWindowMode(enable);
5501     if (enable) {
5502         PendingUpdateSupportWindowModesWhenSwitchMultiWindow();
5503     }
5504     UpdateSupportWindowModesWhenSwitchFreeMultiWindow();
5505     UpdateEnableDragWhenSwitchMultiWindow(enable);
5506     if (!enable && !WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
5507         WindowMode::WINDOW_MODE_FULLSCREEN)) {
5508         UpdateDecorEnable(true);
5509     }
5510     auto mainWindow = FindMainWindowWithContext();
5511     bool isAnco = mainWindow != nullptr && mainWindow->IsAnco();
5512     if (WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING) &&
5513         !isAnco) {
5514         UpdateImmersiveBySwitchMode(enable);
5515     }
5516     SwitchSubWindow(enable, GetPersistentId());
5517     return WSError::WS_OK;
5518 }
5519 
PendingUpdateSupportWindowModesWhenSwitchMultiWindow()5520 void WindowSceneSessionImpl::PendingUpdateSupportWindowModesWhenSwitchMultiWindow()
5521 {
5522     if (pendingWindowModeSupportType_ == WindowModeSupport::WINDOW_MODE_SUPPORT_ALL) {
5523         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "pending data has not set, id: %{public}d", GetPersistentId());
5524         return;
5525     }
5526 
5527     uint32_t windowModeSupportType = pendingWindowModeSupportType_;
5528     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d, windowModeSupportType: %{public}u",
5529         GetPersistentId(), windowModeSupportType);
5530 
5531     pendingWindowModeSupportType_ = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
5532     property_->SetWindowModeSupportType(windowModeSupportType);
5533 
5534     // update windowModeSupportType to server
5535     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
5536     UpdateTitleButtonVisibility();
5537     haveSetSupportedWindowModes_ = true;
5538 
5539     // update window mode immediately when pending window support type take effect
5540     bool onlySupportFullScreen =
5541         WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
5542         !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING);
5543     bool disableFullScreen = property_->IsFullScreenDisabled();
5544     if (onlySupportFullScreen && !disableFullScreen) {
5545         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "only support fullscreen, enter immersive");
5546         Maximize(MaximizePresentation::ENTER_IMMERSIVE);
5547     }
5548 }
5549 
UpdateImmersiveBySwitchMode(bool freeMultiWindowEnable)5550 void WindowSceneSessionImpl::UpdateImmersiveBySwitchMode(bool freeMultiWindowEnable)
5551 {
5552     if (freeMultiWindowEnable && enableImmersiveMode_) {
5553         cacheEnableImmersiveMode_.store(true);
5554         enableImmersiveMode_.store(false);
5555         property_->SetIsLayoutFullScreen(enableImmersiveMode_);
5556         if (auto hostSession = GetHostSession()) {
5557             hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
5558         } else {
5559             TLOGE(WmsLogTag::WMS_LAYOUT, "host session is nullptr, id: %{public}d", GetPersistentId());
5560         }
5561     }
5562     if (!freeMultiWindowEnable && cacheEnableImmersiveMode_) {
5563         enableImmersiveMode_.store(true);
5564         cacheEnableImmersiveMode_.store(false);
5565         property_->SetIsLayoutFullScreen(enableImmersiveMode_);
5566         if (auto hostSession = GetHostSession()) {
5567             hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
5568         } else {
5569             TLOGE(WmsLogTag::WMS_LAYOUT, "host session is nullptr, id: %{public}d", GetPersistentId());
5570         }
5571     }
5572 }
5573 
GetFreeMultiWindowModeEnabledState()5574 bool WindowSceneSessionImpl::GetFreeMultiWindowModeEnabledState()
5575 {
5576     return windowSystemConfig_.freeMultiWindowEnable_ &&
5577         windowSystemConfig_.freeMultiWindowSupport_;
5578 }
5579 
PcAppInPadNormalClose()5580 WSError WindowSceneSessionImpl::PcAppInPadNormalClose()
5581 {
5582     if (IsWindowSessionInvalid()) {
5583         TLOGE(WmsLogTag::WMS_COMPAT, "window session invalid!");
5584         return WSError::WS_ERROR_INVALID_WINDOW;
5585     }
5586     if (!property_->GetIsPcAppInPad()) {
5587         TLOGE(WmsLogTag::WMS_COMPAT, "is not pcAppInPad, can not Close");
5588         return WSError::WS_ERROR_INVALID_WINDOW;
5589     }
5590     Close();
5591     return WSError::WS_OK;
5592 }
5593 
NotifyCompatibleModePropertyChange(const sptr<CompatibleModeProperty> property)5594 WSError WindowSceneSessionImpl::NotifyCompatibleModePropertyChange(const sptr<CompatibleModeProperty> property)
5595 {
5596     if (IsWindowSessionInvalid()) {
5597         TLOGE(WmsLogTag::WMS_COMPAT, "window session invalid!");
5598         return WSError::WS_ERROR_INVALID_WINDOW;
5599     }
5600     property_->SetCompatibleModeProperty(property);
5601     return WSError::WS_OK;
5602 }
5603 
NotifySessionForeground(uint32_t reason,bool withAnimation)5604 void WindowSceneSessionImpl::NotifySessionForeground(uint32_t reason, bool withAnimation)
5605 {
5606     TLOGI(WmsLogTag::WMS_LIFE, "in");
5607     if (!handler_) {
5608         TLOGE(WmsLogTag::WMS_LIFE, "handler is nullptr");
5609         return;
5610     }
5611     handler_->PostTask([weakThis = wptr(this), reason, withAnimation] {
5612         auto window = weakThis.promote();
5613         if (!window) {
5614             TLOGNE(WmsLogTag::WMS_LIFE, "window is nullptr");
5615             return;
5616         }
5617         window->Show(reason, withAnimation);
5618     }, __func__);
5619 }
5620 
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)5621 void WindowSceneSessionImpl::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
5622 {
5623     TLOGI(WmsLogTag::WMS_LIFE, "in");
5624     if (!handler_) {
5625         TLOGE(WmsLogTag::WMS_LIFE, "handler is nullptr");
5626         return;
5627     }
5628     handler_->PostTask([weakThis = wptr(this), reason, withAnimation, isFromInnerkits] {
5629         auto window = weakThis.promote();
5630         if (!window) {
5631             TLOGNE(WmsLogTag::WMS_LIFE, "window is nullptr");
5632             return;
5633         }
5634         window->Hide(reason, withAnimation, isFromInnerkits);
5635     }, __func__);
5636 }
5637 
NotifyPrepareClosePiPWindow()5638 WMError WindowSceneSessionImpl::NotifyPrepareClosePiPWindow()
5639 {
5640     TLOGI(WmsLogTag::WMS_PIP, "type: %{public}u", GetType());
5641     if (!WindowHelper::IsPipWindow(GetType())) {
5642         return WMError::WM_DO_NOTHING;
5643     }
5644     auto hostSession = GetHostSession();
5645     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5646     hostSession->NotifyPiPWindowPrepareClose();
5647     return WMError::WM_OK;
5648 }
5649 
GetWindowLimits(WindowLimits & windowLimits)5650 WMError WindowSceneSessionImpl::GetWindowLimits(WindowLimits& windowLimits)
5651 {
5652     if (IsWindowSessionInvalid()) {
5653         WLOGFE("session is invalid");
5654         return WMError::WM_ERROR_INVALID_WINDOW;
5655     }
5656     const auto& customizedLimits = property_->GetWindowLimits();
5657     windowLimits.minWidth_ = customizedLimits.minWidth_;
5658     windowLimits.minHeight_ = customizedLimits.minHeight_;
5659     windowLimits.maxWidth_ = customizedLimits.maxWidth_;
5660     windowLimits.maxHeight_ = customizedLimits.maxHeight_;
5661     windowLimits.vpRatio_ = customizedLimits.vpRatio_;
5662     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
5663         "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", GetWindowId(), windowLimits.minWidth_,
5664         windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
5665     return WMError::WM_OK;
5666 }
5667 
UpdateNewSize()5668 void WindowSceneSessionImpl::UpdateNewSize()
5669 {
5670     if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING || property_->IsWindowLimitDisabled()) {
5671         TLOGI(WmsLogTag::WMS_LAYOUT, "Fullscreen couldnot update new size, Id: %{public}u", GetWindowId());
5672         return;
5673     }
5674     bool needResize = false;
5675     Rect windowRect = GetRequestRect();
5676     if (windowRect.IsUninitializedSize()) {
5677         windowRect = GetRect();
5678         if (windowRect.IsUninitializedSize()) {
5679             TLOGW(WmsLogTag::WMS_LAYOUT, "The sizes of requestRect and rect are uninitialized. winId: %{public}u",
5680                 GetWindowId());
5681             return;
5682         }
5683     }
5684 
5685     uint32_t width = windowRect.width_;
5686     uint32_t height = windowRect.height_;
5687     const auto& newLimits = property_->GetWindowLimits();
5688     if (width < newLimits.minWidth_) {
5689         width = newLimits.minWidth_;
5690         needResize = true;
5691     }
5692     if (height < newLimits.minHeight_) {
5693         height = newLimits.minHeight_;
5694         needResize = true;
5695     }
5696     if (width > newLimits.maxWidth_) {
5697         width = newLimits.maxWidth_;
5698         needResize = true;
5699     }
5700     if (height > newLimits.maxHeight_) {
5701         height = newLimits.maxHeight_;
5702         needResize = true;
5703     }
5704     if (needResize) {
5705         if (IsPcOrPadFreeMultiWindowMode()) {
5706             isResizedByLimit_ = true;
5707         }
5708         Resize(width, height);
5709         TLOGI(WmsLogTag::WMS_LAYOUT, "Resize window by limits. Id: %{public}u, width: %{public}u,"
5710             " height: %{public}u", GetWindowId(), width, height);
5711     }
5712 }
5713 
SetWindowLimits(WindowLimits & windowLimits,bool isForcible)5714 WMError WindowSceneSessionImpl::SetWindowLimits(WindowLimits& windowLimits, bool isForcible)
5715 {
5716     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
5717         "maxWidth:%{public}u, maxHeight:%{public}u, isForcible:%{public}u", GetWindowId(), windowLimits.minWidth_,
5718         windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, isForcible);
5719     if (IsWindowSessionInvalid()) {
5720         TLOGE(WmsLogTag::WMS_LAYOUT, "session is invalid");
5721         return WMError::WM_ERROR_INVALID_WINDOW;
5722     }
5723 
5724     WindowType windowType = GetType();
5725     bool isDraggableSystemWin = WindowHelper::IsSystemWindow(windowType) && IsWindowDraggable();
5726     if (!WindowHelper::IsMainWindow(windowType) && !WindowHelper::IsSubWindow(windowType) &&
5727         windowType != WindowType::WINDOW_TYPE_DIALOG && !isDraggableSystemWin) {
5728         TLOGE(WmsLogTag::WMS_LAYOUT, "type not support. Id:%{public}u, type:%{public}u",
5729             GetWindowId(), static_cast<uint32_t>(windowType));
5730         return WMError::WM_ERROR_INVALID_CALLING;
5731     }
5732 
5733     const auto& customizedLimits = property_->GetWindowLimits();
5734     uint32_t minWidth = windowLimits.minWidth_ ? windowLimits.minWidth_ : customizedLimits.minWidth_;
5735     uint32_t minHeight = windowLimits.minHeight_ ? windowLimits.minHeight_ : customizedLimits.minHeight_;
5736     uint32_t maxWidth = windowLimits.maxWidth_ ? windowLimits.maxWidth_ : customizedLimits.maxWidth_;
5737     uint32_t maxHeight = windowLimits.maxHeight_ ? windowLimits.maxHeight_ : customizedLimits.maxHeight_;
5738 
5739     property_->SetUserWindowLimits({
5740         maxWidth, maxHeight, minWidth, minHeight, customizedLimits.maxRatio_, customizedLimits.minRatio_
5741     });
5742     forceLimits_ = isForcible;
5743     userLimitsSet_ = true;
5744     UpdateWindowSizeLimits();
5745     WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
5746     if (ret != WMError::WM_OK) {
5747         TLOGE(WmsLogTag::WMS_LAYOUT, "update window proeprty failed! id: %{public}u.", GetWindowId());
5748         return ret;
5749     }
5750     UpdateNewSize();
5751 
5752     fillWindowLimits(windowLimits);
5753     return WMError::WM_OK;
5754 }
5755 
fillWindowLimits(WindowLimits & windowLimits)5756 void WindowSceneSessionImpl::fillWindowLimits(WindowLimits& windowLimits)
5757 {
5758     const auto& newLimits = property_->GetWindowLimits();
5759     windowLimits.minWidth_ = newLimits.minWidth_;
5760     windowLimits.minHeight_ = newLimits.minHeight_;
5761     windowLimits.maxWidth_ = newLimits.maxWidth_;
5762     windowLimits.maxHeight_ = newLimits.maxHeight_;
5763     WLOGFI("success! Id:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
5764         "maxWidth:%{public}u, maxHeight:%{public}u", GetWindowId(), windowLimits.minWidth_,
5765         windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_);
5766 }
5767 
NotifyDialogStateChange(bool isForeground)5768 WSError WindowSceneSessionImpl::NotifyDialogStateChange(bool isForeground)
5769 {
5770     const auto type = GetType();
5771     TLOGI(WmsLogTag::WMS_DIALOG, "state change [name:%{public}s, id:%{public}d, type:%{public}u], state:%{public}u,"
5772         " requestState:%{public}u, isForeground:%{public}d", property_->GetWindowName().c_str(), GetPersistentId(),
5773         type, state_, requestState_, static_cast<int32_t>(isForeground));
5774     if (IsWindowSessionInvalid()) {
5775         TLOGE(WmsLogTag::WMS_DIALOG, "session is invalid, id:%{public}d", GetPersistentId());
5776         return WSError::WS_ERROR_INVALID_WINDOW;
5777     }
5778 
5779     if (isForeground) {
5780         if (state_ == WindowState::STATE_SHOWN) {
5781             return WSError::WS_OK;
5782         }
5783         if (state_ == WindowState::STATE_HIDDEN && requestState_ == WindowState::STATE_SHOWN) {
5784             state_ = WindowState::STATE_SHOWN;
5785             NotifyAfterForeground();
5786         }
5787     } else {
5788         if (state_ == WindowState::STATE_HIDDEN) {
5789             return WSError::WS_OK;
5790         }
5791         if (state_ == WindowState::STATE_SHOWN) {
5792             state_ = WindowState::STATE_HIDDEN;
5793             NotifyAfterBackground();
5794         }
5795     }
5796     TLOGI(WmsLogTag::WMS_DIALOG, "success [name:%{public}s, id:%{public}d, type:%{public}u],"
5797         " state:%{public}u, requestState:%{public}u", property_->GetWindowName().c_str(), property_->GetPersistentId(),
5798         type, state_, requestState_);
5799     return WSError::WS_OK;
5800 }
5801 
SetDefaultDensityEnabled(bool enabled)5802 WMError WindowSceneSessionImpl::SetDefaultDensityEnabled(bool enabled)
5803 {
5804     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Id=%{public}d, enabled=%{public}d", GetWindowId(), enabled);
5805     if (IsWindowSessionInvalid()) {
5806         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "window is invalid");
5807         return WMError::WM_ERROR_INVALID_WINDOW;
5808     }
5809 
5810     if (!WindowHelper::IsMainWindow(GetType())) {
5811         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "must be app main window");
5812         return WMError::WM_ERROR_INVALID_CALLING;
5813     }
5814 
5815     if (defaultDensityEnabledGlobalConfig_ == enabled) {
5816         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "defaultDensityEnabledGlobalConfig not change");
5817         return WMError::WM_OK;
5818     }
5819 
5820     if (auto hostSession = GetHostSession()) {
5821         hostSession->OnDefaultDensityEnabled(enabled);
5822     }
5823 
5824     defaultDensityEnabledGlobalConfig_ = enabled;
5825     SetDefaultDensityEnabledValue(enabled);
5826 
5827     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
5828     for (const auto& winPair : windowSessionMap_) {
5829         auto window = winPair.second.second;
5830         if (window == nullptr) {
5831             TLOGE(WmsLogTag::WMS_ATTRIBUTE, "window is nullptr");
5832             continue;
5833         }
5834         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Id=%{public}d UpdateDensity", window->GetWindowId());
5835         window->SetDefaultDensityEnabledValue(enabled);
5836         window->UpdateDensity();
5837     }
5838     return WMError::WM_OK;
5839 }
5840 
GetDefaultDensityEnabled()5841 bool WindowSceneSessionImpl::GetDefaultDensityEnabled()
5842 {
5843     return isDefaultDensityEnabled_.load();
5844 }
5845 
GetVirtualPixelRatio(const sptr<DisplayInfo> & displayInfo)5846 float WindowSceneSessionImpl::GetVirtualPixelRatio(const sptr<DisplayInfo>& displayInfo)
5847 {
5848     if (displayInfo == nullptr) {
5849         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "displayInfo is nullptr");
5850         return INVALID_DEFAULT_DENSITY;
5851     }
5852     if (IsDefaultDensityEnabled()) {
5853         return displayInfo->GetDefaultVirtualPixelRatio();
5854     }
5855     if (useUniqueDensity_) {
5856         return virtualPixelRatio_;
5857     }
5858     auto vpr = GetMainWindowCustomDensity();
5859     return vpr >= MINIMUM_CUSTOM_DENSITY && vpr <= MAXIMUM_CUSTOM_DENSITY ? vpr : displayInfo->GetVirtualPixelRatio();
5860 }
5861 
HideNonSecureWindows(bool shouldHide)5862 WMError WindowSceneSessionImpl::HideNonSecureWindows(bool shouldHide)
5863 {
5864     return SingletonContainer::Get<WindowAdapter>().AddOrRemoveSecureSession(property_->GetPersistentId(), shouldHide);
5865 }
5866 
SetTextFieldAvoidInfo(double textFieldPositionY,double textFieldHeight)5867 WMError WindowSceneSessionImpl::SetTextFieldAvoidInfo(double textFieldPositionY, double textFieldHeight)
5868 {
5869     TLOGI(WmsLogTag::WMS_KEYBOARD, "textFieldPositionY: %{public}f, textFieldHeight:%{public}f",
5870         textFieldPositionY, textFieldHeight);
5871     property_->SetTextFieldPositionY(textFieldPositionY);
5872     property_->SetTextFieldHeight(textFieldHeight);
5873     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO);
5874     return WMError::WM_OK;
5875 }
5876 
HandleWindowMask(const std::vector<std::vector<uint32_t>> & windowMask)5877 std::unique_ptr<Media::PixelMap> WindowSceneSessionImpl::HandleWindowMask(
5878     const std::vector<std::vector<uint32_t>>& windowMask)
5879 {
5880     const Rect& windowRect = GetRequestRect();
5881     uint32_t maskHeight = windowMask.size();
5882     if (maskHeight == 0) {
5883         WLOGFE("WindowMask is invalid");
5884         return nullptr;
5885     }
5886     uint32_t maskWidth = windowMask[0].size();
5887     if ((windowRect.height_ > 0 && windowRect.height_ != maskHeight) ||
5888         (windowRect.width_ > 0 && windowRect.width_ != maskWidth)) {
5889         WLOGFE("WindowMask is invalid");
5890         return nullptr;
5891     }
5892     constexpr uint32_t bgraChannel = 4;
5893     Media::InitializationOptions opts;
5894     opts.size.width = static_cast<int32_t>(maskWidth);
5895     opts.size.height = static_cast<int32_t>(maskHeight);
5896     uint32_t length = maskWidth * maskHeight * bgraChannel;
5897     uint8_t* data = static_cast<uint8_t*>(malloc(length));
5898     if (data == nullptr) {
5899         WLOGFE("data is nullptr");
5900         return nullptr;
5901     }
5902     constexpr uint32_t fullChannel = 255;
5903     constexpr uint32_t greenChannel = 1;
5904     constexpr uint32_t redChannel = 2;
5905     constexpr uint32_t alphaChannel = 3;
5906     for (uint32_t i = 0; i < maskHeight; i++) {
5907         for (uint32_t j = 0; j < maskWidth; j++) {
5908             uint32_t idx = i * maskWidth + j;
5909             uint32_t channel = windowMask[i][j] > 0 ? fullChannel : 0;
5910             uint32_t channelIndex = idx * bgraChannel;
5911             data[channelIndex] = channel; // blue channel
5912             data[channelIndex + greenChannel] = channel; // green channel
5913             data[channelIndex + redChannel] = fullChannel; // red channel
5914             data[channelIndex + alphaChannel] = channel; // alpha channel
5915         }
5916     }
5917     std::unique_ptr<Media::PixelMap> mask = Media::PixelMap::Create(reinterpret_cast<uint32_t*>(data), length, opts);
5918     free(data);
5919     return mask;
5920 }
5921 
SetWindowMask(const std::vector<std::vector<uint32_t>> & windowMask)5922 WMError WindowSceneSessionImpl::SetWindowMask(const std::vector<std::vector<uint32_t>>& windowMask)
5923 {
5924     TLOGI(WmsLogTag::WMS_PC, "WindowId: %{public}u", GetWindowId());
5925     if (IsWindowSessionInvalid()) {
5926         WLOGFE("session is invalid");
5927         return WMError::WM_ERROR_INVALID_WINDOW;
5928     }
5929 
5930     std::shared_ptr<Media::PixelMap> mask = HandleWindowMask(windowMask);
5931     if (mask == nullptr) {
5932         TLOGE(WmsLogTag::WMS_PC, "Failed to create pixelMap of window mask");
5933         return WMError::WM_ERROR_INVALID_WINDOW;
5934     }
5935 
5936     auto rsMask = RSMask::CreatePixelMapMask(mask);
5937     surfaceNode_->SetCornerRadius(0.0f);
5938     surfaceNode_->SetShadowRadius(0.0f);
5939     surfaceNode_->SetAbilityBGAlpha(0);
5940     surfaceNode_->SetMask(rsMask); // RS interface to set mask
5941     RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
5942 
5943     property_->SetWindowMask(mask);
5944     property_->SetIsShaped(true);
5945     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK);
5946 }
5947 
SetFollowParentMultiScreenPolicy(bool enabled)5948 WMError WindowSceneSessionImpl::SetFollowParentMultiScreenPolicy(bool enabled)
5949 {
5950     if (IsWindowSessionInvalid()) {
5951         return WMError::WM_ERROR_INVALID_WINDOW;
5952     }
5953     if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
5954         TLOGE(WmsLogTag::WMS_SUB, "This is PcAppInpad, not Suppored");
5955         return WMError::WM_OK;
5956     }
5957     if (!IsPcOrPadFreeMultiWindowMode()) {
5958         TLOGE(WmsLogTag::WMS_SUB, "device not support");
5959         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
5960     }
5961     if (!WindowHelper::IsSubWindow(GetType())) {
5962         TLOGE(WmsLogTag::WMS_SUB, "called by invalid window type, type:%{public}d", GetType());
5963         return WMError::WM_ERROR_INVALID_CALLING;
5964     }
5965     auto hostSession = GetHostSession();
5966     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5967     hostSession->NotifyFollowParentMultiScreenPolicy(enabled);
5968     property_->EditSessionInfo().isFollowParentMultiScreenPolicy = enabled;
5969     return WMError::WM_OK;
5970 }
5971 
UseImplicitAnimation(bool useImplicit)5972 WMError WindowSceneSessionImpl::UseImplicitAnimation(bool useImplicit)
5973 {
5974     TLOGI(WmsLogTag::WMS_PC, "WindowId: %{public}u", GetWindowId());
5975     if (IsWindowSessionInvalid()) {
5976         TLOGE(WmsLogTag::WMS_PC, "session is invalid");
5977         return WMError::WM_ERROR_INVALID_WINDOW;
5978     }
5979     auto hostSession = GetHostSession();
5980     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5981     return static_cast<WMError>(hostSession->UseImplicitAnimation(useImplicit));
5982 }
5983 
UpdateDensity()5984 void WindowSceneSessionImpl::UpdateDensity()
5985 {
5986     UpdateDensityInner(nullptr);
5987 }
5988 
UpdateDensityInner(const sptr<DisplayInfo> & info)5989 void WindowSceneSessionImpl::UpdateDensityInner(const sptr<DisplayInfo>& info)
5990 {
5991     if (!userLimitsSet_) {
5992         UpdateWindowSizeLimits();
5993         UpdateNewSize();
5994         WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
5995         if (ret != WMError::WM_OK) {
5996             WLOGFE("update window proeprty failed! id: %{public}u.", GetWindowId());
5997             return;
5998         }
5999     }
6000 
6001     NotifyDisplayInfoChange(info);
6002 
6003     auto preRect = GetRect();
6004     UpdateViewportConfig(preRect, WindowSizeChangeReason::UNDEFINED, nullptr, info);
6005     TLOGD(WmsLogTag::DEFAULT, "[%{public}d, %{public}d, %{public}u, %{public}u]",
6006         preRect.posX_, preRect.posY_, preRect.width_, preRect.height_);
6007 }
6008 
RegisterKeyboardPanelInfoChangeListener(const sptr<IKeyboardPanelInfoChangeListener> & listener)6009 WMError WindowSceneSessionImpl::RegisterKeyboardPanelInfoChangeListener(
6010     const sptr<IKeyboardPanelInfoChangeListener>& listener)
6011 {
6012     std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
6013     if (keyboardPanelInfoChangeListeners_ == nullptr) {
6014         TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d",
6015             GetPersistentId());
6016         keyboardPanelInfoChangeListeners_ = listener;
6017     } else {
6018         TLOGE(WmsLogTag::WMS_KEYBOARD, "listener already registered");
6019         return WMError::WM_ERROR_INVALID_OPERATION;
6020     }
6021 
6022     return WMError::WM_OK;
6023 }
6024 
RegisterWindowAttachStateChangeListener(const sptr<IWindowAttachStateChangeListner> & listener)6025 WMError WindowSceneSessionImpl::RegisterWindowAttachStateChangeListener(
6026     const sptr<IWindowAttachStateChangeListner>& listener)
6027 {
6028     if (listener == nullptr) {
6029         TLOGE(WmsLogTag::WMS_SUB, "id: %{public}d, listener is null", GetPersistentId());
6030         return WMError::WM_ERROR_NULLPTR;
6031     }
6032     {
6033         std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
6034         windowAttachStateChangeListener_ = listener;
6035     }
6036     TLOGD(WmsLogTag::WMS_SUB, "id: %{public}d listener registered", GetPersistentId());
6037     auto hostSession = GetHostSession();
6038     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6039     hostSession->NotifyWindowAttachStateListenerRegistered(true);
6040     return WMError::WM_OK;
6041 }
6042 
UnregisterWindowAttachStateChangeListener()6043 WMError WindowSceneSessionImpl::UnregisterWindowAttachStateChangeListener()
6044 {
6045     {
6046         std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
6047         windowAttachStateChangeListener_ = nullptr;
6048     }
6049     TLOGD(WmsLogTag::WMS_SUB, "id: %{public}d listener unregistered", GetPersistentId());
6050     auto hostSession = GetHostSession();
6051     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6052     hostSession->NotifyWindowAttachStateListenerRegistered(false);
6053     return WMError::WM_OK;
6054 }
6055 
NotifyWindowAttachStateChange(bool isAttach)6056 WSError WindowSceneSessionImpl::NotifyWindowAttachStateChange(bool isAttach)
6057 {
6058     TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", GetPersistentId());
6059     if (lifecycleCallback_) {
6060         TLOGI(WmsLogTag::WMS_SUB, "notifyAttachState id: %{public}d", GetPersistentId());
6061         lifecycleCallback_->OnNotifyAttachState(isAttach);
6062     }
6063     std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
6064     if (!windowAttachStateChangeListener_) {
6065         TLOGW(WmsLogTag::WMS_SUB, "listener is null");
6066         return WSError::WS_ERROR_NULLPTR;
6067     }
6068     if (isAttach) {
6069         windowAttachStateChangeListener_->AfterAttached();
6070     } else {
6071         windowAttachStateChangeListener_->AfterDetached();
6072     }
6073     return WSError::WS_OK;
6074 }
6075 
UnregisterKeyboardPanelInfoChangeListener(const sptr<IKeyboardPanelInfoChangeListener> & listener)6076 WMError WindowSceneSessionImpl::UnregisterKeyboardPanelInfoChangeListener(
6077     const sptr<IKeyboardPanelInfoChangeListener>& listener)
6078 {
6079     std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
6080     keyboardPanelInfoChangeListeners_ = nullptr;
6081     TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d", GetPersistentId());
6082 
6083     return WMError::WM_OK;
6084 }
6085 
NotifyKeyboardPanelInfoChange(const KeyboardPanelInfo & keyboardPanelInfo)6086 void WindowSceneSessionImpl::NotifyKeyboardPanelInfoChange(const KeyboardPanelInfo& keyboardPanelInfo)
6087 {
6088     TLOGI(WmsLogTag::WMS_KEYBOARD, "isShown: %{public}d, gravity: %{public}d"
6089         ", rect_: [%{public}d, %{public}d, %{public}d, %{public}d]", keyboardPanelInfo.isShowing_,
6090         keyboardPanelInfo.gravity_, keyboardPanelInfo.rect_.posX_, keyboardPanelInfo.rect_.posY_,
6091         keyboardPanelInfo.rect_.width_, keyboardPanelInfo.rect_.height_);
6092     std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
6093     if (keyboardPanelInfoChangeListeners_ && keyboardPanelInfoChangeListeners_.GetRefPtr()) {
6094         keyboardPanelInfoChangeListeners_.GetRefPtr()->OnKeyboardPanelInfoChanged(keyboardPanelInfo);
6095     } else {
6096         TLOGI(WmsLogTag::WMS_KEYBOARD, "listener is unRegistered");
6097     }
6098 }
6099 
UpdateDisplayId(DisplayId displayId)6100 WSError WindowSceneSessionImpl::UpdateDisplayId(DisplayId displayId)
6101 {
6102     bool displayIdChanged = property_->GetDisplayId() != displayId;
6103     property_->SetDisplayId(displayId);
6104     NotifyDisplayInfoChange();
6105     if (displayIdChanged) {
6106         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, displayId: %{public}" PRIu64, GetPersistentId(), displayId);
6107         NotifyDisplayIdChange(displayId);
6108     }
6109     return WSError::WS_OK;
6110 }
6111 
UpdateOrientation()6112 WSError WindowSceneSessionImpl::UpdateOrientation()
6113 {
6114     TLOGD(WmsLogTag::DMS, "id: %{public}d", GetPersistentId());
6115     NotifyDisplayInfoChange();
6116     return WSError::WS_OK;
6117 }
6118 
NotifyDisplayInfoChange(const sptr<DisplayInfo> & info)6119 void WindowSceneSessionImpl::NotifyDisplayInfoChange(const sptr<DisplayInfo>& info)
6120 {
6121     TLOGD(WmsLogTag::DMS, "id: %{public}d", GetPersistentId());
6122     sptr<DisplayInfo> displayInfo = nullptr;
6123     DisplayId displayId = 0;
6124     if (info == nullptr) {
6125         displayId = property_->GetDisplayId();
6126         auto display = SingletonContainer::IsDestroyed() ? nullptr :
6127             SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
6128         if (display == nullptr) {
6129             TLOGE(WmsLogTag::DMS, "get display by displayId %{public}" PRIu64 " failed.", displayId);
6130             return;
6131         }
6132         displayInfo = display->GetDisplayInfo();
6133     } else {
6134         displayInfo = info;
6135     }
6136     if (displayInfo == nullptr) {
6137         TLOGE(WmsLogTag::DMS, "get display info %{public}" PRIu64 " failed.", displayId);
6138         return;
6139     }
6140     if (IsSystemDensityChanged(displayInfo)) {
6141         lastSystemDensity_ = displayInfo->GetVirtualPixelRatio();
6142         NotifySystemDensityChange(displayInfo->GetVirtualPixelRatio());
6143     }
6144     float density = GetVirtualPixelRatio(displayInfo);
6145     DisplayOrientation orientation = displayInfo->GetDisplayOrientation();
6146 
6147     // skip scb process
6148     auto context = GetContext();
6149     if (context == nullptr || context->GetBundleName() == AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
6150         TLOGE(WmsLogTag::DMS, "id:%{public}d failed, context is null.", GetPersistentId());
6151         return;
6152     }
6153     auto token = context->GetToken();
6154     if (token == nullptr) {
6155         TLOGE(WmsLogTag::DMS, "get token window:%{public}d failed.", GetPersistentId());
6156         return;
6157     }
6158     SingletonContainer::Get<WindowManager>().NotifyDisplayInfoChange(token, displayId, density, orientation);
6159 }
6160 
MoveAndResizeKeyboard(const KeyboardLayoutParams & params)6161 WMError WindowSceneSessionImpl::MoveAndResizeKeyboard(const KeyboardLayoutParams& params)
6162 {
6163     int32_t displayWidth = 0;
6164     int32_t displayHeight = 0;
6165     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
6166     if (display != nullptr) {
6167         displayWidth = display->GetWidth();
6168         displayHeight = display->GetHeight();
6169     } else {
6170         auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
6171         if (defaultDisplayInfo != nullptr) {
6172             displayWidth = defaultDisplayInfo->GetWidth();
6173             displayHeight = defaultDisplayInfo->GetHeight();
6174         } else {
6175             TLOGE(WmsLogTag::WMS_KEYBOARD, "display is null, name: %{public}s, id: %{public}d",
6176                 property_->GetWindowName().c_str(), GetPersistentId());
6177             return WMError::WM_ERROR_NULLPTR;
6178         }
6179     }
6180     bool isLandscape = displayWidth > displayHeight ? true : false;
6181     Rect newRect = isLandscape ? params.LandscapeKeyboardRect_ : params.PortraitKeyboardRect_;
6182     property_->SetRequestRect(newRect);
6183     TLOGI(WmsLogTag::WMS_KEYBOARD, "Id: %{public}d, newRect: %{public}s, isLandscape: %{public}d, "
6184         "displayWidth: %{public}d, displayHeight: %{public}d", GetPersistentId(), newRect.ToString().c_str(),
6185         isLandscape, displayWidth, displayHeight);
6186     return WMError::WM_OK;
6187 }
6188 
AdjustKeyboardLayout(const KeyboardLayoutParams params)6189 WMError WindowSceneSessionImpl::AdjustKeyboardLayout(const KeyboardLayoutParams params)
6190 {
6191     property_->SetKeyboardLayoutParams(params);
6192     auto ret = MoveAndResizeKeyboard(params);
6193     if (ret != WMError::WM_OK) {
6194         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboard move and resize failed");
6195         return ret;
6196     }
6197     if (auto hostSession = GetHostSession()) {
6198         return static_cast<WMError>(hostSession->AdjustKeyboardLayout(params));
6199     }
6200     return WMError::WM_OK;
6201 }
6202 
SetImmersiveModeEnabledState(bool enable)6203 WMError WindowSceneSessionImpl::SetImmersiveModeEnabledState(bool enable)
6204 {
6205     TLOGD(WmsLogTag::WMS_IMMS, "id: %{public}u, enable: %{public}u", GetWindowId(), enable);
6206     if (IsWindowSessionInvalid()) {
6207         return WMError::WM_ERROR_INVALID_WINDOW;
6208     }
6209     auto hostSession = GetHostSession();
6210     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6211     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
6212         WindowMode::WINDOW_MODE_FULLSCREEN)) {
6213         return WMError::WM_ERROR_INVALID_WINDOW;
6214     }
6215     const WindowType curWindowType = GetType();
6216     if (!WindowHelper::IsMainWindow(curWindowType) && !WindowHelper::IsSubWindow(curWindowType)) {
6217         return WMError::WM_ERROR_INVALID_WINDOW;
6218     }
6219 
6220     enableImmersiveMode_ = enable;
6221     hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
6222     AAFwk::Want want;
6223     want.SetParam(Extension::IMMERSIVE_MODE_ENABLED, enable);
6224     if (auto uiContent = GetUIContentSharedPtr()) {
6225         uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_IMMERSIVE_MODE_ENABLED),
6226             want, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
6227     }
6228     WindowMode mode = GetWindowMode();
6229     if (!windowSystemConfig_.IsPcWindow() || mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
6230         return SetLayoutFullScreen(enableImmersiveMode_);
6231     }
6232     return WMError::WM_OK;
6233 }
6234 
GetImmersiveModeEnabledState() const6235 bool WindowSceneSessionImpl::GetImmersiveModeEnabledState() const
6236 {
6237     TLOGD(WmsLogTag::WMS_IMMS, "id: %{public}u, enableImmersiveMode=%{public}u",
6238         GetWindowId(), enableImmersiveMode_.load());
6239     if (IsWindowSessionInvalid()) {
6240         return false;
6241     }
6242     return enableImmersiveMode_;
6243 }
6244 
IsImmersiveLayout(bool & isImmersiveLayout) const6245 WMError WindowSceneSessionImpl::IsImmersiveLayout(bool& isImmersiveLayout) const
6246 {
6247     if (IsWindowSessionInvalid()) {
6248         return WMError::WM_ERROR_INVALID_WINDOW;
6249     }
6250     isImmersiveLayout = isIgnoreSafeArea_;
6251     return WMError::WM_OK;
6252 }
6253 
6254 template <typename K, typename V>
GetValueByKey(const std::unordered_map<K,V> & map,K key)6255 static V GetValueByKey(const std::unordered_map<K, V>& map, K key)
6256 {
6257     auto it = map.find(key);
6258     return it != map.end() ? it->second : V{};
6259 }
6260 
HandleEventForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6261 void WindowSceneSessionImpl::HandleEventForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6262     MMI::PointerEvent::PointerItem& pointerItem)
6263 {
6264     int32_t action = pointerEvent->GetPointerAction();
6265     switch (action) {
6266         case MMI::PointerEvent::POINTER_ACTION_DOWN:
6267             HandleDownForCompatibleMode(pointerEvent, pointerItem);
6268             break;
6269         case MMI::PointerEvent::POINTER_ACTION_MOVE:
6270             HandleMoveForCompatibleMode(pointerEvent, pointerItem);
6271             break;
6272         case MMI::PointerEvent::POINTER_ACTION_UP:
6273             HandleUpForCompatibleMode(pointerEvent, pointerItem);
6274             break;
6275         default:
6276             break;
6277     }
6278 }
6279 
HandleDownForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6280 void WindowSceneSessionImpl::HandleDownForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6281     MMI::PointerEvent::PointerItem& pointerItem)
6282 {
6283     int32_t displayX = pointerItem.GetDisplayX();
6284     int32_t displayY = pointerItem.GetDisplayY();
6285     int32_t displayId = property_->GetDisplayId();
6286     int32_t pointerCount = pointerEvent->GetPointerCount();
6287     if (pointerCount == 1) {
6288         eventMapTriggerByDisplay_[displayId] = std::vector<bool>(MAX_POINTERS);
6289         eventMapDeltaXByDisplay_[displayId] = std::vector<int32_t>(MAX_POINTERS);
6290         downPointerByDisplay_[displayId] = std::vector<PointInfo>(MAX_POINTERS);
6291         isOverTouchSlop_ = false;
6292         isDown_ = true;
6293     }
6294 
6295     if (IsInMappingRegionForCompatibleMode(displayX, displayY)) {
6296         int32_t pointerId = pointerEvent->GetPointerId();
6297         if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
6298             pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size() ||
6299             pointerId >= GetValueByKey(downPointerByDisplay_, displayId).size()) {
6300             TLOGE(WmsLogTag::DEFAULT, "pointerId: %{public}d out of range", pointerId);
6301             return;
6302         }
6303         eventMapTriggerByDisplay_[displayId][pointerId] = true;
6304         downPointerByDisplay_[displayId][pointerId] = {displayX, displayY};
6305         const auto& windowRect = GetRect();
6306         float xMappingScale = 1.0f;
6307         if (windowRect.posX_ != 0) {
6308             xMappingScale = static_cast<float>(windowRect.width_) / windowRect.posX_;
6309         }
6310         int32_t windowLeft = windowRect.posX_;
6311         int32_t windowRight = windowRect.posX_ + windowRect.width_;
6312         int32_t transferX;
6313         if (displayX <= windowLeft) {
6314             transferX = windowRight - xMappingScale * (windowLeft - displayX);
6315         } else {
6316             transferX = windowLeft + xMappingScale * (displayX - windowRight);
6317         }
6318         if (transferX < 0) {
6319             transferX = 0;
6320         }
6321         TLOGD(WmsLogTag::DEFAULT, "DOWN in mapping region, displayX: %{private}d, transferX: %{public}d, "
6322             "pointerId: %{public}d", displayX, transferX, pointerId);
6323         eventMapDeltaXByDisplay_[displayId][pointerId] = transferX - displayX;
6324         ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
6325     }
6326 }
6327 
HandleMoveForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6328 void WindowSceneSessionImpl::HandleMoveForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6329     MMI::PointerEvent::PointerItem& pointerItem)
6330 {
6331     if (!isDown_) {
6332         TLOGW(WmsLogTag::WMS_COMPAT, "receive move before down, skip");
6333         return;
6334     }
6335     int32_t displayId = property_->GetDisplayId();
6336     int32_t pointerId = pointerEvent->GetPointerId();
6337     if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
6338         pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size() ||
6339         !GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId]) {
6340         return;
6341     }
6342 
6343     int32_t displayX = pointerItem.GetDisplayX();
6344     int32_t displayY = pointerItem.GetDisplayY();
6345     const auto& windowRect = GetRect();
6346     if (!isOverTouchSlop_ && CheckTouchSlop(pointerId, displayX, displayY, windowRect.width_ / TOUCH_SLOP_RATIO)) {
6347         TLOGD(WmsLogTag::WMS_COMPAT, "reach touch slop, threshold: %{public}d", windowRect.width_ / TOUCH_SLOP_RATIO);
6348         isOverTouchSlop_ = true;
6349     }
6350     int32_t transferX = displayX + GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId];
6351     TLOGD(WmsLogTag::WMS_COMPAT, "MOVE, displayX: %{private}d, transferX: %{public}d, pointerId: %{public}d",
6352         displayX, transferX, pointerId);
6353     ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
6354 }
6355 
HandleUpForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6356 void WindowSceneSessionImpl::HandleUpForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6357     MMI::PointerEvent::PointerItem& pointerItem)
6358 {
6359     if (!isDown_) {
6360         TLOGW(WmsLogTag::WMS_COMPAT, "receive up before down, skip");
6361         return;
6362     }
6363     int32_t displayId = property_->GetDisplayId();
6364     int32_t pointerId = pointerEvent->GetPointerId();
6365     if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
6366         pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size()) {
6367         return;
6368     }
6369     if (GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId]) {
6370         int32_t displayX = pointerItem.GetDisplayX();
6371         int32_t transferX = displayX + GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId];
6372         ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
6373         TLOGD(WmsLogTag::WMS_COMPAT, "UP, displayX: %{private}d, transferX: %{public}d, pointerId: %{public}d",
6374             displayX, transferX, pointerId);
6375         GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId] = 0;
6376         GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId] = false;
6377         IgnoreClickEvent(pointerEvent);
6378     }
6379     int32_t pointerCount = pointerEvent->GetPointerCount();
6380     if (pointerCount == 1) {
6381         eventMapDeltaXByDisplay_.erase(displayId);
6382         eventMapTriggerByDisplay_.erase(displayId);
6383         downPointerByDisplay_.erase(displayId);
6384         isDown_ = false;
6385     }
6386 }
6387 
ConvertPointForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem,int32_t transferX)6388 void WindowSceneSessionImpl::ConvertPointForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6389     MMI::PointerEvent::PointerItem& pointerItem, int32_t transferX)
6390 {
6391     const auto& windowRect = GetRect();
6392     int32_t pointerId = pointerEvent->GetPointerId();
6393 
6394     pointerItem.SetDisplayX(transferX);
6395     pointerItem.SetDisplayXPos(static_cast<double>(transferX));
6396     pointerItem.SetWindowX(transferX - windowRect.posX_);
6397     pointerItem.SetWindowXPos(static_cast<double>(transferX - windowRect.posX_));
6398     pointerEvent->UpdatePointerItem(pointerId, pointerItem);
6399 }
6400 
IsInMappingRegionForCompatibleMode(int32_t displayX,int32_t displayY)6401 bool WindowSceneSessionImpl::IsInMappingRegionForCompatibleMode(int32_t displayX, int32_t displayY)
6402 {
6403     const auto& windowRect = GetRect();
6404     Rect pointerRect = { displayX, displayY, 0, 0 };
6405     return !pointerRect.IsInsideOf(windowRect);
6406 }
6407 
CheckTouchSlop(int32_t pointerId,int32_t displayX,int32_t displayY,int32_t threshold)6408 bool WindowSceneSessionImpl::CheckTouchSlop(int32_t pointerId, int32_t displayX, int32_t displayY, int32_t threshold)
6409 {
6410     int32_t displayId = property_->GetDisplayId();
6411     if (downPointerByDisplay_.find(displayId) == downPointerByDisplay_.end()) {
6412         return false;
6413     }
6414     std::vector<PointInfo> downPointers = downPointerByDisplay_[displayId];
6415     return pointerId < downPointers.size() &&
6416         (std::abs(displayX - downPointers[pointerId].x) >= threshold ||
6417         std::abs(displayY - downPointers[pointerId].y) >= threshold);
6418 }
6419 
IgnoreClickEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)6420 void WindowSceneSessionImpl::IgnoreClickEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
6421 {
6422     int32_t action = pointerEvent->GetPointerAction();
6423     if (action != MMI::PointerEvent::POINTER_ACTION_UP) {
6424         return;
6425     }
6426     if (isOverTouchSlop_) {
6427         if (pointerEvent->GetPointerCount() == 1) {
6428             isOverTouchSlop_ = false;
6429         }
6430     } else {
6431         pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
6432         TLOGI(WmsLogTag::DEFAULT, "transfer UP to CANCEL for not over touch slop");
6433     }
6434 }
6435 
GetWindowStatus(WindowStatus & windowStatus)6436 WMError WindowSceneSessionImpl::GetWindowStatus(WindowStatus& windowStatus)
6437 {
6438     if (IsWindowSessionInvalid()) {
6439         TLOGE(WmsLogTag::WMS_PC, "session is invalid");
6440         return WMError::WM_ERROR_INVALID_WINDOW;
6441     }
6442     windowStatus = GetWindowStatusInner(GetWindowMode());
6443     TLOGD(WmsLogTag::WMS_PC, "Id:%{public}u, WindowStatus:%{public}u", GetWindowId(), windowStatus);
6444     return WMError::WM_OK;
6445 }
6446 
GetIsUIExtFirstSubWindow() const6447 bool WindowSceneSessionImpl::GetIsUIExtFirstSubWindow() const
6448 {
6449     return property_->GetIsUIExtFirstSubWindow();
6450 }
6451 
GetIsUIExtAnySubWindow() const6452 bool WindowSceneSessionImpl::GetIsUIExtAnySubWindow() const
6453 {
6454     return property_->GetIsUIExtAnySubWindow();
6455 }
6456 
SetGestureBackEnabled(bool enable)6457 WMError WindowSceneSessionImpl::SetGestureBackEnabled(bool enable)
6458 {
6459     if (windowSystemConfig_.IsPcWindow()) {
6460         TLOGI(WmsLogTag::WMS_IMMS, "device is not support");
6461         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6462     }
6463     TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u, enable %{public}u", GetWindowId(), enable);
6464     gestureBackEnabled_ = enable;
6465     AAFwk::Want want;
6466     want.SetParam(Extension::GESTURE_BACK_ENABLED, enable);
6467     if (auto uiContent = GetUIContentSharedPtr()) {
6468         uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_GESTURE_BACK_ENABLED),
6469             want, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
6470     }
6471     auto hostSession = GetHostSession();
6472     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6473     return hostSession->SetGestureBackEnabled(enable);
6474 }
6475 
GetGestureBackEnabled(bool & enable) const6476 WMError WindowSceneSessionImpl::GetGestureBackEnabled(bool& enable) const
6477 {
6478     if (windowSystemConfig_.IsPcWindow()) {
6479         TLOGI(WmsLogTag::WMS_IMMS, "device not support");
6480         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6481     }
6482     enable = gestureBackEnabled_;
6483     TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u enable %{public}u", GetWindowId(), enable);
6484     return WMError::WM_OK;
6485 }
6486 
SetFullScreenWaterfallMode(bool isWaterfallMode)6487 WSError WindowSceneSessionImpl::SetFullScreenWaterfallMode(bool isWaterfallMode)
6488 {
6489     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "prev: %{public}d, curr: %{public}d, winId: %{public}u",
6490         isFullScreenWaterfallMode_.load(), isWaterfallMode, GetWindowId());
6491     NotifyAcrossDisplaysChange(isWaterfallMode);
6492     if (isValidWaterfallMode_.load() && isFullScreenWaterfallMode_.load() == isWaterfallMode) {
6493         return WSError::WS_DO_NOTHING;
6494     }
6495     isFullScreenWaterfallMode_.store(isWaterfallMode);
6496     if (isWaterfallMode) {
6497         lastWindowModeBeforeWaterfall_.store(property_->GetWindowMode());
6498     } else {
6499         lastWindowModeBeforeWaterfall_.store(WindowMode::WINDOW_MODE_UNDEFINED);
6500     }
6501     isValidWaterfallMode_.store(true);
6502     NotifyWaterfallModeChange(isWaterfallMode);
6503     return WSError::WS_OK;
6504 }
6505 
SetSupportEnterWaterfallMode(bool isSupportEnter)6506 WSError WindowSceneSessionImpl::SetSupportEnterWaterfallMode(bool isSupportEnter)
6507 {
6508     handler_->PostTask([weakThis = wptr(this), isSupportEnter, where = __func__] {
6509         auto window = weakThis.promote();
6510         if (!window) {
6511             TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s window is null", where);
6512             return;
6513         }
6514         if (window->supportEnterWaterfallMode_ == isSupportEnter) {
6515             return;
6516         }
6517         TLOGNI(WmsLogTag::WMS_LAYOUT_PC, "%{public}s prev: %{public}d, curr: %{public}d",
6518             where, window->supportEnterWaterfallMode_, isSupportEnter);
6519         window->supportEnterWaterfallMode_ = isSupportEnter;
6520         std::shared_ptr<Ace::UIContent> uiContent = window->GetUIContentSharedPtr();
6521         if (uiContent == nullptr || !window->IsDecorEnable()) {
6522             TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s uiContent unavailable", where);
6523             return;
6524         }
6525         uiContent->OnContainerModalEvent(WINDOW_WATERFALL_VISIBILITY_EVENT, isSupportEnter ? "true" : "false");
6526     }, __func__);
6527     return WSError::WS_OK;
6528 }
6529 
OnContainerModalEvent(const std::string & eventName,const std::string & value)6530 WMError WindowSceneSessionImpl::OnContainerModalEvent(const std::string& eventName, const std::string& value)
6531 {
6532     TLOGI(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, name: %{public}s, value: %{public}s",
6533         GetPersistentId(), eventName.c_str(), value.c_str());
6534     if (IsWindowSessionInvalid()) {
6535         TLOGE(WmsLogTag::WMS_LAYOUT, "session is invalid");
6536         return WMError::WM_ERROR_INVALID_WINDOW;
6537     }
6538     auto hostSession = GetHostSession();
6539     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
6540     hostSession->OnContainerModalEvent(eventName, value);
6541     if (eventName == WINDOW_WATERFALL_EVENT) {
6542         bool lastFullScreenWaterfallMode = isFullScreenWaterfallMode_.load();
6543         SetFullScreenWaterfallMode(true);
6544         auto ret = Maximize();
6545         if (ret != WMError::WM_OK) {
6546             TLOGE(WmsLogTag::WMS_LAYOUT, "maximize failed");
6547             SetFullScreenWaterfallMode(lastFullScreenWaterfallMode);
6548         }
6549         return ret;
6550     } else if (eventName == BACK_WINDOW_EVENT) {
6551         HandleBackEvent();
6552         return WMError::WM_OK;
6553     } else if (eventName == COMPATIBLE_MAX_WINDOW_EVENT) {
6554         MaximizeForCompatibleMode();
6555         return WMError::WM_OK;
6556     } else if (eventName == COMPATIBLE_RECOVER_WINDOW_EVENT) {
6557         RecoverForCompatibleMode();
6558         return WMError::WM_OK;
6559     }
6560     return WMError::WM_DO_NOTHING;
6561 }
6562 
IsSystemDensityChanged(const sptr<DisplayInfo> & displayInfo)6563 bool WindowSceneSessionImpl::IsSystemDensityChanged(const sptr<DisplayInfo>& displayInfo)
6564 {
6565     if (MathHelper::NearZero(lastSystemDensity_ - displayInfo->GetVirtualPixelRatio())) {
6566         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "System density not change");
6567         return false;
6568     }
6569     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "windowId: %{public}d, lastDensity: %{public}f, currDensity: %{public}f",
6570         GetPersistentId(), lastSystemDensity_, displayInfo->GetVirtualPixelRatio());
6571     return true;
6572 }
6573 
IsDefaultDensityEnabled()6574 bool WindowSceneSessionImpl::IsDefaultDensityEnabled()
6575 {
6576     if (WindowHelper::IsMainWindow(GetType())) {
6577         return GetDefaultDensityEnabled();
6578     }
6579     if (isEnableDefaultDensityWhenCreate_) {
6580         return true;
6581     }
6582     if (auto mainWindow = FindMainWindowWithContext()) {
6583         CopyUniqueDensityParameter(mainWindow);
6584     }
6585     return GetDefaultDensityEnabled();
6586 }
6587 
GetMainWindowCustomDensity()6588 float WindowSceneSessionImpl::GetMainWindowCustomDensity()
6589 {
6590     if (WindowHelper::IsMainWindow(GetType())) {
6591         return GetCustomDensity();
6592     }
6593     auto mainWindow = FindMainWindowWithContext();
6594     return mainWindow ? mainWindow->GetCustomDensity() : UNDEFINED_DENSITY;
6595 }
6596 
GetCustomDensity() const6597 float WindowSceneSessionImpl::GetCustomDensity() const
6598 {
6599     return customDensity_;
6600 }
6601 
SetWindowAnchorInfo(const WindowAnchorInfo & windowAnchorInfo)6602 WMError WindowSceneSessionImpl::SetWindowAnchorInfo(const WindowAnchorInfo& windowAnchorInfo)
6603 {
6604     if (IsWindowSessionInvalid()) {
6605         return WMError::WM_ERROR_INVALID_WINDOW;
6606     }
6607     const auto& property = GetProperty();
6608     if (!WindowHelper::IsSubWindow(property->GetWindowType())) {
6609         TLOGE(WmsLogTag::WMS_SUB, "only sub window is valid");
6610         return WMError::WM_ERROR_INVALID_CALLING;
6611     }
6612     if (WindowHelper::IsFullScreenWindow(property->GetWindowMode())) {
6613         TLOGE(WmsLogTag::WMS_SUB, "not support fullscreen sub window");
6614         return WMError::WM_ERROR_INVALID_CALLING;
6615     }
6616     if (property->GetSubWindowLevel() > 1) {
6617         TLOGI(WmsLogTag::WMS_SUB, "not support more than 1 level window");
6618         return WMError::WM_ERROR_INVALID_CALLING;
6619     }
6620     if (!windowSystemConfig_.supportFollowRelativePositionToParent_) {
6621         TLOGI(WmsLogTag::WMS_SUB, "not support device");
6622         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6623     }
6624     auto hostSession = GetHostSession();
6625     if (!hostSession) {
6626         TLOGI(WmsLogTag::WMS_SUB, "session is nullptr");
6627         return WMError::WM_ERROR_INVALID_SESSION;
6628     }
6629     WSError ret = hostSession->SetWindowAnchorInfo(windowAnchorInfo);
6630     if (ret == WSError::WS_ERROR_DEVICE_NOT_SUPPORT) {
6631         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6632     }
6633     if (ret == WSError::WS_OK) {
6634         property->SetWindowAnchorInfo(windowAnchorInfo);
6635     }
6636     return ret != WSError::WS_OK ? WMError::WM_ERROR_SYSTEM_ABNORMALLY : WMError::WM_OK;
6637 }
6638 
SetFollowParentWindowLayoutEnabled(bool isFollow)6639 WMError WindowSceneSessionImpl::SetFollowParentWindowLayoutEnabled(bool isFollow)
6640 {
6641     if (IsWindowSessionInvalid()) {
6642         return WMError::WM_ERROR_INVALID_WINDOW;
6643     }
6644     const auto& property = GetProperty();
6645     if (!WindowHelper::IsSubWindow(property->GetWindowType()) &&
6646         !WindowHelper::IsDialogWindow(property->GetWindowType())) {
6647         TLOGE(WmsLogTag::WMS_SUB, "only sub window and dialog is valid");
6648         return WMError::WM_ERROR_INVALID_OPERATION;
6649     }
6650     if (property->GetSubWindowLevel() > 1) {
6651         TLOGI(WmsLogTag::WMS_SUB, "not support more than 1 level window");
6652         return WMError::WM_ERROR_INVALID_OPERATION;
6653     }
6654     if (!windowSystemConfig_.supportFollowParentWindowLayout_) {
6655         TLOGI(WmsLogTag::WMS_SUB, "not support device");
6656         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6657     }
6658     if (!GetHostSession()) {
6659         TLOGI(WmsLogTag::WMS_SUB, "session is nullptr");
6660         return WMError::WM_ERROR_INVALID_SESSION;
6661     }
6662     WSError ret = GetHostSession()->SetFollowParentWindowLayoutEnabled(isFollow);
6663     if (ret == WSError::WS_ERROR_DEVICE_NOT_SUPPORT) {
6664         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6665     }
6666     return ret != WSError::WS_OK ? WMError::WM_ERROR_SYSTEM_ABNORMALLY : WMError::WM_OK;
6667 }
6668 
SetWindowTransitionAnimation(WindowTransitionType transitionType,const TransitionAnimation & animation)6669 WMError WindowSceneSessionImpl::SetWindowTransitionAnimation(WindowTransitionType transitionType,
6670     const TransitionAnimation& animation)
6671 {
6672     if (IsWindowSessionInvalid()) {
6673         return WMError::WM_ERROR_INVALID_WINDOW;
6674     }
6675     if (!IsPcOrPadFreeMultiWindowMode()) {
6676         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6677     }
6678     if (!WindowHelper::IsMainWindow(GetType())) {
6679         return WMError::WM_ERROR_INVALID_CALLING;
6680     }
6681     WSError ret = WSError::WS_DO_NOTHING;
6682     auto hostSession = GetHostSession();
6683     if (!hostSession) {
6684         TLOGI(WmsLogTag::WMS_ANIMATION, "session is nullptr");
6685         return WMError::WM_ERROR_INVALID_SESSION;
6686     }
6687     ret = hostSession->SetWindowTransitionAnimation(transitionType, animation);
6688     if (ret == WSError::WS_OK) {
6689         std::lock_guard<std::mutex> lockListener(transitionAnimationConfigMutex_);
6690         property_->SetTransitionAnimationConfig(transitionType, animation);
6691     }
6692     return ret != WSError::WS_OK ? WMError::WM_ERROR_SYSTEM_ABNORMALLY : WMError::WM_OK;
6693 }
6694 
GetWindowTransitionAnimation(WindowTransitionType transitionType)6695 std::shared_ptr<TransitionAnimation> WindowSceneSessionImpl::GetWindowTransitionAnimation(WindowTransitionType
6696     transitionType)
6697 {
6698     if (IsWindowSessionInvalid()) {
6699         return nullptr;
6700     }
6701     if (!IsPcOrPadFreeMultiWindowMode()) {
6702         return nullptr;
6703     }
6704     if (!WindowHelper::IsMainWindow(GetType())) {
6705         return nullptr;
6706     }
6707     std::lock_guard<std::mutex> lockListener(transitionAnimationConfigMutex_);
6708     auto transitionAnimationConfig = property_->GetTransitionAnimationConfig();
6709     if (transitionAnimationConfig.find(transitionType) != transitionAnimationConfig.end()) {
6710         return transitionAnimationConfig[transitionType];
6711     } else {
6712         return nullptr;
6713     }
6714 }
6715 
SetCustomDensity(float density,bool applyToSubWindow)6716 WMError WindowSceneSessionImpl::SetCustomDensity(float density, bool applyToSubWindow)
6717 {
6718     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, density=%{public}f", GetWindowId(), density);
6719     if (IsWindowSessionInvalid()) {
6720         return WMError::WM_ERROR_INVALID_WINDOW;
6721     }
6722     if ((density < MINIMUM_CUSTOM_DENSITY && !MathHelper::NearZero(density - UNDEFINED_DENSITY)) ||
6723         density > MAXIMUM_CUSTOM_DENSITY) {
6724         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u set invalid density=%{public}f", GetWindowId(), density);
6725         return WMError::WM_ERROR_INVALID_PARAM;
6726     }
6727     if (!WindowHelper::IsMainWindow(GetType())) {
6728         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, must be app main window", GetWindowId());
6729         return WMError::WM_ERROR_INVALID_CALLING;
6730     }
6731     if (MathHelper::NearZero(customDensity_ - density) && !applyToSubWindow) {
6732         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u set density not change", GetWindowId());
6733         return WMError::WM_OK;
6734     }
6735     defaultDensityEnabledGlobalConfig_ = false;
6736     SetDefaultDensityEnabledValue(false);
6737     customDensity_ = density;
6738     UpdateDensity();
6739     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
6740     for (const auto& winPair : windowSessionMap_) {
6741         auto window = winPair.second.second;
6742         if (window == nullptr) {
6743             TLOGE(WmsLogTag::WMS_ATTRIBUTE, "window is nullptr");
6744             continue;
6745         }
6746         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Id=%{public}d UpdateDensity", window->GetWindowId());
6747         window->SetDefaultDensityEnabledValue(false);
6748         if (applyToSubWindow) {
6749             window->UpdateDensity();
6750         }
6751     }
6752     return WMError::WM_OK;
6753 }
6754 
GetWindowDensityInfo(WindowDensityInfo & densityInfo)6755 WMError WindowSceneSessionImpl::GetWindowDensityInfo(WindowDensityInfo& densityInfo)
6756 {
6757     if (IsWindowSessionInvalid()) {
6758         return WMError::WM_ERROR_INVALID_WINDOW;
6759     }
6760     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
6761     if (display == nullptr) {
6762         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "display is null, winId=%{public}u", GetWindowId());
6763         return WMError::WM_ERROR_NULLPTR;
6764     }
6765     auto displayInfo = display->GetDisplayInfo();
6766     if (displayInfo == nullptr) {
6767         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "displayInfo is null, winId=%{public}u", GetWindowId());
6768         return WMError::WM_ERROR_NULLPTR;
6769     }
6770     densityInfo.systemDensity = displayInfo->GetVirtualPixelRatio();
6771     densityInfo.defaultDensity = displayInfo->GetDefaultVirtualPixelRatio();
6772     auto customDensity = UNDEFINED_DENSITY;
6773     if (IsDefaultDensityEnabled()) {
6774         customDensity = displayInfo->GetDefaultVirtualPixelRatio();
6775     } else {
6776         customDensity = GetCustomDensity();
6777         customDensity = MathHelper::NearZero(customDensity - UNDEFINED_DENSITY) ? displayInfo->GetVirtualPixelRatio()
6778                                                                                 : customDensity;
6779     }
6780     densityInfo.customDensity = customDensity;
6781     return WMError::WM_OK;
6782 }
6783 
IsMainWindowFullScreenAcrossDisplays(bool & isAcrossDisplays)6784 WMError WindowSceneSessionImpl::IsMainWindowFullScreenAcrossDisplays(bool& isAcrossDisplays)
6785 {
6786     if (IsWindowSessionInvalid()) {
6787         return WMError::WM_ERROR_INVALID_WINDOW;
6788     }
6789     auto hostSession = GetHostSession();
6790     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6791     return hostSession->IsMainWindowFullScreenAcrossDisplays(isAcrossDisplays);
6792 }
6793 
IsFullScreenEnable() const6794 bool WindowSceneSessionImpl::IsFullScreenEnable() const
6795 {
6796     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
6797         WindowMode::WINDOW_MODE_FULLSCREEN)) {
6798         return false;
6799     }
6800     const auto& sizeLimits = property_->GetWindowLimits();
6801     uint32_t displayWidth = 0;
6802     uint32_t displayHeight = 0;
6803     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
6804     if (display == nullptr) {
6805         TLOGE(WmsLogTag::WMS_PC, "display is null, winId=%{public}u", GetWindowId());
6806         return false;
6807     }
6808     displayWidth = static_cast<uint32_t>(display->GetWidth());
6809     displayHeight = static_cast<uint32_t>(display->GetHeight());
6810     if (property_->GetDragEnabled() && (sizeLimits.maxWidth_ < displayWidth || sizeLimits.maxHeight_ < displayHeight)) {
6811         return false;
6812     }
6813     return true;
6814 }
6815 
GetWindowPropertyInfo(WindowPropertyInfo & windowPropertyInfo)6816 WMError WindowSceneSessionImpl::GetWindowPropertyInfo(WindowPropertyInfo& windowPropertyInfo)
6817 {
6818     if (IsWindowSessionInvalid()) {
6819         return WMError::WM_ERROR_INVALID_WINDOW;
6820     }
6821     windowPropertyInfo.windowRect = GetRect();
6822     auto uicontent = GetUIContentSharedPtr();
6823     if (uicontent == nullptr) {
6824         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "uicontent is nullptr");
6825     } else {
6826         uicontent->GetWindowPaintSize(windowPropertyInfo.drawableRect);
6827     }
6828     windowPropertyInfo.globalDisplayRect = property_->GetGlobalDisplayRect();
6829     windowPropertyInfo.type = GetType();
6830     windowPropertyInfo.isLayoutFullScreen = IsLayoutFullScreen();
6831     windowPropertyInfo.isFullScreen = IsFullScreen();
6832     windowPropertyInfo.isTouchable = GetTouchable();
6833     windowPropertyInfo.isFocusable = GetFocusable();
6834     windowPropertyInfo.name = GetWindowName();
6835     windowPropertyInfo.isPrivacyMode = IsPrivacyMode();
6836     windowPropertyInfo.isKeepScreenOn = IsKeepScreenOn();
6837     windowPropertyInfo.brightness = GetBrightness();
6838     windowPropertyInfo.isTransparent = IsTransparent();
6839     windowPropertyInfo.id = GetWindowId();
6840     windowPropertyInfo.displayId = GetDisplayId();
6841     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, globalDisplayRect=%{public}s", GetWindowId(),
6842         windowPropertyInfo.globalDisplayRect.ToString().c_str());
6843     HookWindowSizeByHookWindowInfo(windowPropertyInfo.windowRect);
6844     HookWindowSizeByHookWindowInfo(windowPropertyInfo.globalDisplayRect);
6845     return WMError::WM_OK;
6846 }
6847 
SetHookTargetElementInfo(const AppExecFwk::ElementName & elementName)6848 WMError WindowSceneSessionImpl::SetHookTargetElementInfo(const AppExecFwk::ElementName& elementName)
6849 {
6850     auto context = GetContext();
6851     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
6852     if (!abilityContext) {
6853         TLOGE(WmsLogTag::WMS_LIFE, "abilityContext is nullptr");
6854         return WMError::WM_ERROR_NULLPTR;
6855     }
6856     if (abilityContext->IsHook() && !abilityContext->GetHookOff()) {
6857         property_->EditSessionInfo().bundleName_ = elementName.GetBundleName();
6858         property_->EditSessionInfo().moduleName_ = elementName.GetModuleName();
6859         property_->EditSessionInfo().abilityName_ = elementName.GetAbilityName();
6860     }
6861     return WMError::WM_OK;
6862 }
6863 
GetAppForceLandscapeConfig(AppForceLandscapeConfig & config)6864 WMError WindowSceneSessionImpl::GetAppForceLandscapeConfig(AppForceLandscapeConfig& config)
6865 {
6866     if (IsWindowSessionInvalid()) {
6867         TLOGE(WmsLogTag::DEFAULT, "HostSession is invalid");
6868         return WMError::WM_ERROR_INVALID_WINDOW;
6869     }
6870     auto hostSession = GetHostSession();
6871     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6872     return hostSession->GetAppForceLandscapeConfig(config);
6873 }
6874 
NotifyAppForceLandscapeConfigUpdated()6875 WSError WindowSceneSessionImpl::NotifyAppForceLandscapeConfigUpdated()
6876 {
6877     TLOGI(WmsLogTag::DEFAULT, "in");
6878     WindowType winType = GetType();
6879     AppForceLandscapeConfig config = {};
6880     if (WindowHelper::IsMainWindow(winType) && GetAppForceLandscapeConfig(config) == WMError::WM_OK &&
6881         config.supportSplit_ > 0) {
6882         SetForceSplitEnable(config);
6883         return WSError::WS_OK;
6884     }
6885     return WSError::WS_DO_NOTHING;
6886 }
6887 
GetAppHookWindowInfoFromServer(HookWindowInfo & hookWindowInfo)6888 WMError WindowSceneSessionImpl::GetAppHookWindowInfoFromServer(HookWindowInfo& hookWindowInfo)
6889 {
6890     auto hostSession = GetHostSession();
6891     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6892     return hostSession->GetAppHookWindowInfoFromServer(hookWindowInfo);
6893 }
6894 
NotifyAppHookWindowInfoUpdated()6895 WSError WindowSceneSessionImpl::NotifyAppHookWindowInfoUpdated()
6896 {
6897     TLOGI(WmsLogTag::WMS_LAYOUT, "in");
6898     const WindowType windowType = GetType();
6899     if (!WindowHelper::IsMainWindow(windowType)) {
6900         return WSError::WS_DO_NOTHING;
6901     }
6902 
6903     HookWindowInfo hookWindowInfo{};
6904     if (GetAppHookWindowInfoFromServer(hookWindowInfo) != WMError::WM_OK) {
6905         return WSError::WS_DO_NOTHING;
6906     }
6907 
6908     SetAppHookWindowInfo(hookWindowInfo);
6909     return WSError::WS_OK;
6910 }
6911 
SetSubWindowSource(SubWindowSource source)6912 WMError WindowSceneSessionImpl::SetSubWindowSource(SubWindowSource source)
6913 {
6914     if (IsWindowSessionInvalid()) {
6915         return WMError::WM_ERROR_INVALID_WINDOW;
6916     }
6917     const auto& property = GetProperty();
6918     if (!WindowHelper::IsSubWindow(property->GetWindowType()) &&
6919         !WindowHelper::IsDialogWindow(property->GetWindowType())) {
6920         TLOGE(WmsLogTag::WMS_SUB, "only sub window and dialog is valid");
6921         return WMError::WM_ERROR_INVALID_OPERATION;
6922     }
6923     auto hostSession = GetHostSession();
6924     if (!hostSession) {
6925         TLOGI(WmsLogTag::WMS_SUB, "session is nullptr");
6926         return WMError::WM_ERROR_INVALID_SESSION;
6927     }
6928     WSError ret = hostSession->SetSubWindowSource(source);
6929     if (ret == WSError::WS_ERROR_INVALID_WINDOW) {
6930         return WMError::WM_ERROR_INVALID_WINDOW;
6931     }
6932     return ret != WSError::WS_OK ? WMError::WM_ERROR_SYSTEM_ABNORMALLY : WMError::WM_OK;
6933 }
6934 
CloseSpecificScene()6935 WSError WindowSceneSessionImpl::CloseSpecificScene()
6936 {
6937     if (!property_->IsDecorEnable()) {
6938         TLOGW(WmsLogTag::WMS_SUB, "specific scene can not close id: %{public}d, decor is not enable.",
6939             GetPersistentId());
6940         return WSError::WS_ERROR_INVALID_OPERATION;
6941     }
6942     TLOGI(WmsLogTag::WMS_SUB, "close specific scene id: %{public}d", GetPersistentId());
6943     handler_->PostTask([weakThis = wptr(this)] {
6944         auto window = weakThis.promote();
6945         if (!window) {
6946             TLOGNE(WmsLogTag::WMS_SUB, "window is nullptr");
6947             return;
6948         }
6949         window->Close();
6950     }, __func__);
6951     return WSError::WS_OK;
6952 }
6953 } // namespace Rosen
6954 } // namespace OHOS
6955