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