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