• 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 <transaction/rs_transaction.h>
23 
24 #include <application_context.h>
25 #include "anr_handler.h"
26 #include "color_parser.h"
27 #include "display_info.h"
28 #include "input_transfer_station.h"
29 #include "singleton_container.h"
30 #include "display_manager.h"
31 #include "display_manager_adapter.h"
32 #include "input_transfer_station.h"
33 #include "perform_reporter.h"
34 #include "session_helper.h"
35 #include "session_permission.h"
36 #include "session/container/include/window_event_channel.h"
37 #include "session_manager/include/session_manager.h"
38 #include "window_adapter.h"
39 #include "window_helper.h"
40 #include "window_manager_hilog.h"
41 #include "window_prepare_terminate.h"
42 #include "wm_common.h"
43 #include "wm_common_inner.h"
44 #include "wm_math.h"
45 #include "session_manager_agent_controller.h"
46 #include <transaction/rs_interfaces.h>
47 #include "surface_capture_future.h"
48 #include "pattern_detach_callback.h"
49 #include "picture_in_picture_manager.h"
50 #include "window_session_impl.h"
51 #include "sys_cap_util.h"
52 
53 namespace OHOS {
54 namespace Rosen {
55 union WSColorParam {
56 #if defined(BIG_ENDIANNESS) && BIG_ENDIANNESS
57     struct {
58         uint8_t alpha;
59         uint8_t red;
60         uint8_t green;
61         uint8_t blue;
62     } argb;
63 #else
64     struct {
65         uint8_t blue;
66         uint8_t green;
67         uint8_t red;
68         uint8_t alpha;
69     } argb;
70 #endif
71     uint32_t value;
72 };
73 
74 #define CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession)                         \
75     do {                                                                       \
76         if ((hostSession) == nullptr) {                                        \
77             TLOGE(WmsLogTag::DEFAULT, "hostSession is null");                  \
78             return;                                                            \
79         }                                                                      \
80     } while (false)
81 
82 #define CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, ret)              \
83     do {                                                                       \
84         if ((hostSession) == nullptr) {                                        \
85             TLOGE(WmsLogTag::DEFAULT, "hostSession is null");                  \
86             return ret;                                                        \
87         }                                                                      \
88     } while (false)
89 
90 namespace {
91 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowSceneSessionImpl"};
92 constexpr int32_t WINDOW_DETACH_TIMEOUT = 300;
93 constexpr int32_t WINDOW_LAYOUT_TIMEOUT = 30;
94 const std::string PARAM_DUMP_HELP = "-h";
95 constexpr float MIN_GRAY_SCALE = 0.0f;
96 constexpr float MAX_GRAY_SCALE = 1.0f;
97 constexpr int32_t MAX_POINTERS = 16;
98 constexpr int32_t TOUCH_SLOP_RATIO = 25;
99 const std::unordered_set<WindowType> INVALID_SYSTEM_WINDOW_TYPE = {
100     WindowType::WINDOW_TYPE_NEGATIVE_SCREEN,
101     WindowType::WINDOW_TYPE_THEME_EDITOR,
102     WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR,
103     WindowType::WINDOW_TYPE_SCENE_BOARD,
104     WindowType::WINDOW_TYPE_KEYBOARD_PANEL,
105     WindowType::WINDOW_TYPE_APP_LAUNCHING,
106     WindowType::WINDOW_TYPE_INCOMING_CALL,
107     WindowType::WINDOW_TYPE_BOOT_ANIMATION,
108     WindowType::WINDOW_TYPE_FREEZE_DISPLAY,
109     WindowType::WINDOW_TYPE_PLACEHOLDER
110 };
111 const std::unordered_set<WindowType> INVALID_SCB_WINDOW_TYPE = {
112     WindowType::WINDOW_TYPE_WALLPAPER,
113     WindowType::WINDOW_TYPE_DESKTOP,
114     WindowType::WINDOW_TYPE_DOCK_SLICE,
115     WindowType::WINDOW_TYPE_STATUS_BAR,
116     WindowType::WINDOW_TYPE_KEYGUARD,
117     WindowType::WINDOW_TYPE_NAVIGATION_BAR,
118     WindowType::WINDOW_TYPE_LAUNCHER_RECENT,
119     WindowType::WINDOW_TYPE_LAUNCHER_DOCK
120 };
121 constexpr uint32_t MAX_SUB_WINDOW_LEVEL = 4;
122 constexpr float INVALID_DEFAULT_DENSITY = 1.0f;
123 constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_WIDTH = 40;
124 constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_HEIGHT = 40;
125 }
126 uint32_t WindowSceneSessionImpl::maxFloatingWindowSize_ = 1920;
127 std::mutex WindowSceneSessionImpl::keyboardPanelInfoChangeListenerMutex_;
128 using WindowSessionImplMap = std::map<std::string, std::pair<int32_t, sptr<WindowSessionImpl>>>;
129 std::mutex WindowSceneSessionImpl::windowAttachStateChangeListenerMutex_;
130 
WindowSceneSessionImpl(const sptr<WindowOption> & option)131 WindowSceneSessionImpl::WindowSceneSessionImpl(const sptr<WindowOption>& option) : WindowSessionImpl(option)
132 {
133     WLOGFI("[WMSCom] Constructor");
134 }
135 
~WindowSceneSessionImpl()136 WindowSceneSessionImpl::~WindowSceneSessionImpl()
137 {
138     WLOGFI("[WMSCom] Destructor");
139 }
140 
IsValidSystemWindowType(const WindowType & type)141 bool WindowSceneSessionImpl::IsValidSystemWindowType(const WindowType& type)
142 {
143     if (INVALID_SYSTEM_WINDOW_TYPE.find(type) != INVALID_SYSTEM_WINDOW_TYPE.end()) {
144         TLOGI(WmsLogTag::WMS_SYSTEM, "Invalid type: %{public}u", type);
145         return false;
146     }
147     TLOGI(WmsLogTag::WMS_SYSTEM, "Valid type: %{public}u", type);
148     return true;
149 }
150 
FindParentSessionByParentId(uint32_t parentId)151 sptr<WindowSessionImpl> WindowSceneSessionImpl::FindParentSessionByParentId(uint32_t parentId)
152 {
153     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
154     for (const auto& [_, pair] : windowSessionMap_) {
155         auto& window = pair.second;
156         if (window && window->GetProperty() && window->GetWindowId() == parentId) {
157             if (WindowHelper::IsMainWindow(window->GetType()) || WindowHelper::IsSystemWindow(window->GetType())) {
158                 WLOGFD("Find parent, [parentName: %{public}s, parentId:%{public}u, selfPersistentId: %{public}d]",
159                     window->GetProperty()->GetWindowName().c_str(), parentId,
160                     window->GetProperty()->GetPersistentId());
161                 return window;
162             } else if (WindowHelper::IsSubWindow(window->GetType()) &&
163                 (IsSessionMainWindow(window->GetParentId()) || window->GetProperty()->GetExtensionFlag() ||
164                  VerifySubWindowLevel(window->GetParentId()))) {
165                 // subwindow's grandparent is mainwindow or subwindow's parent is an extension subwindow
166                 return window;
167             }
168         }
169     }
170     WLOGFD("[WMSCom] Can not find parent window, id: %{public}d", parentId);
171     return nullptr;
172 }
173 
FindParentMainSession(uint32_t parentId,const SessionMap & sessionMap)174 sptr<WindowSessionImpl> WindowSceneSessionImpl::FindParentMainSession(uint32_t parentId, const SessionMap& sessionMap)
175 {
176     if (parentId == INVALID_SESSION_ID) {
177         TLOGW(WmsLogTag::WMS_SUB, "invalid parent id");
178         return nullptr;
179     }
180     for (const auto& [_, pair] : sessionMap) {
181         auto& window = pair.second;
182         if (window && window->GetWindowId() == parentId) {
183             if (WindowHelper::IsMainWindow(window->GetType()) ||
184                 (WindowHelper::IsSystemWindow(window->GetType()) && window->GetParentId() == INVALID_SESSION_ID)) {
185                 TLOGD(WmsLogTag::WMS_SUB, "find main session, id:%{public}u", window->GetWindowId());
186                 return window;
187             }
188             return FindParentMainSession(window->GetParentId(), sessionMap);
189         }
190     }
191     TLOGW(WmsLogTag::WMS_SUB, "don't find main session, parentId:%{public}u", parentId);
192     return nullptr;
193 }
194 
IsSessionMainWindow(uint32_t parentId)195 bool WindowSceneSessionImpl::IsSessionMainWindow(uint32_t parentId)
196 {
197     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
198     for (const auto& [_, pair] : windowSessionMap_) {
199         auto& window = pair.second;
200         if (window && window->GetWindowId() == parentId && WindowHelper::IsMainWindow(window->GetType())) {
201             return true;
202         }
203     }
204     return false;
205 }
206 
VerifySubWindowLevel(uint32_t parentId)207 bool WindowSceneSessionImpl::VerifySubWindowLevel(uint32_t parentId)
208 {
209     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
210     for (const auto& [_, pair] : windowSessionMap_) {
211         auto& window = pair.second;
212         if (window && window->GetWindowId() == parentId && window->GetProperty() &&
213             window->GetProperty()->GetSubWindowLevel() < MAX_SUB_WINDOW_LEVEL) {
214             return true;
215         }
216     }
217     return false;
218 }
219 
FindMainWindowOrExtensionSubWindow(uint32_t parentId,const WindowSessionImplMap & sessionMap)220 static sptr<WindowSessionImpl> FindMainWindowOrExtensionSubWindow(uint32_t parentId,
221     const WindowSessionImplMap& sessionMap)
222 {
223     if (parentId == INVALID_SESSION_ID) {
224         TLOGW(WmsLogTag::WMS_SUB, "invalid parent id");
225         return nullptr;
226     }
227     for (const auto& [_, pair] : sessionMap) {
228         auto& window = pair.second;
229         if (window && window->GetWindowId() == parentId) {
230             if (WindowHelper::IsMainWindow(window->GetType()) ||
231                 (WindowHelper::IsSubWindow(window->GetType()) && window->GetProperty()->GetExtensionFlag())) {
232                 TLOGD(WmsLogTag::WMS_SUB, "find main session, id:%{public}u", window->GetWindowId());
233                 return window;
234             }
235             return FindMainWindowOrExtensionSubWindow(window->GetParentId(), sessionMap);
236         }
237     }
238     TLOGW(WmsLogTag::WMS_SUB, "don't find main session, parentId:%{public}u", parentId);
239     return nullptr;
240 }
241 
IsPcOrPadCapabilityEnabled() const242 bool WindowSceneSessionImpl::IsPcOrPadCapabilityEnabled() const
243 {
244     if (windowSystemConfig_.uiType_ != UI_TYPE_PAD) {
245         return windowSystemConfig_.uiType_ == UI_TYPE_PC;
246     }
247     bool isUiExtSubWindow = WindowHelper::IsSubWindow(GetType()) && property_->GetExtensionFlag();
248     if (WindowHelper::IsMainWindow(GetType()) || isUiExtSubWindow || WindowHelper::IsSystemWindow(GetType())) {
249         return WindowSessionImpl::IsPcOrPadCapabilityEnabled();
250     }
251     sptr<WindowSessionImpl> parentWindow = nullptr;
252     {
253         std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
254         parentWindow = FindMainWindowOrExtensionSubWindow(property_->GetParentId(), windowSessionMap_);
255     }
256     if (parentWindow == nullptr) {
257         return false;
258     }
259     return parentWindow->WindowSessionImpl::IsPcOrPadCapabilityEnabled();
260 }
261 
IsPcOrPadFreeMultiWindowMode() const262 bool WindowSceneSessionImpl::IsPcOrPadFreeMultiWindowMode() const
263 {
264     if (windowSystemConfig_.uiType_ != UI_TYPE_PAD) {
265         return windowSystemConfig_.uiType_ == UI_TYPE_PC;
266     }
267     bool isUiExtSubWindow = WindowHelper::IsSubWindow(GetType()) && property_->GetExtensionFlag();
268     if (WindowHelper::IsMainWindow(GetType()) || isUiExtSubWindow || WindowHelper::IsSystemWindow(GetType())) {
269         return IsFreeMultiWindowMode();
270     }
271     sptr<WindowSessionImpl> parentWindow = nullptr;
272     {
273         std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
274         parentWindow = FindMainWindowOrExtensionSubWindow(property_->GetParentId(), windowSessionMap_);
275     }
276     if (parentWindow == nullptr) {
277         return false;
278     }
279     return parentWindow->WindowSessionImpl::IsPcOrPadFreeMultiWindowMode();
280 }
281 
AddSubWindowMapForExtensionWindow()282 void WindowSceneSessionImpl::AddSubWindowMapForExtensionWindow()
283 {
284     // update subWindowSessionMap_
285     auto extensionWindow = FindExtensionWindowWithContext();
286     if (extensionWindow != nullptr) {
287         subWindowSessionMap_[extensionWindow->GetPersistentId()].push_back(this);
288     } else {
289         TLOGE(WmsLogTag::WMS_SUB, "name: %{public}s not found parent extension window",
290             property_->GetWindowName().c_str());
291     }
292 }
293 
GetParentSessionAndVerify(bool isToast,sptr<WindowSessionImpl> & parentSession)294 WMError WindowSceneSessionImpl::GetParentSessionAndVerify(bool isToast, sptr<WindowSessionImpl>& parentSession)
295 {
296     if (isToast) {
297         std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
298         parentSession = FindParentMainSession(property_->GetParentId(), windowSessionMap_);
299     } else {
300         parentSession = FindParentSessionByParentId(property_->GetParentId());
301     }
302     if (parentSession == nullptr) {
303         TLOGE(WmsLogTag::WMS_LIFE, "parent of sub window is nullptr, name: %{public}s, type: %{public}d",
304             property_->GetWindowName().c_str(), GetType());
305         return WMError::WM_ERROR_NULLPTR;
306     }
307     if (!isToast && parentSession->GetProperty()->GetSubWindowLevel() > 1 &&
308         !parentSession->IsPcOrPadCapabilityEnabled()) {
309         TLOGE(WmsLogTag::WMS_SUB, "device not support");
310         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
311     }
312     return WMError::WM_OK;
313 }
314 
CreateAndConnectSpecificSession()315 WMError WindowSceneSessionImpl::CreateAndConnectSpecificSession()
316 {
317     sptr<ISessionStage> iSessionStage(this);
318     sptr<WindowEventChannel> channel = new (std::nothrow) WindowEventChannel(iSessionStage);
319     if (channel == nullptr || property_ == nullptr) {
320         TLOGE(WmsLogTag::WMS_LIFE, "inputChannel or property is nullptr");
321         return WMError::WM_ERROR_NULLPTR;
322     }
323     sptr<IWindowEventChannel> eventChannel(channel);
324     auto persistentId = INVALID_SESSION_ID;
325     sptr<Rosen::ISession> session;
326     sptr<IRemoteObject> token = context_ ? context_->GetToken() : nullptr;
327     if (token) {
328         property_->SetTokenState(true);
329     }
330     const WindowType& type = GetType();
331     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
332     auto& info = property_->EditSessionInfo();
333     if (abilityContext && abilityContext->GetAbilityInfo()) {
334         info.abilityName_ = abilityContext->GetAbilityInfo()->name;
335         info.moduleName_ = context_->GetHapModuleInfo() ? context_->GetHapModuleInfo()->moduleName : "";
336         info.bundleName_ = abilityContext->GetAbilityInfo()->bundleName;
337     } else if (context_) {
338         info.moduleName_ = context_->GetHapModuleInfo() ? context_->GetHapModuleInfo()->moduleName : "";
339         info.bundleName_ = context_->GetBundleName();
340     }
341 
342     bool isToastFlag = property_->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST);
343     bool isUiExtSubWindowFlag = property_->GetIsUIExtensionSubWindowFlag();
344 
345     bool isNormalAppSubWindow = WindowHelper::IsSubWindow(type) &&
346         !property_->GetExtensionFlag() && !isUiExtSubWindowFlag;
347     bool isArkSubSubWindow = WindowHelper::IsSubWindow(type) &&
348         !property_->GetExtensionFlag() && isUiExtSubWindowFlag && !isToastFlag;
349     bool isUiExtSubWindowToast =  WindowHelper::IsSubWindow(type) && isUiExtSubWindowFlag && isToastFlag;
350     bool isUiExtSubWindow = WindowHelper::IsSubWindow(type) && property_->GetExtensionFlag();
351 
352     if (isNormalAppSubWindow || isArkSubSubWindow) { // sub window
353         sptr<WindowSessionImpl> parentSession = nullptr;
354         auto ret = GetParentSessionAndVerify(isToastFlag, parentSession);
355         if (ret != WMError::WM_OK) {
356             return ret;
357         }
358         // set parent persistentId
359         property_->SetParentPersistentId(parentSession->GetPersistentId());
360         property_->SetIsPcAppInPad(parentSession->GetProperty()->GetIsPcAppInPad());
361         property_->SetSubWindowLevel(parentSession->GetProperty()->GetSubWindowLevel() + 1);
362         // creat sub session by parent session
363         SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
364             surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
365         // update subWindowSessionMap_
366         subWindowSessionMap_[parentSession->GetPersistentId()].push_back(this);
367         SetTargetAPIVersion(parentSession->GetTargetAPIVersion());
368     } else if (isUiExtSubWindow || isUiExtSubWindowToast) {
369         property_->SetParentPersistentId(property_->GetParentId());
370         property_->SetIsUIExtensionAbilityProcess(isUIExtensionAbilityProcess_);
371         // creat sub session by parent session
372         SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
373             surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
374         AddSubWindowMapForExtensionWindow();
375     } else { // system window
376         WMError createSystemWindowRet = CreateSystemWindow(type);
377         if (createSystemWindowRet != WMError::WM_OK) {
378             return createSystemWindowRet;
379         }
380         PreProcessCreate();
381         SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
382             surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
383         if (windowSystemConfig_.maxFloatingWindowSize_ != UINT32_MAX) {
384             maxFloatingWindowSize_ = windowSystemConfig_.maxFloatingWindowSize_;
385         }
386     }
387     property_->SetPersistentId(persistentId);
388     if (session == nullptr) {
389         TLOGI(WmsLogTag::WMS_LIFE, "create specific failed, session is nullptr, name: %{public}s",
390             property_->GetWindowName().c_str());
391         return WMError::WM_ERROR_NULLPTR;
392     }
393     {
394         std::lock_guard<std::mutex> lock(hostSessionMutex_);
395         hostSession_ = session;
396     }
397     TLOGI(WmsLogTag::WMS_LIFE, "name:%{public}s,id:%{public}d,parentId:%{public}d,type:%{public}u,"
398         "touchable:%{public}d", property_->GetWindowName().c_str(), property_->GetPersistentId(),
399         property_->GetParentPersistentId(), GetType(), property_->GetTouchable());
400     return WMError::WM_OK;
401 }
402 
CreateSystemWindow(WindowType type)403 WMError WindowSceneSessionImpl::CreateSystemWindow(WindowType type)
404 {
405     if (WindowHelper::IsAppFloatingWindow(type) || WindowHelper::IsPipWindow(type) ||
406         (type == WindowType::WINDOW_TYPE_TOAST)) {
407         property_->SetParentPersistentId(GetFloatingWindowParentId());
408         TLOGI(WmsLogTag::WMS_SYSTEM, "The parentId: %{public}d, type: %{public}d",
409             property_->GetParentPersistentId(), type);
410         auto mainWindow = FindMainWindowWithContext();
411         property_->SetFloatingWindowAppType(mainWindow != nullptr ? true : false);
412         if (mainWindow != nullptr && mainWindow->GetProperty() != nullptr) {
413             property_->SetSubWindowLevel(mainWindow->GetProperty()->GetSubWindowLevel() + 1);
414         }
415     } else if (type == WindowType::WINDOW_TYPE_DIALOG) {
416         auto mainWindow = FindMainWindowWithContext();
417         if (mainWindow != nullptr) {
418             property_->SetParentPersistentId(mainWindow->GetPersistentId());
419             if (mainWindow->GetProperty() != nullptr) {
420                 property_->SetSubWindowLevel(mainWindow->GetProperty()->GetSubWindowLevel() + 1);
421             }
422             TLOGI(WmsLogTag::WMS_DIALOG, "The parentId, parentId:%{public}d", mainWindow->GetPersistentId());
423         }
424         WLOGFD("Cannot find main window to bind");
425     } else if (WindowHelper::IsSystemSubWindow(type)) {
426         auto parentSession = FindParentSessionByParentId(property_->GetParentId());
427         if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
428             TLOGE(WmsLogTag::WMS_LIFE, "parent of system sub window, name: %{public}s, type: %{public}d",
429                 property_->GetWindowName().c_str(), type);
430             return WMError::WM_ERROR_NULLPTR;
431         }
432         if (WindowHelper::IsSystemSubWindow(parentSession->GetType())) {
433             TLOGE(WmsLogTag::WMS_LIFE, "parent is system sub window, name: %{public}s, type: %{public}d",
434                 property_->GetWindowName().c_str(), type);
435             return WMError::WM_ERROR_INVALID_TYPE;
436         }
437         // set parent persistentId
438         property_->SetParentPersistentId(parentSession->GetPersistentId());
439         if (parentSession->GetProperty() != nullptr) {
440             property_->SetSubWindowLevel(parentSession->GetProperty()->GetSubWindowLevel() + 1);
441         }
442     }
443     return WMError::WM_OK;
444 }
445 
RecoverAndConnectSpecificSession()446 WMError WindowSceneSessionImpl::RecoverAndConnectSpecificSession()
447 {
448     auto persistentId = property_->GetPersistentId();
449     TLOGI(WmsLogTag::WMS_RECOVER, "windowName = %{public}s, windowMode = %{public}u, "
450         "windowType = %{public}u, persistentId = %{public}d, windowState = %{public}d", GetWindowName().c_str(),
451         property_->GetWindowMode(), property_->GetWindowType(), persistentId, state_);
452 
453     property_->SetWindowState(state_);
454 
455     sptr<ISessionStage> iSessionStage(this);
456     sptr<IWindowEventChannel> eventChannel = sptr<WindowEventChannel>::MakeSptr(iSessionStage);
457     sptr<Rosen::ISession> session = nullptr;
458     sptr<IRemoteObject> token = context_ ? context_->GetToken() : nullptr;
459     if (token) {
460         property_->SetTokenState(true);
461     }
462     const WindowType type = GetType();
463     if (WindowHelper::IsSubWindow(type) && (property_->GetExtensionFlag() == false)) { // sub window
464         TLOGD(WmsLogTag::WMS_RECOVER, "SubWindow");
465         auto parentSession = FindParentSessionByParentId(property_->GetParentId());
466         if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
467             TLOGE(WmsLogTag::WMS_RECOVER, "parentSession is null");
468             return WMError::WM_ERROR_NULLPTR;
469         }
470     }
471     if (WindowHelper::IsPipWindow(type)) {
472         TLOGI(WmsLogTag::WMS_RECOVER, "pipWindow");
473         PictureInPictureManager::DoClose(true, true);
474         return WMError::WM_OK;
475     }
476     SingletonContainer::Get<WindowAdapter>().RecoverAndConnectSpecificSession(
477         iSessionStage, eventChannel, surfaceNode_, property_, session, token);
478 
479     if (session == nullptr) {
480         TLOGE(WmsLogTag::WMS_RECOVER, "Recover failed, session is nullptr");
481         return WMError::WM_ERROR_NULLPTR;
482     }
483     {
484         std::lock_guard<std::mutex> lock(hostSessionMutex_);
485         hostSession_ = session;
486     }
487     RecoverSessionListener();
488     TLOGI(WmsLogTag::WMS_RECOVER,
489         "over, windowName = %{public}s, persistentId = %{public}d",
490         GetWindowName().c_str(), GetPersistentId());
491     return WMError::WM_OK;
492 }
493 
RecoverAndReconnectSceneSession()494 WMError WindowSceneSessionImpl::RecoverAndReconnectSceneSession()
495 {
496     if (isFocused_) {
497         UpdateFocus(false);
498     }
499     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
500     if (property_ && context_ && context_->GetHapModuleInfo() && abilityContext && abilityContext->GetAbilityInfo()) {
501         property_->EditSessionInfo().abilityName_ = abilityContext->GetAbilityInfo()->name;
502         property_->EditSessionInfo().moduleName_ = context_->GetHapModuleInfo()->moduleName;
503     } else {
504         TLOGE(WmsLogTag::WMS_RECOVER, "property_ or context_ or abilityContext is null, recovered session failed");
505         return WMError::WM_ERROR_NULLPTR;
506     }
507     auto& info = property_->EditSessionInfo();
508     if (auto want = abilityContext->GetWant()) {
509         info.want = want;
510     } else {
511         TLOGE(WmsLogTag::WMS_RECOVER, "want is nullptr!");
512     }
513     property_->SetWindowState(state_);
514     TLOGI(WmsLogTag::WMS_RECOVER,
515         "bundleName=%{public}s, moduleName=%{public}s, abilityName=%{public}s, appIndex=%{public}d, type=%{public}u, "
516         "persistentId=%{public}d, windowState=%{public}d",
517         info.bundleName_.c_str(), info.moduleName_.c_str(), info.abilityName_.c_str(), info.appIndex_, info.windowType_,
518         GetPersistentId(), state_);
519     sptr<ISessionStage> iSessionStage(this);
520     auto windowEventChannel = new (std::nothrow) WindowEventChannel(iSessionStage);
521     if (windowEventChannel == nullptr) {
522         return WMError::WM_ERROR_NULLPTR;
523     }
524     sptr<IWindowEventChannel> iWindowEventChannel(windowEventChannel);
525     sptr<IRemoteObject> token = context_ ? context_->GetToken() : nullptr;
526     sptr<Rosen::ISession> session;
527     auto ret = SingletonContainer::Get<WindowAdapter>().RecoverAndReconnectSceneSession(
528         iSessionStage, iWindowEventChannel, surfaceNode_, session, property_, token);
529     if (session == nullptr) {
530         TLOGE(WmsLogTag::WMS_RECOVER, "session is null, recovered session failed");
531         return WMError::WM_ERROR_NULLPTR;
532     }
533     TLOGI(WmsLogTag::WMS_RECOVER, "Recover and reconnect sceneSession successful");
534     {
535         std::lock_guard<std::mutex> lock(hostSessionMutex_);
536         hostSession_ = session;
537     }
538     RecoverSessionListener();
539     return static_cast<WMError>(ret);
540 }
541 
UpdateWindowState()542 void WindowSceneSessionImpl::UpdateWindowState()
543 {
544     {
545         std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
546         windowSessionMap_.insert(std::make_pair(property_->GetWindowName(),
547         std::pair<uint64_t, sptr<WindowSessionImpl>>(property_->GetPersistentId(), this)));
548     }
549     state_ = WindowState::STATE_CREATED;
550     requestState_ = WindowState::STATE_CREATED;
551     WindowType windowType = GetType();
552     if (WindowHelper::IsMainWindow(windowType)) {
553         if (windowSystemConfig_.maxFloatingWindowSize_ != UINT32_MAX) {
554             maxFloatingWindowSize_ = windowSystemConfig_.maxFloatingWindowSize_;
555         }
556         if (property_->GetIsNeedUpdateWindowMode()) {
557             WLOGFI("UpdateWindowMode %{public}u mode %{public}u",
558                 GetWindowId(), static_cast<uint32_t>(property_->GetWindowMode()));
559             UpdateWindowModeImmediately(property_->GetWindowMode());
560             property_->SetIsNeedUpdateWindowMode(false);
561         } else {
562             SetWindowMode(windowSystemConfig_.defaultWindowMode_);
563         }
564         NotifyWindowNeedAvoid(
565             (property_->GetWindowFlags()) & (static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
566         GetConfigurationFromAbilityInfo();
567     } else {
568         bool isSubWindow = WindowHelper::IsSubWindow(windowType);
569         bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
570         bool isSystemWindow = WindowHelper::IsSystemWindow(windowType);
571         UpdateWindowSizeLimits();
572         if ((isSubWindow || isDialogWindow || isSystemWindow) && IsWindowDraggable()) {
573             WLOGFD("sync window limits to server side in order to make size limits work while resizing");
574             UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
575         }
576     }
577 }
578 
Create(const std::shared_ptr<AbilityRuntime::Context> & context,const sptr<Rosen::ISession> & iSession,const std::string & identityToken)579 WMError WindowSceneSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
580     const sptr<Rosen::ISession>& iSession, const std::string& identityToken)
581 {
582     if (property_ == nullptr) {
583         TLOGE(WmsLogTag::WMS_LIFE, "Window Create failed, property is nullptr");
584         return WMError::WM_ERROR_NULLPTR;
585     }
586     TLOGI(WmsLogTag::WMS_LIFE, "Window Create name:%{public}s, state:%{public}u, windowmode:%{public}u",
587         property_->GetWindowName().c_str(), state_, GetMode());
588     // allow iSession is nullptr when create window by innerkits
589     if (!context) {
590         TLOGW(WmsLogTag::WMS_LIFE, "context is nullptr");
591     }
592     WMError ret = WindowSessionCreateCheck();
593     if (ret != WMError::WM_OK) {
594         return ret;
595     }
596     SetDefaultDisplayIdIfNeed();
597     {
598         std::lock_guard<std::mutex> lock(hostSessionMutex_);
599         hostSession_ = iSession;
600     }
601     context_ = context;
602     identityToken_ = identityToken;
603     AdjustWindowAnimationFlag();
604     if (context && context->GetApplicationInfo() &&
605         context->GetApplicationInfo()->apiCompatibleVersion >= 9 && // 9: api version
606         !SessionPermission::IsSystemCalling()) {
607         WLOGI("Remove window flag WINDOW_FLAG_SHOW_WHEN_LOCKED");
608         property_->SetWindowFlags(property_->GetWindowFlags() &
609             (~(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))));
610     }
611 
612     bool isSpecificSession = false;
613     if (GetHostSession()) { // main window
614         ret = Connect();
615         SetTargetAPIVersion(SysCapUtil::GetApiCompatibleVersion());
616         TLOGD(WmsLogTag::WMS_PC, "targeAPItVersion: %{public}d", GetTargetAPIVersion());
617     } else { // system or sub window
618         TLOGI(WmsLogTag::WMS_LIFE, "Create system or sub window with type = %{public}d", GetType());
619         isSpecificSession = true;
620         const auto& type = GetType();
621         if (WindowHelper::IsSystemWindow(type)) {
622             // Not valid system window type for session should return WMError::WM_OK;
623             if (!IsValidSystemWindowType(type)) {
624                 return WMError::WM_ERROR_INVALID_CALLING;
625             }
626             if (INVALID_SCB_WINDOW_TYPE.find(type) != INVALID_SCB_WINDOW_TYPE.end()) {
627                 TLOGI(WmsLogTag::WMS_SYSTEM, "Invalid SCB type: %{public}u", type);
628                 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
629             }
630             InitSystemSessionDragEnable();
631         } else if (!WindowHelper::IsSubWindow(type)) {
632             TLOGI(WmsLogTag::WMS_LIFE, "create failed not system or sub type, type: %{public}d", type);
633             return WMError::WM_ERROR_INVALID_CALLING;
634         }
635         ret = CreateAndConnectSpecificSession();
636     }
637     if (ret == WMError::WM_OK) {
638         MakeSubOrDialogWindowDragableAndMoveble();
639         UpdateWindowState();
640         RegisterSessionRecoverListener(isSpecificSession);
641         UpdateDefaultStatusBarColor();
642         AddSetUIContentTimeoutCheck();
643         SetUIExtensionDestroyCompleteInSubWindow();
644         InputTransferStation::GetInstance().AddInputWindow(this);
645     }
646     TLOGD(WmsLogTag::WMS_LIFE, "Window Create success [name:%{public}s, "
647         "id:%{public}d], state:%{public}u, mode:%{public}u, displayId:%{public}" PRIu64,
648         property_->GetWindowName().c_str(), property_->GetPersistentId(), state_, GetMode(), property_->GetDisplayId());
649     return ret;
650 }
651 
UpdateDefaultStatusBarColor()652 void WindowSceneSessionImpl::UpdateDefaultStatusBarColor()
653 {
654     SystemBarProperty statusBarProp = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
655     if (static_cast<SystemBarSettingFlag>(static_cast<uint32_t>(statusBarProp.settingFlag_) &
656         static_cast<uint32_t>(SystemBarSettingFlag::COLOR_SETTING)) == SystemBarSettingFlag::COLOR_SETTING) {
657         TLOGD(WmsLogTag::WMS_IMMS, "user has set color");
658         return;
659     }
660     if (!WindowHelper::IsMainWindow(GetType())) {
661         TLOGD(WmsLogTag::WMS_IMMS, "not main window");
662         return;
663     }
664     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
665     if (appContext == nullptr) {
666         TLOGE(WmsLogTag::WMS_IMMS, "app context is nullptr");
667         return;
668     }
669     std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
670     bool isColorModeSetByApp = !config->GetItem(AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_APP).empty();
671     std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
672     uint32_t contentColor;
673     constexpr uint32_t BLACK = 0xFF000000;
674     constexpr uint32_t WHITE = 0xFFFFFFFF;
675     if (isColorModeSetByApp) {
676         TLOGI(WmsLogTag::WMS_IMMS, "winId: %{public}u, type: %{public}u, colorMode: %{public}s",
677             GetPersistentId(), GetType(), colorMode.c_str());
678         contentColor = colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT ? BLACK : WHITE;
679     } else {
680         bool hasDarkRes = false;
681         appContext->AppHasDarkRes(hasDarkRes);
682         TLOGI(WmsLogTag::WMS_IMMS, "winId: %{public}u, type: %{public}u, hasDarkRes: %{public}u, colorMode: %{public}s",
683             GetPersistentId(), GetType(), hasDarkRes, colorMode.c_str());
684         contentColor = colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT ? BLACK :
685             (hasDarkRes ? WHITE : BLACK);
686     }
687 
688     statusBarProp.contentColor_ = contentColor;
689     statusBarProp.settingFlag_ = static_cast<SystemBarSettingFlag>(
690         static_cast<uint32_t>(statusBarProp.settingFlag_) |
691         static_cast<uint32_t>(SystemBarSettingFlag::FOLLOW_SETTING));
692     SetSpecificBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusBarProp);
693 }
694 
InitSystemSessionDragEnable()695 void WindowSceneSessionImpl::InitSystemSessionDragEnable()
696 {
697     if (WindowHelper::IsDialogWindow(GetType())) {
698         TLOGI(WmsLogTag::WMS_LAYOUT, "dialogWindow default draggable, should not init false, id: %{public}d",
699             GetPersistentId());
700         return;
701     }
702     TLOGI(WmsLogTag::WMS_LAYOUT, "windId: %{public}d init dragEnable false", GetPersistentId());
703     property_->SetDragEnabled(false);
704 }
705 
RegisterSessionRecoverListener(bool isSpecificSession)706 void WindowSceneSessionImpl::RegisterSessionRecoverListener(bool isSpecificSession)
707 {
708     TLOGD(WmsLogTag::WMS_RECOVER, "persistentId = %{public}d, isSpecificSession = %{public}s",
709         GetPersistentId(), isSpecificSession ? "true" : "false");
710 
711     if (GetType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
712         TLOGI(WmsLogTag::WMS_RECOVER, "input method window does not need to recover");
713         return;
714     }
715     if (property_ != nullptr && property_->GetCollaboratorType() != CollaboratorType::DEFAULT_TYPE) {
716         TLOGI(WmsLogTag::WMS_RECOVER, "collaboratorType is %{public}" PRId32 ", not need to recover",
717             property_->GetCollaboratorType());
718         return;
719     }
720 
721     wptr<WindowSceneSessionImpl> weakThis = this;
722     auto callbackFunc = [weakThis, isSpecificSession] {
723         auto promoteThis = weakThis.promote();
724         if (promoteThis == nullptr) {
725             TLOGW(WmsLogTag::WMS_RECOVER, "promoteThis is nullptr");
726             return WMError::WM_ERROR_NULLPTR;
727         }
728         if (promoteThis->state_ == WindowState::STATE_DESTROYED) {
729             TLOGW(WmsLogTag::WMS_RECOVER, "windowState is STATE_DESTROYED, no need to recover");
730             return WMError::WM_ERROR_DESTROYED_OBJECT;
731         }
732 
733         auto ret = isSpecificSession ? promoteThis->RecoverAndConnectSpecificSession() :
734 			promoteThis->RecoverAndReconnectSceneSession();
735 
736         TLOGD(WmsLogTag::WMS_RECOVER, "Recover session over, ret = %{public}d", ret);
737         return ret;
738     };
739     SingletonContainer::Get<WindowAdapter>().RegisterSessionRecoverCallbackFunc(GetPersistentId(), callbackFunc);
740 }
741 
HandlePointDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const MMI::PointerEvent::PointerItem & pointerItem,int32_t sourceType,float vpr,const WSRect & rect)742 bool WindowSceneSessionImpl::HandlePointDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
743     const MMI::PointerEvent::PointerItem& pointerItem, int32_t sourceType, float vpr, const WSRect& rect)
744 {
745     bool needNotifyEvent = true;
746     int32_t winX = pointerItem.GetWindowX();
747     int32_t winY = pointerItem.GetWindowY();
748     int32_t titleBarHeight = 0;
749     WMError ret = GetDecorHeight(titleBarHeight);
750     if (ret != WMError::WM_OK || titleBarHeight <= 0) {
751         titleBarHeight = static_cast<int32_t>(WINDOW_TITLE_BAR_HEIGHT * vpr);
752     } else {
753         titleBarHeight = static_cast<int32_t>(titleBarHeight * vpr);
754     }
755     int outside = (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) ? static_cast<int>(HOTZONE_POINTER * vpr) :
756         static_cast<int>(HOTZONE_TOUCH * vpr);
757     AreaType dragType = AreaType::UNDEFINED;
758     WindowType windowType = property_->GetWindowType();
759     bool isSystemDraggableType = WindowHelper::IsSystemWindow(windowType) && IsWindowDraggable();
760     if (property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING || isSystemDraggableType) {
761         dragType = SessionHelper::GetAreaType(winX, winY, sourceType, outside, vpr, rect);
762     }
763     TLOGD(WmsLogTag::WMS_EVENT, "dragType: %{public}d", dragType);
764     bool isDecorDialog = windowType == WindowType::WINDOW_TYPE_DIALOG && property_->IsDecorEnable();
765     bool isFixedSubWin = WindowHelper::IsSubWindow(windowType) && !IsWindowDraggable();
766     bool isFixedSystemWin = WindowHelper::IsSystemWindow(windowType) && !IsWindowDraggable();
767     auto hostSession = GetHostSession();
768     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, needNotifyEvent);
769     TLOGD(WmsLogTag::WMS_EVENT, "isFixedSystemWin %{public}d, isFixedSubWin %{public}d, isDecorDialog %{public}d",
770         isFixedSystemWin, isFixedSubWin, isDecorDialog);
771     if ((isFixedSystemWin || isFixedSubWin) && !isDecorDialog) {
772         hostSession->SendPointEventForMoveDrag(pointerEvent);
773     } else {
774         if (dragType != AreaType::UNDEFINED) {
775             hostSession->SendPointEventForMoveDrag(pointerEvent);
776             needNotifyEvent = false;
777         } else if (WindowHelper::IsMainWindow(windowType) ||
778             WindowHelper::IsSubWindow(windowType) ||
779             WindowHelper::IsSystemWindow(windowType)) {
780             hostSession->SendPointEventForMoveDrag(pointerEvent);
781         } else {
782             hostSession->ProcessPointDownSession(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
783         }
784     }
785     return needNotifyEvent;
786 }
787 
ConsumePointerEventInner(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)788 void WindowSceneSessionImpl::ConsumePointerEventInner(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
789     MMI::PointerEvent::PointerItem& pointerItem)
790 {
791     const int32_t& action = pointerEvent->GetPointerAction();
792     const auto& sourceType = pointerEvent->GetSourceType();
793     const auto& rect = SessionHelper::TransferToWSRect(GetRect());
794     bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
795         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
796     bool needNotifyEvent = true;
797     if (property_->GetCompatibleModeEnableInPad()) {
798         HandleEventForCompatibleMode(pointerEvent, pointerItem);
799     }
800     lastPointerEvent_ = pointerEvent;
801     if (isPointDown) {
802         auto displayInfo = SingletonContainer::Get<DisplayManagerAdapter>().GetDisplayInfo(property_->GetDisplayId());
803         if (displayInfo == nullptr) {
804             WLOGFE("The display or display info is nullptr");
805             pointerEvent->MarkProcessed();
806             return;
807         }
808         float vpr = GetVirtualPixelRatio(displayInfo);
809         if (MathHelper::NearZero(vpr)) {
810             WLOGFW("vpr is zero");
811             pointerEvent->MarkProcessed();
812             return;
813         }
814         needNotifyEvent = HandlePointDownEvent(pointerEvent, pointerItem, sourceType, vpr, rect);
815         RefreshNoInteractionTimeoutMonitor();
816     }
817     bool isPointUp = (action == MMI::PointerEvent::POINTER_ACTION_UP ||
818         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
819         action == MMI::PointerEvent::POINTER_ACTION_CANCEL);
820     if (isPointUp) {
821         auto hostSession = GetHostSession();
822         if (hostSession != nullptr) {
823             hostSession->SendPointEventForMoveDrag(pointerEvent);
824         }
825     }
826 
827     if (needNotifyEvent) {
828         NotifyPointerEvent(pointerEvent);
829     } else {
830         pointerEvent->MarkProcessed();
831     }
832     if (isPointDown || isPointUp) {
833         TLOGI(WmsLogTag::WMS_INPUT_KEY_FLOW, "InputId:%{public}d,wid:%{public}u,pointId:%{public}d"
834             ",srcType:%{public}d,rect:[%{public}d,%{public}d,%{public}u,%{public}u]"
835             ",notify:%{public}d",
836             pointerEvent->GetId(), GetWindowId(), pointerEvent->GetPointerId(),
837             sourceType, rect.posX_, rect.posY_, rect.width_, rect.height_,
838             needNotifyEvent);
839     }
840 }
841 
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)842 void WindowSceneSessionImpl::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
843 {
844     if (pointerEvent == nullptr) {
845         WLOGFE("PointerEvent is nullptr, windowId: %{public}d", GetWindowId());
846         return;
847     }
848 
849     if (GetHostSession() == nullptr) {
850         TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "hostSession is nullptr, windowId: %{public}d", GetWindowId());
851         pointerEvent->MarkProcessed();
852         return;
853     }
854     MMI::PointerEvent::PointerItem pointerItem;
855     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
856         TLOGW(WmsLogTag::WMS_INPUT_KEY_FLOW, "invalid pointerEvent, windowId: %{public}d", GetWindowId());
857         pointerEvent->MarkProcessed();
858         return;
859     }
860 
861     ConsumePointerEventInner(pointerEvent, pointerItem);
862 }
863 
PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)864 bool WindowSceneSessionImpl::PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
865 {
866     bool ret = false;
867     {
868         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
869         if (uiContent != nullptr) {
870             ret = uiContent->ProcessKeyEvent(keyEvent, true);
871         }
872     }
873     RefreshNoInteractionTimeoutMonitor();
874     return ret;
875 }
876 
GetConfigurationFromAbilityInfo()877 void WindowSceneSessionImpl::GetConfigurationFromAbilityInfo()
878 {
879     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
880     if (abilityContext == nullptr) {
881         WLOGFE("abilityContext is nullptr");
882         return;
883     }
884     auto abilityInfo = abilityContext->GetAbilityInfo();
885     if (abilityInfo != nullptr) {
886         property_->SetConfigWindowLimitsVP({
887             abilityInfo->maxWindowWidth, abilityInfo->maxWindowHeight,
888             abilityInfo->minWindowWidth, abilityInfo->minWindowHeight,
889             static_cast<float>(abilityInfo->maxWindowRatio), static_cast<float>(abilityInfo->minWindowRatio)
890         });
891         UpdateWindowSizeLimits();
892         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
893         // get support modes configuration
894         uint32_t windowModeSupportType = 0;
895         std::vector<AppExecFwk::SupportWindowMode> supportedWindowModes;
896         property_->GetSupportedWindowModes(supportedWindowModes);
897         auto size = supportedWindowModes.size();
898         if (size > 0 && size <= WINDOW_SUPPORT_MODE_MAX_SIZE) {
899             windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(supportedWindowModes);
900         } else {
901             windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(abilityInfo->windowModes);
902         }
903         if (windowModeSupportType == 0) {
904             TLOGI(WmsLogTag::WMS_LAYOUT, "mode config param is 0, all modes is supported");
905             windowModeSupportType = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
906         }
907         TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}u, windowModeSupportType: %{public}u",
908             GetWindowId(), windowModeSupportType);
909         property_->SetWindowModeSupportType(windowModeSupportType);
910         // update windowModeSupportType to server
911         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
912         auto isPhone = windowSystemConfig_.uiType_ == UI_TYPE_PHONE;
913         auto isPad = windowSystemConfig_.uiType_ == UI_TYPE_PAD;
914         bool isWindowModeSupportFullscreen = GetTargetAPIVersion() < 15 ? // 15: isolated version
915             (windowModeSupportType == WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN) :
916             (WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
917             !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING));
918         bool onlySupportFullScreen = isWindowModeSupportFullscreen &&
919             ((!isPhone && !isPad) || IsFreeMultiWindowMode());
920         if (onlySupportFullScreen || property_->GetFullScreenStart()) {
921             TLOGI(WmsLogTag::WMS_LAYOUT, "onlySupportFullScreen:%{public}d fullScreenStart:%{public}d",
922                 onlySupportFullScreen, property_->GetFullScreenStart());
923             Maximize(MaximizePresentation::ENTER_IMMERSIVE);
924         }
925     }
926 }
927 
UpdateConfigVal(uint32_t minVal,uint32_t maxVal,uint32_t configVal,uint32_t defaultVal,float vpr)928 uint32_t WindowSceneSessionImpl::UpdateConfigVal(uint32_t minVal, uint32_t maxVal, uint32_t configVal,
929                                                  uint32_t defaultVal, float vpr)
930 {
931     bool validConfig = minVal < (configVal * vpr) && (configVal * vpr) < maxVal;
932     return validConfig ? static_cast<uint32_t>(configVal * vpr) : static_cast<uint32_t>(defaultVal * vpr);
933 }
934 
GetSystemSizeLimits(uint32_t displayWidth,uint32_t displayHeight,float vpr)935 WindowLimits WindowSceneSessionImpl::GetSystemSizeLimits(uint32_t displayWidth,
936     uint32_t displayHeight, float vpr)
937 {
938     WindowLimits systemLimits;
939     systemLimits.maxWidth_ = static_cast<uint32_t>(maxFloatingWindowSize_ * vpr);
940     systemLimits.maxHeight_ = static_cast<uint32_t>(maxFloatingWindowSize_ * vpr);
941 
942     if (WindowHelper::IsMainWindow(GetType())) {
943         systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfMainWindow_,
944                                                  MIN_FLOATING_WIDTH, vpr);
945         systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfMainWindow_,
946                                                   MIN_FLOATING_HEIGHT, vpr);
947     } else if (WindowHelper::IsSubWindow(GetType())) {
948         systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfSubWindow_,
949                                                  MIN_FLOATING_WIDTH, vpr);
950         systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfSubWindow_,
951                                                   MIN_FLOATING_HEIGHT, vpr);
952     } else if (WindowHelper::IsSystemWindow(GetType()) && GetType() != WindowType::WINDOW_TYPE_DIALOG) {
953         systemLimits.minWidth_ = 0;
954         systemLimits.minHeight_ = 0;
955     } else {
956         systemLimits.minWidth_ = static_cast<uint32_t>(MIN_FLOATING_WIDTH * vpr);
957         systemLimits.minHeight_ = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * vpr);
958     }
959     WLOGFI("[System SizeLimits] [maxWidth: %{public}u, minWidth: %{public}u, maxHeight: %{public}u, "
960         "minHeight: %{public}u]", systemLimits.maxWidth_, systemLimits.minWidth_,
961         systemLimits.maxHeight_, systemLimits.minHeight_);
962     return systemLimits;
963 }
964 
CalculateNewLimitsByLimits(WindowLimits & newLimits,WindowLimits & customizedLimits,float & virtualPixelRatio)965 void WindowSceneSessionImpl::CalculateNewLimitsByLimits(
966     WindowLimits& newLimits, WindowLimits& customizedLimits, float& virtualPixelRatio)
967 {
968     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
969     if (display == nullptr) {
970         TLOGE(WmsLogTag::WMS_LAYOUT, "display is null");
971         return;
972     }
973     auto displayInfo = display->GetDisplayInfo();
974     if (displayInfo == nullptr) {
975         TLOGE(WmsLogTag::WMS_LAYOUT, "displayInfo is null");
976         return;
977     }
978     uint32_t displayWidth = static_cast<uint32_t>(display->GetWidth());
979     uint32_t displayHeight = static_cast<uint32_t>(display->GetHeight());
980     if (displayWidth == 0 || displayHeight == 0) {
981         return;
982     }
983     virtualPixelRatio = GetVirtualPixelRatio(displayInfo);
984     const auto& systemLimits = GetSystemSizeLimits(displayWidth, displayHeight, virtualPixelRatio);
985     if (userLimitsSet_) {
986         customizedLimits = property_->GetUserWindowLimits();
987     } else {
988         customizedLimits = property_->GetConfigWindowLimitsVP();
989         customizedLimits.maxWidth_ = static_cast<uint32_t>(customizedLimits.maxWidth_ * virtualPixelRatio);
990         customizedLimits.maxHeight_ = static_cast<uint32_t>(customizedLimits.maxHeight_ * virtualPixelRatio);
991         customizedLimits.minWidth_ = static_cast<uint32_t>(customizedLimits.minWidth_ * virtualPixelRatio);
992         customizedLimits.minHeight_ = static_cast<uint32_t>(customizedLimits.minHeight_ * virtualPixelRatio);
993     }
994     newLimits = systemLimits;
995     // calculate new limit size
996     if (systemLimits.minWidth_ <= customizedLimits.maxWidth_ &&
997         customizedLimits.maxWidth_ <= systemLimits.maxWidth_) {
998         newLimits.maxWidth_ = customizedLimits.maxWidth_;
999     }
1000     if (systemLimits.minHeight_ <= customizedLimits.maxHeight_ &&
1001         customizedLimits.maxHeight_ <= systemLimits.maxHeight_) {
1002         newLimits.maxHeight_ = customizedLimits.maxHeight_;
1003     }
1004     uint32_t limitMinWidth = systemLimits.minWidth_;
1005     uint32_t limitMinHeight = systemLimits.minHeight_;
1006     if (forceLimits_ && windowSystemConfig_.uiType_ == UI_TYPE_PC) {
1007         uint32_t forceLimitMinWidth = static_cast<uint32_t>(FORCE_LIMIT_MIN_FLOATING_WIDTH * virtualPixelRatio);
1008         uint32_t forceLimitMinHeight = static_cast<uint32_t>(FORCE_LIMIT_MIN_FLOATING_HEIGHT * virtualPixelRatio);
1009         limitMinWidth = std::min(forceLimitMinWidth, limitMinWidth);
1010         limitMinHeight = std::min(forceLimitMinHeight, limitMinHeight);
1011         newLimits.minWidth_ = limitMinWidth;
1012         newLimits.minHeight_ = limitMinHeight;
1013     }
1014     if (limitMinWidth <= customizedLimits.minWidth_ &&
1015         customizedLimits.minWidth_ <= newLimits.maxWidth_) {
1016         newLimits.minWidth_ = customizedLimits.minWidth_;
1017     }
1018     if (limitMinHeight <= customizedLimits.minHeight_ &&
1019         customizedLimits.minHeight_ <= newLimits.maxHeight_) {
1020         newLimits.minHeight_ = customizedLimits.minHeight_;
1021     }
1022 }
1023 
CalculateNewLimitsByRatio(WindowLimits & newLimits,WindowLimits & customizedLimits)1024 void WindowSceneSessionImpl::CalculateNewLimitsByRatio(WindowLimits& newLimits, WindowLimits& customizedLimits)
1025 {
1026     newLimits.maxRatio_ = customizedLimits.maxRatio_;
1027     newLimits.minRatio_ = customizedLimits.minRatio_;
1028 
1029     // calculate new limit ratio
1030     double maxRatio = FLT_MAX;
1031     double minRatio = 0.0f;
1032     if (newLimits.minHeight_ != 0) {
1033         maxRatio = static_cast<double>(newLimits.maxWidth_) / static_cast<double>(newLimits.minHeight_);
1034     }
1035     if (newLimits.maxHeight_ != 0) {
1036         minRatio = static_cast<double>(newLimits.minWidth_) / static_cast<double>(newLimits.maxHeight_);
1037     }
1038     if (!MathHelper::GreatNotEqual(minRatio, customizedLimits.maxRatio_) &&
1039         !MathHelper::GreatNotEqual(customizedLimits.maxRatio_, maxRatio)) {
1040         maxRatio = customizedLimits.maxRatio_;
1041     }
1042     if (!MathHelper::GreatNotEqual(minRatio, customizedLimits.minRatio_) &&
1043         !MathHelper::GreatNotEqual(customizedLimits.minRatio_, maxRatio)) {
1044         minRatio = customizedLimits.minRatio_;
1045     }
1046 
1047     // recalculate limit size by new ratio
1048     double newMaxWidthFloat = static_cast<double>(newLimits.maxHeight_) * maxRatio;
1049     uint32_t newMaxWidth = (newMaxWidthFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1050         std::round(newMaxWidthFloat);
1051     newLimits.maxWidth_ = std::min(newMaxWidth, newLimits.maxWidth_);
1052 
1053     double newMinWidthFloat = static_cast<double>(newLimits.minHeight_) * minRatio;
1054     uint32_t newMinWidth = (newMinWidthFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1055         std::round(newMinWidthFloat);
1056     newLimits.minWidth_ = std::max(newMinWidth, newLimits.minWidth_);
1057 
1058     double newMaxHeightFloat = MathHelper::NearZero(minRatio) ? UINT32_MAX :
1059         static_cast<double>(newLimits.maxWidth_) / minRatio;
1060     uint32_t newMaxHeight = (newMaxHeightFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1061         std::round(newMaxHeightFloat);
1062     newLimits.maxHeight_ = std::min(newMaxHeight, newLimits.maxHeight_);
1063 
1064     double newMinHeightFloat = MathHelper::NearZero(maxRatio) ? UINT32_MAX :
1065         static_cast<double>(newLimits.minWidth_) / maxRatio;
1066     uint32_t newMinHeight = (newMinHeightFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1067         std::round(newMinHeightFloat);
1068     newLimits.minHeight_ = std::max(newMinHeight, newLimits.minHeight_);
1069 }
1070 
UpdateWindowSizeLimits()1071 void WindowSceneSessionImpl::UpdateWindowSizeLimits()
1072 {
1073     WindowLimits customizedLimits;
1074     WindowLimits newLimits;
1075     float virtualPixelRatio = 0.0f;
1076 
1077     CalculateNewLimitsByLimits(newLimits, customizedLimits, virtualPixelRatio);
1078     if (MathHelper::NearZero(virtualPixelRatio)) {
1079         return;
1080     }
1081     newLimits.vpRatio_ = virtualPixelRatio;
1082     CalculateNewLimitsByRatio(newLimits, customizedLimits);
1083 
1084     property_->SetWindowLimits(newLimits);
1085     property_->SetLastLimitsVpr(virtualPixelRatio);
1086 }
1087 
PreLayoutOnShow(WindowType type,const sptr<DisplayInfo> & info)1088 void WindowSceneSessionImpl::PreLayoutOnShow(WindowType type, const sptr<DisplayInfo>& info)
1089 {
1090     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1091     if (uiContent == nullptr) {
1092         TLOGW(WmsLogTag::WMS_LIFE, "uiContent is null");
1093         return;
1094     }
1095     const auto& requestRect = GetRequestRect();
1096     TLOGI(WmsLogTag::WMS_LIFE, "name: %{public}s, id: %{public}d, type: %{public}u, requestRect:%{public}s",
1097         property_->GetWindowName().c_str(), GetPersistentId(), type, requestRect.ToString().c_str());
1098     if (requestRect.width_ != 0 && requestRect.height_ != 0) {
1099         UpdateViewportConfig(requestRect, WindowSizeChangeReason::RESIZE, nullptr, info);
1100         if (auto hostSession = GetHostSession()) {
1101             WSRect wsRect = { requestRect.posX_, requestRect.posY_, requestRect.width_, requestRect.height_ };
1102             property_->SetWindowRect(requestRect);
1103             hostSession->UpdateClientRect(wsRect);
1104         } else {
1105             TLOGE(WmsLogTag::DEFAULT, "hostSession is null");
1106         }
1107     }
1108     state_ = WindowState::STATE_SHOWN;
1109     requestState_ = WindowState::STATE_SHOWN;
1110     uiContent->Foreground();
1111     uiContent->PreLayout();
1112 }
1113 
Show(uint32_t reason,bool withAnimation,bool withFocus)1114 WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus)
1115 {
1116     if (property_ == nullptr) {
1117         TLOGE(WmsLogTag::WMS_LIFE, "Window show failed, property is nullptr");
1118         return WMError::WM_ERROR_NULLPTR;
1119     }
1120     const auto& type = GetType();
1121     if (IsWindowSessionInvalid()) {
1122         TLOGI(WmsLogTag::WMS_LIFE, "Window show failed, session is invalid, name: %{public}s, id: %{public}d",
1123             property_->GetWindowName().c_str(), GetPersistentId());
1124         return WMError::WM_ERROR_INVALID_WINDOW;
1125     }
1126     auto hostSession = GetHostSession();
1127     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1128 
1129     TLOGI(WmsLogTag::WMS_LIFE, "Window show [name: %{public}s, id: %{public}d, type: %{public}u], reason: %{public}u,"
1130         " state:%{public}u, requestState:%{public}u", property_->GetWindowName().c_str(),
1131         property_->GetPersistentId(), type, reason, state_, requestState_);
1132     auto isDecorEnable = IsDecorEnable();
1133     UpdateDecorEnableToAce(isDecorEnable);
1134     property_->SetDecorEnable(isDecorEnable);
1135 
1136     if (state_ == WindowState::STATE_SHOWN) {
1137         TLOGD(WmsLogTag::WMS_LIFE, "window session is already shown [name:%{public}s, id:%{public}d, type: %{public}u]",
1138             property_->GetWindowName().c_str(), property_->GetPersistentId(), type);
1139         if (WindowHelper::IsMainWindow(type)) {
1140             hostSession->RaiseAppMainWindowToTop();
1141         }
1142         NotifyAfterForeground(true, false);
1143         RefreshNoInteractionTimeoutMonitor();
1144         return WMError::WM_OK;
1145     }
1146     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
1147     if (display == nullptr) {
1148         TLOGE(WmsLogTag::WMS_LIFE, "Window show failed, display is null, name: %{public}s, id: %{public}d",
1149             property_->GetWindowName().c_str(), GetPersistentId());
1150         return WMError::WM_ERROR_NULLPTR;
1151     }
1152     auto displayInfo = display->GetDisplayInfo();
1153     if (displayInfo == nullptr) {
1154         TLOGE(WmsLogTag::WMS_LIFE, "Window show failed, displayInfo is null, name: %{public}s, id: %{public}d",
1155             property_->GetWindowName().c_str(), GetPersistentId());
1156         return WMError::WM_ERROR_NULLPTR;
1157     }
1158     float density = GetVirtualPixelRatio(displayInfo);
1159     if (!MathHelper::NearZero(virtualPixelRatio_ - density) ||
1160         !MathHelper::NearZero(property_->GetLastLimitsVpr() - density)) {
1161         UpdateDensityInner(displayInfo);
1162     }
1163 
1164     WMError ret = UpdateAnimationFlagProperty(withAnimation);
1165     if (ret != WMError::WM_OK) {
1166         TLOGE(WmsLogTag::WMS_LIFE, "Window show failed, UpdateProperty failed, ret: %{public}d, name: %{public}s"
1167             ", id: %{public}d", static_cast<int32_t>(ret), property_->GetWindowName().c_str(), GetPersistentId());
1168         return ret;
1169     }
1170     UpdateTitleButtonVisibility();
1171     property_->SetFocusableOnShow(withFocus);
1172     if (WindowHelper::IsMainWindow(type)) {
1173         ret = static_cast<WMError>(hostSession->Foreground(property_, true, identityToken_));
1174     } else if (WindowHelper::IsSubWindow(type) || WindowHelper::IsSystemWindow(type)) {
1175         PreLayoutOnShow(type, displayInfo);
1176         // Add maintenance logs before the IPC process.
1177         TLOGI(WmsLogTag::WMS_LIFE, "Show session [name: %{public}s, id: %{public}d]",
1178             property_->GetWindowName().c_str(), GetPersistentId());
1179         ret = static_cast<WMError>(hostSession->Show(property_));
1180     } else {
1181         ret = WMError::WM_ERROR_INVALID_WINDOW;
1182     }
1183     if (ret == WMError::WM_OK) {
1184         // update sub window state
1185         UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_SHOWN);
1186         state_ = WindowState::STATE_SHOWN;
1187         requestState_ = WindowState::STATE_SHOWN;
1188         NotifyAfterForeground(true, WindowHelper::IsMainWindow(type));
1189         RefreshNoInteractionTimeoutMonitor();
1190         TLOGI(WmsLogTag::WMS_LIFE, "Window show success [name:%{public}s, id:%{public}d, type:%{public}u]",
1191             property_->GetWindowName().c_str(), GetPersistentId(), type);
1192     } else {
1193         NotifyForegroundFailed(ret);
1194         TLOGI(WmsLogTag::WMS_LIFE, "Window show failed with errcode: %{public}d, name:%{public}s, id:%{public}d",
1195             static_cast<int32_t>(ret), property_->GetWindowName().c_str(), GetPersistentId());
1196     }
1197     NotifyWindowStatusChange(GetMode());
1198     NotifyDisplayInfoChange(displayInfo);
1199     return ret;
1200 }
1201 
ShowKeyboard(KeyboardViewMode mode)1202 WMError WindowSceneSessionImpl::ShowKeyboard(KeyboardViewMode mode)
1203 {
1204     TLOGI(WmsLogTag::WMS_KEYBOARD, "Show keyboard with view mode: %{public}u", static_cast<uint32_t>(mode));
1205     if (mode >= KeyboardViewMode::VIEW_MODE_END) {
1206         TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid view mode: %{public}u. Use default view mode",
1207             static_cast<uint32_t>(mode));
1208         mode = KeyboardViewMode::NON_IMMERSIVE_MODE;
1209     }
1210     property_->SetKeyboardViewMode(mode);
1211     return Show();
1212 }
1213 
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)1214 WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
1215 {
1216     auto hostSession = GetHostSession();
1217     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1218     if (property_ == nullptr) {
1219         TLOGE(WmsLogTag::WMS_LIFE, "Window hide failed, because of nullptr, id: %{public}d", GetPersistentId());
1220         return WMError::WM_ERROR_NULLPTR;
1221     }
1222     const auto& type = GetType();
1223     TLOGI(WmsLogTag::WMS_LIFE, "Window hide [id:%{public}d, type: %{public}d, reason:%{public}u, state:%{public}u, "
1224         "requestState:%{public}u", GetPersistentId(), type, reason, state_, requestState_);
1225     if (IsWindowSessionInvalid()) {
1226         TLOGI(WmsLogTag::WMS_LIFE, "session is invalid, id:%{public}d", GetPersistentId());
1227         return WMError::WM_ERROR_INVALID_WINDOW;
1228     }
1229 
1230     WindowState validState = state_;
1231     if (WindowHelper::IsSubWindow(type) || WindowHelper::IsDialogWindow(type)) {
1232         validState = requestState_;
1233     }
1234     if (validState == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
1235         TLOGD(WmsLogTag::WMS_LIFE, "window session is alreay hidden, id:%{public}d", property_->GetPersistentId());
1236         NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
1237         return WMError::WM_OK;
1238     }
1239 
1240     WMError res = UpdateAnimationFlagProperty(withAnimation);
1241     if (res != WMError::WM_OK) {
1242         TLOGE(WmsLogTag::WMS_LIFE, "UpdateProperty failed with errCode:%{public}d", static_cast<int32_t>(res));
1243         return res;
1244     }
1245 
1246     /*
1247      * main window no need to notify host, since host knows hide first
1248      * main window notify host temporarily, since host background may failed
1249      * need to SetActive(false) for host session before background
1250      */
1251 
1252     if (WindowHelper::IsMainWindow(type)) {
1253         res = static_cast<WMError>(SetActive(false));
1254         if (res != WMError::WM_OK) {
1255             return res;
1256         }
1257         res = static_cast<WMError>(hostSession->Background(true, identityToken_));
1258     } else if (WindowHelper::IsSubWindow(type) || WindowHelper::IsSystemWindow(type)) {
1259         res = static_cast<WMError>(hostSession->Hide());
1260     } else {
1261         res = WMError::WM_ERROR_INVALID_WINDOW;
1262     }
1263 
1264     if (res == WMError::WM_OK) {
1265         // update sub window state if this is main window
1266         UpdateSubWindowState(type);
1267         state_ = WindowState::STATE_HIDDEN;
1268         requestState_ = WindowState::STATE_HIDDEN;
1269         if (!interactive_) {
1270             hasFirstNotifyInteractive_ = false;
1271         }
1272     }
1273     uint32_t animationFlag = property_->GetAnimationFlag();
1274     if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
1275         animationTransitionController_->AnimationForHidden();
1276         RSTransaction::FlushImplicitTransaction();
1277     }
1278     NotifyWindowStatusChange(GetMode());
1279     escKeyEventTriggered_ = false;
1280     TLOGI(WmsLogTag::WMS_LIFE, "Window hide success [id:%{public}d, type: %{public}d",
1281         property_->GetPersistentId(), type);
1282     return res;
1283 }
1284 
NotifyDrawingCompleted()1285 WMError WindowSceneSessionImpl::NotifyDrawingCompleted()
1286 {
1287     if (IsWindowSessionInvalid()) {
1288         TLOGE(WmsLogTag::WMS_LIFE, "session is invalid, id:%{public}d", GetPersistentId());
1289         return WMError::WM_ERROR_INVALID_WINDOW;
1290     }
1291     const auto type = GetType();
1292     WMError res = WindowHelper::IsMainWindow(type) ?
1293                   static_cast<WMError>(hostSession_->DrawingCompleted()) :
1294                   WMError::WM_ERROR_INVALID_WINDOW;
1295     if (res == WMError::WM_OK) {
1296         TLOGI(WmsLogTag::WMS_LIFE, "success id:%{public}d, type:%{public}d",
1297             GetPersistentId(), type);
1298     }
1299     return res;
1300 }
1301 
NotifyRemoveStartingWindow()1302 WMError WindowSceneSessionImpl::NotifyRemoveStartingWindow()
1303 {
1304     if (IsWindowSessionInvalid()) {
1305         TLOGE(WmsLogTag::WMS_LIFE, "session is invalid, id:%{public}d", GetPersistentId());
1306         return WMError::WM_ERROR_INVALID_WINDOW;
1307     }
1308     auto hostSession = GetHostSession();
1309     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1310     WMError res = WindowHelper::IsMainWindow(GetType()) ?
1311                   static_cast<WMError>(hostSession->RemoveStartingWindow()) :
1312                   WMError::WM_ERROR_INVALID_WINDOW;
1313     if (res == WMError::WM_OK) {
1314         TLOGI(WmsLogTag::WMS_LIFE, "success id:%{public}d", GetPersistentId());
1315     }
1316     return res;
1317 }
1318 
UpdateSubWindowState(const WindowType & type)1319 void WindowSceneSessionImpl::UpdateSubWindowState(const WindowType& type)
1320 {
1321     UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_HIDDEN);
1322     if (WindowHelper::IsSubWindow(type)) {
1323         if (state_ == WindowState::STATE_SHOWN) {
1324             NotifyAfterBackground();
1325         }
1326     } else {
1327         NotifyAfterBackground();
1328     }
1329 }
1330 
PreProcessCreate()1331 void WindowSceneSessionImpl::PreProcessCreate()
1332 {
1333     SetDefaultProperty();
1334 }
1335 
SetDefaultProperty()1336 void WindowSceneSessionImpl::SetDefaultProperty()
1337 {
1338     switch (property_->GetWindowType()) {
1339         case WindowType::WINDOW_TYPE_TOAST:
1340         case WindowType::WINDOW_TYPE_FLOAT:
1341         case WindowType::WINDOW_TYPE_SYSTEM_FLOAT:
1342         case WindowType::WINDOW_TYPE_FLOAT_CAMERA:
1343         case WindowType::WINDOW_TYPE_VOICE_INTERACTION:
1344         case WindowType::WINDOW_TYPE_SEARCHING_BAR:
1345         case WindowType::WINDOW_TYPE_SCREENSHOT:
1346         case WindowType::WINDOW_TYPE_GLOBAL_SEARCH:
1347         case WindowType::WINDOW_TYPE_DIALOG:
1348         case WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW:
1349         case WindowType::WINDOW_TYPE_PANEL:
1350         case WindowType::WINDOW_TYPE_LAUNCHER_DOCK:
1351         case WindowType::WINDOW_TYPE_WALLET_SWIPE_CARD: {
1352             property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1353             break;
1354         }
1355         case WindowType::WINDOW_TYPE_VOLUME_OVERLAY:
1356         case WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT:
1357         case WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR:
1358         case WindowType::WINDOW_TYPE_DOCK_SLICE:
1359         case WindowType::WINDOW_TYPE_STATUS_BAR:
1360         case WindowType::WINDOW_TYPE_NAVIGATION_BAR:
1361         case WindowType::WINDOW_TYPE_FLOAT_NAVIGATION: {
1362             property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1363             property_->SetFocusable(false);
1364             break;
1365         }
1366         case WindowType::WINDOW_TYPE_SYSTEM_TOAST: {
1367             property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1368             property_->SetTouchable(false);
1369             property_->SetFocusable(false);
1370             break;
1371         }
1372         case WindowType::WINDOW_TYPE_POINTER: {
1373             property_->SetFocusable(false);
1374             break;
1375         }
1376         case WindowType::WINDOW_TYPE_SCREEN_CONTROL: {
1377             property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1378             property_->SetTouchable(false);
1379             property_->SetFocusable(false);
1380             SetAlpha(0);
1381             break;
1382         }
1383         default:
1384             break;
1385     }
1386 }
1387 
DestroyInner(bool needNotifyServer)1388 WMError WindowSceneSessionImpl::DestroyInner(bool needNotifyServer)
1389 {
1390     WMError ret = WMError::WM_OK;
1391     if (!WindowHelper::IsMainWindow(GetType()) && needNotifyServer) {
1392         if (WindowHelper::IsSystemWindow(GetType())) {
1393             // main window no need to notify host, since host knows hide first
1394             ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1395         } else if (WindowHelper::IsSubWindow(GetType()) && (property_->GetExtensionFlag() == false)) {
1396             auto parentSession = FindParentSessionByParentId(GetParentId());
1397             if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
1398                 return WMError::WM_ERROR_NULLPTR;
1399             }
1400             ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1401         } else if (property_->GetExtensionFlag() == true) {
1402             ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1403         }
1404     }
1405     if (ret != WMError::WM_OK) {
1406         TLOGE(WmsLogTag::WMS_LIFE, "DestroyInner fail, ret:%{public}d", ret);
1407         return ret;
1408     }
1409 
1410     if (WindowHelper::IsMainWindow(GetType())) {
1411         if (auto hostSession = GetHostSession()) {
1412             ret = static_cast<WMError>(hostSession->Disconnect(true, identityToken_));
1413         }
1414     }
1415     return ret;
1416 }
1417 
SyncDestroyAndDisconnectSpecificSession(int32_t persistentId)1418 WMError WindowSceneSessionImpl::SyncDestroyAndDisconnectSpecificSession(int32_t persistentId)
1419 {
1420     WMError ret = WMError::WM_OK;
1421     if (SysCapUtil::GetBundleName() == AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
1422         TLOGI(WmsLogTag::WMS_LIFE, "Destroy window is scb window");
1423         ret = SingletonContainer::Get<WindowAdapter>().DestroyAndDisconnectSpecificSession(persistentId);
1424         return ret;
1425     }
1426     sptr<PatternDetachCallback> callback = new PatternDetachCallback();
1427     ret = SingletonContainer::Get<WindowAdapter>().DestroyAndDisconnectSpecificSessionWithDetachCallback(persistentId,
1428         callback->AsObject());
1429     if (ret != WMError::WM_OK) {
1430         return ret;
1431     }
1432     auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1433         std::chrono::system_clock::now().time_since_epoch()).count();
1434     callback->GetResult(WINDOW_DETACH_TIMEOUT);
1435     auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1436         std::chrono::system_clock::now().time_since_epoch()).count();
1437     auto waitTime = endTime - startTime;
1438     if (waitTime >= WINDOW_DETACH_TIMEOUT) {
1439         TLOGW(WmsLogTag::WMS_LIFE, "Destroy window timeout, persistentId:%{public}d", persistentId);
1440         callback->GetResult(std::numeric_limits<int>::max());
1441     }
1442     TLOGI(WmsLogTag::WMS_LIFE, "Destroy window persistentId:%{public}d waitTime:%{public}lld", persistentId, waitTime);
1443     return ret;
1444 }
1445 
Destroy(bool needNotifyServer,bool needClearListener)1446 WMError WindowSceneSessionImpl::Destroy(bool needNotifyServer, bool needClearListener)
1447 {
1448     if (property_ == nullptr) {
1449         TLOGE(WmsLogTag::WMS_LIFE, "Window destroy failed, property is nullptr");
1450         return WMError::WM_ERROR_NULLPTR;
1451     }
1452     TLOGI(WmsLogTag::WMS_LIFE, "Destroy start, id: %{public}d, state_:%{public}u, needNotifyServer: %{public}d, "
1453         "needClearListener: %{public}d", GetPersistentId(), state_, needNotifyServer, needClearListener);
1454     InputTransferStation::GetInstance().RemoveInputWindow(GetPersistentId());
1455     if (IsWindowSessionInvalid()) {
1456         TLOGE(WmsLogTag::WMS_LIFE, "session is invalid, id: %{public}d", GetPersistentId());
1457         return WMError::WM_ERROR_INVALID_WINDOW;
1458     }
1459     SingletonContainer::Get<WindowAdapter>().UnregisterSessionRecoverCallbackFunc(property_->GetPersistentId());
1460     auto ret = DestroyInner(needNotifyServer);
1461     if (ret != WMError::WM_OK && ret != WMError::WM_ERROR_NULLPTR) { // nullptr means no session in server
1462         WLOGFW("[WMSLife] Destroy window failed, id: %{public}d", GetPersistentId());
1463         return ret;
1464     }
1465 
1466     // delete after replace WSError with WMError
1467     NotifyBeforeDestroy(GetWindowName());
1468     {
1469         std::lock_guard<std::recursive_mutex> lock(mutex_);
1470         state_ = WindowState::STATE_DESTROYED;
1471         requestState_ = WindowState::STATE_DESTROYED;
1472     }
1473 
1474     DestroySubWindow();
1475     {
1476         std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
1477         windowSessionMap_.erase(property_->GetWindowName());
1478     }
1479     {
1480         std::lock_guard<std::mutex> lock(hostSessionMutex_);
1481         hostSession_ = nullptr;
1482     }
1483     NotifyAfterDestroy();
1484     if (needClearListener) {
1485         ClearListenersById(GetPersistentId());
1486     }
1487     if (context_) {
1488         context_.reset();
1489     }
1490     ClearVsyncStation();
1491     SetUIContentComplete();
1492     surfaceNode_ = nullptr;
1493     TLOGI(WmsLogTag::WMS_LIFE, "Destroy success, id: %{public}d", property_->GetPersistentId());
1494     return WMError::WM_OK;
1495 }
1496 
MoveTo(int32_t x,int32_t y,bool isMoveToGlobal)1497 WMError WindowSceneSessionImpl::MoveTo(int32_t x, int32_t y, bool isMoveToGlobal)
1498 {
1499     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
1500     if (IsWindowSessionInvalid()) {
1501         return WMError::WM_ERROR_INVALID_WINDOW;
1502     }
1503     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1504         TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
1505         return WMError::WM_ERROR_INVALID_OPERATION;
1506     }
1507     const auto& windowRect = GetRect();
1508     const auto& requestRect = GetRequestRect();
1509     if (WindowHelper::IsSubWindow(GetType())) {
1510         auto mainWindow = FindMainWindowWithContext();
1511         if (mainWindow != nullptr && (mainWindow->GetMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
1512                                       mainWindow->GetMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
1513             if (requestRect.posX_ == x && requestRect.posY_ == y) {
1514                 TLOGW(WmsLogTag::WMS_LAYOUT, "Request same position in multiWindow will not update");
1515                 return WMError::WM_OK;
1516             }
1517         }
1518     }
1519     Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
1520     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
1521         "[%{public}d, %{public}d, %{public}d, %{public}d], windowRect: [%{public}d, %{public}d, "
1522         "%{public}d, %{public}d], newRect: [%{public}d, %{public}d, %{public}d, %{public}d]",
1523         property_->GetPersistentId(), state_, GetType(), GetMode(), requestRect.posX_, requestRect.posY_,
1524         requestRect.width_, requestRect.height_, windowRect.posX_, windowRect.posY_,
1525         windowRect.width_, windowRect.height_, newRect.posX_, newRect.posY_,
1526         newRect.width_, newRect.height_);
1527 
1528     property_->SetRequestRect(newRect);
1529 
1530     WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
1531     auto hostSession = GetHostSession();
1532     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1533     auto ret = hostSession->UpdateSessionRect(wsRect, SizeChangeReason::MOVE, isMoveToGlobal);
1534     return static_cast<WMError>(ret);
1535 }
1536 
MoveToAsync(int32_t x,int32_t y)1537 WMError WindowSceneSessionImpl::MoveToAsync(int32_t x, int32_t y)
1538 {
1539     if (IsWindowSessionInvalid()) {
1540         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
1541         return WMError::WM_ERROR_INVALID_WINDOW;
1542     }
1543 
1544     if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
1545         TLOGW(WmsLogTag::WMS_LAYOUT, "window should not move, winId:%{public}u, mode:%{public}u",
1546             GetWindowId(), GetMode());
1547         return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
1548     }
1549     auto ret = MoveTo(x, y);
1550     if (state_ == WindowState::STATE_SHOWN) {
1551         layoutCallback_->ResetMoveToLock();
1552         auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1553             std::chrono::system_clock::now().time_since_epoch()).count();
1554         layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
1555         auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1556             std::chrono::system_clock::now().time_since_epoch()).count();
1557         auto waitTime = endTime - startTime;
1558         if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
1559             TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
1560             layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
1561         }
1562     }
1563     return static_cast<WMError>(ret);
1564 }
1565 
MoveWindowToGlobal(int32_t x,int32_t y)1566 WMError WindowSceneSessionImpl::MoveWindowToGlobal(int32_t x, int32_t y)
1567 {
1568     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
1569     if (IsWindowSessionInvalid()) {
1570         return WMError::WM_ERROR_INVALID_WINDOW;
1571     }
1572 
1573     if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
1574         TLOGW(WmsLogTag::WMS_LAYOUT, "window should not move, winId:%{public}u, mode:%{public}u",
1575             GetWindowId(), GetMode());
1576         return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
1577     }
1578 
1579     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1580         TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
1581         return WMError::WM_ERROR_INVALID_OPERATION;
1582     }
1583     const auto& windowRect = GetRect();
1584     const auto& requestRect = GetRequestRect();
1585     Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
1586     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
1587         "[%{public}d, %{public}d, %{public}d, %{public}d], windowRect: [%{public}d, %{public}d, "
1588         "%{public}d, %{public}d], newRect: [%{public}d, %{public}d, %{public}d, %{public}d]",
1589         property_->GetPersistentId(), state_, GetType(), GetMode(), requestRect.posX_, requestRect.posY_,
1590         requestRect.width_, requestRect.height_, windowRect.posX_, windowRect.posY_,
1591         windowRect.width_, windowRect.height_, newRect.posX_, newRect.posY_,
1592         newRect.width_, newRect.height_);
1593 
1594     property_->SetRequestRect(newRect);
1595 
1596     WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
1597     auto hostSession = GetHostSession();
1598     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1599     auto ret = hostSession->UpdateSessionRect(wsRect, SizeChangeReason::MOVE, false, true);
1600     if (state_ == WindowState::STATE_SHOWN) {
1601         layoutCallback_->ResetMoveToLock();
1602         auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1603             std::chrono::system_clock::now().time_since_epoch()).count();
1604         layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
1605         auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1606             std::chrono::system_clock::now().time_since_epoch()).count();
1607         auto waitTime = endTime - startTime;
1608         if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
1609             TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
1610             layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
1611         }
1612     }
1613     return static_cast<WMError>(ret);
1614 }
1615 
GetGlobalScaledRect(Rect & globalScaledRect)1616 WMError WindowSceneSessionImpl::GetGlobalScaledRect(Rect& globalScaledRect)
1617 {
1618     if (IsWindowSessionInvalid()) {
1619         TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
1620         return WMError::WM_ERROR_INVALID_WINDOW;
1621     }
1622     auto hostSession = GetHostSession();
1623     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1624     auto ret = hostSession->GetGlobalScaledRect(globalScaledRect);
1625     return static_cast<WMError>(ret);
1626 }
1627 
LimitCameraFloatWindowMininumSize(uint32_t & width,uint32_t & height,float & vpr)1628 void WindowSceneSessionImpl::LimitCameraFloatWindowMininumSize(uint32_t& width, uint32_t& height, float& vpr)
1629 {
1630     // Float camera window has a special limit:
1631     // if display sw <= 600dp, portrait: min width = display sw * 30%, landscape: min width = sw * 50%
1632     // if display sw > 600dp, portrait: min width = display sw * 12%, landscape: min width = sw * 30%
1633     if (GetType() != WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
1634         return;
1635     }
1636 
1637     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
1638     if (display == nullptr) {
1639         WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
1640         return;
1641     }
1642     auto displayInfo = display->GetDisplayInfo();
1643     if (displayInfo == nullptr) {
1644         WLOGFE("get displayInfo failed displayId:%{public}" PRIu64, property_->GetDisplayId());
1645         return;
1646     }
1647     uint32_t displayWidth = static_cast<uint32_t>(display->GetWidth());
1648     uint32_t displayHeight = static_cast<uint32_t>(display->GetHeight());
1649     if (displayWidth == 0 || displayHeight == 0) {
1650         return;
1651     }
1652     vpr = GetVirtualPixelRatio(displayInfo);
1653     uint32_t smallWidth = displayHeight <= displayWidth ? displayHeight : displayWidth;
1654     float hwRatio = static_cast<float>(displayHeight) / static_cast<float>(displayWidth);
1655     uint32_t minWidth;
1656     if (smallWidth <= static_cast<uint32_t>(600 * vpr)) { // sw <= 600dp
1657         if (displayWidth <= displayHeight) {
1658             minWidth = static_cast<uint32_t>(smallWidth * 0.3); // ratio : 0.3
1659         } else {
1660             minWidth = static_cast<uint32_t>(smallWidth * 0.5); // ratio : 0.5
1661         }
1662     } else {
1663         if (displayWidth <= displayHeight) {
1664             minWidth = static_cast<uint32_t>(smallWidth * 0.12); // ratio : 0.12
1665         } else {
1666             minWidth = static_cast<uint32_t>(smallWidth * 0.3); // ratio : 0.3
1667         }
1668     }
1669     width = (width < minWidth) ? minWidth : width;
1670     height = static_cast<uint32_t>(width * hwRatio);
1671 }
1672 
UpdateFloatingWindowSizeBySizeLimits(uint32_t & width,uint32_t & height) const1673 void WindowSceneSessionImpl::UpdateFloatingWindowSizeBySizeLimits(uint32_t& width, uint32_t& height) const
1674 {
1675     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
1676         TLOGD(WmsLogTag::WMS_LAYOUT, "float camera type window");
1677         return;
1678     }
1679     // get new limit config with the settings of system and app
1680     const auto& sizeLimits = property_->GetWindowLimits();
1681     // limit minimum size of floating (not system type) window
1682     if ((!WindowHelper::IsSystemWindow(property_->GetWindowType())) ||
1683         (property_->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG)) {
1684         width = std::max(sizeLimits.minWidth_, width);
1685         height = std::max(sizeLimits.minHeight_, height);
1686     }
1687     width = std::min(sizeLimits.maxWidth_, width);
1688     height = std::min(sizeLimits.maxHeight_, height);
1689     if (height == 0) {
1690         return;
1691     }
1692     float curRatio = static_cast<float>(width) / static_cast<float>(height);
1693     // there is no need to fix size by ratio if this is not main floating window
1694     if (!WindowHelper::IsMainFloatingWindow(property_->GetWindowType(), GetMode()) ||
1695         (!MathHelper::GreatNotEqual(sizeLimits.minRatio_, curRatio) &&
1696          !MathHelper::GreatNotEqual(curRatio, sizeLimits.maxRatio_))) {
1697         return;
1698     }
1699 
1700     float newRatio = curRatio < sizeLimits.minRatio_ ? sizeLimits.minRatio_ : sizeLimits.maxRatio_;
1701     if (MathHelper::NearZero(newRatio)) {
1702         return;
1703     }
1704     if (sizeLimits.maxWidth_ == sizeLimits.minWidth_) {
1705         height = static_cast<uint32_t>(static_cast<float>(width) / newRatio);
1706         return;
1707     }
1708     if (sizeLimits.maxHeight_ == sizeLimits.minHeight_) {
1709         width = static_cast<uint32_t>(static_cast<float>(height) * newRatio);
1710         return;
1711     }
1712     WLOGFD("After limit by customize config: %{public}u %{public}u", width, height);
1713 }
1714 
LimitWindowSize(uint32_t & width,uint32_t & height)1715 void WindowSceneSessionImpl::LimitWindowSize(uint32_t& width, uint32_t& height)
1716 {
1717     float vpr = 0.0f;
1718 
1719     // Float camera window has special limits
1720     LimitCameraFloatWindowMininumSize(width, height, vpr);
1721 
1722     if (!MathHelper::NearZero(vpr) || !MathHelper::NearZero(property_->GetLastLimitsVpr() - vpr)) {
1723         UpdateWindowSizeLimits();
1724     }
1725     UpdateFloatingWindowSizeBySizeLimits(width, height);
1726 }
1727 
Resize(uint32_t width,uint32_t height)1728 WMError WindowSceneSessionImpl::Resize(uint32_t width, uint32_t height)
1729 {
1730     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d resize %{public}u %{public}u",
1731         property_->GetPersistentId(), width, height);
1732     if (IsWindowSessionInvalid()) {
1733         return WMError::WM_ERROR_INVALID_WINDOW;
1734     }
1735     if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1736         TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
1737         return WMError::WM_ERROR_INVALID_OPERATION;
1738     }
1739     if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
1740         TLOGW(WmsLogTag::WMS_LAYOUT, "Fullscreen window could not resize, winId: %{public}u", GetWindowId());
1741         return WMError::WM_ERROR_INVALID_OPERATION;
1742     }
1743 
1744     LimitWindowSize(width, height);
1745 
1746     const auto& windowRect = GetRect();
1747     const auto& requestRect = GetRequestRect();
1748 
1749     if (WindowHelper::IsSubWindow(GetType())) {
1750         auto mainWindow = FindMainWindowWithContext();
1751         if (mainWindow != nullptr && (mainWindow->GetMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
1752                                       mainWindow->GetMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
1753             if (width == requestRect.width_ && height == requestRect.height_) {
1754                 TLOGW(WmsLogTag::WMS_LAYOUT, "Request same size in multiWindow will not update, return");
1755                 return WMError::WM_OK;
1756             }
1757         }
1758     }
1759 
1760     Rect newRect = { requestRect.posX_, requestRect.posY_, width, height }; // must keep w/h
1761     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
1762         "[%{public}d, %{public}d, %{public}d, %{public}d], windowRect: [%{public}d, %{public}d, "
1763         "%{public}d, %{public}d], newRect: [%{public}d, %{public}d, %{public}d, %{public}d]",
1764         property_->GetPersistentId(), state_, GetType(), GetMode(), requestRect.posX_, requestRect.posY_,
1765         requestRect.width_, requestRect.height_, windowRect.posX_, windowRect.posY_,
1766         windowRect.width_, windowRect.height_, newRect.posX_, newRect.posY_,
1767         newRect.width_, newRect.height_);
1768 
1769     property_->SetRequestRect(newRect);
1770 
1771     WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
1772     auto hostSession = GetHostSession();
1773     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1774     auto ret = hostSession->UpdateSessionRect(wsRect, SizeChangeReason::RESIZE);
1775     return static_cast<WMError>(ret);
1776 }
1777 
ResizeAsync(uint32_t width,uint32_t height)1778 WMError WindowSceneSessionImpl::ResizeAsync(uint32_t width, uint32_t height)
1779 {
1780     if (IsWindowSessionInvalid()) {
1781         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
1782         return WMError::WM_ERROR_INVALID_WINDOW;
1783     }
1784 
1785     if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
1786         TLOGW(WmsLogTag::WMS_LAYOUT, "window should not resize, winId:%{public}u, mode:%{public}u",
1787             GetWindowId(), GetMode());
1788         return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
1789     }
1790     auto ret = Resize(width, height);
1791     if (state_ == WindowState::STATE_SHOWN) {
1792         layoutCallback_->ResetResizeLock();
1793         auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1794             std::chrono::system_clock::now().time_since_epoch()).count();
1795         layoutCallback_->GetResizeAsyncResult(WINDOW_LAYOUT_TIMEOUT);
1796         auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1797             std::chrono::system_clock::now().time_since_epoch()).count();
1798         auto waitTime = endTime - startTime;
1799         if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
1800             TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
1801             layoutCallback_->GetResizeAsyncResult(WINDOW_LAYOUT_TIMEOUT);
1802         }
1803     }
1804     return static_cast<WMError>(ret);
1805 }
1806 
SetAspectRatio(float ratio)1807 WMError WindowSceneSessionImpl::SetAspectRatio(float ratio)
1808 {
1809     if (IsWindowSessionInvalid()) {
1810         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
1811         return WMError::WM_ERROR_INVALID_WINDOW;
1812     }
1813 
1814     auto hostSession = GetHostSession();
1815     if (property_ == nullptr || hostSession == nullptr) {
1816         WLOGFE("SetAspectRatio failed, because of nullptr");
1817         return WMError::WM_ERROR_NULLPTR;
1818     }
1819     if (ratio == MathHelper::INF || ratio == MathHelper::NAG_INF || std::isnan(ratio) || MathHelper::NearZero(ratio)) {
1820         WLOGFE("SetAspectRatio failed, because of wrong value: %{public}f", ratio);
1821         return WMError::WM_ERROR_INVALID_PARAM;
1822     }
1823     if (hostSession->SetAspectRatio(ratio) != WSError::WS_OK) {
1824         return WMError::WM_ERROR_INVALID_PARAM;
1825     }
1826     return WMError::WM_OK;
1827 }
1828 
ResetAspectRatio()1829 WMError WindowSceneSessionImpl::ResetAspectRatio()
1830 {
1831     auto hostSession = GetHostSession();
1832     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1833     return static_cast<WMError>(hostSession->SetAspectRatio(0.0f));
1834 }
1835 
1836 /** @note @window.hierarchy */
RaiseToAppTop()1837 WMError WindowSceneSessionImpl::RaiseToAppTop()
1838 {
1839     if (IsWindowSessionInvalid()) {
1840         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
1841         return WMError::WM_ERROR_INVALID_WINDOW;
1842     }
1843 
1844     WLOGFI("[WMSCom] id: %{public}d", GetPersistentId());
1845     auto parentId = GetParentId();
1846     if (parentId == INVALID_SESSION_ID) {
1847         WLOGFE("Only the children of the main window can be raised!");
1848         return WMError::WM_ERROR_INVALID_PARENT;
1849     }
1850 
1851     if (!WindowHelper::IsSubWindow(GetType())) {
1852         WLOGFE("Must be app sub window window!");
1853         return WMError::WM_ERROR_INVALID_CALLING;
1854     }
1855 
1856     if (state_ != WindowState::STATE_SHOWN) {
1857         WLOGFE("The sub window must be shown!");
1858         return WMError::WM_DO_NOTHING;
1859     }
1860     auto hostSession = GetHostSession();
1861     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1862     const WSError ret = hostSession->RaiseToAppTop();
1863     return static_cast<WMError>(ret);
1864 }
1865 
1866 /** @note @window.hierarchy */
RaiseAboveTarget(int32_t subWindowId)1867 WMError WindowSceneSessionImpl::RaiseAboveTarget(int32_t subWindowId)
1868 {
1869     if (IsWindowSessionInvalid()) {
1870         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
1871         return WMError::WM_ERROR_INVALID_WINDOW;
1872     }
1873 
1874     auto parentId = GetParentId();
1875     auto currentWindowId = GetWindowId();
1876 
1877     if (parentId == INVALID_SESSION_ID) {
1878         WLOGFE("Only the children of the main window can be raised!");
1879         return WMError::WM_ERROR_INVALID_PARENT;
1880     }
1881 
1882     auto subWindows = Window::GetSubWindow(parentId);
1883     auto targetWindow = find_if(subWindows.begin(), subWindows.end(), [subWindowId](sptr<Window>& window) {
1884         return static_cast<uint32_t>(subWindowId) == window->GetWindowId();
1885     });
1886     if (targetWindow == subWindows.end()) {
1887         return WMError::WM_ERROR_INVALID_PARAM;
1888     }
1889 
1890     if (!WindowHelper::IsSubWindow(GetType())) {
1891         WLOGFE("Must be app sub window window!");
1892         return WMError::WM_ERROR_INVALID_CALLING;
1893     }
1894 
1895     if ((state_ != WindowState::STATE_SHOWN) ||
1896         ((*targetWindow)->GetWindowState() != WindowState::STATE_SHOWN)) {
1897         WLOGFE("The sub window must be shown!");
1898         return WMError::WM_DO_NOTHING;
1899     }
1900     if (currentWindowId == static_cast<uint32_t>(subWindowId)) {
1901         return WMError::WM_OK;
1902     }
1903     auto hostSession = GetHostSession();
1904     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1905     WSError ret = hostSession->RaiseAboveTarget(subWindowId);
1906     return static_cast<WMError>(ret);
1907 }
1908 
GetAvoidAreaByType(AvoidAreaType type,AvoidArea & avoidArea)1909 WMError WindowSceneSessionImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea)
1910 {
1911     if (IsWindowSessionInvalid()) {
1912         return WMError::WM_ERROR_INVALID_WINDOW;
1913     }
1914     auto hostSession = GetHostSession();
1915     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1916     avoidArea = hostSession->GetAvoidAreaByType(type);
1917     getAvoidAreaCnt_++;
1918     TLOGI(WmsLogTag::WMS_IMMS, "Window [%{public}u, %{public}s] type %{public}d times %{public}u area %{public}s",
1919           GetWindowId(), GetWindowName().c_str(), type, getAvoidAreaCnt_.load(), avoidArea.ToString().c_str());
1920     return WMError::WM_OK;
1921 }
1922 
NotifyWindowNeedAvoid(bool status)1923 WMError WindowSceneSessionImpl::NotifyWindowNeedAvoid(bool status)
1924 {
1925     TLOGD(WmsLogTag::WMS_IMMS, "NotifyWindowNeedAvoid called windowId:%{public}u status:%{public}d",
1926         GetWindowId(), static_cast<int32_t>(status));
1927     if (IsWindowSessionInvalid()) {
1928         TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
1929         return WMError::WM_ERROR_INVALID_WINDOW;
1930     }
1931     auto hostSession = GetHostSession();
1932     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1933     hostSession->OnNeedAvoid(status);
1934     return WMError::WM_OK;
1935 }
1936 
SetLayoutFullScreenByApiVersion(bool status)1937 WMError WindowSceneSessionImpl::SetLayoutFullScreenByApiVersion(bool status)
1938 {
1939     if (IsWindowSessionInvalid()) {
1940         TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
1941         return WMError::WM_ERROR_INVALID_WINDOW;
1942     }
1943     uint32_t version = 0;
1944     if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
1945         version = context_->GetApplicationInfo()->apiCompatibleVersion;
1946     }
1947     isIgnoreSafeArea_ = status;
1948     isIgnoreSafeAreaNeedNotify_ = true;
1949     // 10 ArkUI new framework support after API10
1950     if (version >= 10) {
1951         TLOGI(WmsLogTag::WMS_IMMS, "SetIgnoreViewSafeArea winId:%{public}u status:%{public}d",
1952             GetWindowId(), static_cast<int32_t>(status));
1953         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1954         if (uiContent != nullptr) {
1955             uiContent->SetIgnoreViewSafeArea(status);
1956         }
1957     } else {
1958         TLOGI(WmsLogTag::WMS_IMMS, "SetWindowNeedAvoidFlag winId:%{public}u status:%{public}d",
1959             GetWindowId(), static_cast<int32_t>(status));
1960         WMError ret = WMError::WM_OK;
1961         if (status) {
1962             ret = RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
1963             if (ret != WMError::WM_OK) {
1964                 TLOGE(WmsLogTag::WMS_IMMS, "RemoveWindowFlag errCode:%{public}d winId:%{public}u",
1965                     static_cast<int32_t>(ret), GetWindowId());
1966                 return ret;
1967             }
1968         } else {
1969             ret = AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
1970             if (ret != WMError::WM_OK) {
1971                 TLOGE(WmsLogTag::WMS_IMMS, "RemoveWindowFlag errCode:%{public}d winId:%{public}u",
1972                     static_cast<int32_t>(ret), GetWindowId());
1973                 return ret;
1974             }
1975         }
1976         ret = NotifyWindowNeedAvoid(!status);
1977         if (ret != WMError::WM_OK) {
1978             TLOGE(WmsLogTag::WMS_IMMS, "NotifyWindowNeedAvoid errCode:%{public}d winId:%{public}u",
1979                 static_cast<int32_t>(ret), GetWindowId());
1980             return ret;
1981         }
1982     }
1983     return WMError::WM_OK;
1984 }
1985 
SetLayoutFullScreen(bool status)1986 WMError WindowSceneSessionImpl::SetLayoutFullScreen(bool status)
1987 {
1988     TLOGI(WmsLogTag::WMS_IMMS, "winId:%{public}u %{public}s status:%{public}d",
1989         GetWindowId(), GetWindowName().c_str(), static_cast<int32_t>(status));
1990     if (IsWindowSessionInvalid()) {
1991         return WMError::WM_ERROR_INVALID_WINDOW;
1992     }
1993     if (WindowHelper::IsSystemWindow(GetType())) {
1994         TLOGI(WmsLogTag::WMS_IMMS, "system window is not supported");
1995         return WMError::WM_OK;
1996     }
1997 
1998     if ((windowSystemConfig_.uiType_ == UI_TYPE_PC || IsFreeMultiWindowMode()) && property_->GetCompatibleModeInPc()) {
1999         TLOGI(WmsLogTag::WMS_IMMS, "isCompatibleModeInPc, can not LayoutFullScreen");
2000         return WMError::WM_OK;
2001     }
2002 
2003     bool preStatus = property_->IsLayoutFullScreen();
2004     property_->SetIsLayoutFullScreen(status);
2005     auto hostSession = GetHostSession();
2006     if (hostSession != nullptr) {
2007         hostSession->OnLayoutFullScreenChange(status);
2008     }
2009 
2010     if (WindowHelper::IsMainWindow(GetType()) &&
2011         windowSystemConfig_.uiType_ != UI_TYPE_PHONE &&
2012         windowSystemConfig_.uiType_ != UI_TYPE_PAD) {
2013         if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
2014             WindowMode::WINDOW_MODE_FULLSCREEN)) {
2015             TLOGE(WmsLogTag::WMS_IMMS, "fullscreen window mode is not supported");
2016             return WMError::WM_ERROR_INVALID_WINDOW;
2017         }
2018         CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2019         hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
2020         SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
2021     }
2022 
2023     WMError ret = SetLayoutFullScreenByApiVersion(status);
2024     if (ret != WMError::WM_OK) {
2025         property_->SetIsLayoutFullScreen(preStatus);
2026         TLOGE(WmsLogTag::WMS_IMMS, "SetLayoutFullScreenByApiVersion errCode:%{public}d winId:%{public}u",
2027             static_cast<int32_t>(ret), GetWindowId());
2028     }
2029     enableImmersiveMode_ = status;
2030     return ret;
2031 }
2032 
SetTitleAndDockHoverShown(bool isTitleHoverShown,bool isDockHoverShown)2033 WMError WindowSceneSessionImpl::SetTitleAndDockHoverShown(
2034     bool isTitleHoverShown, bool isDockHoverShown)
2035 {
2036     if (IsWindowSessionInvalid()) {
2037         return WMError::WM_ERROR_INVALID_WINDOW;
2038     }
2039     TLOGI(WmsLogTag::WMS_IMMS, "winId:%{public}u %{public}s isTitleHoverShown:%{public}d, "
2040         "isDockHoverShown:%{public}d", GetWindowId(), GetWindowName().c_str(), isTitleHoverShown, isDockHoverShown);
2041     if (!WindowHelper::IsMainWindow(GetType())) {
2042         TLOGE(WmsLogTag::WMS_IMMS, "window is not main window");
2043         return WMError::WM_ERROR_INVALID_CALLING;
2044     }
2045     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
2046     if (!(isPC || IsFreeMultiWindowMode())) {
2047         TLOGE(WmsLogTag::DEFAULT, "The device is not supported");
2048         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2049     }
2050     titleHoverShowEnabled_ = isTitleHoverShown;
2051     dockHoverShowEnabled_ = isDockHoverShown;
2052     if (auto hostSession = GetHostSession()) {
2053         hostSession->OnTitleAndDockHoverShowChange(isTitleHoverShown, isDockHoverShown);
2054     }
2055     return WMError::WM_OK;
2056 }
2057 
IsLayoutFullScreen() const2058 bool WindowSceneSessionImpl::IsLayoutFullScreen() const
2059 {
2060     if (IsWindowSessionInvalid()) {
2061         return false;
2062     }
2063     WindowType winType = property_->GetWindowType();
2064     if (WindowHelper::IsMainWindow(winType)) {
2065         return (GetMode() == WindowMode::WINDOW_MODE_FULLSCREEN && isIgnoreSafeArea_);
2066     }
2067     if (WindowHelper::IsSubWindow(winType)) {
2068         return (isIgnoreSafeAreaNeedNotify_ && isIgnoreSafeArea_);
2069     }
2070     return false;
2071 }
2072 
GetSystemBarPropertyByType(WindowType type) const2073 SystemBarProperty WindowSceneSessionImpl::GetSystemBarPropertyByType(WindowType type) const
2074 {
2075     if (property_ == nullptr) {
2076         return SystemBarProperty();
2077     }
2078     auto curProperties = property_->GetSystemBarProperty();
2079     return curProperties[type];
2080 }
2081 
NotifyWindowSessionProperty()2082 WMError WindowSceneSessionImpl::NotifyWindowSessionProperty()
2083 {
2084     TLOGD(WmsLogTag::WMS_IMMS, "windowId:%{public}u", GetWindowId());
2085     if (IsWindowSessionInvalid()) {
2086         TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
2087         return WMError::WM_ERROR_INVALID_WINDOW;
2088     }
2089     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS);
2090     return WMError::WM_OK;
2091 }
2092 
NotifySpecificWindowSessionProperty(WindowType type,const SystemBarProperty & property)2093 WMError WindowSceneSessionImpl::NotifySpecificWindowSessionProperty(WindowType type, const SystemBarProperty& property)
2094 {
2095     TLOGD(WmsLogTag::WMS_IMMS, "windowId:%{public}u", GetWindowId());
2096     if (IsWindowSessionInvalid()) {
2097         TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
2098         return WMError::WM_ERROR_INVALID_WINDOW;
2099     }
2100     if (type == WindowType::WINDOW_TYPE_STATUS_BAR) {
2101         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS);
2102         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2103         if (uiContent != nullptr) {
2104             uiContent->SetStatusBarItemColor(property.contentColor_);
2105         }
2106     } else if (type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
2107         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS);
2108     } else if (type == WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR) {
2109         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS);
2110     }
2111     return WMError::WM_OK;
2112 }
2113 
SetSpecificBarProperty(WindowType type,const SystemBarProperty & property)2114 WMError WindowSceneSessionImpl::SetSpecificBarProperty(WindowType type, const SystemBarProperty& property)
2115 {
2116     if (IsWindowSessionInvalid()) {
2117         return WMError::WM_ERROR_INVALID_WINDOW;
2118     }
2119     if (!WindowHelper::IsMainWindow(GetType())) {
2120         TLOGI(WmsLogTag::WMS_IMMS, "only main window support");
2121         return WMError::WM_OK;
2122     }
2123     if (!((state_ > WindowState::STATE_INITIAL) && (state_ < WindowState::STATE_BOTTOM))) {
2124         TLOGE(WmsLogTag::WMS_IMMS, "windowId: %{public}u state is invalid", GetWindowId());
2125         return WMError::WM_ERROR_INVALID_WINDOW;
2126     } else if (GetSystemBarPropertyByType(type) == property &&
2127         property.settingFlag_ == SystemBarSettingFlag::DEFAULT_SETTING) {
2128         setSameSystembarPropertyCnt_++;
2129         TLOGI(WmsLogTag::WMS_IMMS, "windowId:%{public}u %{public}s set same property %{public}u times, "
2130             "type:%{public}u, enable:%{public}u bgColor:%{public}x Color:%{public}x enableAnim:%{public}u",
2131             GetWindowId(), GetWindowName().c_str(), setSameSystembarPropertyCnt_,
2132             static_cast<uint32_t>(type), property.enable_, property.backgroundColor_, property.contentColor_,
2133             property.enableAnimation_);
2134         return WMError::WM_OK;
2135     }
2136     setSameSystembarPropertyCnt_ = 0;
2137     TLOGI(WmsLogTag::WMS_IMMS, "windowId:%{public}u %{public}s type:%{public}u, "
2138         "%{public}u %{public}x %{public}x %{public}u %{public}u",
2139         GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type), property.enable_,
2140         property.backgroundColor_, property.contentColor_, property.enableAnimation_, property.settingFlag_);
2141 
2142     if (property_ == nullptr) {
2143         TLOGE(WmsLogTag::WMS_IMMS, "property_ is null!");
2144         return WMError::WM_ERROR_NULLPTR;
2145     }
2146     isSystembarPropertiesSet_ = true;
2147     property_->SetSystemBarProperty(type, property);
2148     WMError ret = NotifySpecificWindowSessionProperty(type, property);
2149     if (ret != WMError::WM_OK) {
2150         TLOGE(WmsLogTag::WMS_IMMS, "winId:%{public}u, errCode:%{public}d",
2151             GetWindowId(), static_cast<int32_t>(ret));
2152     }
2153     return ret;
2154 }
2155 
SetSystemBarProperty(WindowType type,const SystemBarProperty & property)2156 WMError WindowSceneSessionImpl::SetSystemBarProperty(WindowType type, const SystemBarProperty& property)
2157 {
2158     return SetSpecificBarProperty(type, property);
2159 }
2160 
SetSystemBarProperties(const std::map<WindowType,SystemBarProperty> & properties,const std::map<WindowType,SystemBarPropertyFlag> & propertyFlags)2161 WMError WindowSceneSessionImpl::SetSystemBarProperties(const std::map<WindowType, SystemBarProperty>& properties,
2162     const std::map<WindowType, SystemBarPropertyFlag>& propertyFlags)
2163 {
2164     SystemBarProperty current = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
2165     auto flagIter = propertyFlags.find(WindowType::WINDOW_TYPE_STATUS_BAR);
2166     auto propertyIter = properties.find(WindowType::WINDOW_TYPE_STATUS_BAR);
2167     if ((flagIter != propertyFlags.end() && flagIter->second.contentColorFlag) &&
2168         (propertyIter != properties.end() && current.contentColor_ != propertyIter->second.contentColor_)) {
2169         current.contentColor_ = propertyIter->second.contentColor_;
2170         current.settingFlag_ = static_cast<SystemBarSettingFlag>(
2171             static_cast<uint32_t>(propertyIter->second.settingFlag_) |
2172             static_cast<uint32_t>(SystemBarSettingFlag::COLOR_SETTING));
2173         TLOGI(WmsLogTag::WMS_IMMS,
2174             "windowId:%{public}u %{public}s set status bar content color %{public}u",
2175             GetWindowId(), GetWindowName().c_str(), current.contentColor_);
2176         return SetSpecificBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, current);
2177     }
2178     return WMError::WM_OK;
2179 }
2180 
GetSystemBarProperties(std::map<WindowType,SystemBarProperty> & properties)2181 WMError WindowSceneSessionImpl::GetSystemBarProperties(std::map<WindowType, SystemBarProperty>& properties)
2182 {
2183     TLOGI(WmsLogTag::WMS_IMMS, "windowId:%{public}u", GetWindowId());
2184     if (property_ != nullptr) {
2185         auto currProperties = property_->GetSystemBarProperty();
2186         properties[WindowType::WINDOW_TYPE_STATUS_BAR] = currProperties[WindowType::WINDOW_TYPE_STATUS_BAR];
2187     } else {
2188         TLOGW(WmsLogTag::WMS_IMMS, "inner property is null, windowId:%{public}u", GetWindowId());
2189     }
2190     return WMError::WM_OK;
2191 }
2192 
SetFullScreen(bool status)2193 WMError WindowSceneSessionImpl::SetFullScreen(bool status)
2194 {
2195     TLOGI(WmsLogTag::WMS_IMMS,
2196         "winId:%{public}u %{public}s status:%{public}d",
2197         GetWindowId(), GetWindowName().c_str(), static_cast<int32_t>(status));
2198     if (IsWindowSessionInvalid()) {
2199         return WMError::WM_ERROR_INVALID_WINDOW;
2200     }
2201     if (WindowHelper::IsSystemWindow(GetType())) {
2202         TLOGI(WmsLogTag::WMS_IMMS, "system window is not supported");
2203         return WMError::WM_OK;
2204     }
2205 
2206     if (WindowHelper::IsMainWindow(GetType()) || (IsFreeMultiWindowMode() &&
2207         windowSystemConfig_.uiType_ != UI_TYPE_PHONE && windowSystemConfig_.uiType_ != UI_TYPE_PAD)) {
2208         if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
2209             WindowMode::WINDOW_MODE_FULLSCREEN)) {
2210             TLOGE(WmsLogTag::WMS_IMMS, "fullscreen window mode is not supported");
2211             return WMError::WM_ERROR_INVALID_WINDOW;
2212         }
2213         auto hostSession = GetHostSession();
2214         CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2215         hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
2216         SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
2217     };
2218 
2219     WMError ret = SetLayoutFullScreenByApiVersion(status);
2220     if (ret != WMError::WM_OK) {
2221         TLOGE(WmsLogTag::WMS_IMMS, "SetLayoutFullScreenByApiVersion errCode:%{public}d winId:%{public}u",
2222             static_cast<int32_t>(ret), GetWindowId());
2223     }
2224 
2225     UpdateDecorEnable(true);
2226     SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
2227     statusProperty.enable_ = !status;
2228     ret = SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
2229     if (ret != WMError::WM_OK) {
2230         TLOGE(WmsLogTag::WMS_IMMS, "SetSystemBarProperty errCode:%{public}d winId:%{public}u",
2231             static_cast<int32_t>(ret), GetWindowId());
2232     }
2233 
2234     return ret;
2235 }
2236 
IsFullScreen() const2237 bool WindowSceneSessionImpl::IsFullScreen() const
2238 {
2239     SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
2240     return (IsLayoutFullScreen() && !statusProperty.enable_);
2241 }
2242 
IsDecorEnable() const2243 bool WindowSceneSessionImpl::IsDecorEnable() const
2244 {
2245     WindowType windowType = GetType();
2246     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
2247     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
2248     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
2249     bool isValidWindow = isMainWindow ||
2250         ((isSubWindow || isDialogWindow) && property_->IsDecorEnable());
2251     bool isWindowModeSupported = WindowHelper::IsWindowModeSupported(
2252         windowSystemConfig_.decorWindowModeSupportType_, GetMode());
2253     if (windowSystemConfig_.freeMultiWindowSupport_) {
2254         return isValidWindow && windowSystemConfig_.isSystemDecorEnable_;
2255     }
2256     bool enable = isValidWindow && windowSystemConfig_.isSystemDecorEnable_ &&
2257         isWindowModeSupported;
2258     if ((isSubWindow || isDialogWindow) && property_->GetIsPcAppInPad() && property_->IsDecorEnable()) {
2259         enable = true;
2260     }
2261     WLOGFD("get decor enable %{public}d", enable);
2262     return enable;
2263 }
2264 
SetWindowTitle(const std::string & title)2265 WMError WindowSceneSessionImpl::SetWindowTitle(const std::string& title)
2266 {
2267     if (IsWindowSessionInvalid()) {
2268         TLOGE(WmsLogTag::WMS_DECOR, "Session is invalid");
2269         return WMError::WM_ERROR_INVALID_WINDOW;
2270     }
2271     if (!(IsPcWindow() || windowSystemConfig_.uiType_ == UI_TYPE_PAD)) {
2272         TLOGE(WmsLogTag::WMS_DECOR, "device not support");
2273         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2274     }
2275     if (!IsDecorEnable()) {
2276         TLOGE(WmsLogTag::WMS_DECOR, "DecorEnable is false");
2277         return WMError::WM_ERROR_INVALID_WINDOW;
2278     }
2279     if (WindowHelper::IsMainWindow(GetType())) {
2280         auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
2281         if (abilityContext == nullptr) {
2282             return WMError::WM_ERROR_NULLPTR;
2283         }
2284         abilityContext->SetMissionLabel(title);
2285     } else {
2286         return SetAPPWindowLabel(title);
2287     }
2288     return WMError::WM_OK;
2289 }
2290 
Minimize()2291 WMError WindowSceneSessionImpl::Minimize()
2292 {
2293     WLOGFI("WindowSceneSessionImpl::Minimize id: %{public}d", GetPersistentId());
2294     if (IsWindowSessionInvalid()) {
2295         WLOGFE("session is invalid");
2296         return WMError::WM_ERROR_INVALID_WINDOW;
2297     }
2298     auto hostSession = GetHostSession();
2299     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2300     if (WindowHelper::IsMainWindow(GetType())) {
2301         hostSession->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
2302     } else {
2303         WLOGFE("This window state is abnormal.");
2304         return WMError::WM_DO_NOTHING;
2305     }
2306     return WMError::WM_OK;
2307 }
2308 
Maximize()2309 WMError WindowSceneSessionImpl::Maximize()
2310 {
2311     WLOGFI("WindowSceneSessionImpl::Maximize id: %{public}d", GetPersistentId());
2312     if (IsWindowSessionInvalid()) {
2313         WLOGFE("session is invalid");
2314         return WMError::WM_ERROR_INVALID_WINDOW;
2315     }
2316     if (WindowHelper::IsMainWindow(GetType())) {
2317         SetLayoutFullScreen(enableImmersiveMode_);
2318     }
2319     return WMError::WM_OK;
2320 }
2321 
Maximize(MaximizePresentation presentation)2322 WMError WindowSceneSessionImpl::Maximize(MaximizePresentation presentation)
2323 {
2324     if (IsWindowSessionInvalid()) {
2325         return WMError::WM_ERROR_INVALID_WINDOW;
2326     }
2327     if (!WindowHelper::IsMainWindow(GetType())) {
2328         TLOGE(WmsLogTag::WMS_LAYOUT, "maximize fail, not main window");
2329         return WMError::WM_ERROR_INVALID_CALLING;
2330     }
2331     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
2332         WindowMode::WINDOW_MODE_FULLSCREEN)) {
2333         return WMError::WM_ERROR_INVALID_WINDOW;
2334     }
2335     // The device is not supported
2336     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
2337     if (!isPC && !IsFreeMultiWindowMode()) {
2338         TLOGW(WmsLogTag::WMS_LAYOUT, "The device is not supported");
2339         return WMError::WM_OK;
2340     }
2341     if (property_ == nullptr || property_->GetCompatibleModeInPc()) {
2342         TLOGE(WmsLogTag::WMS_IMMS, "isCompatibleModeInPc, can not Maximize");
2343         return WMError::WM_ERROR_INVALID_WINDOW;
2344     }
2345     titleHoverShowEnabled_ = true;
2346     dockHoverShowEnabled_ = true;
2347     switch (presentation) {
2348         case MaximizePresentation::ENTER_IMMERSIVE:
2349             enableImmersiveMode_ = true;
2350             break;
2351         case MaximizePresentation::EXIT_IMMERSIVE:
2352             enableImmersiveMode_ = false;
2353             break;
2354         case MaximizePresentation::ENTER_IMMERSIVE_DISABLE_TITLE_AND_DOCK_HOVER:
2355             enableImmersiveMode_ = true;
2356             titleHoverShowEnabled_ = false;
2357             dockHoverShowEnabled_ = false;
2358             break;
2359         case MaximizePresentation::FOLLOW_APP_IMMERSIVE_SETTING:
2360             break;
2361     }
2362     property_->SetIsLayoutFullScreen(enableImmersiveMode_);
2363     auto hostSession = GetHostSession();
2364     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2365     hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
2366     hostSession->OnTitleAndDockHoverShowChange(titleHoverShowEnabled_, dockHoverShowEnabled_);
2367     SetLayoutFullScreenByApiVersion(enableImmersiveMode_);
2368     TLOGI(WmsLogTag::WMS_LAYOUT, "present: %{public}d, enableImmersiveMode_:%{public}d!",
2369         presentation, enableImmersiveMode_);
2370     hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
2371     return SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
2372 }
2373 
MaximizeFloating()2374 WMError WindowSceneSessionImpl::MaximizeFloating()
2375 {
2376     TLOGI(WmsLogTag::WMS_LAYOUT, "id: %{public}d", GetPersistentId());
2377     if (property_->GetCompatibleModeInPc() && !IsFreeMultiWindowMode()) {
2378         TLOGE(WmsLogTag::WMS_IMMS, "isCompatibleModeInPc, can not MaximizeFloating");
2379         return WMError::WM_ERROR_INVALID_WINDOW;
2380     }
2381 
2382     if (IsWindowSessionInvalid()) {
2383         WLOGFE("session is invalid");
2384         return WMError::WM_ERROR_INVALID_WINDOW;
2385     }
2386     if (!WindowHelper::IsMainWindow(property_->GetWindowType())) {
2387         WLOGFW("SetGlobalMaximizeMode fail, not main window");
2388         return WMError::WM_ERROR_INVALID_WINDOW;
2389     }
2390     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
2391         WindowMode::WINDOW_MODE_FULLSCREEN)) {
2392         return WMError::WM_ERROR_INVALID_WINDOW;
2393     }
2394     if (GetGlobalMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
2395         hostSession_->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
2396         SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
2397         UpdateDecorEnable(true);
2398         property_->SetMaximizeMode(MaximizeMode::MODE_FULL_FILL);
2399     } else {
2400         auto hostSession = GetHostSession();
2401         CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2402         hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE_FLOATING);
2403         SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
2404         property_->SetMaximizeMode(MaximizeMode::MODE_AVOID_SYSTEM_BAR);
2405         UpdateDecorEnable(true);
2406         NotifyWindowStatusChange(GetMode());
2407     }
2408     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
2409 
2410     return WMError::WM_OK;
2411 }
2412 
Recover()2413 WMError WindowSceneSessionImpl::Recover()
2414 {
2415     WLOGFI("WindowSceneSessionImpl::Recover id: %{public}d", GetPersistentId());
2416     if (IsWindowSessionInvalid()) {
2417         WLOGFE("session is invalid");
2418         return WMError::WM_ERROR_INVALID_WINDOW;
2419     }
2420     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING)) {
2421         TLOGE(WmsLogTag::WMS_LAYOUT, "not support floating, can not Recover");
2422         return WMError::WM_ERROR_INVALID_OPERATION;
2423     }
2424     auto hostSession = GetHostSession();
2425     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2426     if (WindowHelper::IsMainWindow(GetType())) {
2427         if (property_->GetMaximizeMode() == MaximizeMode::MODE_RECOVER &&
2428             property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
2429             WLOGFW("Recover fail, already MODE_RECOVER");
2430             return WMError::WM_ERROR_REPEAT_OPERATION;
2431         }
2432         hostSession->OnSessionEvent(SessionEvent::EVENT_RECOVER);
2433         SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
2434         property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
2435         UpdateDecorEnable(true);
2436         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
2437         NotifyWindowStatusChange(GetMode());
2438     } else {
2439         WLOGFE("recovery is invalid on sub window");
2440         return WMError::WM_ERROR_INVALID_OPERATION;
2441     }
2442     return WMError::WM_OK;
2443 }
2444 
Restore()2445 WMError WindowSceneSessionImpl::Restore()
2446 {
2447     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
2448     if (IsWindowSessionInvalid()) {
2449         TLOGE(WmsLogTag::WMS_LIFE, "session is invalid");
2450         return WMError::WM_ERROR_INVALID_WINDOW;
2451     }
2452     if (!WindowHelper::IsMainWindow(GetType())) {
2453         TLOGE(WmsLogTag::WMS_LIFE, "Restore fail, not main window");
2454         return WMError::WM_ERROR_INVALID_CALLING;
2455     }
2456     if (!(windowSystemConfig_.uiType_ == UI_TYPE_PC || property_->GetIsPcAppInPad())) {
2457         TLOGE(WmsLogTag::WMS_LIFE, "This is not PC or PcAppInPad, not supported");
2458         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2459     }
2460     if (property_->GetIsAppSupportPhoneInPc()) {
2461         TLOGE(WmsLogTag::WMS_LIFE, "This is PhoneAppSupportOnPc, not supported");
2462         return WMError::WM_ERROR_INVALID_CALLING;
2463     }
2464     auto hostSession = GetHostSession();
2465     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
2466     hostSession->OnRestoreMainWindow();
2467     return WMError::WM_OK;
2468 }
2469 
Recover(uint32_t reason)2470 WMError WindowSceneSessionImpl::Recover(uint32_t reason)
2471 {
2472     WLOGFI("WindowSceneSessionImpl::Recover id: %{public}d, reason:%{public}u", GetPersistentId(), reason);
2473     if (IsWindowSessionInvalid()) {
2474         WLOGFE("session is invalid");
2475         return WMError::WM_ERROR_INVALID_WINDOW;
2476     }
2477     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
2478     if (!(isPC || IsFreeMultiWindowMode())) {
2479         WLOGFE("The device is not supported");
2480         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2481     }
2482     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING)) {
2483         TLOGE(WmsLogTag::WMS_LAYOUT, "not support floating, can not Recover");
2484         return WMError::WM_ERROR_INVALID_OPERATION;
2485     }
2486     auto hostSession = GetHostSession();
2487     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2488     if (WindowHelper::IsMainWindow(GetType())) {
2489         if (property_->GetMaximizeMode() == MaximizeMode::MODE_RECOVER &&
2490             property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
2491             WLOGFW("Recover fail, already MODE_RECOVER");
2492             return WMError::WM_ERROR_REPEAT_OPERATION;
2493         }
2494         hostSession->OnSessionEvent(SessionEvent::EVENT_RECOVER);
2495         // need notify arkui maximize mode change
2496         if (reason == 1 && property_->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
2497             UpdateMaximizeMode(MaximizeMode::MODE_RECOVER);
2498         }
2499         SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
2500         property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
2501         UpdateDecorEnable(true);
2502         UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
2503         NotifyWindowStatusChange(GetMode());
2504     } else {
2505         WLOGFE("recovery is invalid on sub window");
2506         return WMError::WM_ERROR_INVALID_OPERATION;
2507     }
2508     return WMError::WM_OK;
2509 }
2510 
SetWindowRectAutoSave(bool enabled)2511 WMError WindowSceneSessionImpl::SetWindowRectAutoSave(bool enabled)
2512 {
2513     TLOGI(WmsLogTag::WMS_MAIN, "id: %{public}d", GetPersistentId());
2514     if (IsWindowSessionInvalid()) {
2515         TLOGE(WmsLogTag::WMS_MAIN, "session is invalid");
2516         return WMError::WM_ERROR_INVALID_WINDOW;
2517     }
2518 
2519     if (windowSystemConfig_.uiType_ != UI_TYPE_PC) {
2520         TLOGE(WmsLogTag::WMS_MAIN, "This is not PC, not supported");
2521         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2522     }
2523 
2524     if (!WindowHelper::IsMainWindow(GetType())) {
2525         TLOGE(WmsLogTag::WMS_MAIN, "This is not main window, not supported");
2526         return WMError::WM_ERROR_INVALID_CALLING;
2527     }
2528 
2529     auto hostSession = GetHostSession();
2530     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
2531     hostSession->OnSetWindowRectAutoSave(enabled);
2532     return WMError::WM_OK;
2533 }
2534 
IsWindowRectAutoSave(bool & enabled)2535 WMError WindowSceneSessionImpl::IsWindowRectAutoSave(bool& enabled)
2536 {
2537     if (IsWindowSessionInvalid()) {
2538         TLOGE(WmsLogTag::WMS_MAIN, "session is invalid");
2539         return WMError::WM_ERROR_INVALID_WINDOW;
2540     }
2541 
2542     if (windowSystemConfig_.uiType_ != UI_TYPE_PC) {
2543         TLOGE(WmsLogTag::WMS_MAIN, "This is not PC, not supported");
2544         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2545     }
2546 
2547     if (!WindowHelper::IsMainWindow(GetType())) {
2548         TLOGE(WmsLogTag::WMS_MAIN, "This is not main window, not supported");
2549         return WMError::WM_ERROR_INVALID_CALLING;
2550     }
2551 
2552     if (context_ == nullptr) {
2553         TLOGE(WmsLogTag::WMS_MAIN, "context_ is nullptr");
2554         return WMError::WM_ERROR_NULLPTR;
2555     }
2556     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
2557     std::string bundleName = property_->GetSessionInfo().bundleName_;
2558     std::string moduleName = property_->GetSessionInfo().moduleName_;
2559     std::string abilityName = property_->GetSessionInfo().abilityName_;
2560     if (abilityContext && abilityContext->GetAbilityInfo()) {
2561         abilityName = abilityContext->GetAbilityInfo()->name;
2562         moduleName = context_->GetHapModuleInfo() ? context_->GetHapModuleInfo()->moduleName : "";
2563         bundleName = abilityContext->GetAbilityInfo()->bundleName;
2564     } else if (context_) {
2565         moduleName = context_->GetHapModuleInfo() ? context_->GetHapModuleInfo()->moduleName : "";
2566         bundleName = context_->GetBundleName();
2567     }
2568     std::string key = bundleName + moduleName + abilityName;
2569     auto ret = SingletonContainer::Get<WindowAdapter>().IsWindowRectAutoSave(key, enabled);
2570     return ret;
2571 }
2572 
SetSupportedWindowModes(const std::vector<AppExecFwk::SupportWindowMode> & supportedWindowModes)2573 WMError WindowSceneSessionImpl::SetSupportedWindowModes(
2574     const std::vector<AppExecFwk::SupportWindowMode>& supportedWindowModes)
2575 {
2576     if (IsWindowSessionInvalid()) {
2577         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
2578         return WMError::WM_ERROR_INVALID_WINDOW;
2579     }
2580 
2581     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
2582     if (!(isPC || IsFreeMultiWindowMode())) {
2583         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is not PC, not supported");
2584         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2585     }
2586 
2587     if (!WindowHelper::IsMainWindow(GetType())) {
2588         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is not main window, not supported");
2589         return WMError::WM_ERROR_INVALID_CALLING;
2590     }
2591 
2592     return SetSupportedWindowModesInner(supportedWindowModes);
2593 }
2594 
SetSupportedWindowModesInner(const std::vector<AppExecFwk::SupportWindowMode> & supportedWindowModes)2595 WMError WindowSceneSessionImpl::SetSupportedWindowModesInner(
2596     const std::vector<AppExecFwk::SupportWindowMode>& supportedWindowModes)
2597 {
2598     auto size = supportedWindowModes.size();
2599     if (size <= 0 || size > WINDOW_SUPPORT_MODE_MAX_SIZE) {
2600         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is invalid");
2601         return WMError::WM_ERROR_INVALID_PARAM;
2602     }
2603 
2604     uint32_t windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(supportedWindowModes);
2605     if (windowModeSupportType == 0) {
2606         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is 0");
2607         return WMError::WM_ERROR_INVALID_PARAM;
2608     }
2609     bool onlySupportSplit = windowModeSupportType ==
2610                             (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
2611                              WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY);
2612     if (onlySupportSplit) {
2613         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is only support split");
2614         return WMError::WM_ERROR_INVALID_PARAM;
2615     }
2616     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId: %{public}u, windowModeSupportType: %{public}u",
2617         GetWindowId(), windowModeSupportType);
2618     property_->SetWindowModeSupportType(windowModeSupportType);
2619     // update windowModeSupportType to server
2620     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
2621 
2622     auto hostSession = GetHostSession();
2623     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
2624     hostSession->NotifySupportWindowModesChange(supportedWindowModes);
2625 
2626     UpdateTitleButtonVisibility();
2627     bool onlySupportFullScreen =
2628         WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
2629         !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING);
2630     if (onlySupportFullScreen && !IsLayoutFullScreen()) {
2631         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "onlySupportFullScreen:%{public}d IsLayoutFullScreen:%{public}d",
2632             onlySupportFullScreen, IsLayoutFullScreen());
2633         Maximize(MaximizePresentation::ENTER_IMMERSIVE);
2634         return WMError::WM_OK;
2635     }
2636 
2637     bool onlySupportFloating =
2638         !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
2639         WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING);
2640     if (onlySupportFloating) {
2641         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "onlySupportFloating:%{public}d", onlySupportFloating);
2642         Recover(1);
2643     }
2644 
2645     return WMError::WM_OK;
2646 }
2647 
StartMove()2648 void WindowSceneSessionImpl::StartMove()
2649 {
2650     WLOGFI("WindowSceneSessionImpl::StartMove id:%{public}d", GetPersistentId());
2651     if (IsWindowSessionInvalid()) {
2652         WLOGFE("session is invalid");
2653         return;
2654     }
2655     WindowType windowType = GetType();
2656     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
2657     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
2658     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
2659     bool isDecorDialog = isDialogWindow && property_->IsDecorEnable();
2660     bool isValidWindow = isMainWindow || (IsPcOrPadCapabilityEnabled() && (isSubWindow || isDecorDialog));
2661     auto hostSession = GetHostSession();
2662     if (isValidWindow && hostSession) {
2663         hostSession->OnSessionEvent(SessionEvent::EVENT_START_MOVE);
2664     }
2665     return;
2666 }
2667 
IsStartMoving()2668 bool WindowSceneSessionImpl::IsStartMoving()
2669 {
2670     bool isMoving = false;
2671     if (auto hostSession = GetHostSession()) {
2672         isMoving = hostSession->IsStartMoving();
2673     }
2674     TLOGI(WmsLogTag::WMS_LAYOUT, "id: %{public}d, isMoving: %{public}d", GetPersistentId(), isMoving);
2675     return isMoving;
2676 }
2677 
MainWindowCloseInner()2678 WMError WindowSceneSessionImpl::MainWindowCloseInner()
2679 {
2680     auto hostSession = GetHostSession();
2681     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2682     auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
2683     if (!abilityContext) {
2684         return Destroy(true);
2685     }
2686     bool terminateCloseProcess = false;
2687     WMError res = NotifyMainWindowClose(terminateCloseProcess);
2688     if (res == WMError::WM_OK) {
2689         TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d, not close: %{public}d", GetPersistentId(),
2690             terminateCloseProcess);
2691         if (!terminateCloseProcess) {
2692             hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
2693         }
2694         return res;
2695     }
2696     auto handler = sptr<WindowPrepareTerminateHandler>::MakeSptr();
2697     PrepareTerminateFunc func = [hostSessionWptr = wptr<ISession>(hostSession)] {
2698         auto hostSession = hostSessionWptr.promote();
2699         if (hostSession == nullptr) {
2700             TLOGNE(WmsLogTag::WMS_LIFE, "this session is nullptr");
2701             return;
2702         }
2703         hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
2704     };
2705     handler->SetPrepareTerminateFun(func);
2706     if (AAFwk::AbilityManagerClient::GetInstance()->PrepareTerminateAbility(abilityContext->GetToken(),
2707         handler) != ERR_OK) {
2708         TLOGE(WmsLogTag::WMS_LIFE, "PrepareTerminateAbility failed, do close window");
2709         hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
2710     }
2711     return WMError::WM_OK;
2712 }
2713 
CalcWindowShouldMove()2714 bool WindowSceneSessionImpl::CalcWindowShouldMove()
2715 {
2716     WindowType windowType = GetType();
2717     if (WindowHelper::IsInputWindow(windowType)) {
2718         if (windowSystemConfig_.uiType_ == UI_TYPE_PAD || windowSystemConfig_.uiType_ == UI_TYPE_PHONE) {
2719             return true;
2720         }
2721     }
2722 
2723     if (IsPcOrPadFreeMultiWindowMode()) {
2724         return true;
2725     }
2726     return false;
2727 }
2728 
StartMoveWindow()2729 WmErrorCode WindowSceneSessionImpl::StartMoveWindow()
2730 {
2731     if (!CalcWindowShouldMove()) {
2732         TLOGE(WmsLogTag::WMS_LAYOUT, "The device is not supported");
2733         return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
2734     }
2735     if (auto hostSession = GetHostSession()) {
2736         WSError errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_START_MOVE);
2737         TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, errorCode:%{public}d",
2738             GetPersistentId(), static_cast<int>(errorCode));
2739         switch (errorCode) {
2740             case WSError::WS_ERROR_REPEAT_OPERATION: {
2741                 return WmErrorCode::WM_ERROR_REPEAT_OPERATION;
2742             }
2743             case WSError::WS_ERROR_NULLPTR: {
2744                 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
2745             }
2746             default: {
2747                 return WmErrorCode::WM_OK;
2748             }
2749         }
2750     } else {
2751         TLOGE(WmsLogTag::WMS_LAYOUT, "hostSession is nullptr");
2752         return WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY;
2753     }
2754 }
2755 
StartMoveWindowWithCoordinate(int32_t offsetX,int32_t offsetY)2756 WmErrorCode WindowSceneSessionImpl::StartMoveWindowWithCoordinate(int32_t offsetX, int32_t offsetY)
2757 {
2758     if (!IsPcOrPadFreeMultiWindowMode()) {
2759         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
2760         return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
2761     }
2762     if (IsWindowSessionInvalid()) {
2763         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
2764         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
2765     }
2766     const auto& windowRect = GetRect();
2767     if (offsetX < 0 || offsetX > static_cast<int32_t>(windowRect.width_) ||
2768         offsetY < 0 || offsetY > static_cast<int32_t>(windowRect.height_)) {
2769         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "offset not in window");
2770         return WmErrorCode::WM_ERROR_INVALID_PARAM;
2771     }
2772     auto hostSession = GetHostSession();
2773     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY);
2774     WSError errorCode;
2775     MMI::PointerEvent::PointerItem pointerItem;
2776     if (lastPointerEvent_ != nullptr &&
2777         lastPointerEvent_->GetPointerItem(lastPointerEvent_->GetPointerId(), pointerItem)) {
2778         int32_t lastDisplayX = pointerItem.GetDisplayX();
2779         int32_t lastDisplayY = pointerItem.GetDisplayY();
2780         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "offsetX:%{public}d offsetY:%{public}d lastDisplayX:%{public}d"
2781             " lastDisplayY:%{public}d", offsetX, offsetY, lastDisplayX, lastDisplayY);
2782         errorCode = hostSession->StartMovingWithCoordinate(offsetX, offsetY, lastDisplayX, lastDisplayY);
2783     } else {
2784         errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_START_MOVE);
2785     }
2786     TLOGD(WmsLogTag::WMS_LAYOUT_PC, "id:%{public}d, errorCode:%{public}d",
2787           GetPersistentId(), static_cast<int>(errorCode));
2788     switch (errorCode) {
2789         case WSError::WS_ERROR_REPEAT_OPERATION: {
2790             return WmErrorCode::WM_ERROR_REPEAT_OPERATION;
2791         }
2792         case WSError::WS_ERROR_NULLPTR: {
2793             return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
2794         }
2795         default: {
2796             return WmErrorCode::WM_OK;
2797         }
2798     }
2799 }
2800 
StopMoveWindow()2801 WmErrorCode WindowSceneSessionImpl::StopMoveWindow()
2802 {
2803     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
2804     if (!(isPC || IsFreeMultiWindowMode())) {
2805         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
2806         return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
2807     }
2808     if (IsWindowSessionInvalid()) {
2809         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
2810         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
2811     }
2812     auto hostSession = GetHostSession();
2813     if (!hostSession) {
2814         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "hostSession is nullptr");
2815         return WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY;
2816     }
2817     WSError errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_END_MOVE);
2818     TLOGD(WmsLogTag::WMS_LAYOUT_PC, "id:%{public}d, errorCode:%{public}d",
2819           GetPersistentId(), static_cast<int>(errorCode));
2820     return errorCode == WSError::WS_ERROR_NULLPTR ? WmErrorCode::WM_ERROR_STATE_ABNORMALLY : WmErrorCode::WM_OK;
2821 }
2822 
Close()2823 WMError WindowSceneSessionImpl::Close()
2824 {
2825     TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d", GetPersistentId());
2826     if (IsWindowSessionInvalid()) {
2827         TLOGE(WmsLogTag::WMS_DECOR, "session is invalid");
2828         return WMError::WM_ERROR_INVALID_WINDOW;
2829     }
2830     WindowType windowType = GetType();
2831     bool isSubWindow = WindowHelper::IsSubWindow(windowType);
2832     bool isSystemSubWindow = WindowHelper::IsSystemSubWindow(windowType);
2833     bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
2834     if (WindowHelper::IsMainWindow(windowType) || isSubWindow) {
2835         WMError res = NotifyWindowWillClose(this);
2836         if (res == WMError::WM_OK) {
2837             TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d will close", GetPersistentId());
2838             return res;
2839         }
2840     }
2841     if (WindowHelper::IsMainWindow(windowType)) {
2842         return MainWindowCloseInner();
2843     } else if (isSubWindow || isSystemSubWindow || isDialogWindow) {
2844         TLOGI(WmsLogTag::WMS_DECOR, "subwindow or dialog");
2845         bool terminateCloseProcess = false;
2846         NotifySubWindowClose(terminateCloseProcess);
2847         if (!terminateCloseProcess || isDialogWindow) {
2848             return Destroy(true);
2849         }
2850     }
2851     return WMError::WM_OK;
2852 }
2853 
CloseDirectly()2854 WMError WindowSceneSessionImpl::CloseDirectly()
2855 {
2856     if (IsWindowSessionInvalid()) {
2857         TLOGE(WmsLogTag::WMS_DECOR, "session is invalid");
2858         return WMError::WM_ERROR_INVALID_WINDOW;
2859     }
2860     TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d", GetPersistentId());
2861     if (WindowHelper::IsMainWindow(GetType())) {
2862         auto hostSession = GetHostSession();
2863         CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
2864         hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
2865         return WMError::WM_OK;
2866     }
2867     return Destroy(true);
2868 }
2869 
DisableAppWindowDecor()2870 WMError WindowSceneSessionImpl::DisableAppWindowDecor()
2871 {
2872     if (IsWindowSessionInvalid()) {
2873         return WMError::WM_ERROR_INVALID_WINDOW;
2874     }
2875     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2876         WLOGFE("disable app window decor permission denied!");
2877         return WMError::WM_ERROR_NOT_SYSTEM_APP;
2878     }
2879     if (!WindowHelper::IsMainWindow(GetType())) {
2880         WLOGFE("window decoration is invalid on sub window");
2881         return WMError::WM_ERROR_INVALID_OPERATION;
2882     }
2883     WLOGI("disable app window decoration.");
2884     windowSystemConfig_.isSystemDecorEnable_ = false;
2885     UpdateDecorEnable(true);
2886     return WMError::WM_OK;
2887 }
2888 
PerformBack()2889 void WindowSceneSessionImpl::PerformBack()
2890 {
2891     if (!WindowHelper::IsMainWindow(GetType())) {
2892         WLOGFI("PerformBack is not MainWindow, return");
2893         return;
2894     }
2895     auto hostSession = GetHostSession();
2896     if (hostSession) {
2897         bool needMoveToBackground = false;
2898         auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
2899         if (abilityContext != nullptr) {
2900             abilityContext->OnBackPressedCallBack(needMoveToBackground);
2901         }
2902         WLOGFI("Transfer back event to host session needMoveToBackground %{public}d", needMoveToBackground);
2903         hostSession->RequestSessionBack(needMoveToBackground);
2904     }
2905 }
2906 
SetGlobalMaximizeMode(MaximizeMode mode)2907 WMError WindowSceneSessionImpl::SetGlobalMaximizeMode(MaximizeMode mode)
2908 {
2909     WLOGFI("WindowSceneSessionImpl::SetGlobalMaximizeMode %{public}u", static_cast<uint32_t>(mode));
2910     if (IsWindowSessionInvalid()) {
2911         WLOGFE("session is invalid");
2912         return WMError::WM_ERROR_INVALID_WINDOW;
2913     }
2914     auto hostSession = GetHostSession();
2915     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2916     if (WindowHelper::IsMainWindow(GetType())) {
2917         hostSession->SetGlobalMaximizeMode(mode);
2918         return WMError::WM_OK;
2919     } else {
2920         WLOGFW("SetGlobalMaximizeMode fail, not main window");
2921         return WMError::WM_ERROR_INVALID_PARAM;
2922     }
2923 }
2924 
GetGlobalMaximizeMode() const2925 MaximizeMode WindowSceneSessionImpl::GetGlobalMaximizeMode() const
2926 {
2927     WLOGFD("WindowSceneSessionImpl::GetGlobalMaximizeMode");
2928     MaximizeMode mode = MaximizeMode::MODE_RECOVER;
2929     auto hostSession = GetHostSession();
2930     if (hostSession) {
2931         hostSession->GetGlobalMaximizeMode(mode);
2932     }
2933     return mode;
2934 }
2935 
SetWindowMode(WindowMode mode)2936 WMError WindowSceneSessionImpl::SetWindowMode(WindowMode mode)
2937 {
2938     TLOGD(WmsLogTag::DEFAULT, "SetWindowMode %{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
2939     if (IsWindowSessionInvalid()) {
2940         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
2941         return WMError::WM_ERROR_INVALID_WINDOW;
2942     }
2943     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), mode)) {
2944         TLOGE(WmsLogTag::DEFAULT, "window %{public}u do not support mode: %{public}u",
2945             GetWindowId(), static_cast<uint32_t>(mode));
2946         return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
2947     }
2948     WMError ret = UpdateWindowModeImmediately(mode);
2949     if (ret != WMError::WM_OK) {
2950         TLOGE(WmsLogTag::DEFAULT, "Update window mode fail, ret:%{public}u", ret);
2951         return ret;
2952     }
2953     auto hostSession = GetHostSession();
2954     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2955     if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
2956         hostSession->OnSessionEvent(SessionEvent::EVENT_SPLIT_PRIMARY);
2957     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
2958         hostSession->OnSessionEvent(SessionEvent::EVENT_SPLIT_SECONDARY);
2959     }
2960     return WMError::WM_OK;
2961 }
2962 
SetGrayScale(float grayScale)2963 WMError WindowSceneSessionImpl::SetGrayScale(float grayScale)
2964 {
2965     if (IsWindowSessionInvalid()) {
2966         WLOGFE("session is invalid");
2967         return WMError::WM_ERROR_INVALID_WINDOW;
2968     }
2969     constexpr float eps = 1e-6f;
2970     if (grayScale < (MIN_GRAY_SCALE - eps) || grayScale > (MAX_GRAY_SCALE + eps)) {
2971         WLOGFE("invalid grayScale value: %{public}f", grayScale);
2972         return WMError::WM_ERROR_INVALID_PARAM;
2973     }
2974     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
2975     if (uiContent == nullptr) {
2976         WLOGFE("uicontent is empty");
2977         return WMError::WM_ERROR_NULLPTR;
2978     }
2979     uiContent->SetContentNodeGrayScale(grayScale);
2980     WLOGI("Set window gray scale success, grayScale: %{public}f", grayScale);
2981     return WMError::WM_OK;
2982 }
2983 
GetMode() const2984 WindowMode WindowSceneSessionImpl::GetMode() const
2985 {
2986     return property_->GetWindowMode();
2987 }
2988 
IsTransparent() const2989 bool WindowSceneSessionImpl::IsTransparent() const
2990 {
2991     if (IsWindowSessionInvalid()) {
2992         return false;
2993     }
2994     WSColorParam backgroundColor;
2995     backgroundColor.value = GetBackgroundColor();
2996     WLOGFD("color: %{public}u, alpha: %{public}u", backgroundColor.value, backgroundColor.argb.alpha);
2997     return backgroundColor.argb.alpha == 0x00; // 0x00: completely transparent
2998 }
2999 
SetTransparent(bool isTransparent)3000 WMError WindowSceneSessionImpl::SetTransparent(bool isTransparent)
3001 {
3002     if (IsWindowSessionInvalid()) {
3003         WLOGFE("session is invalid");
3004         return WMError::WM_ERROR_INVALID_WINDOW;
3005     }
3006     WSColorParam backgroundColor;
3007     backgroundColor.value = GetBackgroundColor();
3008     if (isTransparent) {
3009         backgroundColor.argb.alpha = 0x00; // 0x00: completely transparent
3010         return SetBackgroundColor(backgroundColor.value);
3011     } else {
3012         backgroundColor.value = GetBackgroundColor();
3013         if (backgroundColor.argb.alpha == 0x00) {
3014             backgroundColor.argb.alpha = 0xff; // 0xff: completely opaque
3015             return SetBackgroundColor(backgroundColor.value);
3016         }
3017     }
3018     return WMError::WM_OK;
3019 }
3020 
AddWindowFlag(WindowFlag flag)3021 WMError WindowSceneSessionImpl::AddWindowFlag(WindowFlag flag)
3022 {
3023     if (IsWindowSessionInvalid()) {
3024         return WMError::WM_ERROR_INVALID_WINDOW;
3025     }
3026     if (flag == WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED && context_ && context_->GetApplicationInfo() &&
3027         context_->GetApplicationInfo()->apiCompatibleVersion >= 9 && // 9: api version
3028         !SessionPermission::IsSystemCalling()) {
3029         TLOGI(WmsLogTag::DEFAULT, "Can not set show when locked, PersistentId: %{public}u", GetPersistentId());
3030         return WMError::WM_ERROR_INVALID_PERMISSION;
3031     }
3032     if (flag == WindowFlag::WINDOW_FLAG_HANDWRITING && !SessionPermission::IsSystemCalling()) {
3033         TLOGI(WmsLogTag::DEFAULT, "Can not set handwritting, PersistentId: %{public}u", GetPersistentId());
3034         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3035     }
3036     if (flag == WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE && !SessionPermission::IsSystemCalling()) {
3037         TLOGI(WmsLogTag::DEFAULT, "Can not set forbid split move, PersistentId: %{public}u", GetPersistentId());
3038         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3039     }
3040     uint32_t updateFlags = property_->GetWindowFlags() | (static_cast<uint32_t>(flag));
3041     return SetWindowFlags(updateFlags);
3042 }
3043 
RemoveWindowFlag(WindowFlag flag)3044 WMError WindowSceneSessionImpl::RemoveWindowFlag(WindowFlag flag)
3045 {
3046     if (IsWindowSessionInvalid()) {
3047         return WMError::WM_ERROR_INVALID_WINDOW;
3048     }
3049     uint32_t updateFlags = property_->GetWindowFlags() & (~(static_cast<uint32_t>(flag)));
3050     return SetWindowFlags(updateFlags);
3051 }
3052 
SetWindowFlags(uint32_t flags)3053 WMError WindowSceneSessionImpl::SetWindowFlags(uint32_t flags)
3054 {
3055     TLOGI(WmsLogTag::DEFAULT, "Session %{public}u flags %{public}u", GetWindowId(), flags);
3056     if (IsWindowSessionInvalid()) {
3057         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
3058         return WMError::WM_ERROR_INVALID_WINDOW;
3059     }
3060     if (property_->GetWindowFlags() == flags) {
3061         TLOGI(WmsLogTag::DEFAULT, "Session %{public}u set same flags %{public}u", GetWindowId(), flags);
3062         return WMError::WM_OK;
3063     }
3064     auto oriFlags = property_->GetWindowFlags();
3065     property_->SetWindowFlags(flags);
3066     WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_FLAGS);
3067     if (ret != WMError::WM_OK) {
3068         TLOGE(WmsLogTag::DEFAULT, "SetWindowFlags errCode:%{public}d winId:%{public}u",
3069             static_cast<int32_t>(ret), GetWindowId());
3070         property_->SetWindowFlags(oriFlags);
3071     }
3072     return ret;
3073 }
3074 
GetWindowFlags() const3075 uint32_t WindowSceneSessionImpl::GetWindowFlags() const
3076 {
3077     return property_->GetWindowFlags();
3078 }
3079 
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3080 void WindowSceneSessionImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3081 {
3082     {
3083         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3084         if (uiContent != nullptr) {
3085             TLOGD(WmsLogTag::DEFAULT, "notify ace winId:%{public}u", GetWindowId());
3086             uiContent->UpdateConfiguration(configuration);
3087         }
3088     }
3089     UpdateDefaultStatusBarColor();
3090     if (subWindowSessionMap_.count(GetPersistentId()) == 0) {
3091         return;
3092     }
3093     for (auto& subWindowSession : subWindowSessionMap_.at(GetPersistentId())) {
3094         subWindowSession->UpdateConfiguration(configuration);
3095     }
3096 }
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3097 void WindowSceneSessionImpl::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3098 {
3099     TLOGD(WmsLogTag::DEFAULT, "notify scene ace update config");
3100     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
3101     for (const auto& winPair : windowSessionMap_) {
3102         auto window = winPair.second.second;
3103         window->UpdateConfiguration(configuration);
3104     }
3105 }
3106 
UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3107 void WindowSceneSessionImpl::UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3108 {
3109     if (auto uiContent = GetUIContentSharedPtr()) {
3110         TLOGI(WmsLogTag::WMS_IMMS, "winId: %{public}d", GetWindowId());
3111         uiContent->UpdateConfigurationSyncForAll(configuration);
3112     }
3113     if (subWindowSessionMap_.count(GetPersistentId()) == 0) {
3114         TLOGI(WmsLogTag::WMS_IMMS, "no subSession, winId: %{public}d", GetWindowId());
3115         return;
3116     }
3117     for (auto& subWindowSession : subWindowSessionMap_.at(GetPersistentId())) {
3118         subWindowSession->UpdateConfigurationSync(configuration);
3119     }
3120 }
3121 
UpdateConfigurationSyncForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3122 void WindowSceneSessionImpl::UpdateConfigurationSyncForAll(
3123     const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3124 {
3125     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
3126     for (const auto& winPair : windowSessionMap_) {
3127         if (auto window = winPair.second.second) {
3128             window->UpdateConfigurationSync(configuration);
3129         }
3130     }
3131 }
3132 
3133 /** @note @window.hierarchy */
GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context> & context)3134 sptr<Window> WindowSceneSessionImpl::GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context>& context)
3135 {
3136     uint32_t mainWinId = INVALID_WINDOW_ID;
3137     {
3138         std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
3139         if (windowSessionMap_.empty()) {
3140             TLOGE(WmsLogTag::DEFAULT, "[GetTopWin] Please create mainWindow First!");
3141             return nullptr;
3142         }
3143         for (const auto& winPair : windowSessionMap_) {
3144             auto win = winPair.second.second;
3145             if (win && WindowHelper::IsMainWindow(win->GetType()) && context.get() == win->GetContext().get()) {
3146                 mainWinId = win->GetWindowId();
3147                 TLOGD(WmsLogTag::DEFAULT, "[GetTopWin] Find MainWinId:%{public}u.", mainWinId);
3148                 break;
3149             }
3150         }
3151     }
3152     TLOGI(WmsLogTag::DEFAULT, "[GetTopWin] mainId: %{public}u!", mainWinId);
3153     if (mainWinId == INVALID_WINDOW_ID) {
3154         TLOGE(WmsLogTag::DEFAULT, "[GetTopWin] Cannot find topWindow!");
3155         return nullptr;
3156     }
3157     uint32_t topWinId = INVALID_WINDOW_ID;
3158     WMError ret = SingletonContainer::Get<WindowAdapter>().GetTopWindowId(mainWinId, topWinId);
3159     if (ret != WMError::WM_OK) {
3160         TLOGE(WmsLogTag::DEFAULT, "[GetTopWin] failed with errCode:%{public}d", static_cast<int32_t>(ret));
3161         return nullptr;
3162     }
3163     return FindWindowById(topWinId);
3164 }
3165 
3166 /** @note @window.hierarchy */
GetTopWindowWithId(uint32_t mainWinId)3167 sptr<Window> WindowSceneSessionImpl::GetTopWindowWithId(uint32_t mainWinId)
3168 {
3169     TLOGI(WmsLogTag::DEFAULT, "Get top window, mainId:%{public}u", mainWinId);
3170     uint32_t topWinId = INVALID_WINDOW_ID;
3171     WMError ret = SingletonContainer::Get<WindowAdapter>().GetTopWindowId(mainWinId, topWinId);
3172     if (ret != WMError::WM_OK) {
3173         WLOGFE("[GetTopWin] failed with errCode:%{public}d", static_cast<int32_t>(ret));
3174         return nullptr;
3175     }
3176     return FindWindowById(topWinId);
3177 }
3178 
GetMainWindowWithContext(const std::shared_ptr<AbilityRuntime::Context> & context)3179 sptr<Window> WindowSceneSessionImpl::GetMainWindowWithContext(const std::shared_ptr<AbilityRuntime::Context>& context)
3180 {
3181     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
3182     if (windowSessionMap_.empty()) {
3183         TLOGE(WmsLogTag::WMS_MAIN, "Please create mainWindow First!");
3184         return nullptr;
3185     }
3186     for (const auto& winPair : windowSessionMap_) {
3187         auto win = winPair.second.second;
3188         if (win && WindowHelper::IsMainWindow(win->GetType()) && context.get() == win->GetContext().get()) {
3189             TLOGI(WmsLogTag::WMS_MAIN, "Find MainWinId:%{public}u.", win->GetWindowId());
3190             return win;
3191         }
3192     }
3193     TLOGE(WmsLogTag::WMS_MAIN, "Cannot find Window!");
3194     return nullptr;
3195 }
3196 
GetMainWindowWithId(uint32_t mainWinId)3197 sptr<WindowSessionImpl> WindowSceneSessionImpl::GetMainWindowWithId(uint32_t mainWinId)
3198 {
3199     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
3200     if (windowSessionMap_.empty()) {
3201         WLOGFE("Please create mainWindow First!");
3202         return nullptr;
3203     }
3204     for (const auto& winPair : windowSessionMap_) {
3205         auto win = winPair.second.second;
3206         if (win && WindowHelper::IsMainWindow(win->GetType()) && mainWinId == win->GetWindowId()) {
3207             WLOGI("GetTopWindow Find MainWinId:%{public}u.", mainWinId);
3208             return win;
3209         }
3210     }
3211     WLOGFE("Cannot find Window!");
3212     return nullptr;
3213 }
3214 
3215 
GetWindowWithId(uint32_t winId)3216 sptr<WindowSessionImpl> WindowSceneSessionImpl::GetWindowWithId(uint32_t winId)
3217 {
3218     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
3219     if (windowSessionMap_.empty()) {
3220         TLOGE(WmsLogTag::WMS_SYSTEM, "Please create mainWindow First!");
3221         return nullptr;
3222     }
3223     for (const auto& winPair : windowSessionMap_) {
3224         auto win = winPair.second.second;
3225         if (win && winId == win->GetWindowId()) {
3226             TLOGI(WmsLogTag::WMS_SYSTEM, "find window %{public}s, id %{public}d", win->GetWindowName().c_str(), winId);
3227             return win;
3228         }
3229     }
3230     TLOGE(WmsLogTag::WMS_SYSTEM, "Cannot find Window!");
3231     return nullptr;
3232 }
3233 
GetParentMainWindowIdInner(WindowSessionImplMap & sessionMap,int32_t windowId,int32_t & mainWindowId)3234 static WMError GetParentMainWindowIdInner(WindowSessionImplMap& sessionMap, int32_t windowId, int32_t& mainWindowId)
3235 {
3236     for (const auto& [_, pair] : sessionMap) {
3237         const auto& window = pair.second;
3238         if (window == nullptr) {
3239             return WMError::WM_ERROR_NULLPTR;
3240         }
3241         if (window->GetPersistentId() != windowId) {
3242             continue;
3243         }
3244 
3245         if (WindowHelper::IsMainWindow(window->GetType())) {
3246             TLOGI(WmsLogTag::WMS_SUB, "find main window, id:%{public}u", window->GetPersistentId());
3247             mainWindowId = window->GetPersistentId();
3248             return WMError::WM_OK;
3249         }
3250         if (WindowHelper::IsSubWindow(window->GetType()) || WindowHelper::IsDialogWindow(window->GetType())) {
3251             return GetParentMainWindowIdInner(sessionMap, window->GetParentId(), mainWindowId);
3252         }
3253         // not main window, sub window, dialog, set invalid id
3254         mainWindowId = INVALID_SESSION_ID;
3255         return WMError::WM_OK;
3256     }
3257     return WMError::WM_ERROR_INVALID_PARENT;
3258 }
3259 
GetParentMainWindowId(int32_t windowId)3260 int32_t WindowSceneSessionImpl::GetParentMainWindowId(int32_t windowId)
3261 {
3262     if (windowId == INVALID_SESSION_ID) {
3263         TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
3264         return INVALID_SESSION_ID;
3265     }
3266     int32_t mainWindowId = INVALID_SESSION_ID;
3267     {
3268         std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
3269         WMError findRet = GetParentMainWindowIdInner(windowSessionMap_, windowId, mainWindowId);
3270         if (findRet == WMError::WM_OK) {
3271             return mainWindowId;
3272         }
3273     }
3274     // can't find in client, need to find in server find
3275     WMError ret = SingletonContainer::Get<WindowAdapter>().GetParentMainWindowId(windowId, mainWindowId);
3276     if (ret != WMError::WM_OK) {
3277         TLOGE(WmsLogTag::WMS_SUB, "cant't find main window id, err:%{public}d", static_cast<uint32_t>(ret));
3278         return INVALID_SESSION_ID;
3279     }
3280     return mainWindowId;
3281 }
3282 
SetNeedDefaultAnimation(bool needDefaultAnimation)3283 void WindowSceneSessionImpl::SetNeedDefaultAnimation(bool needDefaultAnimation)
3284 {
3285     enableDefaultAnimation_= needDefaultAnimation;
3286     auto hostSession = GetHostSession();
3287     CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
3288     hostSession->UpdateWindowAnimationFlag(needDefaultAnimation);
3289 }
3290 
ConvertRadiusToSigma(float radius)3291 static float ConvertRadiusToSigma(float radius)
3292 {
3293     return radius > 0.0f ? 0.57735f * radius + SK_ScalarHalf : 0.0f; // 0.57735f is blur sigma scale
3294 }
3295 
CheckParmAndPermission()3296 WMError WindowSceneSessionImpl::CheckParmAndPermission()
3297 {
3298     if (surfaceNode_ == nullptr) {
3299         WLOGFE("RSSurface node is null");
3300         return WMError::WM_ERROR_NULLPTR;
3301     }
3302 
3303     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3304         WLOGFE("Check failed, permission denied");
3305         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3306     }
3307 
3308     return WMError::WM_OK;
3309 }
3310 
SetCornerRadius(float cornerRadius)3311 WMError WindowSceneSessionImpl::SetCornerRadius(float cornerRadius)
3312 {
3313     if (surfaceNode_ == nullptr) {
3314         WLOGFE("RSSurface node is null");
3315         return WMError::WM_ERROR_NULLPTR;
3316     }
3317 
3318     WLOGFI("Set window %{public}s corner radius %{public}f", GetWindowName().c_str(), cornerRadius);
3319     surfaceNode_->SetCornerRadius(cornerRadius);
3320     RSTransaction::FlushImplicitTransaction();
3321     return WMError::WM_OK;
3322 }
3323 
SetShadowRadius(float radius)3324 WMError WindowSceneSessionImpl::SetShadowRadius(float radius)
3325 {
3326     WMError ret = CheckParmAndPermission();
3327     if (ret != WMError::WM_OK) {
3328         return ret;
3329     }
3330 
3331     WLOGFI("Set window %{public}s shadow radius %{public}f", GetWindowName().c_str(), radius);
3332     if (MathHelper::LessNotEqual(radius, 0.0)) {
3333         return WMError::WM_ERROR_INVALID_PARAM;
3334     }
3335 
3336     surfaceNode_->SetShadowRadius(radius);
3337     RSTransaction::FlushImplicitTransaction();
3338     return WMError::WM_OK;
3339 }
3340 
SetShadowColor(std::string color)3341 WMError WindowSceneSessionImpl::SetShadowColor(std::string color)
3342 {
3343     WMError ret = CheckParmAndPermission();
3344     if (ret != WMError::WM_OK) {
3345         return ret;
3346     }
3347 
3348     WLOGFI("Set window %{public}s shadow color %{public}s", GetWindowName().c_str(), color.c_str());
3349     uint32_t colorValue = 0;
3350     if (!ColorParser::Parse(color, colorValue)) {
3351         return WMError::WM_ERROR_INVALID_PARAM;
3352     }
3353 
3354     surfaceNode_->SetShadowColor(colorValue);
3355     RSTransaction::FlushImplicitTransaction();
3356     return WMError::WM_OK;
3357 }
3358 
SetShadowOffsetX(float offsetX)3359 WMError WindowSceneSessionImpl::SetShadowOffsetX(float offsetX)
3360 {
3361     WMError ret = CheckParmAndPermission();
3362     if (ret != WMError::WM_OK) {
3363         return ret;
3364     }
3365 
3366     WLOGFI("Set window %{public}s shadow offsetX %{public}f", GetWindowName().c_str(), offsetX);
3367     surfaceNode_->SetShadowOffsetX(offsetX);
3368     RSTransaction::FlushImplicitTransaction();
3369     return WMError::WM_OK;
3370 }
3371 
SetShadowOffsetY(float offsetY)3372 WMError WindowSceneSessionImpl::SetShadowOffsetY(float offsetY)
3373 {
3374     WMError ret = CheckParmAndPermission();
3375     if (ret != WMError::WM_OK) {
3376         return ret;
3377     }
3378 
3379     WLOGFI("Set window %{public}s shadow offsetY %{public}f", GetWindowName().c_str(), offsetY);
3380     surfaceNode_->SetShadowOffsetY(offsetY);
3381     RSTransaction::FlushImplicitTransaction();
3382     return WMError::WM_OK;
3383 }
3384 
SetBlur(float radius)3385 WMError WindowSceneSessionImpl::SetBlur(float radius)
3386 {
3387     WMError ret = CheckParmAndPermission();
3388     if (ret != WMError::WM_OK) {
3389         return ret;
3390     }
3391 
3392     WLOGFI("Set window %{public}s blur radius %{public}f", GetWindowName().c_str(), radius);
3393     if (MathHelper::LessNotEqual(radius, 0.0)) {
3394         return WMError::WM_ERROR_INVALID_PARAM;
3395     }
3396 
3397     radius = ConvertRadiusToSigma(radius);
3398     WLOGFI("Set window %{public}s blur radius after conversion %{public}f", GetWindowName().c_str(), radius);
3399     surfaceNode_->SetFilter(RSFilter::CreateBlurFilter(radius, radius));
3400     RSTransaction::FlushImplicitTransaction();
3401     return WMError::WM_OK;
3402 }
3403 
SetBackdropBlur(float radius)3404 WMError WindowSceneSessionImpl::SetBackdropBlur(float radius)
3405 {
3406     WMError ret = CheckParmAndPermission();
3407     if (ret != WMError::WM_OK) {
3408         return ret;
3409     }
3410 
3411     WLOGFI("Set window %{public}s backdrop blur radius %{public}f", GetWindowName().c_str(), radius);
3412     if (MathHelper::LessNotEqual(radius, 0.0)) {
3413         return WMError::WM_ERROR_INVALID_PARAM;
3414     }
3415 
3416     radius = ConvertRadiusToSigma(radius);
3417     WLOGFI("Set window %{public}s backdrop blur radius after conversion %{public}f", GetWindowName().c_str(), radius);
3418     surfaceNode_->SetBackgroundFilter(RSFilter::CreateBlurFilter(radius, radius));
3419     RSTransaction::FlushImplicitTransaction();
3420     return WMError::WM_OK;
3421 }
3422 
SetBackdropBlurStyle(WindowBlurStyle blurStyle)3423 WMError WindowSceneSessionImpl::SetBackdropBlurStyle(WindowBlurStyle blurStyle)
3424 {
3425     WMError ret = CheckParmAndPermission();
3426     if (ret != WMError::WM_OK) {
3427         return ret;
3428     }
3429 
3430     WLOGFI("Set window %{public}s backdrop blur style %{public}u", GetWindowName().c_str(), blurStyle);
3431     if (blurStyle < WindowBlurStyle::WINDOW_BLUR_OFF || blurStyle > WindowBlurStyle::WINDOW_BLUR_THICK) {
3432         return WMError::WM_ERROR_INVALID_PARAM;
3433     }
3434 
3435     if (blurStyle == WindowBlurStyle::WINDOW_BLUR_OFF) {
3436         surfaceNode_->SetBackgroundFilter(nullptr);
3437     } else {
3438         auto display = SingletonContainer::IsDestroyed() ? nullptr :
3439             SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
3440         if (display == nullptr) {
3441             WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
3442             return WMError::WM_ERROR_INVALID_PARAM;
3443         }
3444         auto displayInfo = display->GetDisplayInfo();
3445         if (displayInfo == nullptr) {
3446             WLOGFE("get displayInfo failed displayId:%{public}" PRIu64, property_->GetDisplayId());
3447             return WMError::WM_ERROR_INVALID_PARAM;
3448         }
3449         surfaceNode_->SetBackgroundFilter(RSFilter::CreateMaterialFilter(
3450             static_cast<int>(blurStyle), GetVirtualPixelRatio(displayInfo)));
3451     }
3452 
3453     RSTransaction::FlushImplicitTransaction();
3454     return WMError::WM_OK;
3455 }
3456 
SetPrivacyMode(bool isPrivacyMode)3457 WMError WindowSceneSessionImpl::SetPrivacyMode(bool isPrivacyMode)
3458 {
3459     if (IsWindowSessionInvalid()) {
3460         return WMError::WM_ERROR_INVALID_WINDOW;
3461     }
3462     WLOGFD("id : %{public}u, SetPrivacyMode, %{public}u", GetWindowId(), isPrivacyMode);
3463     property_->SetPrivacyMode(isPrivacyMode);
3464     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE);
3465 }
3466 
IsPrivacyMode() const3467 bool WindowSceneSessionImpl::IsPrivacyMode() const
3468 {
3469     if (IsWindowSessionInvalid()) {
3470         return false;
3471     }
3472     return property_->GetPrivacyMode();
3473 }
3474 
SetSystemPrivacyMode(bool isSystemPrivacyMode)3475 void WindowSceneSessionImpl::SetSystemPrivacyMode(bool isSystemPrivacyMode)
3476 {
3477     WLOGFD("id : %{public}u, SetSystemPrivacyMode, %{public}u", GetWindowId(), isSystemPrivacyMode);
3478     property_->SetSystemPrivacyMode(isSystemPrivacyMode);
3479     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE);
3480 }
3481 
SetSnapshotSkip(bool isSkip)3482 WMError WindowSceneSessionImpl::SetSnapshotSkip(bool isSkip)
3483 {
3484     if (IsWindowSessionInvalid()) {
3485         return WMError::WM_ERROR_INVALID_WINDOW;
3486     }
3487     bool oldSkipValue = property_->GetSnapshotSkip();
3488     property_->SetSnapshotSkip(isSkip);
3489     auto resError = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP);
3490     if (resError != WMError::WM_OK) {
3491         property_->SetSnapshotSkip(oldSkipValue);
3492     }
3493     return resError;
3494 }
3495 
Snapshot()3496 std::shared_ptr<Media::PixelMap> WindowSceneSessionImpl::Snapshot()
3497 {
3498     if (IsWindowSessionInvalid()) {
3499         return nullptr;
3500     }
3501     std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
3502     auto isSucceeded = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
3503     std::shared_ptr<Media::PixelMap> pixelMap;
3504     if (!isSucceeded) {
3505         WLOGFE("Failed to TakeSurfaceCapture!");
3506         return nullptr;
3507     }
3508     pixelMap = callback->GetResult(2000); // wait for <= 2000ms
3509     if (pixelMap != nullptr) {
3510         WLOGFD("Snapshot succeed, save WxH = %{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
3511     } else {
3512         WLOGFE("Failed to get pixelmap, return nullptr!");
3513     }
3514     return pixelMap;
3515 }
3516 
NotifyMemoryLevel(int32_t level)3517 WMError WindowSceneSessionImpl::NotifyMemoryLevel(int32_t level)
3518 {
3519     TLOGI(WmsLogTag::DEFAULT, "id: %{public}u, notify memory level: %{public}d", GetWindowId(), level);
3520     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3521     if (uiContent == nullptr) {
3522         WLOGFE("Window %{public}s notify memory level failed, ace is null.", GetWindowName().c_str());
3523         return WMError::WM_ERROR_NULLPTR;
3524     }
3525     // notify memory level
3526     uiContent->NotifyMemoryLevel(level);
3527     WLOGFD("WindowSceneSessionImpl::NotifyMemoryLevel End!");
3528     return WMError::WM_OK;
3529 }
3530 
SetTurnScreenOn(bool turnScreenOn)3531 WMError WindowSceneSessionImpl::SetTurnScreenOn(bool turnScreenOn)
3532 {
3533     if (IsWindowSessionInvalid()) {
3534         return WMError::WM_ERROR_INVALID_WINDOW;
3535     }
3536     property_->SetTurnScreenOn(turnScreenOn);
3537     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON);
3538 }
3539 
IsTurnScreenOn() const3540 bool WindowSceneSessionImpl::IsTurnScreenOn() const
3541 {
3542     return property_->IsTurnScreenOn();
3543 }
3544 
SetKeepScreenOn(bool keepScreenOn)3545 WMError WindowSceneSessionImpl::SetKeepScreenOn(bool keepScreenOn)
3546 {
3547     if (IsWindowSessionInvalid()) {
3548         WLOGFE("session is invalid");
3549         return WMError::WM_ERROR_INVALID_WINDOW;
3550     }
3551     property_->SetKeepScreenOn(keepScreenOn);
3552     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON);
3553 }
3554 
IsKeepScreenOn() const3555 bool WindowSceneSessionImpl::IsKeepScreenOn() const
3556 {
3557     return property_->IsKeepScreenOn();
3558 }
3559 
SetTransform(const Transform & trans)3560 WMError WindowSceneSessionImpl::SetTransform(const Transform& trans)
3561 {
3562     TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d", property_->GetPersistentId());
3563     if (IsWindowSessionInvalid()) {
3564         TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
3565         return WMError::WM_ERROR_INVALID_WINDOW;
3566     }
3567     Transform oriTrans = property_->GetTransform();
3568     property_->SetTransform(trans);
3569     TransformSurfaceNode(trans);
3570     return WMError::WM_OK;
3571 }
3572 
GetTransform() const3573 const Transform& WindowSceneSessionImpl::GetTransform() const
3574 {
3575     return property_->GetTransform();
3576 }
3577 
TransformSurfaceNode(const Transform & trans)3578 void WindowSceneSessionImpl::TransformSurfaceNode(const Transform& trans)
3579 {
3580     if (surfaceNode_ == nullptr) {
3581         return;
3582     }
3583     surfaceNode_->SetPivotX(trans.pivotX_);
3584     surfaceNode_->SetPivotY(trans.pivotY_);
3585     surfaceNode_->SetScaleX(trans.scaleX_);
3586     surfaceNode_->SetScaleY(trans.scaleY_);
3587     surfaceNode_->SetTranslateX(trans.translateX_);
3588     surfaceNode_->SetTranslateY(trans.translateY_);
3589     surfaceNode_->SetTranslateZ(trans.translateZ_);
3590     surfaceNode_->SetRotationX(trans.rotationX_);
3591     surfaceNode_->SetRotationY(trans.rotationY_);
3592     surfaceNode_->SetRotation(trans.rotationZ_);
3593     uint32_t animationFlag = property_->GetAnimationFlag();
3594     if (animationFlag != static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
3595         RSTransaction::FlushImplicitTransaction();
3596     }
3597 }
3598 
RegisterAnimationTransitionController(const sptr<IAnimationTransitionController> & listener)3599 WMError WindowSceneSessionImpl::RegisterAnimationTransitionController(
3600     const sptr<IAnimationTransitionController>& listener)
3601 {
3602     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3603         TLOGE(WmsLogTag::WMS_SYSTEM, "register animation transition controller permission denied!");
3604         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3605     }
3606     if (listener == nullptr) {
3607         TLOGE(WmsLogTag::WMS_SYSTEM, "listener is nullptr");
3608         return WMError::WM_ERROR_NULLPTR;
3609     }
3610     animationTransitionController_ = listener;
3611     wptr<WindowSessionProperty> propertyToken(property_);
3612     wptr<IAnimationTransitionController> animationTransitionControllerToken(animationTransitionController_);
3613 
3614     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3615     if (uiContent) {
3616         uiContent->SetNextFrameLayoutCallback([propertyToken, animationTransitionControllerToken]() {
3617             auto property = propertyToken.promote();
3618             auto animationTransitionController = animationTransitionControllerToken.promote();
3619             if (!property || !animationTransitionController) {
3620                 TLOGE(WmsLogTag::WMS_SYSTEM, "property or animation transition controller is nullptr");
3621                 return;
3622             }
3623             uint32_t animationFlag = property->GetAnimationFlag();
3624             if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
3625                 // CustomAnimation is enabled when animationTransitionController_ exists
3626                 animationTransitionController->AnimationForShown();
3627             }
3628             TLOGI(WmsLogTag::WMS_SYSTEM, "AnimationForShown excute sucess %{public}d!", property->GetPersistentId());
3629         });
3630     }
3631     TLOGI(WmsLogTag::WMS_SYSTEM, "RegisterAnimationTransitionController %{public}d!", property_->GetPersistentId());
3632     return WMError::WM_OK;
3633 }
3634 
UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)3635 WMError WindowSceneSessionImpl::UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)
3636 {
3637     TLOGI(WmsLogTag::WMS_SYSTEM, "id: %{public}d, isAdd:%{public}u", property_->GetPersistentId(), isAdd);
3638     if (IsWindowSessionInvalid()) {
3639         return WMError::WM_ERROR_INVALID_WINDOW;
3640     }
3641     if (!WindowHelper::IsSystemWindow(property_->GetWindowType())) {
3642         TLOGE(WmsLogTag::WMS_SYSTEM, "only system window can set");
3643         return WMError::WM_ERROR_INVALID_OPERATION;
3644     }
3645     // set no custom after customAnimation
3646     WMError ret = UpdateAnimationFlagProperty(false);
3647     if (ret != WMError::WM_OK) {
3648         TLOGE(WmsLogTag::WMS_SYSTEM, "UpdateAnimationFlagProperty failed!");
3649         return ret;
3650     }
3651     auto hostSession = GetHostSession();
3652     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3653     ret = static_cast<WMError>(hostSession->UpdateWindowSceneAfterCustomAnimation(isAdd));
3654     return ret;
3655 }
3656 
AdjustWindowAnimationFlag(bool withAnimation)3657 void WindowSceneSessionImpl::AdjustWindowAnimationFlag(bool withAnimation)
3658 {
3659     if (IsWindowSessionInvalid()) {
3660         WLOGW("[WMSCom]AdjustWindowAnimationFlag failed since session invalid!");
3661         return;
3662     }
3663     // when show/hide with animation
3664     // use custom animation when transitionController exists; else use default animation
3665     WindowType winType = property_->GetWindowType();
3666     bool isAppWindow = WindowHelper::IsAppWindow(winType);
3667     if (withAnimation && !isAppWindow && animationTransitionController_) {
3668         // use custom animation
3669         property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
3670     } else if ((isAppWindow && enableDefaultAnimation_) || (withAnimation && !animationTransitionController_)) {
3671         // use default animation
3672         property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::DEFAULT));
3673     } else {
3674         // with no animation
3675         property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
3676     }
3677 }
3678 
UpdateAnimationFlagProperty(bool withAnimation)3679 WMError WindowSceneSessionImpl::UpdateAnimationFlagProperty(bool withAnimation)
3680 {
3681     if (!WindowHelper::IsSystemWindow(GetType())) {
3682         return WMError::WM_OK;
3683     }
3684     AdjustWindowAnimationFlag(withAnimation);
3685     // when show(true) with default, hide() with None, to adjust animationFlag to disabled default animation
3686     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG);
3687 }
3688 
SetAlpha(float alpha)3689 WMError WindowSceneSessionImpl::SetAlpha(float alpha)
3690 {
3691     WLOGI("Window %{public}d alpha %{public}f", property_->GetPersistentId(), alpha);
3692     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3693         WLOGFE("set alpha permission denied!");
3694         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3695     }
3696     if (IsWindowSessionInvalid()) {
3697         return WMError::WM_ERROR_INVALID_WINDOW;
3698     }
3699     surfaceNode_->SetAlpha(alpha);
3700     RSTransaction::FlushImplicitTransaction();
3701     return WMError::WM_OK;
3702 }
3703 
BindDialogTarget(sptr<IRemoteObject> targetToken)3704 WMError WindowSceneSessionImpl::BindDialogTarget(sptr<IRemoteObject> targetToken)
3705 {
3706     if (IsWindowSessionInvalid()) {
3707         TLOGE(WmsLogTag::WMS_DIALOG, "session is invalid");
3708         return WMError::WM_ERROR_INVALID_WINDOW;
3709     }
3710     auto persistentId = property_->GetPersistentId();
3711     TLOGI(WmsLogTag::WMS_DIALOG, "id: %{public}d", persistentId);
3712     WMError ret = SingletonContainer::Get<WindowAdapter>().BindDialogSessionTarget(persistentId, targetToken);
3713     if (ret != WMError::WM_OK) {
3714         TLOGE(WmsLogTag::WMS_DIALOG, "bind window failed with errCode:%{public}d", static_cast<int32_t>(ret));
3715     }
3716     return ret;
3717 }
3718 
SetDialogBackGestureEnabled(bool isEnabled)3719 WMError WindowSceneSessionImpl::SetDialogBackGestureEnabled(bool isEnabled)
3720 {
3721     WindowType windowType = GetType();
3722     if (windowType != WindowType::WINDOW_TYPE_DIALOG) {
3723         TLOGE(WmsLogTag::WMS_DIALOG, "windowType not support. WinId:%{public}u, WindowType:%{public}u",
3724             GetWindowId(), static_cast<uint32_t>(windowType));
3725         return WMError::WM_ERROR_INVALID_CALLING;
3726     }
3727     auto hostSession = GetHostSession();
3728     if (hostSession == nullptr) {
3729         TLOGE(WmsLogTag::WMS_DIALOG, "set window failed because of nullptr");
3730         return WMError::WM_ERROR_NULLPTR;
3731     }
3732     WMError ret = static_cast<WMError>(hostSession->SetDialogSessionBackGestureEnabled(isEnabled));
3733     if (ret != WMError::WM_OK) {
3734         TLOGE(WmsLogTag::WMS_DIALOG, "set window failed with errCode:%{public}d", static_cast<int32_t>(ret));
3735     }
3736     return ret;
3737 }
3738 
SetTouchHotAreas(const std::vector<Rect> & rects)3739 WMError WindowSceneSessionImpl::SetTouchHotAreas(const std::vector<Rect>& rects)
3740 {
3741     if (property_ == nullptr) {
3742         return WMError::WM_ERROR_NULLPTR;
3743     }
3744     std::vector<Rect> lastTouchHotAreas;
3745     property_->GetTouchHotAreas(lastTouchHotAreas);
3746     property_->SetTouchHotAreas(rects);
3747     WMError result = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA);
3748     if (result != WMError::WM_OK) {
3749         property_->SetTouchHotAreas(lastTouchHotAreas);
3750         WLOGFE("SetTouchHotAreas with errCode:%{public}d", static_cast<int32_t>(result));
3751         return result;
3752     }
3753     for (uint32_t i = 0; i < rects.size(); i++) {
3754         WLOGFI("Set areas: %{public}u [x: %{public}d y:%{public}d w:%{public}u h:%{public}u]",
3755             i, rects[i].posX_, rects[i].posY_, rects[i].width_, rects[i].height_);
3756     }
3757     return result;
3758 }
3759 
SetKeyboardTouchHotAreas(const KeyboardTouchHotAreas & hotAreas)3760 WMError WindowSceneSessionImpl::SetKeyboardTouchHotAreas(const KeyboardTouchHotAreas& hotAreas)
3761 {
3762     if (GetType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3763         return WMError::WM_ERROR_INVALID_TYPE;
3764     }
3765     KeyboardTouchHotAreas lastKeyboardTouchHotAreas = property_->GetKeyboardTouchHotAreas();
3766     property_->SetKeyboardTouchHotAreas(hotAreas);
3767     WMError result = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_KEYBOARD_TOUCH_HOT_AREA);
3768     if (result != WMError::WM_OK) {
3769         property_->SetKeyboardTouchHotAreas(lastKeyboardTouchHotAreas);
3770         TLOGE(WmsLogTag::WMS_EVENT, "errCode:%{public}d", static_cast<int32_t>(result));
3771     }
3772     return result;
3773 }
3774 
KeepKeyboardOnFocus(bool keepKeyboardFlag)3775 WmErrorCode WindowSceneSessionImpl::KeepKeyboardOnFocus(bool keepKeyboardFlag)
3776 {
3777     if (property_ == nullptr) {
3778         return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3779     }
3780     property_->KeepKeyboardOnFocus(keepKeyboardFlag);
3781 
3782     return WmErrorCode::WM_OK;
3783 }
3784 
SetCallingWindow(uint32_t callingSessionId)3785 WMError WindowSceneSessionImpl::SetCallingWindow(uint32_t callingSessionId)
3786 {
3787     if (IsWindowSessionInvalid()) {
3788         TLOGE(WmsLogTag::WMS_KEYBOARD, "Set calling session id failed, window session is invalid!");
3789         return WMError::WM_ERROR_INVALID_WINDOW;
3790     }
3791 
3792     if (property_ == nullptr) {
3793         TLOGE(WmsLogTag::WMS_KEYBOARD, "Set calling session id failed, property_ is nullptr!");
3794         return WMError::WM_ERROR_NULLPTR;
3795     }
3796     if (callingSessionId != property_->GetCallingSessionId()) {
3797         TLOGI(WmsLogTag::WMS_KEYBOARD, "Set calling session id form %{public}d to: %{public}d",
3798             property_->GetCallingSessionId(), callingSessionId);
3799     }
3800     auto hostSession = GetHostSession();
3801     if (hostSession) {
3802         hostSession->SetCallingSessionId(callingSessionId);
3803     }
3804     property_->SetCallingSessionId(callingSessionId);
3805     return WMError::WM_OK;
3806 }
3807 
ChangeKeyboardViewMode(KeyboardViewMode mode)3808 WMError WindowSceneSessionImpl::ChangeKeyboardViewMode(KeyboardViewMode mode)
3809 {
3810     TLOGI(WmsLogTag::WMS_KEYBOARD, "Start change keyboard view mode to %{public}u",
3811         static_cast<uint32_t>(mode));
3812     if (mode >= KeyboardViewMode::VIEW_MODE_END) {
3813         TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid view mode!");
3814         return WMError::WM_ERROR_INVALID_PARAM;
3815     }
3816     if (mode == property_->GetKeyboardViewMode()) {
3817         TLOGI(WmsLogTag::WMS_KEYBOARD, "The mode is same.");
3818         return WMError::WM_DO_NOTHING;
3819     }
3820     if (IsWindowSessionInvalid()) {
3821         TLOGE(WmsLogTag::WMS_KEYBOARD, "Session is invalid!");
3822         return WMError::WM_ERROR_INVALID_WINDOW;
3823     }
3824     if (state_ != WindowState::STATE_SHOWN) {
3825         TLOGE(WmsLogTag::WMS_KEYBOARD, "The keyboard is not show status.");
3826         return WMError::WM_ERROR_INVALID_WINDOW;
3827     }
3828 
3829     property_->SetKeyboardViewMode(mode);
3830     auto hostSession = GetHostSession();
3831     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3832     return static_cast<WMError>(hostSession->ChangeKeyboardViewMode(mode));
3833 }
3834 
DumpSessionElementInfo(const std::vector<std::string> & params)3835 void WindowSceneSessionImpl::DumpSessionElementInfo(const std::vector<std::string>& params)
3836 {
3837     WLOGFD("DumpSessionElementInfo");
3838     std::vector<std::string> info;
3839     if (params.size() == 1 && params[0] == PARAM_DUMP_HELP) { // 1: params num
3840         WLOGFD("Dump ArkUI help Info");
3841         Ace::UIContent::ShowDumpHelp(info);
3842         SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
3843         return;
3844     }
3845     WLOGFD("ArkUI:DumpInfo");
3846     {
3847         std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3848         if (uiContent != nullptr) {
3849             uiContent->DumpInfo(params, info);
3850         }
3851     }
3852     for (auto iter = info.begin(); iter != info.end();) {
3853         if ((*iter).size() == 0) {
3854             iter = info.erase(iter);
3855             continue;
3856         }
3857         WLOGFD("ElementInfo size: %{public}u", static_cast<uint32_t>((*iter).size()));
3858         iter++;
3859     }
3860     if (info.size() == 0) {
3861         WLOGFD("ElementInfo is empty");
3862         return;
3863     }
3864     SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
3865 }
3866 
UpdateWindowMode(WindowMode mode)3867 WSError WindowSceneSessionImpl::UpdateWindowMode(WindowMode mode)
3868 {
3869     WLOGFI("UpdateWindowMode %{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
3870     if (IsWindowSessionInvalid()) {
3871         return WSError::WS_ERROR_INVALID_WINDOW;
3872     }
3873     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), mode)) {
3874         WLOGFE("window %{public}u do not support mode: %{public}u",
3875             GetWindowId(), static_cast<uint32_t>(mode));
3876         return WSError::WS_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
3877     }
3878     WMError ret = UpdateWindowModeImmediately(mode);
3879 
3880     if (windowSystemConfig_.uiType_ == UI_TYPE_PC) {
3881         if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
3882             ret = SetLayoutFullScreenByApiVersion(true);
3883             if (ret != WMError::WM_OK) {
3884                 TLOGE(WmsLogTag::WMS_IMMS, "SetLayoutFullScreenByApiVersion errCode:%{public}d winId:%{public}u",
3885                     static_cast<int32_t>(ret), GetWindowId());
3886             }
3887             SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
3888             statusProperty.enable_ = false;
3889             ret = SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
3890             if (ret != WMError::WM_OK) {
3891                 WLOGFE("SetSystemBarProperty errCode:%{public}d winId:%{public}u",
3892                     static_cast<int32_t>(ret), GetWindowId());
3893             }
3894         }
3895     }
3896     return static_cast<WSError>(ret);
3897 }
3898 
UpdateWindowModeImmediately(WindowMode mode)3899 WMError WindowSceneSessionImpl::UpdateWindowModeImmediately(WindowMode mode)
3900 {
3901     if (state_ == WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
3902         property_->SetWindowMode(mode);
3903         UpdateTitleButtonVisibility();
3904         UpdateDecorEnable(true);
3905     } else if (state_ == WindowState::STATE_SHOWN) {
3906         WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE);
3907         if (ret != WMError::WM_OK) {
3908             WLOGFE("update window mode filed! id: %{public}u, mode: %{public}u.", GetWindowId(),
3909                 static_cast<uint32_t>(mode));
3910             return ret;
3911         }
3912         // set client window mode if success.
3913         property_->SetWindowMode(mode);
3914         UpdateTitleButtonVisibility();
3915         UpdateDecorEnable(true, mode);
3916         if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
3917             property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
3918         }
3919     }
3920     NotifyWindowStatusChange(mode);
3921     return WMError::WM_OK;
3922 }
3923 
UpdateMaximizeMode(MaximizeMode mode)3924 WSError WindowSceneSessionImpl::UpdateMaximizeMode(MaximizeMode mode)
3925 {
3926     WLOGFI("UpdateMaximizeMode %{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
3927     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3928     if (uiContent == nullptr) {
3929         WLOGFE("UpdateMaximizeMode uiContent is null");
3930         return WSError::WS_ERROR_INVALID_PARAM;
3931     }
3932     uiContent->UpdateMaximizeMode(mode);
3933     property_->SetMaximizeMode(mode);
3934     return WSError::WS_OK;
3935 }
3936 
NotifySessionFullScreen(bool fullScreen)3937 void WindowSceneSessionImpl::NotifySessionFullScreen(bool fullScreen)
3938 {
3939     TLOGI(WmsLogTag::WMS_LAYOUT, "winId: %{public}u", GetWindowId());
3940     Maximize(fullScreen ? MaximizePresentation::ENTER_IMMERSIVE : MaximizePresentation::EXIT_IMMERSIVE);
3941 }
3942 
UpdateTitleInTargetPos(bool isShow,int32_t height)3943 WSError WindowSceneSessionImpl::UpdateTitleInTargetPos(bool isShow, int32_t height)
3944 {
3945     WLOGFI("UpdateTitleInTargetPos %{public}u isShow %{public}u, height %{public}u", GetWindowId(), isShow, height);
3946     if (IsWindowSessionInvalid()) {
3947         return WSError::WS_ERROR_INVALID_WINDOW;
3948     }
3949     std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3950     if (uiContent == nullptr) {
3951         WLOGFE("UpdateTitleInTargetPos uiContent is null");
3952         return WSError::WS_ERROR_INVALID_PARAM;
3953     }
3954     uiContent->UpdateTitleInTargetPos(isShow, height);
3955     return WSError::WS_OK;
3956 }
3957 
SwitchFreeMultiWindow(bool enable)3958 WSError WindowSceneSessionImpl::SwitchFreeMultiWindow(bool enable)
3959 {
3960     if (IsWindowSessionInvalid()) {
3961         return WSError::WS_ERROR_INVALID_WINDOW;
3962     }
3963     if (windowSystemConfig_.freeMultiWindowEnable_ == enable) {
3964         return WSError::WS_ERROR_REPEAT_OPERATION;
3965     }
3966     NotifySwitchFreeMultiWindow(enable);
3967     //Switch process finish, update system config
3968     windowSystemConfig_.freeMultiWindowEnable_ = enable;
3969     return WSError::WS_OK;
3970 }
3971 
GetFreeMultiWindowModeEnabledState()3972 bool WindowSceneSessionImpl::GetFreeMultiWindowModeEnabledState()
3973 {
3974     return windowSystemConfig_.freeMultiWindowEnable_ &&
3975         windowSystemConfig_.freeMultiWindowSupport_;
3976 }
3977 
NotifyCompatibleModeEnableInPad(bool enable)3978 WSError WindowSceneSessionImpl::NotifyCompatibleModeEnableInPad(bool enable)
3979 {
3980     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d, enable: %{public}d", GetPersistentId(), enable);
3981     if (IsWindowSessionInvalid()) {
3982         TLOGE(WmsLogTag::DEFAULT, "window session invalid!");
3983         return WSError::WS_ERROR_INVALID_WINDOW;
3984     }
3985     property_->SetCompatibleModeEnableInPad(enable);
3986     return WSError::WS_OK;
3987 }
3988 
NotifySessionForeground(uint32_t reason,bool withAnimation)3989 void WindowSceneSessionImpl::NotifySessionForeground(uint32_t reason, bool withAnimation)
3990 {
3991     TLOGI(WmsLogTag::WMS_LIFE, "in");
3992     if (handler_) {
3993         handler_->PostTask([weakThis = wptr(this), reason, withAnimation] {
3994             auto window = weakThis.promote();
3995             if (!window) {
3996                 TLOGNE(WmsLogTag::WMS_LIFE, "window is nullptr");
3997                 return;
3998             }
3999             window->Show(reason, withAnimation);
4000         }, __func__);
4001         return;
4002     }
4003     Show(reason, withAnimation);
4004 }
4005 
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)4006 void WindowSceneSessionImpl::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
4007 {
4008     TLOGI(WmsLogTag::WMS_LIFE, "in");
4009     if (handler_) {
4010         handler_->PostTask([weakThis = wptr(this), reason, withAnimation, isFromInnerkits] {
4011             auto window = weakThis.promote();
4012             if (!window) {
4013                 TLOGNE(WmsLogTag::WMS_LIFE, "window is nullptr");
4014                 return;
4015             }
4016             window->Hide(reason, withAnimation, isFromInnerkits);
4017         }, __func__);
4018         return;
4019     }
4020     Hide(reason, withAnimation, isFromInnerkits);
4021 }
4022 
NotifyPrepareClosePiPWindow()4023 WMError WindowSceneSessionImpl::NotifyPrepareClosePiPWindow()
4024 {
4025     TLOGI(WmsLogTag::WMS_PIP, "NotifyPrepareClosePiPWindow type: %{public}u", GetType());
4026     if (!WindowHelper::IsPipWindow(GetType())) {
4027         return WMError::WM_DO_NOTHING;
4028     }
4029     auto hostSession = GetHostSession();
4030     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
4031     hostSession->NotifyPiPWindowPrepareClose();
4032     return WMError::WM_OK;
4033 }
4034 
GetWindowLimits(WindowLimits & windowLimits)4035 WMError WindowSceneSessionImpl::GetWindowLimits(WindowLimits& windowLimits)
4036 {
4037     if (IsWindowSessionInvalid()) {
4038         WLOGFE("session is invalid");
4039         return WMError::WM_ERROR_INVALID_WINDOW;
4040     }
4041     if (property_ == nullptr) {
4042         WLOGFE("GetWindowLimits property_ is null, WinId:%{public}u", GetWindowId());
4043         return WMError::WM_ERROR_NULLPTR;
4044     }
4045     const auto& customizedLimits = property_->GetWindowLimits();
4046     windowLimits.minWidth_ = customizedLimits.minWidth_;
4047     windowLimits.minHeight_ = customizedLimits.minHeight_;
4048     windowLimits.maxWidth_ = customizedLimits.maxWidth_;
4049     windowLimits.maxHeight_ = customizedLimits.maxHeight_;
4050     windowLimits.vpRatio_ = customizedLimits.vpRatio_;
4051     TLOGI(WmsLogTag::WMS_LAYOUT, "GetWindowLimits WinId:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
4052         "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", GetWindowId(), windowLimits.minWidth_,
4053         windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
4054     return WMError::WM_OK;
4055 }
4056 
UpdateNewSize()4057 void WindowSceneSessionImpl::UpdateNewSize()
4058 {
4059     if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
4060         TLOGI(WmsLogTag::WMS_LAYOUT, "Fullscreen window could not update new size, winId: %{public}u", GetWindowId());
4061         return;
4062     }
4063     bool needResize = false;
4064     Rect windowRect = GetRequestRect();
4065     if (windowRect.IsUninitializedSize()) {
4066         windowRect = GetRect();
4067         if (windowRect.IsUninitializedSize()) {
4068             TLOGW(WmsLogTag::WMS_LAYOUT, "The sizes of requestRect and rect are uninitialized. winId: %{public}u",
4069                 GetWindowId());
4070             return;
4071         }
4072     }
4073 
4074     uint32_t width = windowRect.width_;
4075     uint32_t height = windowRect.height_;
4076     const auto& newLimits = property_->GetWindowLimits();
4077     if (width < newLimits.minWidth_) {
4078         width = newLimits.minWidth_;
4079         needResize = true;
4080     }
4081     if (height < newLimits.minHeight_) {
4082         height = newLimits.minHeight_;
4083         needResize = true;
4084     }
4085     if (width > newLimits.maxWidth_) {
4086         width = newLimits.maxWidth_;
4087         needResize = true;
4088     }
4089     if (height > newLimits.maxHeight_) {
4090         height = newLimits.maxHeight_;
4091         needResize = true;
4092     }
4093     if (needResize) {
4094         Resize(width, height);
4095         TLOGI(WmsLogTag::WMS_LAYOUT, "Resize window by limits. winId: %{public}u, width: %{public}u,"
4096             " height: %{public}u", GetWindowId(), width, height);
4097     }
4098 }
4099 
SetWindowLimits(WindowLimits & windowLimits,bool isForcible)4100 WMError WindowSceneSessionImpl::SetWindowLimits(WindowLimits& windowLimits, bool isForcible)
4101 {
4102     TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
4103         "maxWidth:%{public}u, maxHeight:%{public}u, isForcible:%{public}u", GetWindowId(), windowLimits.minWidth_,
4104         windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, isForcible);
4105     if (IsWindowSessionInvalid()) {
4106         TLOGE(WmsLogTag::WMS_LAYOUT, "session is invalid");
4107         return WMError::WM_ERROR_INVALID_WINDOW;
4108     }
4109 
4110     WindowType windowType = GetType();
4111     bool isDraggableSystemWin = WindowHelper::IsSystemWindow(windowType) && IsWindowDraggable();
4112     if (!WindowHelper::IsMainWindow(windowType) && !WindowHelper::IsSubWindow(windowType) &&
4113         windowType != WindowType::WINDOW_TYPE_DIALOG && !isDraggableSystemWin) {
4114         TLOGE(WmsLogTag::WMS_LAYOUT, "windowType not support. WinId:%{public}u, WindowType:%{public}u",
4115             GetWindowId(), static_cast<uint32_t>(windowType));
4116         return WMError::WM_ERROR_INVALID_CALLING;
4117     }
4118 
4119     if (property_ == nullptr) {
4120         return WMError::WM_ERROR_NULLPTR;
4121     }
4122 
4123     const auto& customizedLimits = property_->GetWindowLimits();
4124     uint32_t minWidth = windowLimits.minWidth_ ? windowLimits.minWidth_ : customizedLimits.minWidth_;
4125     uint32_t minHeight = windowLimits.minHeight_ ? windowLimits.minHeight_ : customizedLimits.minHeight_;
4126     uint32_t maxWidth = windowLimits.maxWidth_ ? windowLimits.maxWidth_ : customizedLimits.maxWidth_;
4127     uint32_t maxHeight = windowLimits.maxHeight_ ? windowLimits.maxHeight_ : customizedLimits.maxHeight_;
4128 
4129     property_->SetUserWindowLimits({
4130         maxWidth, maxHeight, minWidth, minHeight, customizedLimits.maxRatio_, customizedLimits.minRatio_
4131     });
4132     forceLimits_ = isForcible;
4133     userLimitsSet_ = true;
4134     UpdateWindowSizeLimits();
4135     WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
4136     if (ret != WMError::WM_OK) {
4137         TLOGE(WmsLogTag::WMS_LAYOUT, "update window proeprty failed! id: %{public}u.", GetWindowId());
4138         return ret;
4139     }
4140     UpdateNewSize();
4141 
4142     fillWindowLimits(windowLimits);
4143     return WMError::WM_OK;
4144 }
4145 
fillWindowLimits(WindowLimits & windowLimits)4146 void WindowSceneSessionImpl::fillWindowLimits(WindowLimits& windowLimits)
4147 {
4148     const auto& newLimits = property_->GetWindowLimits();
4149     windowLimits.minWidth_ = newLimits.minWidth_;
4150     windowLimits.minHeight_ = newLimits.minHeight_;
4151     windowLimits.maxWidth_ = newLimits.maxWidth_;
4152     windowLimits.maxHeight_ = newLimits.maxHeight_;
4153     WLOGFI("SetWindowLimits success! WinId:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
4154         "maxWidth:%{public}u, maxHeight:%{public}u", GetWindowId(), windowLimits.minWidth_,
4155         windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_);
4156 }
4157 
NotifyDialogStateChange(bool isForeground)4158 WSError WindowSceneSessionImpl::NotifyDialogStateChange(bool isForeground)
4159 {
4160     if (property_ == nullptr) {
4161         TLOGE(WmsLogTag::WMS_DIALOG, "property is nullptr");
4162         return WSError::WS_ERROR_NULLPTR;
4163     }
4164     const auto& type = GetType();
4165     TLOGI(WmsLogTag::WMS_DIALOG, "state change [name:%{public}s, id:%{public}d, type:%{public}u], state:%{public}u,"
4166         " requestState:%{public}u, isForeground:%{public}d", property_->GetWindowName().c_str(), GetPersistentId(),
4167         type, state_, requestState_, static_cast<int32_t>(isForeground));
4168     if (IsWindowSessionInvalid()) {
4169         TLOGE(WmsLogTag::WMS_DIALOG, "session is invalid, id:%{public}d", GetPersistentId());
4170         return WSError::WS_ERROR_INVALID_WINDOW;
4171     }
4172 
4173     if (isForeground) {
4174         if (state_ == WindowState::STATE_SHOWN) {
4175             return WSError::WS_OK;
4176         }
4177         if (state_ == WindowState::STATE_HIDDEN && requestState_ == WindowState::STATE_SHOWN) {
4178             state_ = WindowState::STATE_SHOWN;
4179             NotifyAfterForeground();
4180         }
4181     } else {
4182         if (state_ == WindowState::STATE_HIDDEN) {
4183             return WSError::WS_OK;
4184         }
4185         if (state_ == WindowState::STATE_SHOWN) {
4186             state_ = WindowState::STATE_HIDDEN;
4187             NotifyAfterBackground();
4188         }
4189     }
4190     TLOGI(WmsLogTag::WMS_DIALOG, "dialog state change success [name:%{public}s, id:%{public}d, type:%{public}u],"
4191         " state:%{public}u, requestState:%{public}u", property_->GetWindowName().c_str(), property_->GetPersistentId(),
4192         type, state_, requestState_);
4193     return WSError::WS_OK;
4194 }
4195 
SetDefaultDensityEnabled(bool enabled)4196 WMError WindowSceneSessionImpl::SetDefaultDensityEnabled(bool enabled)
4197 {
4198     TLOGI(WmsLogTag::WMS_LAYOUT, "windowId=%{public}d set default density enabled=%{public}d", GetWindowId(), enabled);
4199 
4200     if (IsWindowSessionInvalid()) {
4201         TLOGE(WmsLogTag::WMS_LAYOUT, "window session is invalid");
4202         return WMError::WM_ERROR_INVALID_WINDOW;
4203     }
4204 
4205     if (!WindowHelper::IsMainWindow(GetType())) {
4206         TLOGE(WmsLogTag::WMS_LAYOUT, "must be app main window");
4207         return WMError::WM_ERROR_INVALID_CALLING;
4208     }
4209 
4210     if (isDefaultDensityEnabled_ == enabled) {
4211         TLOGI(WmsLogTag::WMS_LAYOUT, "isDefaultDensityEnabled_ not change");
4212         return WMError::WM_OK;
4213     }
4214 
4215     if (auto hostSession = GetHostSession()) {
4216         hostSession->OnDefaultDensityEnabled(enabled);
4217     }
4218 
4219     isDefaultDensityEnabled_ = enabled;
4220 
4221     std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4222     for (const auto& winPair : windowSessionMap_) {
4223         auto window = winPair.second.second;
4224         if (window == nullptr) {
4225             TLOGE(WmsLogTag::WMS_LAYOUT, "window is nullptr");
4226             continue;
4227         }
4228         TLOGD(WmsLogTag::WMS_LAYOUT, "windowId=%{public}d UpdateDensity", window->GetWindowId());
4229         window->UpdateDensity();
4230     }
4231     return WMError::WM_OK;
4232 }
4233 
GetDefaultDensityEnabled()4234 bool WindowSceneSessionImpl::GetDefaultDensityEnabled()
4235 {
4236     return isDefaultDensityEnabled_.load();
4237 }
4238 
GetVirtualPixelRatio(const sptr<DisplayInfo> & displayInfo)4239 float WindowSceneSessionImpl::GetVirtualPixelRatio(const sptr<DisplayInfo>& displayInfo)
4240 {
4241     if (displayInfo == nullptr) {
4242         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "displayInfo is nullptr");
4243         return INVALID_DEFAULT_DENSITY;
4244     }
4245     if (IsDefaultDensityEnabled()) {
4246         return displayInfo->GetDefaultVirtualPixelRatio();
4247     }
4248     if (useUniqueDensity_) {
4249         return virtualPixelRatio_;
4250     }
4251     auto vpr = GetMainWindowCustomDensity();
4252     return vpr >= MINIMUM_CUSTOM_DENSITY && vpr <= MAXIMUM_CUSTOM_DENSITY ? vpr : displayInfo->GetVirtualPixelRatio();
4253 }
4254 
HideNonSecureWindows(bool shouldHide)4255 WMError WindowSceneSessionImpl::HideNonSecureWindows(bool shouldHide)
4256 {
4257     return SingletonContainer::Get<WindowAdapter>().AddOrRemoveSecureSession(property_->GetPersistentId(), shouldHide);
4258 }
4259 
SetTextFieldAvoidInfo(double textFieldPositionY,double textFieldHeight)4260 WMError WindowSceneSessionImpl::SetTextFieldAvoidInfo(double textFieldPositionY, double textFieldHeight)
4261 {
4262     TLOGI(WmsLogTag::WMS_KEYBOARD, "Set textFieldPositionY: %{public}f, textFieldHeight:%{public}f",
4263         textFieldPositionY, textFieldHeight);
4264     property_->SetTextFieldPositionY(textFieldPositionY);
4265     property_->SetTextFieldHeight(textFieldHeight);
4266     UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO);
4267     return WMError::WM_OK;
4268 }
4269 
HandleWindowMask(const std::vector<std::vector<uint32_t>> & windowMask)4270 std::unique_ptr<Media::PixelMap> WindowSceneSessionImpl::HandleWindowMask(
4271     const std::vector<std::vector<uint32_t>>& windowMask)
4272 {
4273     const Rect& windowRect = GetRequestRect();
4274     uint32_t maskHeight = windowMask.size();
4275     if (maskHeight == 0) {
4276         WLOGFE("WindowMask is invalid");
4277         return nullptr;
4278     }
4279     uint32_t maskWidth = windowMask[0].size();
4280     if ((windowRect.height_ > 0 && windowRect.height_ != maskHeight) ||
4281         (windowRect.width_ > 0 && windowRect.width_ != maskWidth)) {
4282         WLOGFE("WindowMask is invalid");
4283         return nullptr;
4284     }
4285     const uint32_t bgraChannel = 4;
4286     Media::InitializationOptions opts;
4287     opts.size.width = static_cast<int32_t>(maskWidth);
4288     opts.size.height = static_cast<int32_t>(maskHeight);
4289     uint32_t length = maskWidth * maskHeight * bgraChannel;
4290     uint8_t* data = static_cast<uint8_t*>(malloc(length));
4291     if (data == nullptr) {
4292         WLOGFE("data is nullptr");
4293         return nullptr;
4294     }
4295     const uint32_t fullChannel = 255;
4296     const uint32_t greenChannel = 1;
4297     const uint32_t redChannel = 2;
4298     const uint32_t alphaChannel = 3;
4299     for (uint32_t i = 0; i < maskHeight; i++) {
4300         for (uint32_t j = 0; j < maskWidth; j++) {
4301             uint32_t idx = i * maskWidth + j;
4302             uint32_t channel = windowMask[i][j] > 0 ? fullChannel : 0;
4303             uint32_t channelIndex = idx * bgraChannel;
4304             data[channelIndex] = channel; // blue channel
4305             data[channelIndex + greenChannel] = channel; // green channel
4306             data[channelIndex + redChannel] = fullChannel; // red channel
4307             data[channelIndex + alphaChannel] = channel; // alpha channel
4308         }
4309     }
4310     std::unique_ptr<Media::PixelMap> mask = Media::PixelMap::Create(reinterpret_cast<uint32_t*>(data), length, opts);
4311     free(data);
4312     return mask;
4313 }
4314 
SetWindowMask(const std::vector<std::vector<uint32_t>> & windowMask)4315 WMError WindowSceneSessionImpl::SetWindowMask(const std::vector<std::vector<uint32_t>>& windowMask)
4316 {
4317     WLOGFI("SetWindowMask, WindowId: %{public}u", GetWindowId());
4318     if (IsWindowSessionInvalid()) {
4319         WLOGFE("session is invalid");
4320         return WMError::WM_ERROR_INVALID_WINDOW;
4321     }
4322 
4323     std::shared_ptr<Media::PixelMap> mask = HandleWindowMask(windowMask);
4324     if (mask == nullptr) {
4325         WLOGFE("Failed to create pixelMap of window mask");
4326         return WMError::WM_ERROR_INVALID_WINDOW;
4327     }
4328 
4329     auto rsMask = RSMask::CreatePixelMapMask(mask);
4330     surfaceNode_->SetCornerRadius(0.0f);
4331     surfaceNode_->SetShadowRadius(0.0f);
4332     surfaceNode_->SetAbilityBGAlpha(0);
4333     surfaceNode_->SetMask(rsMask); // RS interface to set mask
4334     RSTransaction::FlushImplicitTransaction();
4335 
4336     property_->SetWindowMask(mask);
4337     property_->SetIsShaped(true);
4338     return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK);
4339 }
4340 
UpdateDensity()4341 void WindowSceneSessionImpl::UpdateDensity()
4342 {
4343     UpdateDensityInner(nullptr);
4344 }
4345 
UpdateDensityInner(const sptr<DisplayInfo> & info)4346 void WindowSceneSessionImpl::UpdateDensityInner(const sptr<DisplayInfo>& info)
4347 {
4348     if (!userLimitsSet_) {
4349         UpdateWindowSizeLimits();
4350         UpdateNewSize();
4351         WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
4352         if (ret != WMError::WM_OK) {
4353             WLOGFE("update window proeprty failed! id: %{public}u.", GetWindowId());
4354             return;
4355         }
4356     }
4357 
4358     NotifyDisplayInfoChange(info);
4359 
4360     auto preRect = GetRect();
4361     UpdateViewportConfig(preRect, WindowSizeChangeReason::UNDEFINED, nullptr, info);
4362     WLOGFI("WindowSceneSessionImpl::UpdateDensity [%{public}d, %{public}d, %{public}u, %{public}u]",
4363         preRect.posX_, preRect.posY_, preRect.width_, preRect.height_);
4364 }
4365 
RegisterKeyboardPanelInfoChangeListener(const sptr<IKeyboardPanelInfoChangeListener> & listener)4366 WMError WindowSceneSessionImpl::RegisterKeyboardPanelInfoChangeListener(
4367     const sptr<IKeyboardPanelInfoChangeListener>& listener)
4368 {
4369     std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
4370     if (keyboardPanelInfoChangeListeners_ == nullptr) {
4371         TLOGI(WmsLogTag::WMS_KEYBOARD, "Register keyboard Panel info change listener id: %{public}d",
4372             GetPersistentId());
4373         keyboardPanelInfoChangeListeners_ = listener;
4374     } else {
4375         TLOGE(WmsLogTag::WMS_KEYBOARD, "Keyboard Panel info change, listener already registered");
4376         return WMError::WM_ERROR_INVALID_OPERATION;
4377     }
4378 
4379     return WMError::WM_OK;
4380 }
4381 
RegisterWindowAttachStateChangeListener(const sptr<IWindowAttachStateChangeListner> & listener)4382 WMError WindowSceneSessionImpl::RegisterWindowAttachStateChangeListener(
4383     const sptr<IWindowAttachStateChangeListner>& listener)
4384 {
4385     if (listener == nullptr) {
4386         TLOGE(WmsLogTag::WMS_SUB, "id: %{public}d, listener is null", GetPersistentId());
4387         return WMError::WM_ERROR_NULLPTR;
4388     }
4389     std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
4390     windowAttachStateChangeListener_ = listener;
4391     TLOGD(WmsLogTag::WMS_SUB, "id: %{public}d listener registered", GetPersistentId());
4392     return WMError::WM_OK;
4393 }
4394 
UnregisterWindowAttachStateChangeListener()4395 WMError WindowSceneSessionImpl::UnregisterWindowAttachStateChangeListener()
4396 {
4397     std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
4398     windowAttachStateChangeListener_ = nullptr;
4399     TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", GetPersistentId());
4400     return WMError::WM_OK;
4401 }
4402 
NotifyWindowAttachStateChange(bool isAttach)4403 WSError WindowSceneSessionImpl::NotifyWindowAttachStateChange(bool isAttach)
4404 {
4405     TLOGD(WmsLogTag::WMS_SUB, "id: %{public}d", GetPersistentId());
4406     std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
4407     if (!windowAttachStateChangeListener_) {
4408         TLOGW(WmsLogTag::WMS_SUB, "listener is null");
4409         return WSError::WS_ERROR_NULLPTR;
4410     }
4411 
4412     if (isAttach) {
4413         windowAttachStateChangeListener_->AfterAttached();
4414     } else {
4415         windowAttachStateChangeListener_->AfterDetached();
4416     }
4417     return WSError::WS_OK;
4418 }
4419 
UnregisterKeyboardPanelInfoChangeListener(const sptr<IKeyboardPanelInfoChangeListener> & listener)4420 WMError WindowSceneSessionImpl::UnregisterKeyboardPanelInfoChangeListener(
4421     const sptr<IKeyboardPanelInfoChangeListener>& listener)
4422 {
4423     std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
4424     keyboardPanelInfoChangeListeners_ = nullptr;
4425     TLOGI(WmsLogTag::WMS_KEYBOARD, "UnRegister keyboard Panel info change listener id: %{public}d", GetPersistentId());
4426 
4427     return WMError::WM_OK;
4428 }
4429 
NotifyKeyboardPanelInfoChange(const KeyboardPanelInfo & keyboardPanelInfo)4430 void WindowSceneSessionImpl::NotifyKeyboardPanelInfoChange(const KeyboardPanelInfo& keyboardPanelInfo)
4431 {
4432     TLOGI(WmsLogTag::WMS_KEYBOARD, "isKeyboardPanelShown: %{public}d, gravity: %{public}d"
4433         ", rect_: [%{public}d, %{public}d, %{public}d, %{public}d]", keyboardPanelInfo.isShowing_,
4434         keyboardPanelInfo.gravity_, keyboardPanelInfo.rect_.posX_, keyboardPanelInfo.rect_.posY_,
4435         keyboardPanelInfo.rect_.width_, keyboardPanelInfo.rect_.height_);
4436     std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
4437     if (keyboardPanelInfoChangeListeners_ && keyboardPanelInfoChangeListeners_.GetRefPtr()) {
4438         keyboardPanelInfoChangeListeners_.GetRefPtr()->OnKeyboardPanelInfoChanged(keyboardPanelInfo);
4439     } else {
4440         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanelInfoChangeListeners_ is unRegistered");
4441     }
4442 }
4443 
UpdateDisplayId(DisplayId displayId)4444 WSError WindowSceneSessionImpl::UpdateDisplayId(DisplayId displayId)
4445 {
4446     bool displayIdChanged = property_->GetDisplayId() != displayId;
4447     property_->SetDisplayId(displayId);
4448     NotifyDisplayInfoChange();
4449     if (displayIdChanged) {
4450         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, displayId: %{public}" PRIu64, GetPersistentId(), displayId);
4451         NotifyDisplayIdChange(displayId);
4452     }
4453     return WSError::WS_OK;
4454 }
4455 
UpdateOrientation()4456 WSError WindowSceneSessionImpl::UpdateOrientation()
4457 {
4458     TLOGD(WmsLogTag::DMS, "UpdateOrientation, wid: %{public}d", GetPersistentId());
4459     NotifyDisplayInfoChange();
4460     return WSError::WS_OK;
4461 }
4462 
NotifyDisplayInfoChange(const sptr<DisplayInfo> & info)4463 void WindowSceneSessionImpl::NotifyDisplayInfoChange(const sptr<DisplayInfo>& info)
4464 {
4465     TLOGD(WmsLogTag::DMS, "NotifyDisplayInfoChange, wid: %{public}d", GetPersistentId());
4466     sptr<DisplayInfo> displayInfo = nullptr;
4467     DisplayId displayId = 0;
4468     if (info == nullptr) {
4469         displayId = property_->GetDisplayId();
4470         auto display = SingletonContainer::IsDestroyed() ? nullptr :
4471             SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
4472         if (display == nullptr) {
4473             TLOGE(WmsLogTag::DMS, "get display by displayId %{public}" PRIu64 " failed.", displayId);
4474             return;
4475         }
4476         displayInfo = display->GetDisplayInfo();
4477     } else {
4478         displayInfo = info;
4479     }
4480     if (displayInfo == nullptr) {
4481         TLOGE(WmsLogTag::DMS, "get display info %{public}" PRIu64 " failed.", displayId);
4482         return;
4483     }
4484     if (IsSystemDensityChanged(displayInfo)) {
4485         lastSystemDensity_ = displayInfo->GetVirtualPixelRatio();
4486         NotifySystemDensityChange(displayInfo->GetVirtualPixelRatio());
4487     }
4488     float density = GetVirtualPixelRatio(displayInfo);
4489     DisplayOrientation orientation = displayInfo->GetDisplayOrientation();
4490 
4491     if (context_ == nullptr) {
4492         TLOGE(WmsLogTag::DMS, "get token of window:%{public}d failed because of context is null.", GetPersistentId());
4493         return;
4494     }
4495     auto token = context_->GetToken();
4496     if (token == nullptr) {
4497         TLOGE(WmsLogTag::DMS, "get token of window:%{public}d failed.", GetPersistentId());
4498         return;
4499     }
4500     SingletonContainer::Get<WindowManager>().NotifyDisplayInfoChange(token, displayId, density, orientation);
4501 }
4502 
MoveAndResizeKeyboard(const KeyboardLayoutParams & params)4503 WMError WindowSceneSessionImpl::MoveAndResizeKeyboard(const KeyboardLayoutParams& params)
4504 {
4505     Rect newRect = {0, 0, 0, 0};
4506     int32_t displayWidth = 0;
4507     int32_t displayHeight = 0;
4508     if (property_ == nullptr) {
4509         TLOGE(WmsLogTag::WMS_KEYBOARD, "property is nullptr");
4510         return WMError::WM_ERROR_NULLPTR;
4511     }
4512     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
4513     if (display != nullptr) {
4514         displayWidth = display->GetWidth();
4515         displayHeight = display->GetHeight();
4516     } else {
4517         auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
4518         if (defaultDisplayInfo != nullptr) {
4519             displayWidth = defaultDisplayInfo->GetWidth();
4520             displayHeight = defaultDisplayInfo->GetHeight();
4521         } else {
4522             TLOGE(WmsLogTag::WMS_KEYBOARD, "display is null, name: %{public}s, id: %{public}d",
4523                 property_->GetWindowName().c_str(), GetPersistentId());
4524             return WMError::WM_ERROR_NULLPTR;
4525         }
4526     }
4527     bool isLandscape = displayWidth > displayHeight ? true : false;
4528     newRect = isLandscape ? params.LandscapeKeyboardRect_ : params.PortraitKeyboardRect_;
4529     property_->SetRequestRect(newRect);
4530     TLOGI(WmsLogTag::WMS_KEYBOARD, "success, Id: %{public}d, newRect: %{public}s, isLandscape: %{public}d, "
4531         "displayWidth: %{public}d, displayHeight: %{public}d", GetPersistentId(), newRect.ToString().c_str(),
4532         isLandscape, displayWidth, displayHeight);
4533     return WMError::WM_OK;
4534 }
4535 
AdjustKeyboardLayout(const KeyboardLayoutParams & params)4536 WMError WindowSceneSessionImpl::AdjustKeyboardLayout(const KeyboardLayoutParams& params)
4537 {
4538     TLOGI(WmsLogTag::WMS_KEYBOARD, "gravity: %{public}u, "
4539         "landscapeAvoidHeight: %{public}d, portraitAvoidHeight: %{public}d "
4540         "LandscapeKeyboardRect: %{public}s, PortraitKeyboardRect: %{public}s, "
4541         "LandscapePanelRect: %{public}s, PortraitPanelRect: %{public}s",
4542         static_cast<uint32_t>(params.gravity_), params.landscapeAvoidHeight_, params.portraitAvoidHeight_,
4543         params.LandscapeKeyboardRect_.ToString().c_str(), params.PortraitKeyboardRect_.ToString().c_str(),
4544         params.LandscapePanelRect_.ToString().c_str(), params.PortraitPanelRect_.ToString().c_str());
4545     if (property_ == nullptr) {
4546         TLOGE(WmsLogTag::WMS_KEYBOARD, "property is nullptr");
4547         return WMError::WM_ERROR_NULLPTR;
4548     }
4549     property_->SetKeyboardLayoutParams(params);
4550     auto ret = MoveAndResizeKeyboard(params);
4551     if (ret != WMError::WM_OK) {
4552         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboard move and resize failed");
4553         return ret;
4554     }
4555     auto hostSession = GetHostSession();
4556     if (hostSession != nullptr) {
4557         return static_cast<WMError>(hostSession->AdjustKeyboardLayout(params));
4558     }
4559     return WMError::WM_OK;
4560 }
4561 
SetImmersiveModeEnabledState(bool enable)4562 WMError WindowSceneSessionImpl::SetImmersiveModeEnabledState(bool enable)
4563 {
4564     TLOGD(WmsLogTag::WMS_IMMS, "id: %{public}u, enable: %{public}u", GetWindowId(), enable);
4565     if (IsWindowSessionInvalid()) {
4566         return WMError::WM_ERROR_INVALID_WINDOW;
4567     }
4568     if (GetHostSession() == nullptr) {
4569         return WMError::WM_ERROR_NULLPTR;
4570     }
4571     if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
4572         WindowMode::WINDOW_MODE_FULLSCREEN)) {
4573         return WMError::WM_ERROR_INVALID_WINDOW;
4574     }
4575     const WindowType curWindowType = GetType();
4576     if (!WindowHelper::IsMainWindow(curWindowType) && !WindowHelper::IsSubWindow(curWindowType)) {
4577         return WMError::WM_ERROR_INVALID_WINDOW;
4578     }
4579 
4580     enableImmersiveMode_ = enable;
4581     hostSession_->OnLayoutFullScreenChange(enableImmersiveMode_);
4582     WindowMode mode = GetMode();
4583     auto isPC = windowSystemConfig_.uiType_ == UI_TYPE_PC;
4584     if (!isPC || mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
4585         return SetLayoutFullScreen(enableImmersiveMode_);
4586     }
4587     return WMError::WM_OK;
4588 }
4589 
GetImmersiveModeEnabledState() const4590 bool WindowSceneSessionImpl::GetImmersiveModeEnabledState() const
4591 {
4592     TLOGD(WmsLogTag::WMS_IMMS, "id: %{public}u, GetImmersiveModeEnabledState = %{public}u",
4593         GetWindowId(), enableImmersiveMode_);
4594     if (IsWindowSessionInvalid()) {
4595         return false;
4596     }
4597     return enableImmersiveMode_;
4598 }
4599 
4600 template <typename K, typename V>
GetValueByKey(const std::unordered_map<K,V> & map,K key)4601 static V GetValueByKey(const std::unordered_map<K, V>& map, K key)
4602 {
4603     auto it = map.find(key);
4604     return it != map.end() ? it->second : V{};
4605 }
4606 
HandleEventForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)4607 void WindowSceneSessionImpl::HandleEventForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
4608     MMI::PointerEvent::PointerItem& pointerItem)
4609 {
4610     int32_t action = pointerEvent->GetPointerAction();
4611     switch (action) {
4612         case MMI::PointerEvent::POINTER_ACTION_DOWN:
4613             HandleDownForCompatibleMode(pointerEvent, pointerItem);
4614             break;
4615         case MMI::PointerEvent::POINTER_ACTION_MOVE:
4616             HandleMoveForCompatibleMode(pointerEvent, pointerItem);
4617             break;
4618         case MMI::PointerEvent::POINTER_ACTION_UP:
4619             HandleUpForCompatibleMode(pointerEvent, pointerItem);
4620             break;
4621         default:
4622             break;
4623     }
4624 }
4625 
HandleDownForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)4626 void WindowSceneSessionImpl::HandleDownForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
4627     MMI::PointerEvent::PointerItem& pointerItem)
4628 {
4629     int32_t displayX = pointerItem.GetDisplayX();
4630     int32_t displayY = pointerItem.GetDisplayY();
4631     int32_t displayId = property_->GetDisplayId();
4632     int32_t pointerCount = pointerEvent->GetPointerCount();
4633     if (pointerCount == 1) {
4634         eventMapTriggerByDisplay_[displayId] = std::vector<bool>(MAX_POINTERS);
4635         eventMapDeltaXByDisplay_[displayId] = std::vector<int32_t>(MAX_POINTERS);
4636         downPointerByDisplay_[displayId] = std::vector<PointInfo>(MAX_POINTERS);
4637         isOverTouchSlop_ = false;
4638         isDown_ = true;
4639     }
4640 
4641     if (IsInMappingRegionForCompatibleMode(displayX, displayY)) {
4642         int32_t pointerId = pointerEvent->GetPointerId();
4643         if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
4644             pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size() ||
4645             pointerId >= GetValueByKey(downPointerByDisplay_, displayId).size()) {
4646             TLOGE(WmsLogTag::DEFAULT, "pointerId: %{public}d out of range", pointerId);
4647             return;
4648         }
4649         eventMapTriggerByDisplay_[displayId][pointerId] = true;
4650         downPointerByDisplay_[displayId][pointerId] = {displayX, displayY};
4651         const auto& windowRect = GetRect();
4652         float xMappingScale = 1.0f;
4653         if (windowRect.posX_ != 0) {
4654             xMappingScale = static_cast<float>(windowRect.width_) / windowRect.posX_;
4655         }
4656         int32_t windowLeft = windowRect.posX_;
4657         int32_t windowRight = windowRect.posX_ + windowRect.width_;
4658         int32_t transferX;
4659         if (displayX <= windowLeft) {
4660             transferX = windowRight - xMappingScale * (windowLeft - displayX);
4661         } else {
4662             transferX = windowLeft + xMappingScale * (displayX - windowRight);
4663         }
4664         if (transferX < 0) {
4665             transferX = 0;
4666         }
4667         TLOGI(WmsLogTag::DEFAULT, "DOWN in mapping region, displayX: %{public}d, transferX: %{public}d, "
4668             "pointerId: %{public}d", displayX, transferX, pointerId);
4669         eventMapDeltaXByDisplay_[displayId][pointerId] = transferX - displayX;
4670         ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
4671     }
4672 }
4673 
HandleMoveForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)4674 void WindowSceneSessionImpl::HandleMoveForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
4675     MMI::PointerEvent::PointerItem& pointerItem)
4676 {
4677     if (!isDown_) {
4678         TLOGW(WmsLogTag::DEFAULT, "receive move before down, skip");
4679         return;
4680     }
4681     int32_t displayId = property_->GetDisplayId();
4682     int32_t pointerId = pointerEvent->GetPointerId();
4683     if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
4684         pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size() ||
4685         !GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId]) {
4686         return;
4687     }
4688 
4689     int32_t displayX = pointerItem.GetDisplayX();
4690     int32_t displayY = pointerItem.GetDisplayY();
4691     const auto& windowRect = GetRect();
4692     if (!isOverTouchSlop_ && CheckTouchSlop(pointerId, displayX, displayY, windowRect.width_ / TOUCH_SLOP_RATIO)) {
4693         TLOGD(WmsLogTag::DEFAULT, "reach touch slop, threshold: %{public}d", windowRect.width_ / TOUCH_SLOP_RATIO);
4694         isOverTouchSlop_ = true;
4695     }
4696     int32_t transferX = displayX + GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId];
4697     TLOGD(WmsLogTag::DEFAULT, "MOVE, displayX: %{public}d, transferX: %{public}d, pointerId: %{public}d",
4698         displayX, transferX, pointerId);
4699     ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
4700 }
4701 
HandleUpForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)4702 void WindowSceneSessionImpl::HandleUpForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
4703     MMI::PointerEvent::PointerItem& pointerItem)
4704 {
4705     if (!isDown_) {
4706         TLOGW(WmsLogTag::DEFAULT, "receive up before down, skip");
4707         return;
4708     }
4709     int32_t displayId = property_->GetDisplayId();
4710     int32_t pointerId = pointerEvent->GetPointerId();
4711     if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
4712         pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size()) {
4713         return;
4714     }
4715     if (GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId]) {
4716         int32_t displayX = pointerItem.GetDisplayX();
4717         int32_t transferX = displayX + GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId];
4718         ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
4719         TLOGI(WmsLogTag::DEFAULT, "UP, displayX: %{public}d, transferX: %{public}d, pointerId: %{public}d",
4720             displayX, transferX, pointerId);
4721         GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId] = 0;
4722         GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId] = false;
4723         IgnoreClickEvent(pointerEvent);
4724     }
4725     int32_t pointerCount = pointerEvent->GetPointerCount();
4726     if (pointerCount == 1) {
4727         eventMapDeltaXByDisplay_.erase(displayId);
4728         eventMapTriggerByDisplay_.erase(displayId);
4729         downPointerByDisplay_.erase(displayId);
4730         isDown_ = false;
4731     }
4732 }
4733 
ConvertPointForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem,int32_t transferX)4734 void WindowSceneSessionImpl::ConvertPointForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
4735     MMI::PointerEvent::PointerItem& pointerItem, int32_t transferX)
4736 {
4737     const auto& windowRect = GetRect();
4738     int32_t pointerId = pointerEvent->GetPointerId();
4739 
4740     pointerItem.SetDisplayX(transferX);
4741     pointerItem.SetDisplayXPos(static_cast<double>(transferX));
4742     pointerItem.SetWindowX(transferX - windowRect.posX_);
4743     pointerItem.SetWindowXPos(static_cast<double>(transferX - windowRect.posX_));
4744     pointerEvent->UpdatePointerItem(pointerId, pointerItem);
4745 }
4746 
IsInMappingRegionForCompatibleMode(int32_t displayX,int32_t displayY)4747 bool WindowSceneSessionImpl::IsInMappingRegionForCompatibleMode(int32_t displayX, int32_t displayY)
4748 {
4749     const auto& windowRect = GetRect();
4750     Rect pointerRect = { displayX, displayY, 0, 0 };
4751     return !pointerRect.IsInsideOf(windowRect);
4752 }
4753 
CheckTouchSlop(int32_t pointerId,int32_t displayX,int32_t displayY,int32_t threshold)4754 bool WindowSceneSessionImpl::CheckTouchSlop(int32_t pointerId, int32_t displayX, int32_t displayY, int32_t threshold)
4755 {
4756     int32_t displayId = property_->GetDisplayId();
4757     if (downPointerByDisplay_.find(displayId) == downPointerByDisplay_.end()) {
4758         return false;
4759     }
4760     std::vector<PointInfo> downPointers = downPointerByDisplay_[displayId];
4761     return pointerId < downPointers.size() &&
4762         (std::abs(displayX - downPointers[pointerId].x) >= threshold ||
4763         std::abs(displayY - downPointers[pointerId].y) >= threshold);
4764 }
4765 
IgnoreClickEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)4766 void WindowSceneSessionImpl::IgnoreClickEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
4767 {
4768     int32_t action = pointerEvent->GetPointerAction();
4769     if (action != MMI::PointerEvent::POINTER_ACTION_UP) {
4770         return;
4771     }
4772     if (isOverTouchSlop_) {
4773         if (pointerEvent->GetPointerCount() == 1) {
4774             isOverTouchSlop_ = false;
4775         }
4776     } else {
4777         pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
4778         TLOGI(WmsLogTag::DEFAULT, "transfer UP to CANCEL for not over touch slop");
4779     }
4780 }
4781 
GetWindowStatus(WindowStatus & windowStatus)4782 WMError WindowSceneSessionImpl::GetWindowStatus(WindowStatus& windowStatus)
4783 {
4784     if (IsWindowSessionInvalid()) {
4785         TLOGE(WmsLogTag::DEFAULT, "session is invalid");
4786         return WMError::WM_ERROR_INVALID_WINDOW;
4787     }
4788     if (property_ == nullptr) {
4789         TLOGE(WmsLogTag::DEFAULT, "property_ is null, WinId:%{public}u", GetWindowId());
4790         return WMError::WM_ERROR_NULLPTR;
4791     }
4792     windowStatus = GetWindowStatusInner(GetMode());
4793     TLOGD(WmsLogTag::DEFAULT, "WinId:%{public}u, WindowStatus:%{public}u", GetWindowId(), windowStatus);
4794     return WMError::WM_OK;
4795 }
4796 
GetIsUIExtensionFlag() const4797 bool WindowSceneSessionImpl::GetIsUIExtensionFlag() const
4798 {
4799     return property_->GetExtensionFlag();
4800 }
4801 
GetIsUIExtensionSubWindowFlag() const4802 bool WindowSceneSessionImpl::GetIsUIExtensionSubWindowFlag() const
4803 {
4804     return property_->GetIsUIExtensionSubWindowFlag();
4805 }
4806 
SetGestureBackEnabled(bool enable)4807 WMError WindowSceneSessionImpl::SetGestureBackEnabled(bool enable)
4808 {
4809     if (windowSystemConfig_.uiType_ == UI_TYPE_PC) {
4810         TLOGI(WmsLogTag::WMS_IMMS, "device is not support.");
4811         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
4812     }
4813     if (!WindowHelper::IsMainFullScreenWindow(GetType(), property_->GetWindowMode()) || IsFreeMultiWindowMode()) {
4814         TLOGI(WmsLogTag::WMS_IMMS, "not full screen main window.");
4815         return WMError::WM_ERROR_INVALID_PARAM;
4816     }
4817     TLOGD(WmsLogTag::WMS_IMMS, "id: %{public}u, enable: %{public}u", GetWindowId(), enable);
4818     gestureBackEnabled_ = enable;
4819     auto hostSession = GetHostSession();
4820     CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
4821     return hostSession->SetGestureBackEnabled(enable);
4822 }
4823 
GetGestureBackEnabled(bool & enable)4824 WMError WindowSceneSessionImpl::GetGestureBackEnabled(bool& enable)
4825 {
4826     if (windowSystemConfig_.uiType_ == UI_TYPE_PC) {
4827         TLOGI(WmsLogTag::WMS_IMMS, "device is not support.");
4828         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
4829     }
4830     if (!WindowHelper::IsMainFullScreenWindow(GetType(), property_->GetWindowMode()) || IsFreeMultiWindowMode()) {
4831         TLOGI(WmsLogTag::WMS_IMMS, "not full screen main window.");
4832         return WMError::WM_ERROR_INVALID_TYPE;
4833     }
4834     enable = gestureBackEnabled_;
4835     TLOGD(WmsLogTag::WMS_IMMS, "id: %{public}u, enable: %{public}u", GetWindowId(), enable);
4836     return WMError::WM_OK;
4837 }
4838 
IsSystemDensityChanged(const sptr<DisplayInfo> & displayInfo)4839 bool WindowSceneSessionImpl::IsSystemDensityChanged(const sptr<DisplayInfo>& displayInfo)
4840 {
4841     if (MathHelper::NearZero(lastSystemDensity_ - displayInfo->GetVirtualPixelRatio())) {
4842         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "System density not change");
4843         return false;
4844     }
4845     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "windowId: %{public}d, lastDensity: %{public}f, currDensity: %{public}f",
4846         GetPersistentId(), lastSystemDensity_, displayInfo->GetVirtualPixelRatio());
4847     return true;
4848 }
4849 
IsDefaultDensityEnabled()4850 bool WindowSceneSessionImpl::IsDefaultDensityEnabled()
4851 {
4852     if (WindowHelper::IsMainWindow(GetType())) {
4853         return GetDefaultDensityEnabled();
4854     }
4855     if (auto mainWindow = FindMainWindowWithContext()) {
4856         CopyUniqueDensityParameter(mainWindow);
4857         return mainWindow->GetDefaultDensityEnabled();
4858     }
4859     return false;
4860 }
4861 
GetMainWindowCustomDensity()4862 float WindowSceneSessionImpl::GetMainWindowCustomDensity()
4863 {
4864     if (WindowHelper::IsMainWindow(GetType())) {
4865         return GetCustomDensity();
4866     }
4867     auto mainWindow = FindMainWindowWithContext();
4868     return mainWindow ? mainWindow->GetCustomDensity() : UNDEFINED_DENSITY;
4869 }
4870 
GetCustomDensity() const4871 float WindowSceneSessionImpl::GetCustomDensity() const
4872 {
4873     return customDensity_;
4874 }
4875 
SetCustomDensity(float density)4876 WMError WindowSceneSessionImpl::SetCustomDensity(float density)
4877 {
4878     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, density=%{public}f", GetWindowId(), density);
4879     if (IsWindowSessionInvalid()) {
4880         return WMError::WM_ERROR_INVALID_WINDOW;
4881     }
4882     if ((density < MINIMUM_CUSTOM_DENSITY && !MathHelper::NearZero(density - UNDEFINED_DENSITY)) ||
4883         density > MAXIMUM_CUSTOM_DENSITY) {
4884         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u set invalid density=%{public}f", GetWindowId(), density);
4885         return WMError::WM_ERROR_INVALID_PARAM;
4886     }
4887     if (!WindowHelper::IsMainWindow(GetType())) {
4888         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, must be app main window", GetWindowId());
4889         return WMError::WM_ERROR_INVALID_CALLING;
4890     }
4891     if (MathHelper::NearZero(customDensity_ - density)) {
4892         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u set density not change", GetWindowId());
4893         return WMError::WM_OK;
4894     }
4895     isDefaultDensityEnabled_ = false;
4896     customDensity_ = density;
4897     UpdateDensity();
4898 
4899     return WMError::WM_OK;
4900 }
4901 
GetWindowDensityInfo(WindowDensityInfo & densityInfo)4902 WMError WindowSceneSessionImpl::GetWindowDensityInfo(WindowDensityInfo& densityInfo)
4903 {
4904     if (IsWindowSessionInvalid()) {
4905         return WMError::WM_ERROR_INVALID_WINDOW;
4906     }
4907     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
4908     if (display == nullptr) {
4909         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "display is null, winId=%{public}u", GetWindowId());
4910         return WMError::WM_ERROR_NULLPTR;
4911     }
4912     auto displayInfo = display->GetDisplayInfo();
4913     if (displayInfo == nullptr) {
4914         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "displayInfo is null, winId=%{public}u", GetWindowId());
4915         return WMError::WM_ERROR_NULLPTR;
4916     }
4917     densityInfo.systemDensity = displayInfo->GetVirtualPixelRatio();
4918     densityInfo.defaultDensity = displayInfo->GetDefaultVirtualPixelRatio();
4919     auto customDensity = UNDEFINED_DENSITY;
4920     if (IsDefaultDensityEnabled()) {
4921         customDensity = displayInfo->GetDefaultVirtualPixelRatio();
4922     } else {
4923         customDensity = GetCustomDensity();
4924         customDensity = MathHelper::NearZero(customDensity - UNDEFINED_DENSITY) ? displayInfo->GetVirtualPixelRatio()
4925                                                                                 : customDensity;
4926     }
4927     densityInfo.customDensity = customDensity;
4928     return WMError::WM_OK;
4929 }
4930 } // namespace Rosen
4931 } // namespace OHOS
4932