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