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