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 <sstream>
23 #include <string>
24 #include <transaction/rs_transaction.h>
25 #include <hitrace_meter.h>
26 #include <hisysevent.h>
27
28 #include <application_context.h>
29 #include "color_parser.h"
30 #include "common/include/fold_screen_state_internel.h"
31 #include "common/include/fold_screen_common.h"
32 #include "configuration.h"
33 #include "display_manager.h"
34 #include "display_manager_adapter.h"
35 #include "dm_common.h"
36 #include "extension/extension_business_info.h"
37 #include "fold_screen_controller/super_fold_state_manager.h"
38 #include "input_transfer_station.h"
39 #include "perform_reporter.h"
40 #include "rs_adapter.h"
41 #include "session_helper.h"
42 #include "session_permission.h"
43 #include "session/container/include/window_event_channel.h"
44 #include "session_manager/include/session_manager.h"
45 #include "singleton_container.h"
46 #include "sys_cap_util.h"
47 #include "window_adapter.h"
48 #include "window_helper.h"
49 #include "window_inspector.h"
50 #include "window_manager_hilog.h"
51 #include "window_prepare_terminate.h"
52 #include "wm_common.h"
53 #include "wm_common_inner.h"
54 #include "wm_math.h"
55 #include "session_manager_agent_controller.h"
56 #include <transaction/rs_interfaces.h>
57 #include "surface_capture_future.h"
58 #include "pattern_detach_callback.h"
59 #include "picture_in_picture_manager.h"
60 #include "window_session_impl.h"
61 #include "sys_cap_util.h"
62
63 namespace OHOS {
64 namespace Rosen {
65 union WSColorParam {
66 #if defined(BIG_ENDIANNESS) && BIG_ENDIANNESS
67 struct {
68 uint8_t alpha;
69 uint8_t red;
70 uint8_t green;
71 uint8_t blue;
72 } argb;
73 #else
74 struct {
75 uint8_t blue;
76 uint8_t green;
77 uint8_t red;
78 uint8_t alpha;
79 } argb;
80 #endif
81 uint32_t value;
82 };
83
84 #define CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession) \
85 do { \
86 if ((hostSession) == nullptr) { \
87 TLOGE(WmsLogTag::DEFAULT, "hostSession is null"); \
88 return; \
89 } \
90 } while (false)
91
92 #define CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, ret) \
93 do { \
94 if ((hostSession) == nullptr) { \
95 TLOGE(WmsLogTag::DEFAULT, "hostSession is null"); \
96 return ret; \
97 } \
98 } while (false)
99
100 namespace {
101 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowSceneSessionImpl"};
102 constexpr int32_t WINDOW_DETACH_TIMEOUT = 300;
103 constexpr int32_t WINDOW_LAYOUT_TIMEOUT = 30;
104 constexpr int32_t WINDOW_PAGE_ROTATION_TIMEOUT = 2000;
105 const std::string PARAM_DUMP_HELP = "-h";
106 constexpr float MIN_GRAY_SCALE = 0.0f;
107 constexpr float MAX_GRAY_SCALE = 1.0f;
108 constexpr int32_t DISPLAY_ID_C = 999;
109 constexpr int32_t MAX_POINTERS = 16;
110 constexpr int32_t TOUCH_SLOP_RATIO = 25;
111 const std::string BACK_WINDOW_EVENT = "scb_back_window_event";
112 const std::string COMPATIBLE_MAX_WINDOW_EVENT = "win_compatible_max_event";
113 const std::string COMPATIBLE_RECOVER_WINDOW_EVENT = "win_compatible_recover_event";
114 const std::unordered_set<WindowType> INVALID_SYSTEM_WINDOW_TYPE = {
115 WindowType::WINDOW_TYPE_NEGATIVE_SCREEN,
116 WindowType::WINDOW_TYPE_THEME_EDITOR,
117 WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR,
118 WindowType::WINDOW_TYPE_SCENE_BOARD,
119 WindowType::WINDOW_TYPE_KEYBOARD_PANEL,
120 WindowType::WINDOW_TYPE_APP_LAUNCHING,
121 WindowType::WINDOW_TYPE_INCOMING_CALL,
122 WindowType::WINDOW_TYPE_BOOT_ANIMATION,
123 WindowType::WINDOW_TYPE_FREEZE_DISPLAY,
124 WindowType::WINDOW_TYPE_PLACEHOLDER
125 };
126 const std::unordered_set<WindowType> INVALID_SCB_WINDOW_TYPE = {
127 WindowType::WINDOW_TYPE_WALLPAPER,
128 WindowType::WINDOW_TYPE_DESKTOP,
129 WindowType::WINDOW_TYPE_DOCK_SLICE,
130 WindowType::WINDOW_TYPE_STATUS_BAR,
131 WindowType::WINDOW_TYPE_KEYGUARD,
132 WindowType::WINDOW_TYPE_NAVIGATION_BAR,
133 WindowType::WINDOW_TYPE_LAUNCHER_RECENT,
134 WindowType::WINDOW_TYPE_LAUNCHER_DOCK
135 };
136 constexpr uint32_t MAX_SUB_WINDOW_LEVEL = 10;
137 constexpr float INVALID_DEFAULT_DENSITY = 1.0f;
138 constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_WIDTH = 40;
139 constexpr uint32_t FORCE_LIMIT_MIN_FLOATING_HEIGHT = 40;
140 constexpr int32_t API_VERSION_18 = 18;
141 constexpr uint32_t SNAPSHOT_TIMEOUT = 2000; // MS
142 constexpr uint32_t REASON_MAXIMIZE_MODE_CHANGE = 1;
143 }
144 std::mutex WindowSceneSessionImpl::keyboardPanelInfoChangeListenerMutex_;
145 using WindowSessionImplMap = std::map<std::string, std::pair<int32_t, sptr<WindowSessionImpl>>>;
146 std::mutex WindowSceneSessionImpl::windowAttachStateChangeListenerMutex_;
147
WindowSceneSessionImpl(const sptr<WindowOption> & option)148 WindowSceneSessionImpl::WindowSceneSessionImpl(const sptr<WindowOption>& option) : WindowSessionImpl(option)
149 {
150 WLOGFI("[WMSCom] Constructor %{public}s", GetWindowName().c_str());
151 }
152
~WindowSceneSessionImpl()153 WindowSceneSessionImpl::~WindowSceneSessionImpl()
154 {
155 WLOGFI("[WMSCom] Destructor %{public}d, %{public}s", GetPersistentId(), GetWindowName().c_str());
156 }
157
IsValidSystemWindowType(const WindowType & type)158 bool WindowSceneSessionImpl::IsValidSystemWindowType(const WindowType& type)
159 {
160 if (INVALID_SYSTEM_WINDOW_TYPE.find(type) != INVALID_SYSTEM_WINDOW_TYPE.end()) {
161 TLOGI(WmsLogTag::WMS_SYSTEM, "Invalid type: %{public}u", type);
162 return false;
163 }
164 TLOGI(WmsLogTag::WMS_SYSTEM, "Valid type: %{public}u", type);
165 return true;
166 }
167
FindParentSessionByParentId(uint32_t parentId)168 sptr<WindowSessionImpl> WindowSceneSessionImpl::FindParentSessionByParentId(uint32_t parentId)
169 {
170 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
171 for (const auto& [_, pair] : windowSessionMap_) {
172 auto& window = pair.second;
173 if (window && window->GetWindowId() == parentId) {
174 if (WindowHelper::IsMainWindow(window->GetType()) || WindowHelper::IsSystemWindow(window->GetType())) {
175 TLOGD(WmsLogTag::WMS_SUB, "Find parent window [%{public}s, %{public}u, %{public}d]",
176 window->GetProperty()->GetWindowName().c_str(), parentId,
177 window->GetProperty()->GetPersistentId());
178 return window;
179 } else if (WindowHelper::IsSubWindow(window->GetType()) &&
180 (IsSessionMainWindow(window->GetParentId()) ||
181 window->GetProperty()->GetIsUIExtFirstSubWindow() ||
182 window->GetProperty()->GetSubWindowLevel() < MAX_SUB_WINDOW_LEVEL)) {
183 // subwindow's grandparent is mainwindow or subwindow's parent is an extension subwindow
184 TLOGD(WmsLogTag::WMS_SUB, "Find parent window [%{public}s, %{public}u, %{public}d]",
185 window->GetProperty()->GetWindowName().c_str(), parentId,
186 window->GetProperty()->GetPersistentId());
187 return window;
188 }
189 }
190 }
191 TLOGD(WmsLogTag::WMS_SUB, "Can not find parent window, id: %{public}d", parentId);
192 return nullptr;
193 }
194
FindParentMainSession(uint32_t parentId,const SessionMap & sessionMap)195 sptr<WindowSessionImpl> WindowSceneSessionImpl::FindParentMainSession(uint32_t parentId, const SessionMap& sessionMap)
196 {
197 if (parentId == INVALID_SESSION_ID) {
198 TLOGW(WmsLogTag::WMS_SUB, "invalid parent id");
199 return nullptr;
200 }
201 for (const auto& [_, pair] : sessionMap) {
202 auto& window = pair.second;
203 if (window && window->GetWindowId() == parentId) {
204 if (WindowHelper::IsMainWindow(window->GetType()) ||
205 (WindowHelper::IsSystemWindow(window->GetType()) && window->GetParentId() == INVALID_SESSION_ID)) {
206 TLOGD(WmsLogTag::WMS_SUB, "find main session, id:%{public}u", window->GetWindowId());
207 return window;
208 }
209 return FindParentMainSession(window->GetParentId(), sessionMap);
210 }
211 }
212 TLOGW(WmsLogTag::WMS_SUB, "don't find main session, parentId:%{public}u", parentId);
213 return nullptr;
214 }
215
IsSessionMainWindow(uint32_t parentId)216 bool WindowSceneSessionImpl::IsSessionMainWindow(uint32_t parentId)
217 {
218 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
219 for (const auto& [_, pair] : windowSessionMap_) {
220 auto& window = pair.second;
221 if (window && window->GetWindowId() == parentId && WindowHelper::IsMainWindow(window->GetType())) {
222 return true;
223 }
224 }
225 return false;
226 }
227
AddSubWindowMapForExtensionWindow()228 void WindowSceneSessionImpl::AddSubWindowMapForExtensionWindow()
229 {
230 // update subWindowSessionMap_
231 auto extensionWindow = FindExtensionWindowWithContext();
232 if (extensionWindow != nullptr) {
233 auto parentWindowId = extensionWindow->GetPersistentId();
234 std::lock_guard<std::recursive_mutex> lock(subWindowSessionMutex_);
235 subWindowSessionMap_[parentWindowId].push_back(this);
236 } else {
237 TLOGE(WmsLogTag::WMS_SUB, "name: %{public}s not found parent extension window",
238 property_->GetWindowName().c_str());
239 }
240 }
241
GetParentSessionAndVerify(bool isToast,sptr<WindowSessionImpl> & parentSession)242 WMError WindowSceneSessionImpl::GetParentSessionAndVerify(bool isToast, sptr<WindowSessionImpl>& parentSession)
243 {
244 if (isToast) {
245 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
246 parentSession = FindParentMainSession(property_->GetParentId(), windowSessionMap_);
247 } else {
248 parentSession = FindParentSessionByParentId(property_->GetParentId());
249 }
250 if (parentSession == nullptr) {
251 TLOGE(WmsLogTag::WMS_LIFE, "parent of sub window is nullptr, name: %{public}s, type: %{public}d",
252 property_->GetWindowName().c_str(), GetType());
253 return WMError::WM_ERROR_NULLPTR;
254 }
255 return WindowSceneSessionImpl::VerifySubWindowLevel(false, parentSession);
256 }
257
VerifySubWindowLevel(bool isToast,const sptr<WindowSessionImpl> & parentSession)258 WMError WindowSceneSessionImpl::VerifySubWindowLevel(bool isToast, const sptr<WindowSessionImpl>& parentSession)
259 {
260 if (parentSession == nullptr) {
261 TLOGE(WmsLogTag::WMS_SUB, "parent of sub window is nullptr");
262 return WMError::WM_ERROR_NULLPTR;
263 }
264 if (!isToast && !parentSession->GetIsUIExtFirstSubWindow() &&
265 parentSession->GetProperty()->GetSubWindowLevel() >= 1 &&
266 !parentSession->IsPcOrFreeMultiWindowCapabilityEnabled()) {
267 TLOGE(WmsLogTag::WMS_SUB, "device not support");
268 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
269 }
270 return WMError::WM_OK;
271 }
272
AdjustPropertySessionInfo(const std::shared_ptr<AbilityRuntime::Context> & context,SessionInfo & info)273 static void AdjustPropertySessionInfo(const std::shared_ptr<AbilityRuntime::Context>& context, SessionInfo& info)
274 {
275 if (!context) {
276 TLOGE(WmsLogTag::WMS_LIFE, "context is null");
277 return;
278 }
279 info.moduleName_ = context->GetHapModuleInfo() ? context->GetHapModuleInfo()->moduleName : "";
280 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
281 if (abilityContext && abilityContext->GetAbilityInfo()) {
282 info.abilityName_ = abilityContext->GetAbilityInfo()->name;
283 info.bundleName_ = abilityContext->GetAbilityInfo()->bundleName;
284 } else {
285 info.bundleName_ = context->GetBundleName();
286 }
287 }
288
CreateAndConnectSpecificSession()289 WMError WindowSceneSessionImpl::CreateAndConnectSpecificSession()
290 {
291 sptr<ISessionStage> iSessionStage(this);
292 sptr<IWindowEventChannel> eventChannel = sptr<WindowEventChannel>::MakeSptr(iSessionStage);
293 auto persistentId = INVALID_SESSION_ID;
294 sptr<Rosen::ISession> session;
295 auto context = GetContext();
296 sptr<IRemoteObject> token = context ? context->GetToken() : nullptr;
297 if (token) {
298 property_->SetTokenState(true);
299 }
300 AdjustPropertySessionInfo(context, property_->EditSessionInfo());
301
302 const WindowType type = GetType();
303 bool hasToastFlag = property_->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST);
304 if (WindowHelper::IsSubWindow(type) && (property_->GetIsUIExtFirstSubWindow() ||
305 (property_->GetIsUIExtAnySubWindow() && hasToastFlag))) {
306 property_->SetParentPersistentId(property_->GetParentId());
307 SetDefaultDisplayIdIfNeed();
308 property_->SetIsUIExtensionAbilityProcess(isUIExtensionAbilityProcess_);
309 // create sub session by parent session
310 SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
311 surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
312 if (!hasToastFlag) {
313 AddSubWindowMapForExtensionWindow();
314 }
315 } else if (WindowHelper::IsSubWindow(type)) {
316 sptr<WindowSessionImpl> parentSession = nullptr;
317 auto ret = WindowSceneSessionImpl::VerifySubWindowLevel(hasToastFlag, parentSession);
318 if (ret != WMError::WM_OK) {
319 return ret;
320 }
321 property_->SetDisplayId(parentSession->GetDisplayId());
322 // set parent persistentId
323 auto parentWindowId = parentSession->GetPersistentId();
324 property_->SetParentPersistentId(parentWindowId);
325 property_->SetIsPcAppInPad(parentSession->GetProperty()->GetIsPcAppInPad());
326 property_->SetPcAppInpadCompatibleMode(parentSession->GetProperty()->GetPcAppInpadCompatibleMode());
327 // creat sub session by parent session
328 SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
329 surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
330 {
331 std::lock_guard<std::recursive_mutex> lock(subWindowSessionMutex_);
332 // update subWindowSessionMap_
333 subWindowSessionMap_[parentWindowId].push_back(this);
334 }
335 SetTargetAPIVersion(parentSession->GetTargetAPIVersion());
336 } else { // system window
337 WMError createSystemWindowRet = CreateSystemWindow(type);
338 if (createSystemWindowRet != WMError::WM_OK) {
339 return createSystemWindowRet;
340 }
341 auto parentSession = FindParentSessionByParentId(property_->GetParentPersistentId());
342 if (parentSession != nullptr) {
343 property_->SetIsPcAppInPad(parentSession->GetProperty()->GetIsPcAppInPad());
344 }
345 PreProcessCreate();
346 SingletonContainer::Get<WindowAdapter>().CreateAndConnectSpecificSession(iSessionStage, eventChannel,
347 surfaceNode_, property_, persistentId, session, windowSystemConfig_, token);
348 }
349 property_->SetPersistentId(persistentId);
350 if (session == nullptr) {
351 TLOGI(WmsLogTag::WMS_LIFE, "create specific failed, session is nullptr, name: %{public}s",
352 property_->GetWindowName().c_str());
353 return WMError::WM_ERROR_NULLPTR;
354 }
355 {
356 std::lock_guard<std::mutex> lock(hostSessionMutex_);
357 hostSession_ = session;
358 }
359 TLOGI(WmsLogTag::WMS_LIFE, "name:%{public}s,id:%{public}d,parentId:%{public}d,type:%{public}u,"
360 "touchable:%{public}d,displayId:%{public}" PRIu64, property_->GetWindowName().c_str(),
361 property_->GetPersistentId(), property_->GetParentPersistentId(), GetType(),
362 property_->GetTouchable(), property_->GetDisplayId());
363 return WMError::WM_OK;
364 }
365
CreateSystemWindow(WindowType type)366 WMError WindowSceneSessionImpl::CreateSystemWindow(WindowType type)
367 {
368 if (WindowHelper::IsAppFloatingWindow(type) || WindowHelper::IsPipWindow(type) ||
369 type == WindowType::WINDOW_TYPE_TOAST || WindowHelper::IsFbWindow(type)) {
370 property_->SetParentPersistentId(GetFloatingWindowParentId());
371 TLOGI(WmsLogTag::WMS_SYSTEM, "parentId: %{public}d, type: %{public}d",
372 property_->GetParentPersistentId(), type);
373 auto mainWindow = FindMainWindowWithContext();
374 property_->SetFloatingWindowAppType(mainWindow != nullptr ? true : false);
375 if (mainWindow != nullptr) {
376 if (property_->GetDisplayId() == DISPLAY_ID_INVALID) {
377 property_->SetDisplayId(mainWindow->GetDisplayId());
378 }
379 }
380 } else if (type == WindowType::WINDOW_TYPE_DIALOG) {
381 if (auto mainWindow = FindMainWindowWithContext()) {
382 property_->SetParentPersistentId(mainWindow->GetPersistentId());
383 property_->SetDisplayId(mainWindow->GetDisplayId());
384 TLOGI(WmsLogTag::WMS_DIALOG, "The parentId: %{public}d", mainWindow->GetPersistentId());
385 }
386 } else if (WindowHelper::IsSystemSubWindow(type)) {
387 auto parentSession = FindParentSessionByParentId(property_->GetParentId());
388 if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
389 TLOGE(WmsLogTag::WMS_LIFE, "parent of system sub window, name: %{public}s, type: %{public}d",
390 property_->GetWindowName().c_str(), type);
391 return WMError::WM_ERROR_NULLPTR;
392 }
393 if (WindowHelper::IsSystemSubWindow(parentSession->GetType())) {
394 TLOGE(WmsLogTag::WMS_LIFE, "parent is system sub window, name: %{public}s, type: %{public}d",
395 property_->GetWindowName().c_str(), type);
396 return WMError::WM_ERROR_INVALID_TYPE;
397 }
398 // set parent persistentId
399 property_->SetParentPersistentId(parentSession->GetPersistentId());
400 property_->SetDisplayId(parentSession->GetDisplayId());
401 }
402 return WMError::WM_OK;
403 }
404
RecoverAndConnectSpecificSession()405 WMError WindowSceneSessionImpl::RecoverAndConnectSpecificSession()
406 {
407 TLOGI(WmsLogTag::WMS_RECOVER, "windowName=%{public}s, windowMode=%{public}u, windowType=%{public}u, "
408 "persistentId=%{public}d, windowState=%{public}d, requestWindowState=%{public}d, parentId=%{public}d",
409 GetWindowName().c_str(), property_->GetWindowMode(), property_->GetWindowType(), GetPersistentId(), state_,
410 requestState_, property_->GetParentId());
411
412 const WindowType type = GetType();
413 if (WindowHelper::IsSubWindow(type) && !property_->GetIsUIExtFirstSubWindow()) { // sub window
414 TLOGD(WmsLogTag::WMS_RECOVER, "SubWindow");
415 auto parentSession = FindParentSessionByParentId(property_->GetParentId());
416 if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
417 TLOGE(WmsLogTag::WMS_RECOVER, "parentSession is null");
418 return WMError::WM_ERROR_NULLPTR;
419 }
420 }
421 if (WindowHelper::IsPipWindow(type)) {
422 TLOGI(WmsLogTag::WMS_RECOVER, "pipWindow");
423 PictureInPictureManager::DoClose(true, true);
424 return WMError::WM_OK;
425 }
426 windowRecoverStateChangeFunc_(true, WindowRecoverState::WINDOW_START_RECONNECT);
427 sptr<ISessionStage> iSessionStage(this);
428 sptr<IWindowEventChannel> eventChannel = sptr<WindowEventChannel>::MakeSptr(iSessionStage);
429 sptr<Rosen::ISession> session = nullptr;
430 auto context = GetContext();
431 sptr<IRemoteObject> token = context ? context->GetToken() : nullptr;
432 windowRecoverStateChangeFunc_(true, WindowRecoverState::WINDOW_DOING_RECONNECT);
433 SingletonContainer::Get<WindowAdapter>().RecoverAndConnectSpecificSession(
434 iSessionStage, eventChannel, surfaceNode_, property_, session, token);
435
436 if (session == nullptr) {
437 TLOGE(WmsLogTag::WMS_RECOVER, "Recover failed, session is nullptr");
438 windowRecoverStateChangeFunc_(true, WindowRecoverState::WINDOW_NOT_RECONNECT);
439 return WMError::WM_ERROR_NULLPTR;
440 }
441 {
442 std::lock_guard<std::mutex> lock(hostSessionMutex_);
443 hostSession_ = session;
444 }
445 windowRecoverStateChangeFunc_(true, WindowRecoverState::WINDOW_FINISH_RECONNECT);
446 TLOGI(WmsLogTag::WMS_RECOVER,
447 "over, windowName=%{public}s, persistentId=%{public}d",
448 GetWindowName().c_str(), GetPersistentId());
449 return WMError::WM_OK;
450 }
451
RecoverAndReconnectSceneSession()452 WMError WindowSceneSessionImpl::RecoverAndReconnectSceneSession()
453 {
454 TLOGI(WmsLogTag::WMS_RECOVER, "windowName=%{public}s, windowMode=%{public}u, windowType=%{public}u, "
455 "persistentId=%{public}d, windowState=%{public}d, requestWindowState=%{public}d", GetWindowName().c_str(),
456 property_->GetWindowMode(), property_->GetWindowType(), GetPersistentId(), state_, requestState_);
457
458 if (isFocused_) {
459 UpdateFocus(false);
460 }
461 auto context = GetContext();
462 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
463 if (context && context->GetHapModuleInfo() && abilityContext && abilityContext->GetAbilityInfo()) {
464 if (!abilityContext->IsHook() || (abilityContext->IsHook() && abilityContext->GetHookOff())) {
465 property_->EditSessionInfo().abilityName_ = abilityContext->GetAbilityInfo()->name;
466 property_->EditSessionInfo().moduleName_ = context->GetHapModuleInfo()->moduleName;
467 }
468 } else {
469 TLOGE(WmsLogTag::WMS_RECOVER, "context or abilityContext is null, recovered session failed");
470 return WMError::WM_ERROR_NULLPTR;
471 }
472 auto& info = property_->EditSessionInfo();
473 if (auto want = abilityContext->GetWant()) {
474 info.want = want;
475 } else {
476 TLOGE(WmsLogTag::WMS_RECOVER, "want is nullptr!");
477 }
478 windowRecoverStateChangeFunc_(false, WindowRecoverState::WINDOW_START_RECONNECT);
479 sptr<ISessionStage> iSessionStage(this);
480 sptr<IWindowEventChannel> iWindowEventChannel = sptr<WindowEventChannel>::MakeSptr(iSessionStage);
481 sptr<IRemoteObject> token = context ? context->GetToken() : nullptr;
482 sptr<Rosen::ISession> session = nullptr;
483 windowRecoverStateChangeFunc_(false, WindowRecoverState::WINDOW_DOING_RECONNECT);
484 auto ret = SingletonContainer::Get<WindowAdapter>().RecoverAndReconnectSceneSession(
485 iSessionStage, iWindowEventChannel, surfaceNode_, session, property_, token);
486 if (session == nullptr) {
487 TLOGE(WmsLogTag::WMS_RECOVER, "session is null, recovered session failed");
488 windowRecoverStateChangeFunc_(false, WindowRecoverState::WINDOW_NOT_RECONNECT);
489 return WMError::WM_ERROR_NULLPTR;
490 }
491 {
492 std::lock_guard<std::mutex> lock(hostSessionMutex_);
493 hostSession_ = session;
494 }
495 windowRecoverStateChangeFunc_(false, WindowRecoverState::WINDOW_FINISH_RECONNECT);
496 TLOGI(WmsLogTag::WMS_RECOVER, "Successful, persistentId=%{public}d", GetPersistentId());
497 return static_cast<WMError>(ret);
498 }
499
TransferLifeCycleEventToString(LifeCycleEvent type) const500 std::string WindowSceneSessionImpl::TransferLifeCycleEventToString(LifeCycleEvent type) const
501 {
502 std::string event;
503 switch (type) {
504 case LifeCycleEvent::CREATE_EVENT:
505 event = "CREATE";
506 break;
507 case LifeCycleEvent::SHOW_EVENT:
508 event = "SHOW";
509 break;
510 case LifeCycleEvent::HIDE_EVENT:
511 event = "HIDE";
512 break;
513 case LifeCycleEvent::DESTROY_EVENT:
514 event = "DESTROY";
515 break;
516 default:
517 event = "UNDEFINE";
518 break;
519 }
520 return event;
521 }
522
RecordLifeCycleExceptionEvent(LifeCycleEvent event,WMError errCode) const523 void WindowSceneSessionImpl::RecordLifeCycleExceptionEvent(LifeCycleEvent event, WMError errCode) const
524 {
525 if (!(errCode > WMError::WM_ERROR_NEED_REPORT_BASE && errCode < WMError::WM_ERROR_PIP_REPEAT_OPERATION)) {
526 return;
527 }
528 std::ostringstream oss;
529 oss << "life cycle is abnormal: " << "window_name: " << GetWindowName().c_str()
530 << ", id:" << GetWindowId() << ", event: " << TransferLifeCycleEventToString(event)
531 << ", errCode: " << static_cast<int32_t>(errCode) << ";";
532 std::string info = oss.str();
533 TLOGI(WmsLogTag::WMS_LIFE, "window life cycle exception: %{public}s", info.c_str());
534 int32_t ret = HiSysEventWrite(
535 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
536 "WINDOW_LIFE_CYCLE_EXCEPTION",
537 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
538 "PID", getpid(),
539 "UID", getuid(),
540 "MSG", info);
541 if (ret != 0) {
542 TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret:%{public}d", ret);
543 }
544 }
545
UpdateWindowState()546 void WindowSceneSessionImpl::UpdateWindowState()
547 {
548 {
549 std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
550 windowSessionMap_.insert(std::make_pair(property_->GetWindowName(),
551 std::pair<uint64_t, sptr<WindowSessionImpl>>(property_->GetPersistentId(), this)));
552 }
553 state_ = WindowState::STATE_CREATED;
554 requestState_ = WindowState::STATE_CREATED;
555 WindowType windowType = GetType();
556 if (WindowHelper::IsMainWindow(windowType)) {
557 if (property_->GetIsNeedUpdateWindowMode()) {
558 WLOGFI("UpdateWindowMode %{public}u mode %{public}u",
559 GetWindowId(), static_cast<uint32_t>(property_->GetWindowMode()));
560 UpdateWindowModeImmediately(property_->GetWindowMode());
561 property_->SetIsNeedUpdateWindowMode(false);
562 } else {
563 SetWindowMode(windowSystemConfig_.defaultWindowMode_);
564 }
565 NotifyWindowNeedAvoid(
566 (property_->GetWindowFlags()) & (static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
567 GetConfigurationFromAbilityInfo();
568 } else {
569 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
570 bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
571 bool isSysytemWindow = WindowHelper::IsSystemWindow(windowType);
572 UpdateWindowSizeLimits();
573 if ((isSubWindow || isDialogWindow || isSysytemWindow) && IsWindowDraggable()) {
574 WLOGFD("sync window limits to server side to make size limits work while resizing");
575 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
576 }
577 }
578 }
579
Create(const std::shared_ptr<AbilityRuntime::Context> & context,const sptr<Rosen::ISession> & iSession,const std::string & identityToken,bool isModuleAbilityHookEnd)580 WMError WindowSceneSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
581 const sptr<Rosen::ISession>& iSession, const std::string& identityToken, bool isModuleAbilityHookEnd)
582 {
583 TLOGI(WmsLogTag::WMS_LIFE, "Window Create name:%{public}s, state:%{public}u, mode:%{public}u",
584 property_->GetWindowName().c_str(), state_, GetWindowMode());
585 // allow iSession is nullptr when create window by innerkits
586 if (!context) {
587 TLOGW(WmsLogTag::WMS_LIFE, "context is nullptr");
588 }
589 WMError ret = WindowSessionCreateCheck();
590 if (ret != WMError::WM_OK) {
591 return ret;
592 }
593 // Since here is init of this window, no other threads will rw it.
594 hostSession_ = iSession;
595 SetContext(context);
596 identityToken_ = identityToken;
597 property_->SetIsAbilityHookOff(isModuleAbilityHookEnd);
598 TLOGI(WmsLogTag::WMS_LIFE, "SetIsAbilityHookOff %{public}d", isModuleAbilityHookEnd);
599 AdjustWindowAnimationFlag();
600 if (context && context->GetApplicationInfo() &&
601 context->GetApplicationInfo()->apiCompatibleVersion >= 9 && // 9: api version
602 !SessionPermission::IsSystemCalling()) {
603 WLOGI("Remove window flag WINDOW_FLAG_SHOW_WHEN_LOCKED");
604 property_->SetWindowFlags(property_->GetWindowFlags() &
605 (~(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED))));
606 }
607 int32_t zLevel = GetSubWindowZLevelByFlags(GetType(), GetWindowFlags(), IsTopmost());
608 if (zLevel != NORMAL_SUB_WINDOW_Z_LEVEL) {
609 property_->SetSubWindowZLevel(zLevel);
610 }
611
612 bool isSpecificSession = false;
613 const auto& initRect = GetRequestRect();
614 if (GetHostSession()) { // main window
615 SetDefaultDisplayIdIfNeed();
616 ret = Connect();
617 SetTargetAPIVersion(SysCapUtil::GetApiCompatibleVersion());
618 TLOGD(WmsLogTag::WMS_PC, "targeAPItVersion: %{public}d", GetTargetAPIVersion());
619 } else { // system or sub window
620 TLOGI(WmsLogTag::WMS_LIFE, "Create system or sub window with type=%{public}d", GetType());
621 isSpecificSession = true;
622 const auto& type = GetType();
623 if (WindowHelper::IsSystemWindow(type)) {
624 // Not valid system window type for session should return WMError::WM_OK;
625 if (!IsValidSystemWindowType(type)) {
626 return WMError::WM_ERROR_INVALID_CALLING;
627 }
628 if (INVALID_SCB_WINDOW_TYPE.find(type) != INVALID_SCB_WINDOW_TYPE.end()) {
629 TLOGI(WmsLogTag::WMS_SYSTEM, "Invalid SCB type: %{public}u", type);
630 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
631 }
632 InitSystemSessionDragEnable();
633 } else if (!WindowHelper::IsSubWindow(type)) {
634 TLOGI(WmsLogTag::WMS_LIFE, "create failed not system or sub type, type: %{public}d", type);
635 return WMError::WM_ERROR_INVALID_CALLING;
636 }
637 isEnableDefaultDensityWhenCreate_ = windowOption_->IsDefaultDensityEnabled();
638 ret = CreateAndConnectSpecificSession();
639 }
640
641 RecordLifeCycleExceptionEvent(LifeCycleEvent::CREATE_EVENT, ret);
642 if (ret == WMError::WM_OK) {
643 MakeSubOrDialogWindowDragableAndMoveble();
644 UpdateWindowState();
645 RegisterWindowRecoverStateChangeListener();
646 RegisterSessionRecoverListener(isSpecificSession);
647 UpdateDefaultStatusBarColor();
648 AddSetUIContentTimeoutCheck();
649 SetUIExtensionDestroyCompleteInSubWindow();
650 SetSubWindowZLevelToProperty();
651 InputTransferStation::GetInstance().AddInputWindow(this);
652 if (WindowHelper::IsSubWindow(GetType()) && !initRect.IsUninitializedRect()) {
653 auto hostSession = GetHostSession();
654 if (IsFullScreenSizeWindow(initRect.width_, initRect.height_) && (hostSession != nullptr)) {
655 // Full screen size sub window don't need to resize when dpi change
656 TLOGI(WmsLogTag::WMS_LIFE, "Full screen size sub window set isDefaultDensityEnabled true");
657 hostSession->OnDefaultDensityEnabled(true);
658 }
659 Resize(initRect.width_, initRect.height_);
660 }
661 RegisterWindowInspectorCallback();
662 SetPcAppInpadSpecificSystemBarInvisible();
663 SetPcAppInpadOrientationLandscape();
664 }
665 TLOGD(WmsLogTag::WMS_LIFE, "Window Create success [name:%{public}s, id:%{public}d], state:%{public}u, "
666 "mode:%{public}u, enableDefaultDensity:%{public}d, displayId:%{public}" PRIu64,
667 property_->GetWindowName().c_str(), property_->GetPersistentId(), state_, GetWindowMode(),
668 isEnableDefaultDensityWhenCreate_, property_->GetDisplayId());
669 return ret;
670 }
671
SetPcAppInpadSpecificSystemBarInvisible()672 WMError WindowSceneSessionImpl::SetPcAppInpadSpecificSystemBarInvisible()
673 {
674 TLOGI(WmsLogTag::WMS_COMPAT, "isPcAppInpadSpecificSystemBarInvisible: %{public}d",
675 property_->GetPcAppInpadSpecificSystemBarInvisible());
676 if (WindowHelper::IsMainWindow(GetType()) && IsPadAndNotFreeMutiWindowCompatibleMode() &&
677 property_->GetPcAppInpadSpecificSystemBarInvisible()) {
678 SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
679 UpdateSpecificSystemBarEnabled(false, false, statusProperty);
680 SetSpecificBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
681
682 SystemBarProperty NavigationIndicatorPorperty =
683 GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR);
684 UpdateSpecificSystemBarEnabled(false, false, NavigationIndicatorPorperty);
685 SetSpecificBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, NavigationIndicatorPorperty);
686 return WMError::WM_OK;
687 }
688 return WMError::WM_ERROR_INVALID_CALLING;
689 }
690
SetPcAppInpadOrientationLandscape()691 WMError WindowSceneSessionImpl::SetPcAppInpadOrientationLandscape()
692 {
693 TLOGI(WmsLogTag::WMS_COMPAT, "isPcAppInpadOrientationLandscape: %{public}d",
694 property_->GetPcAppInpadOrientationLandscape());
695 if (WindowHelper::IsMainWindow(GetType()) && IsPadAndNotFreeMutiWindowCompatibleMode() &&
696 property_->GetPcAppInpadOrientationLandscape()) {
697 SetRequestedOrientation(Orientation::HORIZONTAL, false);
698 return WMError::WM_OK;
699 }
700 return WMError::WM_ERROR_INVALID_CALLING;
701 }
702
IsFullScreenSizeWindow(uint32_t width,uint32_t height)703 bool WindowSceneSessionImpl::IsFullScreenSizeWindow(uint32_t width, uint32_t height)
704 {
705 DisplayId displayId = property_->GetDisplayId();
706 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
707 if (display == nullptr) {
708 TLOGE(WmsLogTag::WMS_LAYOUT, "display is null");
709 return false;
710 }
711 auto displayInfo = display->GetDisplayInfo();
712 if (displayInfo == nullptr) {
713 TLOGE(WmsLogTag::WMS_LAYOUT, "displayInfo is null");
714 return false;
715 }
716 uint32_t displayWidth = static_cast<uint32_t>(displayInfo->GetWidth());
717 uint32_t displayHeight = static_cast<uint32_t>(displayInfo->GetHeight());
718 if (displayWidth == width && displayHeight == height) {
719 return true;
720 }
721 if (!FoldScreenStateInternel::IsSuperFoldDisplayDevice() ||
722 DisplayManager::GetInstance().GetFoldStatus() != FoldStatus::HALF_FOLD) {
723 return false;
724 }
725 // if is super fold device and in half fold state, check virtual screen
726 auto virtualDisplay = SingletonContainer::Get<DisplayManager>().GetDisplayById(DISPLAY_ID_C);
727 if (virtualDisplay == nullptr) {
728 TLOGE(WmsLogTag::WMS_LAYOUT, "virtual display is null");
729 return false;
730 }
731 auto virtualDisplayInfo = virtualDisplay->GetDisplayInfo();
732 if (virtualDisplayInfo == nullptr) {
733 TLOGE(WmsLogTag::WMS_LAYOUT, "virtual displayInfo is null");
734 return false;
735 }
736 displayWidth = static_cast<uint32_t>(virtualDisplayInfo->GetWidth());
737 displayHeight = static_cast<uint32_t>(virtualDisplayInfo->GetHeight());
738 if (displayWidth == width && displayHeight == height) {
739 return true;
740 }
741 return false;
742 }
743
SetParentWindowInner(int32_t oldParentWindowId,const sptr<WindowSessionImpl> & newParentWindow)744 WMError WindowSceneSessionImpl::SetParentWindowInner(int32_t oldParentWindowId,
745 const sptr<WindowSessionImpl>& newParentWindow)
746 {
747 auto newParentWindowId = newParentWindow->GetPersistentId();
748 auto subWindowId = GetPersistentId();
749 TLOGI(WmsLogTag::WMS_SUB, "subWindowId: %{public}d, oldParentWindowId: %{public}d, "
750 "newParentWindowId: %{public}d", subWindowId, oldParentWindowId, newParentWindowId);
751 WMError ret = SingletonContainer::Get<WindowAdapter>().SetParentWindow(subWindowId, newParentWindowId);
752 if (ret != WMError::WM_OK) {
753 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d set parent window failed errCode: %{public}d",
754 subWindowId, static_cast<int32_t>(ret));
755 return ret;
756 }
757 RemoveSubWindow(oldParentWindowId);
758 {
759 std::lock_guard<std::recursive_mutex> lock(subWindowSessionMutex_);
760 subWindowSessionMap_[newParentWindowId].push_back(this);
761 }
762 property_->SetParentPersistentId(newParentWindowId);
763 UpdateSubWindowInfo(newParentWindow->GetProperty()->GetSubWindowLevel() + 1,
764 newParentWindow->GetContext());
765 if (state_ == WindowState::STATE_SHOWN &&
766 newParentWindow->GetWindowState() == WindowState::STATE_HIDDEN) {
767 UpdateSubWindowStateAndNotify(newParentWindowId, WindowState::STATE_HIDDEN);
768 }
769 return WMError::WM_OK;
770 }
771
SetParentWindow(int32_t newParentWindowId)772 WMError WindowSceneSessionImpl::SetParentWindow(int32_t newParentWindowId)
773 {
774 auto subWindowId = GetPersistentId();
775 if (property_->GetPcAppInpadCompatibleMode()) {
776 TLOGE(WmsLogTag::WMS_SUB, "This is PcAppInPad, not Supported");
777 return WMError::WM_OK;
778 }
779 if (!IsPcWindow()) {
780 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d device not support", subWindowId);
781 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
782 }
783 if (IsWindowSessionInvalid()) {
784 return WMError::WM_ERROR_INVALID_WINDOW;
785 }
786 if (!WindowHelper::IsSubWindow(GetType())) {
787 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d called by invalid window type %{public}d",
788 subWindowId, GetType());
789 return WMError::WM_ERROR_INVALID_CALLING;
790 }
791 auto oldParentWindowId = property_->GetParentPersistentId();
792 if (oldParentWindowId == newParentWindowId || subWindowId == newParentWindowId) {
793 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d newParentWindowId is the same as "
794 "oldParentWindowId or subWindowId", subWindowId);
795 return WMError::WM_ERROR_INVALID_PARENT;
796 }
797 auto oldParentWindow = GetWindowWithId(oldParentWindowId);
798 if (oldParentWindow == nullptr) {
799 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d find not old parent window By Id: %{public}d",
800 subWindowId, oldParentWindowId);
801 return WMError::WM_ERROR_INVALID_PARENT;
802 }
803 auto oldWindowType = oldParentWindow->GetType();
804 if (!WindowHelper::IsMainWindow(oldWindowType) && !WindowHelper::IsFloatOrSubWindow(oldWindowType)) {
805 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d old parent window type invalid", subWindowId);
806 return WMError::WM_ERROR_INVALID_PARENT;
807 }
808 auto newParentWindow = GetWindowWithId(newParentWindowId);
809 if (newParentWindow == nullptr) {
810 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d find not new parent window By Id: %{public}d",
811 subWindowId, newParentWindowId);
812 return WMError::WM_ERROR_INVALID_PARENT;
813 }
814 auto newWindowType = newParentWindow->GetType();
815 if (!WindowHelper::IsMainWindow(newWindowType) && !WindowHelper::IsFloatOrSubWindow(newWindowType)) {
816 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d new parent window type invalid", subWindowId);
817 return WMError::WM_ERROR_INVALID_PARENT;
818 }
819 return SetParentWindowInner(oldParentWindowId, newParentWindow);
820 }
821
GetParentWindow(sptr<Window> & parentWindow)822 WMError WindowSceneSessionImpl::GetParentWindow(sptr<Window>& parentWindow)
823 {
824 if (property_->GetPcAppInpadCompatibleMode()) {
825 TLOGE(WmsLogTag::WMS_SUB, "This is PcAppInPad, not Supported");
826 return WMError::WM_OK;
827 }
828 if (!IsPcWindow()) {
829 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d device not support", GetPersistentId());
830 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
831 }
832 if (IsWindowSessionInvalid()) {
833 return WMError::WM_ERROR_INVALID_WINDOW;
834 }
835 if (!WindowHelper::IsSubWindow(GetType())) {
836 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d called by invalid window type %{public}d",
837 GetPersistentId(), GetType());
838 return WMError::WM_ERROR_INVALID_CALLING;
839 }
840 if (property_->GetIsUIExtFirstSubWindow()) {
841 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d UIExtension sub window not get parent window",
842 GetPersistentId());
843 return WMError::WM_ERROR_INVALID_CALLING;
844 }
845 parentWindow = FindWindowById(property_->GetParentPersistentId());
846 if (parentWindow == nullptr) {
847 TLOGE(WmsLogTag::WMS_SUB, "winId: %{public}d parentWindow is nullptr", GetPersistentId());
848 return WMError::WM_ERROR_INVALID_PARENT;
849 }
850 return WMError::WM_OK;
851 }
852
InitSystemSessionDragEnable()853 void WindowSceneSessionImpl::InitSystemSessionDragEnable()
854 {
855 if (WindowHelper::IsDialogWindow(GetType())) {
856 TLOGI(WmsLogTag::WMS_LAYOUT, "dialogWindow default draggable, should not init false, id: %{public}d",
857 GetPersistentId());
858 return;
859 }
860 TLOGI(WmsLogTag::WMS_LAYOUT, "windId: %{public}d init dragEnable false",
861 GetPersistentId());
862 property_->SetDragEnabled(false);
863 }
864
UpdateDefaultStatusBarColor()865 void WindowSceneSessionImpl::UpdateDefaultStatusBarColor()
866 {
867 SystemBarProperty statusBarProp = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
868 if (static_cast<SystemBarSettingFlag>(static_cast<uint32_t>(statusBarProp.settingFlag_) &
869 static_cast<uint32_t>(SystemBarSettingFlag::COLOR_SETTING)) == SystemBarSettingFlag::COLOR_SETTING) {
870 TLOGD(WmsLogTag::WMS_IMMS, "user has set color");
871 return;
872 }
873 if (!WindowHelper::IsMainWindow(GetType())) {
874 TLOGD(WmsLogTag::WMS_IMMS, "not main window");
875 return;
876 }
877 uint32_t contentColor;
878 constexpr uint32_t BLACK = 0xFF000000;
879 constexpr uint32_t WHITE = 0xFFFFFFFF;
880 bool isColorModeSetByApp = !specifiedColorMode_.empty();
881 std::string colorMode = specifiedColorMode_;
882 if (isColorModeSetByApp) {
883 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u type %{public}u colorMode %{public}s",
884 GetPersistentId(), GetType(), colorMode.c_str());
885 contentColor = colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT ? BLACK : WHITE;
886 } else {
887 auto appContext = AbilityRuntime::Context::GetApplicationContext();
888 if (appContext == nullptr) {
889 TLOGE(WmsLogTag::WMS_IMMS, "app context is nullptr");
890 return;
891 }
892 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
893 if (config == nullptr) {
894 TLOGE(WmsLogTag::WMS_IMMS, "config is null, winId: %{public}d", GetPersistentId());
895 return;
896 }
897 colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
898 isColorModeSetByApp = !config->GetItem(AAFwk::GlobalConfigurationKey::COLORMODE_IS_SET_BY_APP).empty();
899 if (isColorModeSetByApp) {
900 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "win=%{public}u, appColor=%{public}s", GetWindowId(), colorMode.c_str());
901 contentColor = colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT ? BLACK : WHITE;
902 } else {
903 bool hasDarkRes = false;
904 appContext->AppHasDarkRes(hasDarkRes);
905 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u type %{public}u hasDarkRes %{public}u colorMode %{public}s",
906 GetPersistentId(), GetType(), hasDarkRes, colorMode.c_str());
907 contentColor = colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT ? BLACK :
908 (hasDarkRes ? WHITE : BLACK);
909 }
910 }
911 statusBarProp.contentColor_ = contentColor;
912 statusBarProp.settingFlag_ = static_cast<SystemBarSettingFlag>(
913 static_cast<uint32_t>(statusBarProp.settingFlag_) |
914 static_cast<uint32_t>(SystemBarSettingFlag::FOLLOW_SETTING));
915 SetSpecificBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusBarProp);
916 }
917
RegisterSessionRecoverListener(bool isSpecificSession)918 void WindowSceneSessionImpl::RegisterSessionRecoverListener(bool isSpecificSession)
919 {
920 TLOGD(WmsLogTag::WMS_RECOVER, "Id=%{public}d, isSpecificSession=%{public}s",
921 GetPersistentId(), isSpecificSession ? "true" : "false");
922
923 if (GetType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
924 TLOGI(WmsLogTag::WMS_RECOVER, "input method window does not need to recover");
925 return;
926 }
927 if (property_->GetCollaboratorType() != CollaboratorType::DEFAULT_TYPE) {
928 TLOGI(WmsLogTag::WMS_RECOVER, "collaboratorType is %{public}" PRId32 ", not need to recover",
929 property_->GetCollaboratorType());
930 return;
931 }
932
933 wptr<WindowSceneSessionImpl> weakThis = this;
934 auto callbackFunc = [weakThis, isSpecificSession] {
935 auto promoteThis = weakThis.promote();
936 if (promoteThis == nullptr) {
937 TLOGW(WmsLogTag::WMS_RECOVER, "promoteThis is nullptr");
938 return WMError::WM_ERROR_NULLPTR;
939 }
940 if (promoteThis->state_ == WindowState::STATE_DESTROYED) {
941 TLOGW(WmsLogTag::WMS_RECOVER, "windowState is STATE_DESTROYED, no need to recover");
942 return WMError::WM_ERROR_DESTROYED_OBJECT;
943 }
944 if (promoteThis->windowRecoverStateChangeFunc_ == nullptr) {
945 TLOGW(WmsLogTag::WMS_RECOVER, "windowRecoverStateChangeFunc_ is nullptr");
946 return WMError::WM_ERROR_NULLPTR;
947 }
948
949 auto ret = isSpecificSession ? promoteThis->RecoverAndConnectSpecificSession() :
950 promoteThis->RecoverAndReconnectSceneSession();
951
952 TLOGD(WmsLogTag::WMS_RECOVER, "Recover session over, ret=%{public}d", ret);
953 return ret;
954 };
955 SingletonContainer::Get<WindowAdapter>().RegisterSessionRecoverCallbackFunc(GetPersistentId(), callbackFunc);
956 }
957
RegisterWindowRecoverStateChangeListener()958 void WindowSceneSessionImpl::RegisterWindowRecoverStateChangeListener()
959 {
960 windowRecoverStateChangeFunc_ = [weakThis = wptr(this)](bool isSpecificSession,
961 const WindowRecoverState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
962 auto window = weakThis.promote();
963 if (window == nullptr) {
964 TLOGNE(WmsLogTag::WMS_RECOVER, "window is null");
965 return;
966 }
967 window->OnWindowRecoverStateChange(isSpecificSession, state);
968 };
969 }
970
OnWindowRecoverStateChange(bool isSpecificSession,const WindowRecoverState & state)971 void WindowSceneSessionImpl::OnWindowRecoverStateChange(bool isSpecificSession, const WindowRecoverState& state)
972 {
973 TLOGI(WmsLogTag::WMS_RECOVER, "id: %{public}d, state:%{public}u", GetPersistentId(), state);
974 switch (state) {
975 case WindowRecoverState::WINDOW_START_RECONNECT:
976 UpdateStartRecoverProperty(isSpecificSession);
977 break;
978 case WindowRecoverState::WINDOW_FINISH_RECONNECT:
979 UpdateFinishRecoverProperty(isSpecificSession);
980 RecoverSessionListener();
981 break;
982 default:
983 break;
984 }
985 }
986
UpdateStartRecoverProperty(bool isSpecificSession)987 void WindowSceneSessionImpl::UpdateStartRecoverProperty(bool isSpecificSession)
988 {
989 if (isSpecificSession) {
990 property_->SetWindowState(requestState_);
991 if (GetContext() && GetContext()->GetToken()) {
992 property_->SetTokenState(true);
993 }
994 } else {
995 property_->SetWindowState(state_);
996 property_->SetIsFullScreenWaterfallMode(isFullScreenWaterfallMode_.load());
997 }
998 }
999
UpdateFinishRecoverProperty(bool isSpecificSession)1000 void WindowSceneSessionImpl::UpdateFinishRecoverProperty(bool isSpecificSession)
1001 {
1002 property_->SetWindowState(state_);
1003 }
1004
HandlePointDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const MMI::PointerEvent::PointerItem & pointerItem)1005 bool WindowSceneSessionImpl::HandlePointDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1006 const MMI::PointerEvent::PointerItem& pointerItem)
1007 {
1008 bool needNotifyEvent = true;
1009 WindowType windowType = property_->GetWindowType();
1010 AreaType dragType = GetDragAreaByDownEvent(pointerEvent, pointerItem);
1011 TLOGD(WmsLogTag::WMS_EVENT, "dragType: %{public}d", dragType);
1012 bool isDecorDialog = windowType == WindowType::WINDOW_TYPE_DIALOG && property_->IsDecorEnable();
1013 bool isFixedSubWin = WindowHelper::IsSubWindow(windowType) && !IsWindowDraggable();
1014 bool isFixedSystemWin = WindowHelper::IsSystemWindow(windowType) && !IsWindowDraggable();
1015 auto hostSession = GetHostSession();
1016 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, needNotifyEvent);
1017 TLOGD(WmsLogTag::WMS_EVENT, "isFixedSystemWin %{public}d, isFixedSubWin %{public}d, isDecorDialog %{public}d",
1018 isFixedSystemWin, isFixedSubWin, isDecorDialog);
1019 if ((isFixedSystemWin || isFixedSubWin) && !isDecorDialog) {
1020 hostSession->SendPointEventForMoveDrag(pointerEvent, isExecuteDelayRaise_);
1021 } else {
1022 if (dragType != AreaType::UNDEFINED) {
1023 hostSession->SendPointEventForMoveDrag(pointerEvent, isExecuteDelayRaise_);
1024 needNotifyEvent = false;
1025 } else if (WindowHelper::IsMainWindow(windowType) ||
1026 WindowHelper::IsSubWindow(windowType) ||
1027 WindowHelper::IsSystemWindow(windowType)) {
1028 hostSession->SendPointEventForMoveDrag(pointerEvent, isExecuteDelayRaise_);
1029 } else {
1030 hostSession->ProcessPointDownSession(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
1031 }
1032 }
1033 return needNotifyEvent;
1034 }
1035
GetDragAreaByDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const MMI::PointerEvent::PointerItem & pointerItem)1036 AreaType WindowSceneSessionImpl::GetDragAreaByDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1037 const MMI::PointerEvent::PointerItem& pointerItem)
1038 {
1039 AreaType dragType = AreaType::UNDEFINED;
1040 float vpr = WindowSessionImpl::GetVirtualPixelRatio();
1041 if (MathHelper::NearZero(vpr)) {
1042 return dragType;
1043 }
1044 const auto& sourceType = pointerEvent->GetSourceType();
1045 int outside = (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) ? static_cast<int>(HOTZONE_POINTER * vpr) :
1046 static_cast<int>(HOTZONE_TOUCH * vpr);
1047 int32_t winX = pointerItem.GetWindowX();
1048 int32_t winY = pointerItem.GetWindowY();
1049 WindowType windowType = property_->GetWindowType();
1050 bool isSystemDraggableType = WindowHelper::IsSystemWindow(windowType) && IsWindowDraggable();
1051 const auto& rect = SessionHelper::TransferToWSRect(GetRect());
1052 if (property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING || isSystemDraggableType) {
1053 dragType = SessionHelper::GetAreaType(winX, winY, sourceType, outside, vpr, rect);
1054 }
1055 return dragType;
1056 }
1057
ResetSuperFoldDisplayY(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1058 void WindowSceneSessionImpl::ResetSuperFoldDisplayY(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1059 {
1060 if (superFoldOffsetY_ == -1) {
1061 auto foldCreaseRegion = DisplayManager::GetInstance().GetCurrentFoldCreaseRegion();
1062 if (foldCreaseRegion == nullptr) {
1063 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "foldCreaseRegion is nullptr");
1064 return;
1065 }
1066 const auto& creaseRects = foldCreaseRegion->GetCreaseRects();
1067 if (creaseRects.empty()) {
1068 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "creaseRects is empty");
1069 return;
1070 }
1071 const auto& rect = creaseRects.front();
1072 superFoldOffsetY_ = rect.height_ + rect.posY_;
1073 TLOGI(WmsLogTag::WMS_EVENT, "height: %{public}d, posY: %{public}d", rect.height_, rect.posY_);
1074 }
1075 std::vector<int32_t> pointerIds = pointerEvent->GetPointerIds();
1076 for (int32_t pointerId : pointerIds) {
1077 MMI::PointerEvent::PointerItem pointerItem;
1078 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
1079 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "Get pointerItem failed");
1080 return;
1081 }
1082 if (auto displayYPos = pointerItem.GetDisplayYPos();
1083 !MathHelper::LessNotEqual(displayYPos, superFoldOffsetY_)) {
1084 pointerItem.SetDisplayYPos(displayYPos - superFoldOffsetY_);
1085 pointerEvent->UpdatePointerItem(pointerId, pointerItem);
1086 pointerEvent->SetTargetDisplayId(DISPLAY_ID_C);
1087 TLOGD(WmsLogTag::WMS_EVENT, "Calculated superFoldOffsetY:%{public}d,displayId:%{public}d,"
1088 "InputId:%{public}d,pointerId:%{public}d,displayXPos:%{private}f,displayYPos:%{private}f,",
1089 superFoldOffsetY_, pointerEvent->GetTargetDisplayId(), pointerEvent->GetId(),
1090 pointerId, pointerItem.GetDisplayXPos(), pointerItem.GetDisplayYPos());
1091 }
1092 }
1093 }
1094
ConsumePointerEventInner(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem,bool isHitTargetDraggable)1095 void WindowSceneSessionImpl::ConsumePointerEventInner(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1096 MMI::PointerEvent::PointerItem& pointerItem, bool isHitTargetDraggable)
1097 {
1098 const int32_t& action = pointerEvent->GetPointerAction();
1099 const auto& sourceType = pointerEvent->GetSourceType();
1100 const auto& rect = SessionHelper::TransferToWSRect(GetRect());
1101 bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
1102 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
1103 bool needNotifyEvent = true;
1104 if (property_->IsAdaptToEventMapping()) {
1105 HandleEventForCompatibleMode(pointerEvent, pointerItem);
1106 }
1107 lastPointerEvent_ = pointerEvent;
1108 if (isPointDown) {
1109 float vpr = WindowSessionImpl::GetVirtualPixelRatio();
1110 if (MathHelper::NearZero(vpr)) {
1111 WLOGFW("vpr is zero");
1112 pointerEvent->MarkProcessed();
1113 return;
1114 }
1115 if (IsWindowDelayRaiseEnabled() && isHitTargetDraggable) {
1116 isExecuteDelayRaise_ = true;
1117 }
1118 needNotifyEvent = HandlePointDownEvent(pointerEvent, pointerItem);
1119 RefreshNoInteractionTimeoutMonitor();
1120 }
1121 bool isPointUp = (action == MMI::PointerEvent::POINTER_ACTION_UP ||
1122 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
1123 action == MMI::PointerEvent::POINTER_ACTION_CANCEL);
1124 if (isPointUp) {
1125 if (auto hostSession = GetHostSession()) {
1126 hostSession->SendPointEventForMoveDrag(pointerEvent, isExecuteDelayRaise_);
1127 }
1128 }
1129
1130 bool isPointPullUp = action == MMI::PointerEvent::POINTER_ACTION_PULL_UP;
1131 if (isExecuteDelayRaise_ && (isPointUp || isPointPullUp)) {
1132 isExecuteDelayRaise_ = false;
1133 }
1134 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() &&
1135 property_->GetDisplayId() == DISPLAY_ID_C &&
1136 DisplayManager::GetInstance().GetFoldStatus() == FoldStatus::HALF_FOLD) {
1137 ResetSuperFoldDisplayY(pointerEvent);
1138 }
1139 if (needNotifyEvent) {
1140 NotifyPointerEvent(pointerEvent);
1141 } else {
1142 pointerEvent->MarkProcessed();
1143 }
1144 if (isPointDown || isPointUp) {
1145 TLOGNI(WmsLogTag::WMS_INPUT_KEY_FLOW, "Consume:id:%{public}d,wid:%{public}u,pointId:%{public}d"
1146 ",srcType:%{public}d,rect:[%{public}d,%{public}d,%{public}u,%{public}u],notify:%{public}d",
1147 pointerEvent->GetId(), GetWindowId(), pointerEvent->GetPointerId(),
1148 sourceType, rect.posX_, rect.posY_, rect.width_, rect.height_, needNotifyEvent);
1149 }
1150 }
1151
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1152 void WindowSceneSessionImpl::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1153 {
1154 if (pointerEvent == nullptr) {
1155 WLOGFE("PointerEvent is nullptr, windowId: %{public}d", GetWindowId());
1156 return;
1157 }
1158
1159 if (GetHostSession() == nullptr) {
1160 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "hostSession is nullptr, windowId: %{public}d", GetWindowId());
1161 pointerEvent->MarkProcessed();
1162 return;
1163 }
1164 MMI::PointerEvent::PointerItem pointerItem;
1165 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
1166 TLOGW(WmsLogTag::WMS_INPUT_KEY_FLOW, "invalid pointerEvent, windowId: %{public}d", GetWindowId());
1167 pointerEvent->MarkProcessed();
1168 return;
1169 }
1170
1171 bool isPointDown = pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN ||
1172 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN;
1173 AreaType dragType = AreaType::UNDEFINED;
1174 if (isPointDown) {
1175 dragType = GetDragAreaByDownEvent(pointerEvent, pointerItem);
1176 }
1177 if (!IsWindowDelayRaiseEnabled() || dragType != AreaType::UNDEFINED) {
1178 ConsumePointerEventInner(pointerEvent, pointerItem, false);
1179 return;
1180 }
1181 if (auto uiContent = GetUIContentSharedPtr()) {
1182 uiContent->ProcessPointerEvent(pointerEvent,
1183 [weakThis = wptr(this), pointerEvent, pointerItem](bool isHitTargetDraggable) mutable {
1184 auto window = weakThis.promote();
1185 if (window == nullptr) {
1186 TLOGNE(WmsLogTag::WMS_FOCUS, "window is null");
1187 return;
1188 }
1189 window->ConsumePointerEventInner(pointerEvent, pointerItem, isHitTargetDraggable);
1190 });
1191 } else {
1192 TLOGE(WmsLogTag::WMS_FOCUS, "uiContent is nullptr, windowId: %{public}u", GetWindowId());
1193 pointerEvent->MarkProcessed();
1194 }
1195 }
1196
PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)1197 bool WindowSceneSessionImpl::PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
1198 {
1199 bool isConsumed = false;
1200 if (auto uiContent = GetUIContentSharedPtr()) {
1201 isConsumed = uiContent->ProcessKeyEvent(keyEvent, true);
1202 }
1203 RefreshNoInteractionTimeoutMonitor();
1204 if ((keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_TAB ||
1205 keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_ENTER) && isConsumed &&
1206 keyEvent->GetKeyAction() == MMI::KeyEvent::KEY_ACTION_DOWN) {
1207 TLOGD(WmsLogTag::WMS_EVENT, "wid:%{public}d, keyCode:%{public}d, isConsumed:%{public}d",
1208 GetWindowId(), keyEvent->GetKeyCode(), isConsumed);
1209 NotifyWatchGestureConsumeResult(keyEvent->GetKeyCode(), isConsumed);
1210 }
1211 SetWatchGestureConsumed(isConsumed);
1212 return isConsumed;
1213 }
1214
GetWindowSizeLimits(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo,WindowSizeLimits & windowSizeLimits)1215 static void GetWindowSizeLimits(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo,
1216 WindowSizeLimits& windowSizeLimits)
1217 {
1218 windowSizeLimits.maxWindowWidth = windowSizeLimits.maxWindowWidth > 0 ?
1219 windowSizeLimits.maxWindowWidth : abilityInfo->maxWindowWidth;
1220 windowSizeLimits.maxWindowHeight = windowSizeLimits.maxWindowHeight > 0 ?
1221 windowSizeLimits.maxWindowHeight : abilityInfo->maxWindowHeight;
1222 windowSizeLimits.minWindowWidth = windowSizeLimits.minWindowWidth > 0 ?
1223 windowSizeLimits.minWindowWidth : abilityInfo->minWindowWidth;
1224 windowSizeLimits.minWindowHeight = windowSizeLimits.minWindowHeight > 0 ?
1225 windowSizeLimits.minWindowHeight : abilityInfo->minWindowHeight;
1226 }
1227
HandleWindowLimitsInCompatibleMode(WindowSizeLimits & windowSizeLimits)1228 void WindowSceneSessionImpl::HandleWindowLimitsInCompatibleMode(WindowSizeLimits& windowSizeLimits)
1229 {
1230 if (!property_->IsWindowLimitDisabled()) {
1231 return;
1232 }
1233 windowSizeLimits.maxWindowWidth = windowSystemConfig_.maxFloatingWindowSize_;
1234 windowSizeLimits.maxWindowHeight = windowSystemConfig_.maxFloatingWindowSize_;
1235 if (WindowHelper::IsMainWindow(GetType())) {
1236 windowSizeLimits.minWindowWidth = windowSystemConfig_.miniWidthOfMainWindow_;
1237 windowSizeLimits.minWindowHeight = windowSystemConfig_.miniHeightOfMainWindow_;
1238 } else if (WindowHelper::IsSubWindow(GetType())) {
1239 windowSizeLimits.minWindowWidth = windowSystemConfig_.miniWidthOfSubWindow_;
1240 windowSizeLimits.minWindowHeight = windowSystemConfig_.miniHeightOfSubWindow_;
1241 } else if (WindowHelper::IsDialogWindow(GetType())) {
1242 windowSizeLimits.minWindowWidth = windowSystemConfig_.miniWidthOfDialogWindow_;
1243 windowSizeLimits.minWindowHeight = windowSystemConfig_.miniHeightOfDialogWindow_;
1244 } else {
1245 windowSizeLimits.minWindowWidth = MIN_FLOATING_WIDTH;
1246 windowSizeLimits.minWindowHeight = MIN_FLOATING_HEIGHT;
1247 }
1248 TLOGI(WmsLogTag::WMS_COMPAT, "maxWidth: %{public}u, minWidth: %{public}u, maxHeight: %{public}u, "
1249 "minHeight: %{public}u", windowSizeLimits.maxWindowWidth, windowSizeLimits.minWindowWidth,
1250 windowSizeLimits.maxWindowHeight, windowSizeLimits.minWindowHeight);
1251 }
1252
ExtractSupportWindowModeFromMetaData(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)1253 std::vector<AppExecFwk::SupportWindowMode> WindowSceneSessionImpl::ExtractSupportWindowModeFromMetaData(
1254 const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
1255 {
1256 std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
1257 if (windowSystemConfig_.IsPcWindow() || IsFreeMultiWindowMode()) {
1258 auto metadata = abilityInfo->metadata;
1259 for (auto item : metadata) {
1260 if (item.name == "ohos.ability.window.supportWindowModeInFreeMultiWindow") {
1261 updateWindowModes = ParseWindowModeFromMetaData(item.value);
1262 }
1263 }
1264 }
1265 if (updateWindowModes.empty()) {
1266 updateWindowModes = abilityInfo->windowModes;
1267 }
1268 return updateWindowModes;
1269 }
1270
ParseWindowModeFromMetaData(const std::string & supportModesInFreeMultiWindow)1271 std::vector<AppExecFwk::SupportWindowMode> WindowSceneSessionImpl::ParseWindowModeFromMetaData(
1272 const std::string& supportModesInFreeMultiWindow)
1273 {
1274 std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
1275 std::stringstream supportModes(supportModesInFreeMultiWindow);
1276 std::string supportWindowMode;
1277 while (getline(supportModes, supportWindowMode, ',')) {
1278 if (supportWindowMode == "fullscreen") {
1279 updateWindowModes.push_back(AppExecFwk::SupportWindowMode::FULLSCREEN);
1280 } else if (supportWindowMode == "split") {
1281 updateWindowModes.push_back(AppExecFwk::SupportWindowMode::SPLIT);
1282 } else if (supportWindowMode == "floating") {
1283 updateWindowModes.push_back(AppExecFwk::SupportWindowMode::FLOATING);
1284 }
1285 }
1286 return updateWindowModes;
1287 }
1288
GetConfigurationFromAbilityInfo()1289 void WindowSceneSessionImpl::GetConfigurationFromAbilityInfo()
1290 {
1291 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(GetContext());
1292 if (abilityContext == nullptr) {
1293 WLOGFE("abilityContext is nullptr");
1294 return;
1295 }
1296 auto abilityInfo = abilityContext->GetAbilityInfo();
1297 if (abilityInfo != nullptr) {
1298 WindowSizeLimits windowSizeLimits = property_->GetWindowSizeLimits();
1299 GetWindowSizeLimits(abilityInfo, windowSizeLimits);
1300 if (property_->IsWindowLimitDisabled()) {
1301 HandleWindowLimitsInCompatibleMode(windowSizeLimits);
1302 }
1303 property_->SetConfigWindowLimitsVP({
1304 windowSizeLimits.maxWindowWidth, windowSizeLimits.maxWindowHeight,
1305 windowSizeLimits.minWindowWidth, windowSizeLimits.minWindowHeight,
1306 static_cast<float>(abilityInfo->maxWindowRatio), static_cast<float>(abilityInfo->minWindowRatio)
1307 });
1308 UpdateWindowSizeLimits();
1309 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
1310 // get support modes configuration
1311 uint32_t windowModeSupportType = 0;
1312 std::vector<AppExecFwk::SupportWindowMode> supportedWindowModes;
1313 property_->GetSupportedWindowModes(supportedWindowModes);
1314 auto size = supportedWindowModes.size();
1315 if (size > 0 && size <= WINDOW_SUPPORT_MODE_MAX_SIZE) {
1316 windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(supportedWindowModes);
1317 } else {
1318 std::vector<AppExecFwk::SupportWindowMode> updateWindowModes =
1319 ExtractSupportWindowModeFromMetaData(abilityInfo);
1320 if (auto hostSession = GetHostSession()) {
1321 hostSession->NotifySupportWindowModesChange(updateWindowModes);
1322 };
1323 windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(updateWindowModes);
1324 }
1325 if (windowModeSupportType == 0) {
1326 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "mode config param is 0, all modes is supported");
1327 windowModeSupportType = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
1328 } else {
1329 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId: %{public}u, windowModeSupportType: %{public}u",
1330 GetWindowId(), windowModeSupportType);
1331 }
1332 if (property_->IsSupportRotateFullScreen()) {
1333 windowModeSupportType = (WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN |
1334 WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING);
1335 }
1336 property_->SetWindowModeSupportType(windowModeSupportType);
1337 // update windowModeSupportType to server
1338 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
1339 bool isWindowModeSupportFullscreen = GetTargetAPIVersion() < 15 ? // 15: isolated version
1340 (windowModeSupportType == WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN) :
1341 (WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
1342 !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING));
1343 auto mainWindow = FindMainWindowWithContext();
1344 bool isAnco = mainWindow != nullptr && mainWindow->IsAnco();
1345 bool onlySupportFullScreen = (isWindowModeSupportFullscreen || isAnco) &&
1346 ((!windowSystemConfig_.IsPhoneWindow() && !windowSystemConfig_.IsPadWindow()) || IsFreeMultiWindowMode());
1347 bool compatibleDisableFullScreen = property_->IsFullScreenDisabled();
1348 if ((onlySupportFullScreen || property_->GetFullScreenStart()) && !compatibleDisableFullScreen) {
1349 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "onlySupportFullScreen:%{public}d fullScreenStart:%{public}d",
1350 onlySupportFullScreen, property_->GetFullScreenStart());
1351 Maximize(MaximizePresentation::ENTER_IMMERSIVE);
1352 }
1353 }
1354 }
1355
UpdateConfigVal(uint32_t minVal,uint32_t maxVal,uint32_t configVal,uint32_t defaultVal,float vpr)1356 uint32_t WindowSceneSessionImpl::UpdateConfigVal(uint32_t minVal, uint32_t maxVal, uint32_t configVal,
1357 uint32_t defaultVal, float vpr)
1358 {
1359 bool validConfig = minVal < (configVal * vpr) && (configVal * vpr) < maxVal;
1360 return validConfig ? static_cast<uint32_t>(configVal * vpr) : static_cast<uint32_t>(defaultVal * vpr);
1361 }
1362
GetSystemSizeLimits(uint32_t displayWidth,uint32_t displayHeight,float vpr)1363 WindowLimits WindowSceneSessionImpl::GetSystemSizeLimits(uint32_t displayWidth,
1364 uint32_t displayHeight, float vpr)
1365 {
1366 WindowLimits systemLimits;
1367 systemLimits.maxWidth_ = static_cast<uint32_t>(windowSystemConfig_.maxFloatingWindowSize_ * vpr);
1368 systemLimits.maxHeight_ = static_cast<uint32_t>(windowSystemConfig_.maxFloatingWindowSize_ * vpr);
1369
1370 if (WindowHelper::IsMainWindow(GetType())) {
1371 systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfMainWindow_,
1372 MIN_FLOATING_WIDTH, vpr);
1373 systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfMainWindow_,
1374 MIN_FLOATING_HEIGHT, vpr);
1375 } else if (WindowHelper::IsSubWindow(GetType())) {
1376 systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfSubWindow_,
1377 MIN_FLOATING_WIDTH, vpr);
1378 systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfSubWindow_,
1379 MIN_FLOATING_HEIGHT, vpr);
1380 } else if (WindowHelper::IsDialogWindow(GetType())) {
1381 systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfDialogWindow_,
1382 MIN_FLOATING_WIDTH, vpr);
1383 systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfDialogWindow_,
1384 MIN_FLOATING_HEIGHT, vpr);
1385 } else if (WindowHelper::IsSystemWindow(GetType())) {
1386 systemLimits.minWidth_ = 0;
1387 systemLimits.minHeight_ = 0;
1388 } else {
1389 systemLimits.minWidth_ = static_cast<uint32_t>(MIN_FLOATING_WIDTH * vpr);
1390 systemLimits.minHeight_ = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * vpr);
1391 }
1392 TLOGI(WmsLogTag::WMS_LAYOUT, "maxWidth: %{public}u, minWidth: %{public}u, maxHeight: %{public}u, "
1393 "minHeight: %{public}u, maxFloatingWindowSize: %{public}u, vpr: %{public}f", systemLimits.maxWidth_,
1394 systemLimits.minWidth_, systemLimits.maxHeight_, systemLimits.minHeight_,
1395 windowSystemConfig_.maxFloatingWindowSize_, vpr);
1396 return systemLimits;
1397 }
1398
1399 /** @note @window.layout */
CalculateNewLimitsByLimits(WindowLimits & newLimits,WindowLimits & customizedLimits,float & virtualPixelRatio)1400 void WindowSceneSessionImpl::CalculateNewLimitsByLimits(
1401 WindowLimits& newLimits, WindowLimits& customizedLimits, float& virtualPixelRatio)
1402 {
1403 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
1404 if (display == nullptr) {
1405 TLOGE(WmsLogTag::WMS_LAYOUT, "display is null");
1406 return;
1407 }
1408 auto displayInfo = display->GetDisplayInfo();
1409 if (displayInfo == nullptr) {
1410 TLOGE(WmsLogTag::WMS_LAYOUT, "displayInfo is null");
1411 return;
1412 }
1413 uint32_t displayWidth = static_cast<uint32_t>(displayInfo->GetWidth());
1414 uint32_t displayHeight = static_cast<uint32_t>(displayInfo->GetHeight());
1415 if (displayWidth == 0 || displayHeight == 0) {
1416 return;
1417 }
1418 virtualPixelRatio = GetVirtualPixelRatio(displayInfo);
1419 const auto& systemLimits = GetSystemSizeLimits(displayWidth, displayHeight, virtualPixelRatio);
1420 if (userLimitsSet_) {
1421 customizedLimits = property_->GetUserWindowLimits();
1422 } else {
1423 customizedLimits = property_->GetConfigWindowLimitsVP();
1424 customizedLimits.maxWidth_ = static_cast<uint32_t>(customizedLimits.maxWidth_ * virtualPixelRatio);
1425 customizedLimits.maxHeight_ = static_cast<uint32_t>(customizedLimits.maxHeight_ * virtualPixelRatio);
1426 customizedLimits.minWidth_ = static_cast<uint32_t>(customizedLimits.minWidth_ * virtualPixelRatio);
1427 customizedLimits.minHeight_ = static_cast<uint32_t>(customizedLimits.minHeight_ * virtualPixelRatio);
1428 }
1429 newLimits = systemLimits;
1430 uint32_t limitMinWidth = systemLimits.minWidth_;
1431 uint32_t limitMinHeight = systemLimits.minHeight_;
1432 if (forceLimits_ && IsPcOrFreeMultiWindowCapabilityEnabled()) {
1433 uint32_t forceLimitMinWidth = static_cast<uint32_t>(FORCE_LIMIT_MIN_FLOATING_WIDTH * virtualPixelRatio);
1434 uint32_t forceLimitMinHeight = static_cast<uint32_t>(FORCE_LIMIT_MIN_FLOATING_HEIGHT * virtualPixelRatio);
1435 limitMinWidth = std::min(forceLimitMinWidth, limitMinWidth);
1436 limitMinHeight = std::min(forceLimitMinHeight, limitMinHeight);
1437 newLimits.minWidth_ = limitMinWidth;
1438 newLimits.minHeight_ = limitMinHeight;
1439 }
1440 // calculate new limit size
1441 if (limitMinWidth <= customizedLimits.maxWidth_ &&
1442 customizedLimits.maxWidth_ <= systemLimits.maxWidth_) {
1443 newLimits.maxWidth_ = customizedLimits.maxWidth_;
1444 }
1445 if (limitMinHeight <= customizedLimits.maxHeight_ &&
1446 customizedLimits.maxHeight_ <= systemLimits.maxHeight_) {
1447 newLimits.maxHeight_ = customizedLimits.maxHeight_;
1448 }
1449 if (limitMinWidth <= customizedLimits.minWidth_ &&
1450 customizedLimits.minWidth_ <= newLimits.maxWidth_) {
1451 newLimits.minWidth_ = customizedLimits.minWidth_;
1452 }
1453 if (limitMinHeight <= customizedLimits.minHeight_ &&
1454 customizedLimits.minHeight_ <= newLimits.maxHeight_) {
1455 newLimits.minHeight_ = customizedLimits.minHeight_;
1456 }
1457 }
1458
1459 /** @note @window.layout */
CalculateNewLimitsByRatio(WindowLimits & newLimits,WindowLimits & customizedLimits)1460 void WindowSceneSessionImpl::CalculateNewLimitsByRatio(WindowLimits& newLimits, WindowLimits& customizedLimits)
1461 {
1462 newLimits.maxRatio_ = customizedLimits.maxRatio_;
1463 newLimits.minRatio_ = customizedLimits.minRatio_;
1464
1465 // calculate new limit ratio
1466 double maxRatio = FLT_MAX;
1467 double minRatio = 0.0f;
1468 if (newLimits.minHeight_ != 0) {
1469 maxRatio = static_cast<double>(newLimits.maxWidth_) / static_cast<double>(newLimits.minHeight_);
1470 }
1471 if (newLimits.maxHeight_ != 0) {
1472 minRatio = static_cast<double>(newLimits.minWidth_) / static_cast<double>(newLimits.maxHeight_);
1473 }
1474 if (!MathHelper::GreatNotEqual(minRatio, customizedLimits.maxRatio_) &&
1475 !MathHelper::GreatNotEqual(customizedLimits.maxRatio_, maxRatio)) {
1476 maxRatio = customizedLimits.maxRatio_;
1477 }
1478 if (!MathHelper::GreatNotEqual(minRatio, customizedLimits.minRatio_) &&
1479 !MathHelper::GreatNotEqual(customizedLimits.minRatio_, maxRatio)) {
1480 minRatio = customizedLimits.minRatio_;
1481 }
1482
1483 // recalculate limit size by new ratio
1484 double newMaxWidthFloat = static_cast<double>(newLimits.maxHeight_) * maxRatio;
1485 uint32_t newMaxWidth = (newMaxWidthFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1486 std::round(newMaxWidthFloat);
1487 newLimits.maxWidth_ = std::min(newMaxWidth, newLimits.maxWidth_);
1488
1489 double newMinWidthFloat = static_cast<double>(newLimits.minHeight_) * minRatio;
1490 uint32_t newMinWidth = (newMinWidthFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1491 std::round(newMinWidthFloat);
1492 newLimits.minWidth_ = std::max(newMinWidth, newLimits.minWidth_);
1493
1494 double newMaxHeightFloat = MathHelper::NearZero(minRatio) ? UINT32_MAX :
1495 static_cast<double>(newLimits.maxWidth_) / minRatio;
1496 uint32_t newMaxHeight = (newMaxHeightFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1497 std::round(newMaxHeightFloat);
1498 newLimits.maxHeight_ = std::min(newMaxHeight, newLimits.maxHeight_);
1499
1500 double newMinHeightFloat = MathHelper::NearZero(maxRatio) ? UINT32_MAX :
1501 static_cast<double>(newLimits.minWidth_) / maxRatio;
1502 uint32_t newMinHeight = (newMinHeightFloat > static_cast<double>(UINT32_MAX)) ? UINT32_MAX :
1503 std::round(newMinHeightFloat);
1504 newLimits.minHeight_ = std::max(newMinHeight, newLimits.minHeight_);
1505 }
1506
1507 /** @note @window.layout */
UpdateWindowSizeLimits()1508 void WindowSceneSessionImpl::UpdateWindowSizeLimits()
1509 {
1510 WindowLimits customizedLimits;
1511 WindowLimits newLimits;
1512 float virtualPixelRatio = 0.0f;
1513
1514 CalculateNewLimitsByLimits(newLimits, customizedLimits, virtualPixelRatio);
1515 if (MathHelper::NearZero(virtualPixelRatio)) {
1516 return;
1517 }
1518 newLimits.vpRatio_ = virtualPixelRatio;
1519 CalculateNewLimitsByRatio(newLimits, customizedLimits);
1520
1521 property_->SetWindowLimits(newLimits);
1522 property_->SetLastLimitsVpr(virtualPixelRatio);
1523 }
1524
PreLayoutOnShow(WindowType type,const sptr<DisplayInfo> & info)1525 void WindowSceneSessionImpl::PreLayoutOnShow(WindowType type, const sptr<DisplayInfo>& info)
1526 {
1527 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1528 if (uiContent == nullptr) {
1529 TLOGW(WmsLogTag::WMS_LIFE, "uiContent is null");
1530 return;
1531 }
1532 const auto& requestRect = GetRequestRect();
1533 TLOGI(WmsLogTag::WMS_LIFE, "name: %{public}s, id: %{public}d, type: %{public}u, requestRect:%{public}s",
1534 property_->GetWindowName().c_str(), GetPersistentId(), type, requestRect.ToString().c_str());
1535 if (requestRect.width_ != 0 && requestRect.height_ != 0) {
1536 UpdateViewportConfig(requestRect, WindowSizeChangeReason::RESIZE, nullptr, info);
1537 if (auto hostSession = GetHostSession()) {
1538 WSRect wsRect = { requestRect.posX_, requestRect.posY_, requestRect.width_, requestRect.height_ };
1539 if (type != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1540 SetNotifySizeChangeFlag(true);
1541 property_->SetWindowRect(requestRect);
1542 }
1543 hostSession->UpdateClientRect(wsRect);
1544 } else {
1545 TLOGE(WmsLogTag::WMS_LAYOUT, "hostSession is null");
1546 }
1547 }
1548 uiContent->PreLayout();
1549 }
1550
Show(uint32_t reason,bool withAnimation,bool withFocus)1551 WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus)
1552 {
1553 return Show(reason, withAnimation, withFocus, false);
1554 }
1555
Show(uint32_t reason,bool withAnimation,bool withFocus,bool waitAttach)1556 WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus, bool waitAttach)
1557 {
1558 if (reason == static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH)) {
1559 TLOGI(WmsLogTag::WMS_MULTI_USER, "Switch to current user, NotifyAfterForeground");
1560 NotifyAfterForeground(true, false);
1561 NotifyAfterDidForeground(reason);
1562 return WMError::WM_OK;
1563 }
1564 const auto type = GetType();
1565 if (IsWindowSessionInvalid()) {
1566 TLOGI(WmsLogTag::WMS_LIFE, "Window show failed, session is invalid, name: %{public}s, id: %{public}d",
1567 property_->GetWindowName().c_str(), GetPersistentId());
1568 return WMError::WM_ERROR_INVALID_WINDOW;
1569 }
1570 auto hostSession = GetHostSession();
1571 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1572
1573 TLOGI(WmsLogTag::WMS_LIFE, "Window show [name: %{public}s, id: %{public}d, type: %{public}u], reason: %{public}u,"
1574 " state:%{public}u, requestState:%{public}u", property_->GetWindowName().c_str(),
1575 property_->GetPersistentId(), type, reason, state_, requestState_);
1576 auto isDecorEnable = IsDecorEnable();
1577 UpdateDecorEnableToAce(isDecorEnable);
1578 property_->SetDecorEnable(isDecorEnable);
1579
1580 if (state_ == WindowState::STATE_SHOWN) {
1581 TLOGI(WmsLogTag::WMS_LIFE, "window is already shown [name:%{public}s, id:%{public}d, type: %{public}u]",
1582 property_->GetWindowName().c_str(), property_->GetPersistentId(), type);
1583 if (WindowHelper::IsMainWindow(type)) {
1584 hostSession->RaiseAppMainWindowToTop();
1585 }
1586 NotifyAfterForeground(true, false);
1587 NotifyAfterDidForeground(reason);
1588 RefreshNoInteractionTimeoutMonitor();
1589 return WMError::WM_OK;
1590 }
1591 auto displayInfo = GetDisplayInfo();
1592 if (displayInfo == nullptr) {
1593 TLOGE(WmsLogTag::WMS_LIFE, "Window show failed, displayInfo is null, name: %{public}s, id: %{public}d",
1594 property_->GetWindowName().c_str(), GetPersistentId());
1595 return WMError::WM_ERROR_NULLPTR;
1596 }
1597 float density = GetVirtualPixelRatio(displayInfo);
1598 if (!MathHelper::NearZero(virtualPixelRatio_ - density) ||
1599 !MathHelper::NearZero(property_->GetLastLimitsVpr() - density)) {
1600 UpdateDensityInner(displayInfo);
1601 }
1602
1603 WMError ret = UpdateAnimationFlagProperty(withAnimation);
1604 if (ret != WMError::WM_OK) {
1605 TLOGE(WmsLogTag::WMS_LIFE, "Window show failed, UpdateProperty failed, ret: %{public}d, name: %{public}s"
1606 ", id: %{public}d", static_cast<int32_t>(ret), property_->GetWindowName().c_str(), GetPersistentId());
1607 return ret;
1608 }
1609 UpdateTitleButtonVisibility();
1610 property_->SetFocusableOnShow(withFocus);
1611 if (WindowHelper::IsMainWindow(type)) {
1612 ret = static_cast<WMError>(hostSession->Foreground(property_, true, identityToken_));
1613 } else if (WindowHelper::IsSystemOrSubWindow(type)) {
1614 if (waitAttach && !lifecycleCallback_ && !WindowHelper::IsKeyboardWindow(type) &&
1615 SysCapUtil::GetBundleName() != AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
1616 lifecycleCallback_ = sptr<LifecycleFutureCallback>::MakeSptr();
1617 TLOGI(WmsLogTag::WMS_LIFE, "init lifecycleCallback, id:%{public}d", GetPersistentId());
1618 }
1619 if (waitAttach && lifecycleCallback_) {
1620 lifecycleCallback_->ResetAttachLock();
1621 }
1622 PreLayoutOnShow(type, displayInfo);
1623 // Add maintenance logs before the IPC process.
1624 TLOGD(WmsLogTag::WMS_LIFE, "Show session [name: %{public}s, id: %{public}d]",
1625 property_->GetWindowName().c_str(), GetPersistentId());
1626 ret = static_cast<WMError>(hostSession->Show(property_));
1627 } else {
1628 ret = WMError::WM_ERROR_INVALID_WINDOW;
1629 }
1630 RecordLifeCycleExceptionEvent(LifeCycleEvent::SHOW_EVENT, ret);
1631 if (ret == WMError::WM_OK) {
1632 // update sub window state
1633 UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_SHOWN);
1634 state_ = WindowState::STATE_SHOWN;
1635 requestState_ = WindowState::STATE_SHOWN;
1636 NotifyAfterForeground(true, true, waitAttach);
1637 NotifyAfterDidForeground(reason);
1638 NotifyFreeMultiWindowModeResume();
1639 RefreshNoInteractionTimeoutMonitor();
1640 TLOGI(WmsLogTag::WMS_LIFE, "Window show success [name:%{public}s, id:%{public}d, type:%{public}u]",
1641 property_->GetWindowName().c_str(), GetPersistentId(), type);
1642 } else {
1643 NotifyForegroundFailed(ret);
1644 TLOGI(WmsLogTag::WMS_LIFE, "Window show failed with errcode: %{public}d, name:%{public}s, id:%{public}d",
1645 static_cast<int32_t>(ret), property_->GetWindowName().c_str(), GetPersistentId());
1646 }
1647 NotifyWindowStatusChange(GetWindowMode());
1648 NotifyWindowStatusDidChange(GetWindowMode());
1649 NotifyDisplayInfoChange(displayInfo);
1650 return ret;
1651 }
1652
GetDisplayInfo() const1653 sptr<DisplayInfo> WindowSceneSessionImpl::GetDisplayInfo() const
1654 {
1655 const auto type = GetType();
1656 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
1657 if (display == nullptr && (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
1658 type == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || WindowHelper::IsSubWindow(type))) {
1659 display = SingletonContainer::Get<DisplayManager>().GetDefaultDisplay();
1660 if (display != nullptr) {
1661 property_->SetDisplayId(display->GetId());
1662 TLOGI(WmsLogTag::WMS_KEYBOARD, "use default display id: %{public}" PRIu64, display->GetId());
1663 }
1664 }
1665 if (display == nullptr) {
1666 TLOGE(WmsLogTag::WMS_LIFE, "failed, display is null, name: %{public}s, id: %{public}d",
1667 property_->GetWindowName().c_str(), GetPersistentId());
1668 return nullptr;
1669 }
1670 return display->GetDisplayInfo();
1671 }
1672
ShowKeyboard(KeyboardEffectOption effectOption)1673 WMError WindowSceneSessionImpl::ShowKeyboard(KeyboardEffectOption effectOption)
1674 {
1675 TLOGI(WmsLogTag::WMS_KEYBOARD, "Effect option: %{public}s", effectOption.ToString().c_str());
1676 if (effectOption.viewMode_ >= KeyboardViewMode::VIEW_MODE_END) {
1677 TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid view mode: %{public}u. Use default mode",
1678 static_cast<uint32_t>(effectOption.viewMode_));
1679 effectOption.viewMode_ = KeyboardViewMode::NON_IMMERSIVE_MODE;
1680 }
1681 if (effectOption.flowLightMode_ >= KeyboardFlowLightMode::END) {
1682 TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid flow light mode: %{public}u. Use default mode",
1683 static_cast<uint32_t>(effectOption.flowLightMode_));
1684 effectOption.flowLightMode_ = KeyboardFlowLightMode::NONE;
1685 }
1686 if (effectOption.gradientMode_ >= KeyboardGradientMode::END) {
1687 TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid gradient mode: %{public}u. Use default mode",
1688 static_cast<uint32_t>(effectOption.gradientMode_));
1689 effectOption.gradientMode_ = KeyboardGradientMode::NONE;
1690 }
1691 property_->SetKeyboardEffectOption(effectOption);
1692 return Show();
1693 }
1694
NotifyFreeMultiWindowModeResume()1695 void WindowSceneSessionImpl::NotifyFreeMultiWindowModeResume()
1696 {
1697 TLOGI(WmsLogTag::WMS_MAIN, "IsPcMode %{public}d, isColdStart %{public}d", IsPcOrFreeMultiWindowCapabilityEnabled(),
1698 isColdStart_);
1699 if (IsPcOrFreeMultiWindowCapabilityEnabled() && !isColdStart_) {
1700 isDidForeground_ = true;
1701 NotifyAfterLifecycleResumed();
1702 }
1703 }
1704
Resume()1705 void WindowSceneSessionImpl::Resume()
1706 {
1707 TLOGI(WmsLogTag::WMS_LIFE, "in, isColdStart: %{public}d, isDidForeground: %{public}d",
1708 isColdStart_, isDidForeground_);
1709 isDidForeground_ = true;
1710 isColdStart_ = false;
1711 NotifyAfterLifecycleResumed();
1712 }
1713
Pause()1714 void WindowSceneSessionImpl::Pause()
1715 {
1716 TLOGI(WmsLogTag::WMS_LIFE, "in, isColdStart: %{public}d", isColdStart_);
1717 isColdStart_ = false;
1718 NotifyAfterLifecyclePaused();
1719 }
1720
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)1721 WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
1722 {
1723 return Hide(reason, withAnimation, isFromInnerkits, false);
1724 }
1725
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits,bool waitDetach)1726 WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits, bool waitDetach)
1727 {
1728 if (reason == static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH)) {
1729 TLOGI(WmsLogTag::WMS_MULTI_USER, "Switch to another user, NotifyAfterBackground");
1730 NotifyAfterBackground(true, false);
1731 NotifyAfterDidBackground(reason);
1732 return WMError::WM_OK;
1733 }
1734
1735 const auto type = GetType();
1736 TLOGI(WmsLogTag::WMS_LIFE, "Window hide [id:%{public}d, type: %{public}d, reason:%{public}u, state:%{public}u, "
1737 "requestState:%{public}u", GetPersistentId(), type, reason, state_, requestState_);
1738 if (IsWindowSessionInvalid()) {
1739 TLOGI(WmsLogTag::WMS_LIFE, "session is invalid, id:%{public}d", GetPersistentId());
1740 return WMError::WM_ERROR_INVALID_WINDOW;
1741 }
1742 auto hostSession = GetHostSession();
1743 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
1744
1745 WindowState validState = state_;
1746 if (WindowHelper::IsSubWindow(type) || WindowHelper::IsDialogWindow(type)) {
1747 validState = requestState_;
1748 }
1749 if (validState == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
1750 TLOGD(WmsLogTag::WMS_LIFE, "window is alreay hidden, id:%{public}d", property_->GetPersistentId());
1751 NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
1752 return WMError::WM_OK;
1753 }
1754
1755 WMError res = UpdateAnimationFlagProperty(withAnimation);
1756 if (res != WMError::WM_OK) {
1757 TLOGE(WmsLogTag::WMS_LIFE, "UpdateProperty failed with errCode:%{public}d", static_cast<int32_t>(res));
1758 return res;
1759 }
1760
1761 /*
1762 * main window no need to notify host, since host knows hide first
1763 * main window notify host temporarily, since host background may failed
1764 * need to SetActive(false) for host session before background
1765 */
1766
1767 if (WindowHelper::IsMainWindow(type)) {
1768 res = static_cast<WMError>(SetActive(false));
1769 if (res != WMError::WM_OK) {
1770 return res;
1771 }
1772 res = static_cast<WMError>(hostSession->Background(true, identityToken_));
1773 } else if (WindowHelper::IsSystemOrSubWindow(type)) {
1774 if (waitDetach && !lifecycleCallback_ && !WindowHelper::IsKeyboardWindow(type) &&
1775 SysCapUtil::GetBundleName() != AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
1776 lifecycleCallback_ = sptr<LifecycleFutureCallback>::MakeSptr();
1777 TLOGI(WmsLogTag::WMS_LIFE, "init lifecycleCallback, id:%{public}d", GetPersistentId());
1778 }
1779 if (waitDetach && lifecycleCallback_) {
1780 lifecycleCallback_->ResetDetachLock();
1781 }
1782 res = static_cast<WMError>(hostSession->Hide());
1783 } else {
1784 res = WMError::WM_ERROR_INVALID_WINDOW;
1785 }
1786
1787 RecordLifeCycleExceptionEvent(LifeCycleEvent::HIDE_EVENT, res);
1788 if (res == WMError::WM_OK) {
1789 // update sub window state if this is main window
1790 UpdateSubWindowState(type, waitDetach);
1791 NotifyAfterDidBackground(reason);
1792 state_ = WindowState::STATE_HIDDEN;
1793 requestState_ = WindowState::STATE_HIDDEN;
1794 isDidForeground_ = false;
1795 if (!interactive_) {
1796 hasFirstNotifyInteractive_ = false;
1797 }
1798 }
1799 uint32_t animationFlag = property_->GetAnimationFlag();
1800 if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
1801 animationTransitionController_->AnimationForHidden();
1802 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
1803 }
1804 NotifyWindowStatusChange(GetWindowMode());
1805 NotifyWindowStatusDidChange(GetWindowMode());
1806 escKeyEventTriggered_ = false;
1807 TLOGI(WmsLogTag::WMS_LIFE, "Window hide success [id:%{public}d, type: %{public}d",
1808 property_->GetPersistentId(), type);
1809 return res;
1810 }
1811
NotifyDrawingCompleted()1812 WMError WindowSceneSessionImpl::NotifyDrawingCompleted()
1813 {
1814 if (IsWindowSessionInvalid()) {
1815 TLOGE(WmsLogTag::WMS_LIFE, "session is invalid, id:%{public}d", GetPersistentId());
1816 return WMError::WM_ERROR_INVALID_WINDOW;
1817 }
1818 auto hostSession = GetHostSession();
1819 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1820 WMError res = WindowHelper::IsMainWindow(GetType()) ?
1821 static_cast<WMError>(hostSession->DrawingCompleted()) :
1822 WMError::WM_ERROR_INVALID_WINDOW;
1823 if (res == WMError::WM_OK) {
1824 TLOGI(WmsLogTag::WMS_LIFE, "success id:%{public}d", GetPersistentId());
1825 }
1826 return res;
1827 }
1828
NotifyRemoveStartingWindow()1829 WMError WindowSceneSessionImpl::NotifyRemoveStartingWindow()
1830 {
1831 if (IsWindowSessionInvalid()) {
1832 TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "session is invalid, id:%{public}d", GetPersistentId());
1833 return WMError::WM_ERROR_INVALID_WINDOW;
1834 }
1835 auto hostSession = GetHostSession();
1836 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
1837 WMError res = WindowHelper::IsMainWindow(GetType()) ?
1838 static_cast<WMError>(hostSession->RemoveStartingWindow()) :
1839 WMError::WM_ERROR_INVALID_WINDOW;
1840 if (res == WMError::WM_OK) {
1841 TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "success id:%{public}d", GetPersistentId());
1842 }
1843 return res;
1844 }
1845
UpdateSubWindowState(const WindowType & type,bool waitDetach)1846 void WindowSceneSessionImpl::UpdateSubWindowState(const WindowType& type, bool waitDetach)
1847 {
1848 UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_HIDDEN);
1849 if (WindowHelper::IsSubWindow(type)) {
1850 if (state_ == WindowState::STATE_SHOWN) {
1851 NotifyAfterBackground(true, true, waitDetach);
1852 }
1853 } else {
1854 NotifyAfterBackground(true, true, waitDetach);
1855 }
1856 }
1857
PreProcessCreate()1858 void WindowSceneSessionImpl::PreProcessCreate()
1859 {
1860 SetDefaultProperty();
1861 }
1862
SetDefaultProperty()1863 void WindowSceneSessionImpl::SetDefaultProperty()
1864 {
1865 switch (property_->GetWindowType()) {
1866 case WindowType::WINDOW_TYPE_TOAST:
1867 case WindowType::WINDOW_TYPE_FLOAT:
1868 case WindowType::WINDOW_TYPE_SYSTEM_FLOAT:
1869 case WindowType::WINDOW_TYPE_FLOAT_CAMERA:
1870 case WindowType::WINDOW_TYPE_VOICE_INTERACTION:
1871 case WindowType::WINDOW_TYPE_SEARCHING_BAR:
1872 case WindowType::WINDOW_TYPE_SCREENSHOT:
1873 case WindowType::WINDOW_TYPE_GLOBAL_SEARCH:
1874 case WindowType::WINDOW_TYPE_DIALOG:
1875 case WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW:
1876 case WindowType::WINDOW_TYPE_PANEL:
1877 case WindowType::WINDOW_TYPE_LAUNCHER_DOCK:
1878 case WindowType::WINDOW_TYPE_WALLET_SWIPE_CARD:
1879 case WindowType::WINDOW_TYPE_MUTISCREEN_COLLABORATION:
1880 case WindowType::WINDOW_TYPE_MAGNIFICATION:
1881 case WindowType::WINDOW_TYPE_MAGNIFICATION_MENU:
1882 case WindowType::WINDOW_TYPE_SELECTION:
1883 case WindowType::WINDOW_TYPE_DYNAMIC: {
1884 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1885 break;
1886 }
1887 case WindowType::WINDOW_TYPE_VOLUME_OVERLAY:
1888 case WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT:
1889 case WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR:
1890 case WindowType::WINDOW_TYPE_DOCK_SLICE:
1891 case WindowType::WINDOW_TYPE_STATUS_BAR:
1892 case WindowType::WINDOW_TYPE_NAVIGATION_BAR:
1893 case WindowType::WINDOW_TYPE_FLOAT_NAVIGATION: {
1894 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1895 property_->SetFocusable(false);
1896 break;
1897 }
1898 case WindowType::WINDOW_TYPE_SYSTEM_TOAST: {
1899 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1900 property_->SetTouchable(false);
1901 property_->SetFocusable(false);
1902 break;
1903 }
1904 case WindowType::WINDOW_TYPE_POINTER: {
1905 property_->SetFocusable(false);
1906 break;
1907 }
1908 case WindowType::WINDOW_TYPE_SCREEN_CONTROL: {
1909 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1910 property_->SetTouchable(false);
1911 property_->SetFocusable(false);
1912 SetAlpha(0);
1913 break;
1914 }
1915 default:
1916 break;
1917 }
1918 }
1919
DestroyInner(bool needNotifyServer)1920 WMError WindowSceneSessionImpl::DestroyInner(bool needNotifyServer)
1921 {
1922 WMError ret = WMError::WM_OK;
1923 if (!WindowHelper::IsMainWindow(GetType()) && needNotifyServer) {
1924 if (WindowHelper::IsSystemWindow(GetType())) {
1925 // main window no need to notify host, since host knows hide first
1926 ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1927 } else if (WindowHelper::IsSubWindow(GetType()) && !property_->GetIsUIExtFirstSubWindow()) {
1928 auto parentSession = FindParentSessionByParentId(GetParentId());
1929 if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
1930 return WMError::WM_ERROR_NULLPTR;
1931 }
1932 ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1933 } else if (property_->GetIsUIExtFirstSubWindow()) {
1934 ret = SyncDestroyAndDisconnectSpecificSession(property_->GetPersistentId());
1935 }
1936 }
1937 if (ret != WMError::WM_OK) {
1938 TLOGE(WmsLogTag::WMS_LIFE, "DestroyInner fail, ret:%{public}d", ret);
1939 return ret;
1940 }
1941
1942 if (WindowHelper::IsMainWindow(GetType())) {
1943 if (auto hostSession = GetHostSession()) {
1944 ret = static_cast<WMError>(hostSession->Disconnect(true, identityToken_));
1945 }
1946 }
1947 return ret;
1948 }
1949
SyncDestroyAndDisconnectSpecificSession(int32_t persistentId)1950 WMError WindowSceneSessionImpl::SyncDestroyAndDisconnectSpecificSession(int32_t persistentId)
1951 {
1952 WMError ret = WMError::WM_OK;
1953 if (SysCapUtil::GetBundleName() == AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
1954 TLOGI(WmsLogTag::WMS_LIFE, "Destroy window is scb window");
1955 ret = SingletonContainer::Get<WindowAdapter>().DestroyAndDisconnectSpecificSession(persistentId);
1956 return ret;
1957 }
1958 sptr<PatternDetachCallback> callback = sptr<PatternDetachCallback>::MakeSptr();
1959 ret = SingletonContainer::Get<WindowAdapter>().DestroyAndDisconnectSpecificSessionWithDetachCallback(persistentId,
1960 callback->AsObject());
1961 if (ret != WMError::WM_OK) {
1962 return ret;
1963 }
1964 auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1965 std::chrono::system_clock::now().time_since_epoch()).count();
1966 callback->GetResult(WINDOW_DETACH_TIMEOUT);
1967 auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
1968 std::chrono::system_clock::now().time_since_epoch()).count();
1969 auto waitTime = endTime - startTime;
1970 if (waitTime >= WINDOW_DETACH_TIMEOUT) {
1971 TLOGW(WmsLogTag::WMS_LIFE, "Destroy window timeout, persistentId:%{public}d", persistentId);
1972 callback->GetResult(std::numeric_limits<int>::max());
1973 }
1974 TLOGI(WmsLogTag::WMS_LIFE, "Destroy window persistentId:%{public}d waitTime:%{public}lld", persistentId, waitTime);
1975 return ret;
1976 }
1977
DestroyHookWindow()1978 WMError WindowSceneSessionImpl::DestroyHookWindow()
1979 {
1980 TLOGI(WmsLogTag::WMS_LIFE, "in");
1981 InputTransferStation::GetInstance().RemoveInputWindow(GetPersistentId());
1982 if (IsWindowSessionInvalid()) {
1983 TLOGE(WmsLogTag::WMS_LIFE, "session invalid, id: %{public}d", GetPersistentId());
1984 return WMError::WM_ERROR_INVALID_WINDOW;
1985 }
1986 {
1987 std::lock_guard<std::recursive_mutex> lock(mutex_);
1988 state_ = WindowState::STATE_DESTROYED;
1989 requestState_ = WindowState::STATE_DESTROYED;
1990 }
1991
1992 DestroySubWindow();
1993 {
1994 std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
1995 windowSessionMap_.erase(property_->GetWindowName());
1996 }
1997 {
1998 std::lock_guard<std::mutex> lock(hostSessionMutex_);
1999 hostSession_ = nullptr;
2000 }
2001 NotifyAfterDestroy();
2002 ClearListenersById(GetPersistentId());
2003 ClearVsyncStation();
2004 SetUIContentComplete();
2005 TLOGI(WmsLogTag::WMS_LIFE, "Destroy hook window success, id: %{public}d", property_->GetPersistentId());
2006 return WMError::WM_OK;
2007 }
2008
GetWindowLifecycleInfo() const2009 WindowLifeCycleInfo WindowSceneSessionImpl::GetWindowLifecycleInfo() const
2010 {
2011 WindowLifeCycleInfo lifeCycleInfo;
2012 lifeCycleInfo.windowId = GetPersistentId();
2013 lifeCycleInfo.windowType = GetType();
2014 lifeCycleInfo.windowName = GetWindowName();
2015 return lifeCycleInfo;
2016 }
2017
Destroy(bool needNotifyServer,bool needClearListener,uint32_t reason)2018 WMError WindowSceneSessionImpl::Destroy(bool needNotifyServer, bool needClearListener, uint32_t reason)
2019 {
2020 TLOGI(WmsLogTag::WMS_LIFE, "Destroy start, id:%{public}d, state:%{public}u, needNotifyServer:%{public}d, "
2021 "needClearListener:%{public}d, reason:%{public}u", GetPersistentId(), state_, needNotifyServer,
2022 needClearListener, reason);
2023 if (reason == static_cast<uint32_t>(WindowStateChangeReason::ABILITY_HOOK)) {
2024 return DestroyHookWindow();
2025 }
2026 InputTransferStation::GetInstance().RemoveInputWindow(GetPersistentId());
2027 if (IsWindowSessionInvalid()) {
2028 TLOGE(WmsLogTag::WMS_LIFE, "session invalid, id: %{public}d", GetPersistentId());
2029 return WMError::WM_ERROR_INVALID_WINDOW;
2030 }
2031 WindowInspector::GetInstance().UnregisterGetWMSWindowListCallback(GetWindowId());
2032 SingletonContainer::Get<WindowAdapter>().UnregisterSessionRecoverCallbackFunc(property_->GetPersistentId());
2033
2034 auto ret = DestroyInner(needNotifyServer);
2035 RecordLifeCycleExceptionEvent(LifeCycleEvent::DESTROY_EVENT, ret);
2036 if (ret != WMError::WM_OK && ret != WMError::WM_ERROR_NULLPTR) { // nullptr means no session in server
2037 WLOGFW("Destroy window failed, id: %{public}d", GetPersistentId());
2038 return ret;
2039 }
2040 WindowLifeCycleInfo windowLifeCycleInfo = GetWindowLifecycleInfo();
2041 SingletonContainer::Get<WindowManager>().NotifyWMSWindowDestroyed(windowLifeCycleInfo);
2042
2043 // delete after replace WSError with WMError
2044 NotifyBeforeDestroy(GetWindowName());
2045 {
2046 std::lock_guard<std::recursive_mutex> lock(mutex_);
2047 state_ = WindowState::STATE_DESTROYED;
2048 requestState_ = WindowState::STATE_DESTROYED;
2049 }
2050
2051 DestroySubWindow();
2052 {
2053 std::unique_lock<std::shared_mutex> lock(windowSessionMutex_);
2054 windowSessionMap_.erase(property_->GetWindowName());
2055 }
2056 {
2057 std::lock_guard<std::mutex> lock(hostSessionMutex_);
2058 hostSession_ = nullptr;
2059 }
2060 NotifyAfterDestroy();
2061 if (needClearListener) {
2062 ClearListenersById(GetPersistentId());
2063 }
2064 auto context = GetContext();
2065 if (context) {
2066 context.reset();
2067 }
2068 ClearVsyncStation();
2069 SetUIContentComplete();
2070 surfaceNode_ = nullptr;
2071 TLOGI(WmsLogTag::WMS_LIFE, "Destroy success, id: %{public}d", property_->GetPersistentId());
2072 return WMError::WM_OK;
2073 }
2074
2075 /** @note @window.layout */
CheckMoveConfiguration(MoveConfiguration & moveConfiguration)2076 void WindowSceneSessionImpl::CheckMoveConfiguration(MoveConfiguration& moveConfiguration)
2077 {
2078 std::vector<DisplayId> displayIds = SingletonContainer::Get<DisplayManagerAdapter>().GetAllDisplayIds();
2079 if (std::find(displayIds.begin(), displayIds.end(), moveConfiguration.displayId) ==
2080 displayIds.end()) { // need to be found in displayIds, otherwise the value is DISPLAY_ID_INVALID
2081 TLOGD(WmsLogTag::WMS_LAYOUT, "Id:%{public}d not find displayId moveConfiguration %{public}s",
2082 property_->GetPersistentId(), moveConfiguration.ToString().c_str());
2083 moveConfiguration.displayId = DISPLAY_ID_INVALID;
2084 }
2085 }
2086
2087 /** @note @window.layout */
MoveTo(int32_t x,int32_t y,bool isMoveToGlobal,MoveConfiguration moveConfiguration)2088 WMError WindowSceneSessionImpl::MoveTo(int32_t x, int32_t y, bool isMoveToGlobal, MoveConfiguration moveConfiguration)
2089 {
2090 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d MoveTo %{public}d %{public}d isMoveToGlobal %{public}d "
2091 "moveConfiguration %{public}s", property_->GetPersistentId(), x, y, isMoveToGlobal,
2092 moveConfiguration.ToString().c_str());
2093 if (IsWindowSessionInvalid()) {
2094 return WMError::WM_ERROR_INVALID_WINDOW;
2095 }
2096 if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2097 TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
2098 return WMError::WM_ERROR_INVALID_OPERATION;
2099 }
2100 const auto& windowRect = GetRect();
2101 const auto& requestRect = GetRequestRect();
2102 if (WindowHelper::IsSubWindow(GetType())) {
2103 auto mainWindow = FindMainWindowWithContext();
2104 if (mainWindow != nullptr && (mainWindow->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
2105 mainWindow->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
2106 if (requestRect.posX_ == x && requestRect.posY_ == y) {
2107 TLOGW(WmsLogTag::WMS_LAYOUT, "Request same position in multiWindow will not update");
2108 return WMError::WM_OK;
2109 }
2110 }
2111 }
2112 Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
2113 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
2114 "%{public}s, windowRect: %{public}s, newRect: %{public}s",
2115 property_->GetPersistentId(), state_, GetType(), GetWindowMode(), requestRect.ToString().c_str(),
2116 windowRect.ToString().c_str(), newRect.ToString().c_str());
2117
2118 property_->SetRequestRect(newRect);
2119
2120 CheckMoveConfiguration(moveConfiguration);
2121 WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
2122 auto hostSession = GetHostSession();
2123 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2124 auto ret = hostSession->UpdateSessionRect(wsRect, SizeChangeReason::MOVE, isMoveToGlobal, false, moveConfiguration);
2125 return static_cast<WMError>(ret);
2126 }
2127
MoveWindowToGlobal(int32_t x,int32_t y,MoveConfiguration moveConfiguration)2128 WMError WindowSceneSessionImpl::MoveWindowToGlobal(int32_t x, int32_t y, MoveConfiguration moveConfiguration)
2129 {
2130 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
2131 if (IsWindowSessionInvalid()) {
2132 return WMError::WM_ERROR_INVALID_WINDOW;
2133 }
2134
2135 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
2136 TLOGW(WmsLogTag::WMS_LAYOUT, "window should not move, winId:%{public}u, mode:%{public}u",
2137 GetWindowId(), GetWindowMode());
2138 return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
2139 }
2140
2141 if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2142 TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
2143 return WMError::WM_ERROR_INVALID_OPERATION;
2144 }
2145 const auto& windowRect = GetRect();
2146 const auto& requestRect = GetRequestRect();
2147 Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
2148 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
2149 "%{public}s, windowRect: %{public}s, newRect: %{public}s",
2150 property_->GetPersistentId(), state_, GetType(), GetWindowMode(), requestRect.ToString().c_str(),
2151 windowRect.ToString().c_str(), newRect.ToString().c_str());
2152
2153 property_->SetRequestRect(newRect);
2154
2155 CheckMoveConfiguration(moveConfiguration);
2156 WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
2157 auto hostSession = GetHostSession();
2158 RectAnimationConfig rectAnimationConfig = moveConfiguration.rectAnimationConfig;
2159 SizeChangeReason reason = rectAnimationConfig.duration > 0 ? SizeChangeReason::MOVE_WITH_ANIMATION :
2160 SizeChangeReason::MOVE;
2161 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2162 auto ret = hostSession->UpdateSessionRect(wsRect, reason, false, true, moveConfiguration, rectAnimationConfig);
2163 if (state_ == WindowState::STATE_SHOWN) {
2164 layoutCallback_->ResetMoveToLock();
2165 auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2166 std::chrono::system_clock::now().time_since_epoch()).count();
2167 layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2168 auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2169 std::chrono::system_clock::now().time_since_epoch()).count();
2170 auto waitTime = endTime - startTime;
2171 if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
2172 TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
2173 layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2174 }
2175 }
2176 return static_cast<WMError>(ret);
2177 }
2178
MoveToAsync(int32_t x,int32_t y,MoveConfiguration moveConfiguration)2179 WMError WindowSceneSessionImpl::MoveToAsync(int32_t x, int32_t y, MoveConfiguration moveConfiguration)
2180 {
2181 if (IsWindowSessionInvalid()) {
2182 TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
2183 return WMError::WM_ERROR_INVALID_WINDOW;
2184 }
2185
2186 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
2187 TLOGW(WmsLogTag::WMS_LAYOUT, "window should not move, winId:%{public}u, mode:%{public}u",
2188 GetWindowId(), GetWindowMode());
2189 return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
2190 }
2191 auto ret = MoveTo(x, y, false, moveConfiguration);
2192 if (state_ == WindowState::STATE_SHOWN) {
2193 layoutCallback_->ResetMoveToLock();
2194 auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2195 std::chrono::system_clock::now().time_since_epoch()).count();
2196 layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2197 auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2198 std::chrono::system_clock::now().time_since_epoch()).count();
2199 auto waitTime = endTime - startTime;
2200 if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
2201 TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
2202 layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2203 }
2204 }
2205 return static_cast<WMError>(ret);
2206 }
2207
2208 /** @note @window.layout */
MoveWindowToGlobalDisplay(int32_t x,int32_t y,MoveConfiguration)2209 WMError WindowSceneSessionImpl::MoveWindowToGlobalDisplay(
2210 int32_t x, int32_t y, MoveConfiguration /*moveConfiguration*/)
2211 {
2212 if (IsWindowSessionInvalid()) {
2213 TLOGE(WmsLogTag::WMS_LAYOUT, "Invalid session");
2214 return WMError::WM_ERROR_INVALID_WINDOW;
2215 }
2216 auto mode = GetWindowMode();
2217 if (mode != WindowMode::WINDOW_MODE_FLOATING) {
2218 TLOGW(WmsLogTag::WMS_LAYOUT, "window should not move, windowId: %{public}u, mode: %{public}u",
2219 GetWindowId(), mode);
2220 return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
2221 }
2222 auto winId = GetPersistentId();
2223 const auto curGlobalDisplayRect = GetGlobalDisplayRect();
2224 if (curGlobalDisplayRect.IsSamePosition(x, y)) {
2225 TLOGW(WmsLogTag::WMS_LAYOUT, "windowId: %{public}u, request same position: [%{public}d, %{public}d]",
2226 winId, x, y);
2227 return WMError::WM_OK;
2228 }
2229 // Use RequestRect to quickly get width and height from Resize method.
2230 const auto requestRect = GetRequestRect();
2231 if (!Rect::IsRightBottomValid(x, y, requestRect.width_, requestRect.height_)) {
2232 TLOGE(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, illegal position: [%{public}d, %{public}d]", winId, x, y);
2233 return WMError::WM_ERROR_ILLEGAL_PARAM;
2234 }
2235 WSRect newGlobalDisplayRect = { x, y, requestRect.width_, requestRect.height_ };
2236 TLOGI(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, newGlobalDisplayRect: %{public}s",
2237 winId, newGlobalDisplayRect.ToString().c_str());
2238 auto hostSession = GetHostSession();
2239 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2240 auto ret = hostSession->UpdateGlobalDisplayRectFromClient(newGlobalDisplayRect, SizeChangeReason::MOVE);
2241 // If the window is shown, wait for the layout result from the server, so that the
2242 // caller can directly obtain the updated globalDisplayRect from the window properties.
2243 if (state_ == WindowState::STATE_SHOWN) {
2244 layoutCallback_->ResetMoveWindowToGlobalDisplayLock();
2245 const auto now = [] {
2246 return std::chrono::duration_cast<std::chrono::milliseconds>(
2247 std::chrono::system_clock::now().time_since_epoch()).count();
2248 };
2249 const auto startTime = now();
2250 layoutCallback_->GetMoveWindowToGlobalDisplayAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2251 const auto waitDuration = now() - startTime;
2252 if (waitDuration >= WINDOW_LAYOUT_TIMEOUT) {
2253 TLOGW(WmsLogTag::WMS_LAYOUT, "Window layout timeout, windowId: %{public}d", winId);
2254 layoutCallback_->GetMoveWindowToGlobalDisplayAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2255 }
2256 }
2257 return static_cast<WMError>(ret);
2258 }
2259
GetGlobalScaledRect(Rect & globalScaledRect)2260 WMError WindowSceneSessionImpl::GetGlobalScaledRect(Rect& globalScaledRect)
2261 {
2262 if (IsWindowSessionInvalid()) {
2263 TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
2264 return WMError::WM_ERROR_INVALID_WINDOW;
2265 }
2266 auto hostSession = GetHostSession();
2267 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2268 auto ret = hostSession->GetGlobalScaledRect(globalScaledRect);
2269 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, globalScaledRect:%{public}s, ret:%{public}d",
2270 GetPersistentId(), globalScaledRect.ToString().c_str(), ret);
2271 if (WMError::WM_OK == static_cast<WMError>(ret)) {
2272 HookWindowSizeByHookWindowInfo(globalScaledRect);
2273 }
2274 return static_cast<WMError>(ret);
2275 }
2276
LimitCameraFloatWindowMininumSize(uint32_t & width,uint32_t & height,float & vpr)2277 void WindowSceneSessionImpl::LimitCameraFloatWindowMininumSize(uint32_t& width, uint32_t& height, float& vpr)
2278 {
2279 // Float camera window has a special limit:
2280 // if display sw <= 600dp, portrait: min width = display sw * 30%, landscape: min width = sw * 50%
2281 // if display sw > 600dp, portrait: min width = display sw * 12%, landscape: min width = sw * 30%
2282 if (GetType() != WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2283 return;
2284 }
2285
2286 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2287 if (display == nullptr) {
2288 WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2289 return;
2290 }
2291 auto displayInfo = display->GetDisplayInfo();
2292 if (displayInfo == nullptr) {
2293 WLOGFE("get displayInfo failed displayId:%{public}" PRIu64, property_->GetDisplayId());
2294 return;
2295 }
2296 uint32_t displayWidth = static_cast<uint32_t>(display->GetWidth());
2297 uint32_t displayHeight = static_cast<uint32_t>(display->GetHeight());
2298 if (displayWidth == 0 || displayHeight == 0) {
2299 return;
2300 }
2301 vpr = GetVirtualPixelRatio(displayInfo);
2302 uint32_t smallWidth = displayHeight <= displayWidth ? displayHeight : displayWidth;
2303 float hwRatio = static_cast<float>(displayHeight) / static_cast<float>(displayWidth);
2304 uint32_t minWidth;
2305 if (smallWidth <= static_cast<uint32_t>(600 * vpr)) { // sw <= 600dp
2306 if (displayWidth <= displayHeight) {
2307 minWidth = static_cast<uint32_t>(smallWidth * 0.3); // ratio : 0.3
2308 } else {
2309 minWidth = static_cast<uint32_t>(smallWidth * 0.5); // ratio : 0.5
2310 }
2311 } else {
2312 if (displayWidth <= displayHeight) {
2313 minWidth = static_cast<uint32_t>(smallWidth * 0.12); // ratio : 0.12
2314 } else {
2315 minWidth = static_cast<uint32_t>(smallWidth * 0.3); // ratio : 0.3
2316 }
2317 }
2318 width = (width < minWidth) ? minWidth : width;
2319 height = static_cast<uint32_t>(width * hwRatio);
2320 }
2321
2322 /** @note @window.layout */
UpdateFloatingWindowSizeBySizeLimits(uint32_t & width,uint32_t & height) const2323 void WindowSceneSessionImpl::UpdateFloatingWindowSizeBySizeLimits(uint32_t& width, uint32_t& height) const
2324 {
2325 if (property_->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
2326 TLOGD(WmsLogTag::WMS_LAYOUT, "float camera type window");
2327 return;
2328 }
2329 // get new limit config with the settings of system and app
2330 const auto& sizeLimits = property_->GetWindowLimits();
2331 // limit minimum size of floating (not system type) window
2332 if (!WindowHelper::IsSystemWindow(property_->GetWindowType()) ||
2333 property_->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
2334 width = std::max(sizeLimits.minWidth_, width);
2335 height = std::max(sizeLimits.minHeight_, height);
2336 }
2337 width = std::min(sizeLimits.maxWidth_, width);
2338 height = std::min(sizeLimits.maxHeight_, height);
2339 if (height == 0) {
2340 return;
2341 }
2342 float curRatio = static_cast<float>(width) / static_cast<float>(height);
2343 // there is no need to fix size by ratio if this is not main floating window
2344 if (!WindowHelper::IsMainFloatingWindow(property_->GetWindowType(), GetWindowMode()) ||
2345 (!MathHelper::GreatNotEqual(sizeLimits.minRatio_, curRatio) &&
2346 !MathHelper::GreatNotEqual(curRatio, sizeLimits.maxRatio_))) {
2347 return;
2348 }
2349
2350 float newRatio = curRatio < sizeLimits.minRatio_ ? sizeLimits.minRatio_ : sizeLimits.maxRatio_;
2351 if (MathHelper::NearZero(newRatio)) {
2352 return;
2353 }
2354 if (sizeLimits.maxWidth_ == sizeLimits.minWidth_) {
2355 height = static_cast<uint32_t>(static_cast<float>(width) / newRatio);
2356 return;
2357 }
2358 if (sizeLimits.maxHeight_ == sizeLimits.minHeight_) {
2359 width = static_cast<uint32_t>(static_cast<float>(height) * newRatio);
2360 return;
2361 }
2362 WLOGFD("After limit by customize config: %{public}u %{public}u", width, height);
2363 }
2364
2365 /** @note @window.layout */
LimitWindowSize(uint32_t & width,uint32_t & height)2366 void WindowSceneSessionImpl::LimitWindowSize(uint32_t& width, uint32_t& height)
2367 {
2368 float vpr = 0.0f;
2369
2370 // Float camera window has special limits
2371 LimitCameraFloatWindowMininumSize(width, height, vpr);
2372
2373 if (!MathHelper::NearZero(vpr) || !MathHelper::NearZero(property_->GetLastLimitsVpr() - vpr)) {
2374 UpdateWindowSizeLimits();
2375 }
2376 UpdateFloatingWindowSizeBySizeLimits(width, height);
2377 }
2378
CheckAndModifyWindowRect(uint32_t & width,uint32_t & height)2379 WMError WindowSceneSessionImpl::CheckAndModifyWindowRect(uint32_t& width, uint32_t& height)
2380 {
2381 if (width == 0 || height == 0) {
2382 TLOGE(WmsLogTag::WMS_LAYOUT, "width or height should greater than 0!");
2383 return WMError::WM_ERROR_INVALID_PARAM;
2384 }
2385 if (IsWindowSessionInvalid()) {
2386 return WMError::WM_ERROR_INVALID_WINDOW;
2387 }
2388 if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2389 TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
2390 return WMError::WM_ERROR_INVALID_OPERATION;
2391 }
2392 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING && !IsFullScreenPcAppInPadMode()) {
2393 TLOGW(WmsLogTag::WMS_LAYOUT, "Fullscreen window could not resize, winId: %{public}u", GetWindowId());
2394 return WMError::WM_ERROR_INVALID_OPERATION;
2395 }
2396 if (IsFullScreenPcAppInPadMode() && IsFullScreenEnable()) {
2397 NotifyClientWindowSize();
2398 return WMError::WM_ERROR_INVALID_OPERATION;
2399 }
2400
2401 LimitWindowSize(width, height);
2402 return WMError::WM_OK;
2403 }
2404
2405 /** @note @window.layout */
Resize(uint32_t width,uint32_t height,const RectAnimationConfig & rectAnimationConfig)2406 WMError WindowSceneSessionImpl::Resize(uint32_t width, uint32_t height, const RectAnimationConfig& rectAnimationConfig)
2407 {
2408 auto reason = SizeChangeReason::RESIZE;
2409 if (isResizedByLimit_) {
2410 reason = SizeChangeReason::RESIZE_BY_LIMIT;
2411 isResizedByLimit_ = false;
2412 }
2413 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d resize %{public}u %{public}u",
2414 property_->GetPersistentId(), width, height);
2415
2416 if (CheckAndModifyWindowRect(width, height) != WMError::WM_OK) {
2417 return WMError::WM_ERROR_INVALID_OPERATION;
2418 }
2419 const auto& windowRect = GetRect();
2420 const auto& requestRect = GetRequestRect();
2421
2422 if (WindowHelper::IsSubWindow(GetType())) {
2423 auto mainWindow = FindMainWindowWithContext();
2424 if (mainWindow != nullptr && (mainWindow->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
2425 mainWindow->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
2426 if (width == requestRect.width_ && height == requestRect.height_) {
2427 TLOGW(WmsLogTag::WMS_LAYOUT, "Request same size in multiWindow will not update, return");
2428 return WMError::WM_OK;
2429 }
2430 }
2431 }
2432
2433 Rect newRect = { requestRect.posX_, requestRect.posY_, width, height }; // must keep w/h
2434 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
2435 "%{public}s, windowRect: %{public}s, newRect: %{public}s",
2436 property_->GetPersistentId(), state_, GetType(), GetWindowMode(), requestRect.ToString().c_str(),
2437 windowRect.ToString().c_str(), newRect.ToString().c_str());
2438
2439 property_->SetRequestRect(newRect);
2440 property_->SetRectAnimationConfig(rectAnimationConfig);
2441
2442 WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
2443 auto hostSession = GetHostSession();
2444 if (rectAnimationConfig.duration > 0 && reason == SizeChangeReason::RESIZE) {
2445 reason = SizeChangeReason::RESIZE_WITH_ANIMATION;
2446 }
2447
2448 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2449 auto ret = hostSession->UpdateSessionRect(wsRect, reason, false, false, {}, rectAnimationConfig);
2450 return static_cast<WMError>(ret);
2451 }
2452
ResizeAsync(uint32_t width,uint32_t height,const RectAnimationConfig & rectAnimationConfig)2453 WMError WindowSceneSessionImpl::ResizeAsync(uint32_t width, uint32_t height,
2454 const RectAnimationConfig& rectAnimationConfig)
2455 {
2456 if (IsWindowSessionInvalid()) {
2457 TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
2458 return WMError::WM_ERROR_INVALID_WINDOW;
2459 }
2460
2461 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING && !property_->GetIsPcAppInPad()) {
2462 TLOGW(WmsLogTag::WMS_LAYOUT, "window should not resize, winId:%{public}u, mode:%{public}u",
2463 GetWindowId(), GetWindowMode());
2464 return WMError::WM_ERROR_INVALID_OP_IN_CUR_STATUS;
2465 }
2466 auto ret = Resize(width, height, rectAnimationConfig);
2467 if (state_ == WindowState::STATE_SHOWN) {
2468 layoutCallback_->ResetResizeLock();
2469 auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2470 std::chrono::system_clock::now().time_since_epoch()).count();
2471 layoutCallback_->GetResizeAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2472 auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
2473 std::chrono::system_clock::now().time_since_epoch()).count();
2474 auto waitTime = endTime - startTime;
2475 if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
2476 TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
2477 layoutCallback_->GetResizeAsyncResult(WINDOW_LAYOUT_TIMEOUT);
2478 }
2479 }
2480 return static_cast<WMError>(ret);
2481 }
2482
SetFrameRectForPartialZoomIn(const Rect & frameRect)2483 WMError WindowSceneSessionImpl::SetFrameRectForPartialZoomIn(const Rect& frameRect)
2484 {
2485 TLOGI(WmsLogTag::WMS_ANIMATION, "set frame rect start, rect: %{public}s", frameRect.ToString().c_str());
2486 if (GetType() != WindowType::WINDOW_TYPE_MAGNIFICATION) {
2487 TLOGE(WmsLogTag::WMS_ANIMATION, "window type is invalid");
2488 return WMError::WM_ERROR_INVALID_WINDOW;
2489 }
2490
2491 if (IsWindowSessionInvalid()) {
2492 return WMError::WM_ERROR_INVALID_WINDOW;
2493 }
2494 auto hostSession = GetHostSession();
2495 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
2496 return static_cast<WMError>(hostSession->SetFrameRectForPartialZoomIn(frameRect));
2497 }
2498
UpdateWindowModeForUITest(int32_t updateMode)2499 WMError WindowSceneSessionImpl::UpdateWindowModeForUITest(int32_t updateMode)
2500 {
2501 TLOGI(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, updateMode: %{public}d", GetPersistentId(), updateMode);
2502 switch (updateMode) {
2503 case static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN):
2504 return Maximize();
2505 case static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING):
2506 return Recover();
2507 case static_cast<int32_t>(WindowMode::WINDOW_MODE_SPLIT_PRIMARY):
2508 return SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
2509 case static_cast<int32_t>(WindowMode::WINDOW_MODE_SPLIT_SECONDARY):
2510 return SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_SECONDARY);
2511 default:
2512 break;
2513 }
2514 return WMError::WM_DO_NOTHING;
2515 }
2516
GetTargetOrientationConfigInfo(Orientation targetOrientation,const std::map<WindowType,SystemBarProperty> & properties,Ace::ViewportConfig & config,std::map<AvoidAreaType,AvoidArea> & avoidAreas)2517 WMError WindowSceneSessionImpl::GetTargetOrientationConfigInfo(Orientation targetOrientation,
2518 const std::map<WindowType, SystemBarProperty>& properties, Ace::ViewportConfig& config,
2519 std::map<AvoidAreaType, AvoidArea>& avoidAreas)
2520 {
2521 if (IsWindowSessionInvalid()) {
2522 TLOGE(WmsLogTag::WMS_ROTATION, "Session is invalid");
2523 return WMError::WM_ERROR_INVALID_WINDOW;
2524 }
2525 std::map<WindowType, SystemBarProperty> pageProperties;
2526 GetSystemBarPropertyForPage(properties, pageProperties);
2527 auto hostSession = GetHostSession();
2528 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2529
2530 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2531 if (display == nullptr) {
2532 TLOGE(WmsLogTag::WMS_ROTATION, "display is null, winId=%{public}u", GetWindowId());
2533 return WMError::WM_ERROR_NULLPTR;
2534 }
2535 sptr<DisplayInfo> displayInfo = display ? display->GetDisplayInfo() : nullptr;
2536 if (displayInfo == nullptr) {
2537 TLOGE(WmsLogTag::WMS_ROTATION, "displayInfo is null!");
2538 return WMError::WM_ERROR_NULLPTR;
2539 }
2540 WSError ret;
2541 if (targetOrientation == Orientation::INVALID) {
2542 Orientation requestedOrientation = ConvertInvalidOrientation();
2543 ret = hostSession->GetTargetOrientationConfigInfo(requestedOrientation, pageProperties);
2544 } else {
2545 ret = hostSession->GetTargetOrientationConfigInfo(targetOrientation, pageProperties);
2546 }
2547 getTargetInfoCallback_->ResetGetTargetRotationLock();
2548 OrientationInfo info = getTargetInfoCallback_->GetTargetOrientationResult(WINDOW_PAGE_ROTATION_TIMEOUT);
2549 avoidAreas = info.avoidAreas;
2550 config = FillTargetOrientationConfig(info, displayInfo, GetDisplayId());
2551 TLOGI(WmsLogTag::WMS_ROTATION,
2552 "win:%{public}u, rotate:%{public}d, rect:%{public}s, avoidAreas:%{public}s,%{public}s,%{public}s,%{public}s",
2553 GetWindowId(), info.rotation, info.rect.ToString().c_str(),
2554 avoidAreas[AvoidAreaType::TYPE_SYSTEM].ToString().c_str(),
2555 avoidAreas[AvoidAreaType::TYPE_CUTOUT].ToString().c_str(),
2556 avoidAreas[AvoidAreaType::TYPE_KEYBOARD].ToString().c_str(),
2557 avoidAreas[AvoidAreaType::TYPE_NAVIGATION_INDICATOR].ToString().c_str());
2558 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
2559 "GetTargetOrientationConfigInfo: targetOrientation:%u, rotation:%d, rect:%s",
2560 static_cast<uint32_t>(targetOrientation), info.rotation, info.rect.ToString().c_str());
2561
2562 return static_cast<WMError>(ret);
2563 }
2564
FillTargetOrientationConfig(const OrientationInfo & info,const sptr<DisplayInfo> & displayInfo,uint64_t displayId)2565 Ace::ViewportConfig WindowSceneSessionImpl::FillTargetOrientationConfig(
2566 const OrientationInfo& info, const sptr<DisplayInfo>& displayInfo, uint64_t displayId)
2567 {
2568 Ace::ViewportConfig config;
2569 Rect targetRect = info.rect;
2570 uint32_t targetRotation = info.rotation;
2571 if (displayInfo == nullptr) {
2572 TLOGE(WmsLogTag::WMS_ROTATION, "displayInfo is null!");
2573 return config;
2574 }
2575 auto deviceRotation = static_cast<uint32_t>(displayInfo->GetDefaultDeviceRotationOffset());
2576 uint32_t transformHint = (targetRotation + deviceRotation) % FULL_CIRCLE_DEGREE;
2577 float density = GetVirtualPixelRatio(displayInfo);
2578 int32_t orientation = static_cast<int32_t>(targetRotation) / ONE_FOURTH_FULL_CIRCLE_DEGREE;
2579 virtualPixelRatio_ = density;
2580 config.SetSize(targetRect.width_, targetRect.height_);
2581 config.SetPosition(targetRect.posX_, targetRect.posY_);
2582 config.SetDensity(density);
2583 config.SetOrientation(orientation);
2584 config.SetTransformHint(transformHint);
2585 config.SetDisplayId(displayId);
2586 return config;
2587 }
2588
NotifyTargetRotationInfo(OrientationInfo & info)2589 WSError WindowSceneSessionImpl::NotifyTargetRotationInfo(OrientationInfo& info)
2590 {
2591 WSError ret = WSError::WS_OK;
2592 if (getTargetInfoCallback_) {
2593 ret = getTargetInfoCallback_->OnUpdateTargetOrientationInfo(info);
2594 }
2595 return ret;
2596 }
2597
SetAspectRatio(float ratio)2598 WMError WindowSceneSessionImpl::SetAspectRatio(float ratio)
2599 {
2600 if (IsWindowSessionInvalid()) {
2601 TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
2602 return WMError::WM_ERROR_INVALID_WINDOW;
2603 }
2604
2605 auto hostSession = GetHostSession();
2606 if (hostSession == nullptr) {
2607 WLOGFE("failed, because of nullptr");
2608 return WMError::WM_ERROR_NULLPTR;
2609 }
2610 if (ratio == MathHelper::INF || ratio == MathHelper::NAG_INF || std::isnan(ratio) || MathHelper::NearZero(ratio)) {
2611 WLOGFE("failed, because of wrong value: %{public}f", ratio);
2612 return WMError::WM_ERROR_INVALID_PARAM;
2613 }
2614 if (hostSession->SetAspectRatio(ratio) != WSError::WS_OK) {
2615 return WMError::WM_ERROR_INVALID_PARAM;
2616 }
2617 return WMError::WM_OK;
2618 }
2619
ResetAspectRatio()2620 WMError WindowSceneSessionImpl::ResetAspectRatio()
2621 {
2622 auto hostSession = GetHostSession();
2623 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2624 return static_cast<WMError>(hostSession->SetAspectRatio(0.0f));
2625 }
2626
2627 /** @note @window.hierarchy */
RaiseToAppTop()2628 WMError WindowSceneSessionImpl::RaiseToAppTop()
2629 {
2630 if (IsWindowSessionInvalid()) {
2631 TLOGE(WmsLogTag::WMS_HIERARCHY, "Session is invalid");
2632 return WMError::WM_ERROR_INVALID_WINDOW;
2633 }
2634
2635 WLOGFI("id: %{public}d", GetPersistentId());
2636 auto parentId = GetParentId();
2637 if (parentId == INVALID_SESSION_ID) {
2638 WLOGFE("Only the children of the main window can be raised!");
2639 return WMError::WM_ERROR_INVALID_PARENT;
2640 }
2641
2642 if (!WindowHelper::IsSubWindow(GetType())) {
2643 WLOGFE("Must be app sub window window!");
2644 return WMError::WM_ERROR_INVALID_CALLING;
2645 }
2646
2647 if (state_ != WindowState::STATE_SHOWN) {
2648 WLOGFE("The sub window must be shown!");
2649 return WMError::WM_DO_NOTHING;
2650 }
2651 auto hostSession = GetHostSession();
2652 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2653 WSError ret = hostSession->RaiseToAppTop();
2654 return static_cast<WMError>(ret);
2655 }
2656
2657 /** @note @window.hierarchy */
RaiseAboveTarget(int32_t subWindowId)2658 WMError WindowSceneSessionImpl::RaiseAboveTarget(int32_t subWindowId)
2659 {
2660 if (IsWindowSessionInvalid()) {
2661 TLOGE(WmsLogTag::WMS_HIERARCHY, "Session is invalid");
2662 return WMError::WM_ERROR_INVALID_WINDOW;
2663 }
2664
2665 auto parentId = GetParentId();
2666 auto currentWindowId = GetWindowId();
2667
2668 if (parentId == INVALID_SESSION_ID) {
2669 WLOGFE("Only the children of the main window can be raised!");
2670 return WMError::WM_ERROR_INVALID_PARENT;
2671 }
2672
2673 auto subWindows = Window::GetSubWindow(parentId);
2674 auto targetWindow = find_if(subWindows.begin(), subWindows.end(), [subWindowId](sptr<Window>& window) {
2675 return static_cast<uint32_t>(subWindowId) == window->GetWindowId();
2676 });
2677 if (targetWindow == subWindows.end()) {
2678 return WMError::WM_ERROR_INVALID_PARAM;
2679 }
2680
2681 if (!WindowHelper::IsSubWindow(GetType())) {
2682 WLOGFE("Must be app sub window window!");
2683 return WMError::WM_ERROR_INVALID_CALLING;
2684 }
2685
2686 if ((state_ != WindowState::STATE_SHOWN) ||
2687 ((*targetWindow)->GetWindowState() != WindowState::STATE_SHOWN)) {
2688 WLOGFE("The sub window must be shown!");
2689 return WMError::WM_DO_NOTHING;
2690 }
2691 if (currentWindowId == static_cast<uint32_t>(subWindowId)) {
2692 return WMError::WM_OK;
2693 }
2694 auto hostSession = GetHostSession();
2695 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2696 WSError ret = hostSession->RaiseAboveTarget(subWindowId);
2697 return static_cast<WMError>(ret);
2698 }
2699
2700 /** @note @window.hierarchy */
RaiseMainWindowAboveTarget(int32_t targetId)2701 WMError WindowSceneSessionImpl::RaiseMainWindowAboveTarget(int32_t targetId)
2702 {
2703 TLOGI(WmsLogTag::WMS_HIERARCHY, "source id: %{public}u, target id: %{public}u", GetWindowId(), targetId);
2704 if (!IsPcOrPadFreeMultiWindowMode()) {
2705 TLOGE(WmsLogTag::WMS_HIERARCHY, "device type not supported");
2706 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2707 }
2708 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
2709 auto targetIter = std::find_if(windowSessionMap_.begin(), windowSessionMap_.end(),
2710 [targetId](const auto& windowInfoPair) {return windowInfoPair.second.first == targetId;});
2711 if (targetIter == windowSessionMap_.end()) {
2712 TLOGE(WmsLogTag::WMS_HIERARCHY, "target id invalid or pid inconsistent with source window pid");
2713 return WMError::WM_ERROR_INVALID_WINDOW;
2714 }
2715 auto targetSessionImpl = targetIter->second.second;
2716 if (IsWindowSessionInvalid() || targetSessionImpl == nullptr || targetSessionImpl->GetHostSession() == nullptr ||
2717 targetSessionImpl->state_ == WindowState::STATE_DESTROYED) {
2718 TLOGE(WmsLogTag::WMS_HIERARCHY, "source window or target window is null or destroyed");
2719 return WMError::WM_ERROR_INVALID_WINDOW;
2720 }
2721 if (state_ != WindowState::STATE_SHOWN || targetSessionImpl->state_ != WindowState::STATE_SHOWN) {
2722 TLOGE(WmsLogTag::WMS_HIERARCHY, "both source window and target window must be shown");
2723 return WMError::WM_ERROR_INVALID_WINDOW;
2724 }
2725 if (!WindowHelper::IsMainWindow(GetType()) || !WindowHelper::IsMainWindow(targetSessionImpl->GetType())) {
2726 TLOGE(WmsLogTag::WMS_HIERARCHY, "window type not supported");
2727 return WMError::WM_ERROR_INVALID_CALLING;
2728 }
2729 if (WindowHelper::IsModalMainWindow(GetType(), GetWindowFlags()) ||
2730 WindowHelper::IsModalMainWindow(targetSessionImpl->GetType(), targetSessionImpl->GetWindowFlags())) {
2731 TLOGE(WmsLogTag::WMS_HIERARCHY, "both source window and target window must be not modal");
2732 return WMError::WM_ERROR_INVALID_CALLING;
2733 }
2734 if (IsApplicationModalSubWindowShowing(GetWindowId()) || IsApplicationModalSubWindowShowing(targetId)) {
2735 TLOGE(WmsLogTag::WMS_HIERARCHY, "application sub window is not allowed");
2736 return WMError::WM_ERROR_INVALID_CALLING;
2737 }
2738 if (IsMainWindowTopmost() || targetSessionImpl->IsMainWindowTopmost() || IsTopmost() ||
2739 targetSessionImpl->IsTopmost()) {
2740 TLOGE(WmsLogTag::WMS_HIERARCHY, "both source window and target window must be not topmost");
2741 return WMError::WM_ERROR_INVALID_CALLING;
2742 }
2743 auto hostSession = GetHostSession();
2744 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2745 WSError ret = hostSession->RaiseMainWindowAboveTarget(targetId);
2746 return static_cast<WMError>(ret);
2747 }
2748
2749 /** @note @window.hierarchy */
SetSubWindowZLevel(int32_t zLevel)2750 WMError WindowSceneSessionImpl::SetSubWindowZLevel(int32_t zLevel)
2751 {
2752 TLOGD(WmsLogTag::WMS_HIERARCHY, "%{public}d", zLevel);
2753 if (IsWindowSessionInvalid()) {
2754 TLOGE(WmsLogTag::WMS_HIERARCHY, "session is invalid");
2755 return WMError::WM_ERROR_INVALID_WINDOW;
2756 }
2757
2758 if (!windowSystemConfig_.supportZLevel_) {
2759 TLOGE(WmsLogTag::WMS_HIERARCHY, "The device is not supported");
2760 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2761 }
2762
2763 if (!WindowHelper::IsNormalSubWindow(GetType(), property_->GetWindowFlags())) {
2764 TLOGE(WmsLogTag::WMS_HIERARCHY, "must be normal app sub window");
2765 return WMError::WM_ERROR_INVALID_CALLING;
2766 }
2767 if (GetParentId() == INVALID_SESSION_ID) {
2768 TLOGE(WmsLogTag::WMS_HIERARCHY, "only the children of the main window can be raised");
2769 return WMError::WM_ERROR_INVALID_PARENT;
2770 }
2771 if (zLevel > MAXIMUM_Z_LEVEL || zLevel < MINIMUM_Z_LEVEL) {
2772 TLOGE(WmsLogTag::WMS_HIERARCHY, "zLevel value %{public}d exceeds valid range [-10000, 10000]!", zLevel);
2773 return WMError::WM_ERROR_INVALID_PARAM;
2774 }
2775
2776 auto currentZLevel = property_->GetSubWindowZLevel();
2777 if (currentZLevel == static_cast<int32_t>(zLevel)) {
2778 return WMError::WM_OK;
2779 }
2780 property_->SetSubWindowZLevel(zLevel);
2781 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SUB_WINDOW_Z_LEVEL);
2782 }
2783
2784 /** @note @window.hierarchy */
GetSubWindowZLevel(int32_t & zLevel)2785 WMError WindowSceneSessionImpl::GetSubWindowZLevel(int32_t& zLevel)
2786 {
2787 if (IsWindowSessionInvalid()) {
2788 TLOGE(WmsLogTag::WMS_HIERARCHY, "session is invalid");
2789 return WMError::WM_ERROR_INVALID_WINDOW;
2790 }
2791
2792 if (!windowSystemConfig_.supportZLevel_) {
2793 TLOGE(WmsLogTag::WMS_HIERARCHY, "The device is not supported");
2794 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2795 }
2796
2797 if (!WindowHelper::IsSubWindow(GetType()) || !WindowHelper::IsDialogWindow(GetType())) {
2798 TLOGE(WmsLogTag::WMS_HIERARCHY, "must be app sub window!");
2799 return WMError::WM_ERROR_INVALID_CALLING;
2800 }
2801 zLevel = property_->GetSubWindowZLevel();
2802 TLOGI(WmsLogTag::WMS_HIERARCHY, "Id:%{public}u, zLevel:%{public}d", GetWindowId(), zLevel);
2803 return WMError::WM_OK;
2804 }
2805
GetAvoidAreaByType(AvoidAreaType type,AvoidArea & avoidArea,const Rect & rect,int32_t apiVersion)2806 WMError WindowSceneSessionImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea,
2807 const Rect& rect, int32_t apiVersion)
2808 {
2809 uint32_t currentApiVersion = GetTargetAPIVersionByApplicationInfo();
2810 apiVersion = (apiVersion == API_VERSION_INVALID) ? static_cast<int32_t>(currentApiVersion) : apiVersion;
2811 if (apiVersion < API_VERSION_18 && WindowHelper::IsSystemWindow(property_->GetWindowType())) {
2812 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u type %{public}d api %{public}u not supported",
2813 GetWindowId(), type, apiVersion);
2814 return WMError::WM_OK;
2815 }
2816 if (IsWindowSessionInvalid()) {
2817 return WMError::WM_ERROR_INVALID_WINDOW;
2818 }
2819 auto hostSession = GetHostSession();
2820 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2821 WSRect sessionRect = {
2822 rect.posX_, rect.posY_, static_cast<int32_t>(rect.width_), static_cast<int32_t>(rect.height_)
2823 };
2824 avoidArea = hostSession->GetAvoidAreaByType(type, sessionRect, apiVersion);
2825 getAvoidAreaCnt_++;
2826 TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] type %{public}d times %{public}u area %{public}s",
2827 GetWindowId(), GetWindowName().c_str(), type, getAvoidAreaCnt_.load(), avoidArea.ToString().c_str());
2828 return WMError::WM_OK;
2829 }
2830
NotifyWindowNeedAvoid(bool status)2831 WMError WindowSceneSessionImpl::NotifyWindowNeedAvoid(bool status)
2832 {
2833 TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u status %{public}d",
2834 GetWindowId(), static_cast<int32_t>(status));
2835 if (IsWindowSessionInvalid()) {
2836 TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
2837 return WMError::WM_ERROR_INVALID_WINDOW;
2838 }
2839 auto hostSession = GetHostSession();
2840 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2841 hostSession->OnNeedAvoid(status);
2842 return WMError::WM_OK;
2843 }
2844
SetIgnoreSafeArea(bool isIgnoreSafeArea)2845 WMError WindowSceneSessionImpl::SetIgnoreSafeArea(bool isIgnoreSafeArea)
2846 {
2847 return SetLayoutFullScreenByApiVersion(isIgnoreSafeArea);
2848 }
2849
SetLayoutFullScreenByApiVersion(bool status)2850 WMError WindowSceneSessionImpl::SetLayoutFullScreenByApiVersion(bool status)
2851 {
2852 if (IsWindowSessionInvalid()) {
2853 TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
2854 return WMError::WM_ERROR_INVALID_WINDOW;
2855 }
2856 uint32_t version = 0;
2857 auto context = GetContext();
2858 if ((context != nullptr) && (context->GetApplicationInfo() != nullptr)) {
2859 version = context->GetApplicationInfo()->apiCompatibleVersion;
2860 }
2861 isIgnoreSafeArea_ = status;
2862 isIgnoreSafeAreaNeedNotify_ = true;
2863 // 10 ArkUI new framework support after API10
2864 if (version >= 10) {
2865 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u status %{public}d",
2866 GetWindowId(), static_cast<int32_t>(status));
2867 if (auto uiContent = GetUIContentSharedPtr()) {
2868 uiContent->SetIgnoreViewSafeArea(status);
2869 }
2870 } else {
2871 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u status %{public}d",
2872 GetWindowId(), static_cast<int32_t>(status));
2873 WMError ret = WMError::WM_OK;
2874 if (status) {
2875 ret = RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
2876 if (ret != WMError::WM_OK) {
2877 TLOGE(WmsLogTag::WMS_IMMS, "remove window flag, win %{public}u errCode %{public}d",
2878 GetWindowId(), static_cast<int32_t>(ret));
2879 return ret;
2880 }
2881 } else {
2882 ret = AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
2883 if (ret != WMError::WM_OK) {
2884 TLOGE(WmsLogTag::WMS_IMMS, "add window flag, win %{public}u errCode %{public}d",
2885 GetWindowId(), static_cast<int32_t>(ret));
2886 return ret;
2887 }
2888 }
2889 ret = NotifyWindowNeedAvoid(!status);
2890 if (ret != WMError::WM_OK) {
2891 TLOGE(WmsLogTag::WMS_IMMS, "notify window need avoid, win %{public}u errCode %{public}d",
2892 GetWindowId(), static_cast<int32_t>(ret));
2893 return ret;
2894 }
2895 }
2896 return WMError::WM_OK;
2897 }
2898
SetLayoutFullScreen(bool status)2899 WMError WindowSceneSessionImpl::SetLayoutFullScreen(bool status)
2900 {
2901 TLOGD(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] status %{public}d",
2902 GetWindowId(), GetWindowName().c_str(), static_cast<int32_t>(status));
2903 if (IsWindowSessionInvalid()) {
2904 return WMError::WM_ERROR_INVALID_WINDOW;
2905 }
2906 if (WindowHelper::IsSystemWindow(GetType())) {
2907 TLOGI(WmsLogTag::WMS_IMMS, "system window not supported");
2908 return WMError::WM_OK;
2909 }
2910
2911 if (IsPcOrPadFreeMultiWindowMode() && property_->IsAdaptToImmersive()) {
2912 SetLayoutFullScreenByApiVersion(status);
2913 // compatibleMode app may set statusBarColor before ignoreSafeArea
2914 auto systemBarProperties = property_->GetSystemBarProperty();
2915 if (status && systemBarProperties.find(WindowType::WINDOW_TYPE_STATUS_BAR) != systemBarProperties.end()) {
2916 auto statusBarProperty = systemBarProperties[WindowType::WINDOW_TYPE_STATUS_BAR];
2917 HookDecorButtonStyleInCompatibleMode(statusBarProperty.contentColor_);
2918 }
2919 return WMError::WM_OK;
2920 }
2921
2922 bool preStatus = property_->IsLayoutFullScreen();
2923 property_->SetIsLayoutFullScreen(status);
2924 auto hostSession = GetHostSession();
2925 if (hostSession != nullptr) {
2926 hostSession->OnLayoutFullScreenChange(status);
2927 }
2928
2929 if (WindowHelper::IsMainWindow(GetType()) && !windowSystemConfig_.IsPhoneWindow() &&
2930 !windowSystemConfig_.IsPadWindow()) {
2931 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
2932 WindowMode::WINDOW_MODE_FULLSCREEN)) {
2933 TLOGE(WmsLogTag::WMS_IMMS, "fullscreen window mode not supported");
2934 return WMError::WM_ERROR_INVALID_WINDOW;
2935 }
2936 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
2937 auto event = SessionEvent::EVENT_MAXIMIZE;
2938 if (isFullScreenWaterfallMode_.load()) {
2939 event = SessionEvent::EVENT_MAXIMIZE_WATERFALL;
2940 } else if (isWaterfallToMaximize_.load()) {
2941 event = SessionEvent::EVENT_WATERFALL_TO_MAXIMIZE;
2942 isWaterfallToMaximize_.store(false);
2943 }
2944 hostSession->OnSessionEvent(event);
2945 SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
2946 }
2947
2948 WMError ret = SetLayoutFullScreenByApiVersion(status);
2949 if (ret != WMError::WM_OK) {
2950 property_->SetIsLayoutFullScreen(preStatus);
2951 TLOGE(WmsLogTag::WMS_IMMS, "failed, win %{public}u errCode %{public}d",
2952 GetWindowId(), static_cast<int32_t>(ret));
2953 }
2954 enableImmersiveMode_ = status;
2955 return ret;
2956 }
2957
SetTitleAndDockHoverShown(bool isTitleHoverShown,bool isDockHoverShown)2958 WMError WindowSceneSessionImpl::SetTitleAndDockHoverShown(
2959 bool isTitleHoverShown, bool isDockHoverShown)
2960 {
2961 if (IsWindowSessionInvalid()) {
2962 return WMError::WM_ERROR_INVALID_WINDOW;
2963 }
2964 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId:%{public}u %{public}s isTitleHoverShown:%{public}d, "
2965 "isDockHoverShown:%{public}d", GetWindowId(), GetWindowName().c_str(), isTitleHoverShown, isDockHoverShown);
2966 if (!WindowHelper::IsMainWindow(GetType())) {
2967 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "window is not main window");
2968 return WMError::WM_ERROR_INVALID_CALLING;
2969 }
2970 if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
2971 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is PcAppInPad, not supported");
2972 return WMError::WM_OK;
2973 }
2974 if (!IsPcOrPadFreeMultiWindowMode()) {
2975 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
2976 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2977 }
2978 titleHoverShowEnabled_ = isTitleHoverShown;
2979 dockHoverShowEnabled_ = isDockHoverShown;
2980 if (auto hostSession = GetHostSession()) {
2981 hostSession->OnTitleAndDockHoverShowChange(isTitleHoverShown, isDockHoverShown);
2982 }
2983 return WMError::WM_OK;
2984 }
2985
IsLayoutFullScreen() const2986 bool WindowSceneSessionImpl::IsLayoutFullScreen() const
2987 {
2988 if (IsWindowSessionInvalid()) {
2989 return false;
2990 }
2991 WindowType winType = property_->GetWindowType();
2992 if (WindowHelper::IsMainWindow(winType)) {
2993 return (GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && isIgnoreSafeArea_);
2994 }
2995 if (WindowHelper::IsSubWindow(winType)) {
2996 return (isIgnoreSafeAreaNeedNotify_ && isIgnoreSafeArea_);
2997 }
2998 return false;
2999 }
3000
GetSystemBarPropertyByType(WindowType type) const3001 SystemBarProperty WindowSceneSessionImpl::GetSystemBarPropertyByType(WindowType type) const
3002 {
3003 auto curProperties = property_->GetSystemBarProperty();
3004 return curProperties[type];
3005 }
3006
NotifyWindowSessionProperty()3007 WMError WindowSceneSessionImpl::NotifyWindowSessionProperty()
3008 {
3009 TLOGD(WmsLogTag::WMS_IMMS, "windowId:%{public}u", GetWindowId());
3010 if (IsWindowSessionInvalid()) {
3011 TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
3012 return WMError::WM_ERROR_INVALID_WINDOW;
3013 }
3014 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS);
3015 return WMError::WM_OK;
3016 }
3017
NotifySpecificWindowSessionProperty(WindowType type,const SystemBarProperty & property)3018 WMError WindowSceneSessionImpl::NotifySpecificWindowSessionProperty(WindowType type, const SystemBarProperty& property)
3019 {
3020 TLOGD(WmsLogTag::WMS_IMMS, "windowId:%{public}u", GetWindowId());
3021 if (IsWindowSessionInvalid()) {
3022 TLOGE(WmsLogTag::WMS_IMMS, "session is invalid");
3023 return WMError::WM_ERROR_INVALID_WINDOW;
3024 }
3025 if (type == WindowType::WINDOW_TYPE_STATUS_BAR) {
3026 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS);
3027 if (auto uiContent = GetUIContentSharedPtr()) {
3028 uiContent->SetStatusBarItemColor(property.contentColor_);
3029 AAFwk::Want want;
3030 want.SetParam(Extension::HOST_STATUS_BAR_CONTENT_COLOR, static_cast<int32_t>(property.contentColor_));
3031 uiContent->SendUIExtProprty(
3032 static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_STATUS_BAR_CONTENT_COLOR), want,
3033 static_cast<uint8_t>(SubSystemId::WM_UIEXT));
3034 }
3035 if (property_->IsAdaptToImmersive() && isIgnoreSafeArea_) {
3036 HookDecorButtonStyleInCompatibleMode(property.contentColor_);
3037 }
3038 } else if (type == WindowType::WINDOW_TYPE_NAVIGATION_BAR) {
3039 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS);
3040 } else if (type == WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR) {
3041 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS);
3042 }
3043 return WMError::WM_OK;
3044 }
3045
HookDecorButtonStyleInCompatibleMode(uint32_t color)3046 void WindowSceneSessionImpl::HookDecorButtonStyleInCompatibleMode(uint32_t color)
3047 {
3048 if (!property_->IsAdaptToImmersive()) {
3049 return;
3050 }
3051 // alpha Color Channel
3052 auto alpha = (color >> 24) & 0xFF;
3053 // R Color Channel
3054 auto red = (color >> 16) & 0xFF;
3055 // G Color Channel
3056 auto green = (color >> 8) & 0xFF;
3057 // B Color Channel
3058 auto blue = color & 0xFF;
3059 // calculate luminance, Identify whether a color is more black or more white.
3060 double luminance = 0.299 * red + 0.587 * green + 0.114 * blue;
3061 DecorButtonStyle style;
3062 style.colorMode = ((luminance > (0xFF>>1)) || (alpha == 0x00)) ? LIGHT_COLOR_MODE : DARK_COLOR_MODE;
3063 TLOGI(WmsLogTag::WMS_DECOR, "contentColor:%{public}d luminance:%{public}f colorMode:%{public}d",
3064 color, luminance, style.colorMode);
3065 SetDecorButtonStyle(style);
3066 }
3067
SetSpecificBarProperty(WindowType type,const SystemBarProperty & property)3068 WMError WindowSceneSessionImpl::SetSpecificBarProperty(WindowType type, const SystemBarProperty& property)
3069 {
3070 if (IsWindowSessionInvalid()) {
3071 return WMError::WM_ERROR_INVALID_WINDOW;
3072 }
3073 if (!WindowHelper::IsMainWindow(GetType())) {
3074 TLOGI(WmsLogTag::WMS_IMMS, "only main window support");
3075 return WMError::WM_OK;
3076 }
3077 if (!(state_ > WindowState::STATE_INITIAL && state_ < WindowState::STATE_BOTTOM)) {
3078 TLOGE(WmsLogTag::WMS_IMMS, "win %{public}u invalid state", GetWindowId());
3079 return WMError::WM_ERROR_INVALID_WINDOW;
3080 } else if (GetSystemBarPropertyByType(type) == property &&
3081 property.settingFlag_ == SystemBarSettingFlag::DEFAULT_SETTING) {
3082 setSameSystembarPropertyCnt_++;
3083 TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] set "
3084 "%{public}u %{public}u %{public}x %{public}x %{public}u, for %{public}u times",
3085 GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type), property.enable_,
3086 property.backgroundColor_, property.contentColor_, property.enableAnimation_,
3087 setSameSystembarPropertyCnt_);
3088 return WMError::WM_OK;
3089 }
3090 setSameSystembarPropertyCnt_ = 0;
3091 TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] type %{public}u "
3092 "%{public}u %{public}x %{public}x %{public}u %{public}u",
3093 GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type), property.enable_,
3094 property.backgroundColor_, property.contentColor_, property.enableAnimation_, property.settingFlag_);
3095
3096 isSystembarPropertiesSet_ = true;
3097 property_->SetSystemBarProperty(type, property);
3098 WMError ret = NotifySpecificWindowSessionProperty(type, property);
3099 if (ret != WMError::WM_OK) {
3100 TLOGE(WmsLogTag::WMS_IMMS, "win %{public}u errCode %{public}d",
3101 GetWindowId(), static_cast<int32_t>(ret));
3102 }
3103 return ret;
3104 }
3105
UpdateSystemBarProperties(const std::unordered_map<WindowType,SystemBarProperty> & systemBarProperties,const std::unordered_map<WindowType,SystemBarPropertyFlag> & systemBarPropertyFlags)3106 WMError WindowSceneSessionImpl::UpdateSystemBarProperties(
3107 const std::unordered_map<WindowType, SystemBarProperty>& systemBarProperties,
3108 const std::unordered_map<WindowType, SystemBarPropertyFlag>& systemBarPropertyFlags)
3109 {
3110 for (auto [systemBarType, systemBarPropertyFlag] : systemBarPropertyFlags) {
3111 if (systemBarProperties.find(systemBarType) == systemBarProperties.end()) {
3112 TLOGE(WmsLogTag::WMS_IMMS, "system bar type is invalid");
3113 return WMError::WM_DO_NOTHING;
3114 }
3115 auto property = GetSystemBarPropertyByType(systemBarType);
3116 property.enable_ = systemBarPropertyFlag.enableFlag ?
3117 systemBarProperties.at(systemBarType).enable_ : property.enable_;
3118 property.backgroundColor_ = systemBarPropertyFlag.backgroundColorFlag ?
3119 systemBarProperties.at(systemBarType).backgroundColor_ : property.backgroundColor_;
3120 property.contentColor_ = systemBarPropertyFlag.contentColorFlag ?
3121 systemBarProperties.at(systemBarType).contentColor_ : property.contentColor_;
3122 property.enableAnimation_ = systemBarPropertyFlag.enableAnimationFlag ?
3123 systemBarProperties.at(systemBarType).enableAnimation_ : property.enableAnimation_;
3124
3125 if (systemBarPropertyFlag.enableFlag) {
3126 property.settingFlag_ |= SystemBarSettingFlag::ENABLE_SETTING;
3127 }
3128 if (systemBarPropertyFlag.backgroundColorFlag || systemBarPropertyFlag.contentColorFlag) {
3129 property.settingFlag_ |= SystemBarSettingFlag::COLOR_SETTING;
3130 }
3131 if (systemBarPropertyFlag.enableFlag || systemBarPropertyFlag.backgroundColorFlag ||
3132 systemBarPropertyFlag.contentColorFlag || systemBarPropertyFlag.enableAnimationFlag) {
3133 auto err = SetSystemBarProperty(systemBarType, property);
3134 if (err != WMError::WM_OK) {
3135 return err;
3136 }
3137 }
3138 }
3139 return WMError::WM_OK;
3140 }
3141
SetSystemBarProperty(WindowType type,const SystemBarProperty & property)3142 WMError WindowSceneSessionImpl::SetSystemBarProperty(WindowType type, const SystemBarProperty& property)
3143 {
3144 return SetSpecificBarProperty(type, property);
3145 }
3146
SetSystemBarProperties(const std::map<WindowType,SystemBarProperty> & properties,const std::map<WindowType,SystemBarPropertyFlag> & propertyFlags)3147 WMError WindowSceneSessionImpl::SetSystemBarProperties(const std::map<WindowType, SystemBarProperty>& properties,
3148 const std::map<WindowType, SystemBarPropertyFlag>& propertyFlags)
3149 {
3150 SystemBarProperty current = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
3151 auto flagIter = propertyFlags.find(WindowType::WINDOW_TYPE_STATUS_BAR);
3152 auto propertyIter = properties.find(WindowType::WINDOW_TYPE_STATUS_BAR);
3153 if ((flagIter != propertyFlags.end() && flagIter->second.contentColorFlag) &&
3154 (propertyIter != properties.end() && current.contentColor_ != propertyIter->second.contentColor_)) {
3155 current.contentColor_ = propertyIter->second.contentColor_;
3156 current.settingFlag_ = static_cast<SystemBarSettingFlag>(
3157 static_cast<uint32_t>(propertyIter->second.settingFlag_) |
3158 static_cast<uint32_t>(SystemBarSettingFlag::COLOR_SETTING));
3159 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u set status bar content color %{public}u",
3160 GetWindowId(), current.contentColor_);
3161 return SetSpecificBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, current);
3162 }
3163 return WMError::WM_OK;
3164 }
3165
GetSystemBarProperties(std::map<WindowType,SystemBarProperty> & properties)3166 WMError WindowSceneSessionImpl::GetSystemBarProperties(std::map<WindowType, SystemBarProperty>& properties)
3167 {
3168 auto currProperties = property_->GetSystemBarProperty();
3169 properties[WindowType::WINDOW_TYPE_STATUS_BAR] = currProperties[WindowType::WINDOW_TYPE_STATUS_BAR];
3170 return WMError::WM_OK;
3171 }
3172
SetSystemBarPropertyForPage(WindowType type,std::optional<SystemBarProperty> property)3173 WMError WindowSceneSessionImpl::SetSystemBarPropertyForPage(WindowType type, std::optional<SystemBarProperty> property)
3174 {
3175 if (IsWindowSessionInvalid()) {
3176 TLOGE(WmsLogTag::WMS_IMMS, "win %{public}u invalid state", GetWindowId());
3177 return WMError::WM_ERROR_INVALID_WINDOW;
3178 }
3179 if (!WindowHelper::IsMainWindow(GetType())) {
3180 TLOGI(WmsLogTag::WMS_IMMS, "only main window support, win %{public}u", GetWindowId());
3181 return WMError::WM_DO_NOTHING;
3182 }
3183 if (property == std::nullopt) {
3184 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u property is nullptr use main window prop", GetWindowId());
3185 return NotifySpecificWindowSessionProperty(type, GetSystemBarPropertyByType(type));
3186 }
3187 TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] type %{public}u "
3188 "%{public}u %{public}x %{public}x %{public}u %{public}u",
3189 GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type),
3190 property->enable_, property->backgroundColor_,
3191 property->contentColor_, property->enableAnimation_, property->settingFlag_);
3192 auto lastProperty = GetSystemBarPropertyByType(type);
3193 property_->SetSystemBarProperty(type, property.value());
3194 auto ret = NotifySpecificWindowSessionProperty(type, property.value());
3195 property_->SetSystemBarProperty(type, lastProperty);
3196 if (ret != WMError::WM_OK) {
3197 TLOGE(WmsLogTag::WMS_IMMS, "set prop fail, ret %{public}u", ret);
3198 return ret;
3199 }
3200 return WMError::WM_OK;
3201 }
3202
GetSystemBarPropertyForPage(const std::map<WindowType,SystemBarProperty> & properties,std::map<WindowType,SystemBarProperty> & pageProperties)3203 void WindowSceneSessionImpl::GetSystemBarPropertyForPage(const std::map<WindowType, SystemBarProperty>& properties,
3204 std::map<WindowType, SystemBarProperty>& pageProperties)
3205 {
3206 for (auto type : { WindowType::WINDOW_TYPE_STATUS_BAR, WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR }) {
3207 if (properties.find(type) != properties.end()) {
3208 pageProperties[type] = properties.at(type);
3209 } else {
3210 pageProperties[type] = GetSystemBarPropertyByType(type);
3211 }
3212 TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] type %{public}u "
3213 "%{public}u %{public}x %{public}x %{public}u %{public}u",
3214 GetWindowId(), GetWindowName().c_str(), static_cast<uint32_t>(type),
3215 pageProperties[type].enable_, pageProperties[type].backgroundColor_,
3216 pageProperties[type].contentColor_, pageProperties[type].enableAnimation_,
3217 pageProperties[type].settingFlag_);
3218 }
3219 }
3220
SetFullScreen(bool status)3221 WMError WindowSceneSessionImpl::SetFullScreen(bool status)
3222 {
3223 TLOGI(WmsLogTag::WMS_IMMS, "win [%{public}u %{public}s] status %{public}d",
3224 GetWindowId(), GetWindowName().c_str(), static_cast<int32_t>(status));
3225 if (IsWindowSessionInvalid()) {
3226 return WMError::WM_ERROR_INVALID_WINDOW;
3227 }
3228 if (WindowHelper::IsSystemWindow(GetType())) {
3229 TLOGI(WmsLogTag::WMS_IMMS, "system window not supported");
3230 return WMError::WM_OK;
3231 }
3232
3233 if (WindowHelper::IsMainWindow(GetType()) && IsPcOrPadFreeMultiWindowMode()) {
3234 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
3235 WindowMode::WINDOW_MODE_FULLSCREEN)) {
3236 TLOGE(WmsLogTag::WMS_IMMS, "fullscreen window not supported");
3237 return WMError::WM_ERROR_INVALID_WINDOW;
3238 }
3239 auto hostSession = GetHostSession();
3240 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
3241 hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
3242 SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
3243 };
3244
3245 WMError ret = SetLayoutFullScreenByApiVersion(status);
3246 if (ret != WMError::WM_OK) {
3247 TLOGE(WmsLogTag::WMS_IMMS, "failed, win %{public}u errCode %{public}d",
3248 GetWindowId(), static_cast<int32_t>(ret));
3249 }
3250
3251 UpdateDecorEnable(true);
3252 SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
3253 statusProperty.enable_ = !status;
3254 ret = SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
3255 if (ret != WMError::WM_OK) {
3256 TLOGE(WmsLogTag::WMS_IMMS, "SetSystemBarProperty win %{public}u errCode %{public}d",
3257 GetWindowId(), static_cast<int32_t>(ret));
3258 }
3259
3260 return ret;
3261 }
3262
IsFullScreen() const3263 bool WindowSceneSessionImpl::IsFullScreen() const
3264 {
3265 SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
3266 return (IsLayoutFullScreen() && !statusProperty.enable_);
3267 }
3268
IsDecorEnable() const3269 bool WindowSceneSessionImpl::IsDecorEnable() const
3270 {
3271 WindowType windowType = GetType();
3272 bool isMainWindow = WindowHelper::IsMainWindow(windowType);
3273 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
3274 bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
3275 bool isValidWindow = isMainWindow ||
3276 ((isSubWindow || isDialogWindow) && property_->IsDecorEnable());
3277 bool isWindowModeSupported = WindowHelper::IsWindowModeSupported(
3278 windowSystemConfig_.decorWindowModeSupportType_, GetWindowMode());
3279 if (windowSystemConfig_.freeMultiWindowSupport_) {
3280 return isValidWindow && windowSystemConfig_.isSystemDecorEnable_;
3281 }
3282 bool enable = isValidWindow && windowSystemConfig_.isSystemDecorEnable_ &&
3283 isWindowModeSupported;
3284 if ((isSubWindow || isDialogWindow) && property_->GetIsPcAppInPad() && property_->IsDecorEnable()) {
3285 enable = true;
3286 }
3287 TLOGD(WmsLogTag::WMS_DECOR, "get decor enable %{public}d", enable);
3288 return enable;
3289 }
3290
SetWindowTitle(const std::string & title)3291 WMError WindowSceneSessionImpl::SetWindowTitle(const std::string& title)
3292 {
3293 if (IsWindowSessionInvalid()) {
3294 TLOGE(WmsLogTag::WMS_DECOR, "Session is invalid");
3295 return WMError::WM_ERROR_INVALID_WINDOW;
3296 }
3297 if (property_->GetPcAppInpadCompatibleMode() && !IsDecorEnable()) {
3298 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is PcAppInPad, not supported");
3299 return WMError::WM_OK;
3300 }
3301 if (!(windowSystemConfig_.IsPcWindow() || windowSystemConfig_.IsPadWindow() ||
3302 IsDeviceFeatureCapableForFreeMultiWindow())) {
3303 TLOGE(WmsLogTag::WMS_DECOR, "device not support");
3304 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3305 }
3306 if (!IsDecorEnable()) {
3307 TLOGE(WmsLogTag::WMS_DECOR, "DecorEnable is false");
3308 return WMError::WM_ERROR_INVALID_WINDOW;
3309 }
3310 if (WindowHelper::IsMainWindow(GetType())) {
3311 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(GetContext());
3312 if (abilityContext == nullptr) {
3313 return WMError::WM_ERROR_NULLPTR;
3314 }
3315 abilityContext->SetMissionLabel(title);
3316 } else {
3317 return SetAPPWindowLabel(title);
3318 }
3319 return WMError::WM_OK;
3320 }
3321
Minimize()3322 WMError WindowSceneSessionImpl::Minimize()
3323 {
3324 WLOGFI("id: %{public}d", GetPersistentId());
3325 if (IsWindowSessionInvalid()) {
3326 WLOGFE("session is invalid");
3327 return WMError::WM_ERROR_INVALID_WINDOW;
3328 }
3329 auto hostSession = GetHostSession();
3330 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3331 if (WindowHelper::IsMainWindow(GetType())) {
3332 hostSession->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
3333 } else {
3334 WLOGFE("This window state is abnormal.");
3335 return WMError::WM_DO_NOTHING;
3336 }
3337 return WMError::WM_OK;
3338 }
3339
MaximizeForCompatibleMode()3340 WMError WindowSceneSessionImpl::MaximizeForCompatibleMode()
3341 {
3342 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3343 if (IsWindowSessionInvalid()) {
3344 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3345 return WMError::WM_ERROR_INVALID_WINDOW;
3346 }
3347 if (!WindowHelper::IsMainWindow(GetType())) {
3348 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "maximize fail, not main");
3349 return WMError::WM_ERROR_INVALID_CALLING;
3350 }
3351 auto hostSession = GetHostSession();
3352 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
3353 hostSession->OnSessionEvent(SessionEvent::EVENT_COMPATIBLE_TO_MAXIMIZE);
3354 return WMError::WM_OK;
3355 }
3356
RecoverForCompatibleMode()3357 WMError WindowSceneSessionImpl::RecoverForCompatibleMode()
3358 {
3359 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3360 if (IsWindowSessionInvalid()) {
3361 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3362 return WMError::WM_ERROR_INVALID_WINDOW;
3363 }
3364 if (!WindowHelper::IsMainWindow(GetType())) {
3365 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "recover fail, not main");
3366 return WMError::WM_ERROR_INVALID_CALLING;
3367 }
3368 auto hostSession = GetHostSession();
3369 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
3370 hostSession->OnSessionEvent(SessionEvent::EVENT_COMPATIBLE_TO_RECOVER);
3371 return WMError::WM_OK;
3372 }
3373
Maximize()3374 WMError WindowSceneSessionImpl::Maximize()
3375 {
3376 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3377 if (IsWindowSessionInvalid()) {
3378 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3379 return WMError::WM_ERROR_INVALID_WINDOW;
3380 }
3381 if (WindowHelper::IsMainWindow(GetType())) {
3382 SetLayoutFullScreen(enableImmersiveMode_);
3383 }
3384 return WMError::WM_OK;
3385 }
3386
Maximize(MaximizePresentation presentation)3387 WMError WindowSceneSessionImpl::Maximize(MaximizePresentation presentation)
3388 {
3389 if (IsWindowSessionInvalid()) {
3390 return WMError::WM_ERROR_INVALID_WINDOW;
3391 }
3392 if (!WindowHelper::IsMainWindow(GetType())) {
3393 if (IsSubWindowMaximizeSupported()) {
3394 return MaximizeFloating();
3395 }
3396 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "maximize fail, not main or sub window");
3397 return WMError::WM_ERROR_INVALID_CALLING;
3398 }
3399 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
3400 WindowMode::WINDOW_MODE_FULLSCREEN)) {
3401 return WMError::WM_ERROR_INVALID_WINDOW;
3402 }
3403 // The device is not supported
3404 if (!IsPcOrPadFreeMultiWindowMode() || property_->IsFullScreenDisabled()) {
3405 TLOGW(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3406 return WMError::WM_OK;
3407 }
3408 titleHoverShowEnabled_ = true;
3409 dockHoverShowEnabled_ = true;
3410 switch (presentation) {
3411 case MaximizePresentation::ENTER_IMMERSIVE:
3412 enableImmersiveMode_ = true;
3413 break;
3414 case MaximizePresentation::EXIT_IMMERSIVE:
3415 enableImmersiveMode_ = false;
3416 break;
3417 case MaximizePresentation::ENTER_IMMERSIVE_DISABLE_TITLE_AND_DOCK_HOVER:
3418 enableImmersiveMode_ = true;
3419 titleHoverShowEnabled_ = false;
3420 dockHoverShowEnabled_ = false;
3421 break;
3422 case MaximizePresentation::FOLLOW_APP_IMMERSIVE_SETTING:
3423 break;
3424 }
3425 property_->SetIsLayoutFullScreen(enableImmersiveMode_);
3426 auto hostSession = GetHostSession();
3427 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
3428 hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
3429 hostSession->OnTitleAndDockHoverShowChange(titleHoverShowEnabled_, dockHoverShowEnabled_);
3430 SetLayoutFullScreenByApiVersion(enableImmersiveMode_);
3431 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "present: %{public}d, enableImmersiveMode_:%{public}d!",
3432 presentation, enableImmersiveMode_.load());
3433 hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
3434 return SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
3435 }
3436
MaximizeFloating()3437 WMError WindowSceneSessionImpl::MaximizeFloating()
3438 {
3439 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3440 if (IsWindowSessionInvalid()) {
3441 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3442 return WMError::WM_ERROR_INVALID_WINDOW;
3443 }
3444 auto hostSession = GetHostSession();
3445 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3446 if (!WindowHelper::IsMainWindow(property_->GetWindowType()) && !IsSubWindowMaximizeSupported()) {
3447 TLOGW(WmsLogTag::WMS_LAYOUT_PC,
3448 "SetGlobalMaximizeMode fail, not main or sub window, id %{public}d",
3449 GetPersistentId());
3450 return WMError::WM_ERROR_INVALID_WINDOW;
3451 }
3452 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
3453 WindowMode::WINDOW_MODE_FULLSCREEN)) {
3454 return WMError::WM_ERROR_INVALID_WINDOW;
3455 }
3456 if (property_->IsFullScreenDisabled()) {
3457 TLOGW(WmsLogTag::WMS_COMPAT, "diable fullScreen in compatibleMode window ,id:%{public}d", GetPersistentId());
3458 return WMError::WM_ERROR_INVALID_WINDOW;
3459 }
3460 if (GetGlobalMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
3461 hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
3462 SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
3463 UpdateDecorEnable(true);
3464 property_->SetMaximizeMode(MaximizeMode::MODE_FULL_FILL);
3465 } else {
3466 hostSession->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE_FLOATING);
3467 SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3468 property_->SetMaximizeMode(MaximizeMode::MODE_AVOID_SYSTEM_BAR);
3469 UpdateDecorEnable(true);
3470 NotifyWindowStatusChange(GetWindowMode());
3471 }
3472 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
3473
3474 return WMError::WM_OK;
3475 }
3476
Recover()3477 WMError WindowSceneSessionImpl::Recover()
3478 {
3479 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3480 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && isFullScreenWaterfallMode_.load() &&
3481 lastWindowModeBeforeWaterfall_.load() == WindowMode::WINDOW_MODE_FULLSCREEN) {
3482 isWaterfallToMaximize_.store(true);
3483 SetFullScreenWaterfallMode(false);
3484 WMError ret = Maximize();
3485 if (ret != WMError::WM_OK) {
3486 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "recover to fullscreen failed");
3487 isWaterfallToMaximize_.store(false);
3488 SetFullScreenWaterfallMode(true);
3489 }
3490 return ret;
3491 }
3492 if (IsWindowSessionInvalid()) {
3493 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3494 return WMError::WM_ERROR_INVALID_WINDOW;
3495 }
3496 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING)) {
3497 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "not support floating, can not Recover");
3498 return WMError::WM_ERROR_INVALID_OPERATION;
3499 }
3500 auto hostSession = GetHostSession();
3501 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3502 if (WindowHelper::IsMainWindow(GetType()) || IsSubWindowMaximizeSupported()) {
3503 if (property_->GetMaximizeMode() == MaximizeMode::MODE_RECOVER &&
3504 property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
3505 TLOGW(WmsLogTag::WMS_LAYOUT_PC, "Recover fail, already MODE_RECOVER");
3506 return WMError::WM_ERROR_REPEAT_OPERATION;
3507 }
3508 if (enableImmersiveMode_) {
3509 enableImmersiveMode_ = false;
3510 property_->SetIsLayoutFullScreen(enableImmersiveMode_);
3511 hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
3512 }
3513 hostSession->OnSessionEvent(SessionEvent::EVENT_RECOVER);
3514 SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3515 property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
3516 UpdateDecorEnable(true);
3517 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
3518 NotifyWindowStatusChange(GetWindowMode());
3519 } else {
3520 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "recovery is invalid, window id: %{public}d", GetPersistentId());
3521 return WMError::WM_ERROR_INVALID_OPERATION;
3522 }
3523 return WMError::WM_OK;
3524 }
3525
Restore()3526 WMError WindowSceneSessionImpl::Restore()
3527 {
3528 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d", GetPersistentId());
3529 if (IsWindowSessionInvalid()) {
3530 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3531 return WMError::WM_ERROR_INVALID_WINDOW;
3532 }
3533 if (!WindowHelper::IsMainWindow(GetType())) {
3534 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "Restore fail, not main window");
3535 return WMError::WM_ERROR_INVALID_CALLING;
3536 }
3537 if (!(windowSystemConfig_.IsPcWindow() || property_->GetIsPcAppInPad())) {
3538 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is not PC or PcAppInPad, not supported");
3539 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3540 }
3541 if (property_->GetIsAppSupportPhoneInPc()) {
3542 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is PhoneAppSupportOnPc, not supported");
3543 return WMError::WM_ERROR_INVALID_CALLING;
3544 }
3545 auto hostSession = GetHostSession();
3546 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
3547 hostSession->OnRestoreMainWindow();
3548 return WMError::WM_OK;
3549 }
3550
Recover(uint32_t reason)3551 WMError WindowSceneSessionImpl::Recover(uint32_t reason)
3552 {
3553 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d, reason: %{public}u", GetPersistentId(), reason);
3554 if (IsWindowSessionInvalid()) {
3555 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3556 return WMError::WM_ERROR_INVALID_WINDOW;
3557 }
3558 if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
3559 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3560 return WMError::WM_OK;
3561 }
3562 if (!IsPcOrPadFreeMultiWindowMode()) {
3563 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3564 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3565 }
3566 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING)) {
3567 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "not support floating, can not Recover");
3568 return WMError::WM_ERROR_INVALID_OPERATION;
3569 }
3570 auto hostSession = GetHostSession();
3571 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
3572 if (WindowHelper::IsMainWindow(GetType()) || IsSubWindowMaximizeSupported()) {
3573 if (property_->GetMaximizeMode() == MaximizeMode::MODE_RECOVER &&
3574 property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
3575 TLOGW(WmsLogTag::WMS_LAYOUT_PC, "Recover fail, already MODE_RECOVER");
3576 return WMError::WM_ERROR_REPEAT_OPERATION;
3577 }
3578 if (enableImmersiveMode_) {
3579 enableImmersiveMode_ = false;
3580 property_->SetIsLayoutFullScreen(enableImmersiveMode_);
3581 hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
3582 }
3583 hostSession->OnSessionEvent(SessionEvent::EVENT_RECOVER);
3584 // need notify arkui maximize mode change
3585 if (reason == REASON_MAXIMIZE_MODE_CHANGE &&
3586 property_->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
3587 UpdateMaximizeMode(MaximizeMode::MODE_RECOVER);
3588 }
3589 SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3590 property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
3591 UpdateDecorEnable(true);
3592 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
3593 NotifyWindowStatusChange(GetWindowMode());
3594 } else {
3595 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "recovery is invalid on sub window");
3596 return WMError::WM_ERROR_INVALID_OPERATION;
3597 }
3598 return WMError::WM_OK;
3599 }
3600
SetWindowRectAutoSave(bool enabled,bool isSaveBySpecifiedFlag)3601 WMError WindowSceneSessionImpl::SetWindowRectAutoSave(bool enabled, bool isSaveBySpecifiedFlag)
3602 {
3603 TLOGI(WmsLogTag::WMS_MAIN, "id: %{public}d", GetPersistentId());
3604 if (IsWindowSessionInvalid()) {
3605 TLOGE(WmsLogTag::WMS_MAIN, "session is invalid");
3606 return WMError::WM_ERROR_INVALID_WINDOW;
3607 }
3608
3609 if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
3610 TLOGE(WmsLogTag::WMS_MAIN, "This is PcAppInPad, not supported");
3611 return WMError::WM_OK;
3612 }
3613
3614 if (!IsPcOrPadFreeMultiWindowMode()) {
3615 TLOGE(WmsLogTag::WMS_MAIN, "This is not PC mode or free multi window mode, not supported");
3616 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3617 }
3618
3619 if (!WindowHelper::IsMainWindow(GetType())) {
3620 TLOGE(WmsLogTag::WMS_MAIN, "This is not main window, not supported");
3621 return WMError::WM_ERROR_INVALID_CALLING;
3622 }
3623
3624 auto hostSession = GetHostSession();
3625 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
3626 hostSession->OnSetWindowRectAutoSave(enabled, isSaveBySpecifiedFlag);
3627 return WMError::WM_OK;
3628 }
3629
IsWindowRectAutoSave(bool & enabled)3630 WMError WindowSceneSessionImpl::IsWindowRectAutoSave(bool& enabled)
3631 {
3632 if (IsWindowSessionInvalid()) {
3633 TLOGE(WmsLogTag::WMS_MAIN, "session is invalid");
3634 return WMError::WM_ERROR_INVALID_WINDOW;
3635 }
3636
3637 if (property_->GetPcAppInpadCompatibleMode()) {
3638 TLOGE(WmsLogTag::WMS_MAIN, "This is PcAppInPad, not supported");
3639 return WMError::WM_OK;
3640 }
3641
3642 if (!windowSystemConfig_.IsPcWindow()) {
3643 TLOGE(WmsLogTag::WMS_MAIN, "This is not PC, not supported");
3644 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3645 }
3646
3647 if (!WindowHelper::IsMainWindow(GetType())) {
3648 TLOGE(WmsLogTag::WMS_MAIN, "This is not main window, not supported");
3649 return WMError::WM_ERROR_INVALID_CALLING;
3650 }
3651 auto context = GetContext();
3652 if (context == nullptr) {
3653 TLOGE(WmsLogTag::WMS_MAIN, "context is nullptr");
3654 return WMError::WM_ERROR_NULLPTR;
3655 }
3656 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
3657 std::string bundleName = property_->GetSessionInfo().bundleName_;
3658 std::string moduleName = property_->GetSessionInfo().moduleName_;
3659 std::string abilityName = property_->GetSessionInfo().abilityName_;
3660 if (abilityContext && abilityContext->GetAbilityInfo()) {
3661 abilityName = abilityContext->GetAbilityInfo()->name;
3662 moduleName = context->GetHapModuleInfo() ? context->GetHapModuleInfo()->moduleName : "";
3663 bundleName = abilityContext->GetAbilityInfo()->bundleName;
3664 } else if (context) {
3665 moduleName = context->GetHapModuleInfo() ? context->GetHapModuleInfo()->moduleName : "";
3666 bundleName = context->GetBundleName();
3667 }
3668 std::string key = bundleName + moduleName + abilityName;
3669 int persistentId = GetPersistentId();
3670 auto ret = SingletonContainer::Get<WindowAdapter>().IsWindowRectAutoSave(key, enabled, persistentId);
3671 return ret;
3672 }
3673
SetSupportedWindowModes(const std::vector<AppExecFwk::SupportWindowMode> & supportedWindowModes,bool grayOutMaximizeButton)3674 WMError WindowSceneSessionImpl::SetSupportedWindowModes(
3675 const std::vector<AppExecFwk::SupportWindowMode>& supportedWindowModes, bool grayOutMaximizeButton)
3676 {
3677 if (IsWindowSessionInvalid()) {
3678 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3679 return WMError::WM_ERROR_INVALID_WINDOW;
3680 }
3681
3682 if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
3683 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is PcAppInpad, not supported");
3684 return WMError::WM_OK;
3685 }
3686
3687 if (!(windowSystemConfig_.IsPcWindow() || windowSystemConfig_.freeMultiWindowSupport_)) {
3688 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "Neither is Pc nor support free multi window, invalid calling");
3689 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3690 }
3691
3692 if (!WindowHelper::IsMainWindow(GetType())) {
3693 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "This is not main window, not supported");
3694 return WMError::WM_ERROR_INVALID_CALLING;
3695 }
3696
3697 if (grayOutMaximizeButton) {
3698 size_t size = supportedWindowModes.size();
3699 if (size == 0 || size > WINDOW_SUPPORT_MODE_MAX_SIZE) {
3700 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is invalid");
3701 return WMError::WM_ERROR_ILLEGAL_PARAM;
3702 }
3703 if (std::find(supportedWindowModes.begin(), supportedWindowModes.end(),
3704 AppExecFwk::SupportWindowMode::FULLSCREEN) != supportedWindowModes.end()) {
3705 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "Supports full screen cannot be grayed out");
3706 return WMError::WM_ERROR_ILLEGAL_PARAM;
3707 }
3708 GrayOutMaximizeButton(true);
3709 } else if (grayOutMaximizeButton_) {
3710 GrayOutMaximizeButton(false);
3711 }
3712
3713 return SetSupportedWindowModesInner(supportedWindowModes);
3714 }
3715
GrayOutMaximizeButton(bool isGrayOut)3716 WMError WindowSceneSessionImpl::GrayOutMaximizeButton(bool isGrayOut)
3717 {
3718 if (grayOutMaximizeButton_ == isGrayOut) {
3719 TLOGW(WmsLogTag::WMS_LAYOUT_PC, "Duplicate settings are gray out: %{public}d", isGrayOut);
3720 return WMError::WM_DO_NOTHING;
3721 }
3722 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
3723 if (uiContent == nullptr) {
3724 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "uicontent is empty");
3725 return WMError::WM_ERROR_NULLPTR;
3726 }
3727 grayOutMaximizeButton_ = isGrayOut;
3728 uiContent->OnContainerModalEvent(WINDOW_GRAY_OUT_MAXIMIZE_EVENT, isGrayOut ? "true" : "false");
3729 return WMError::WM_OK;
3730 }
3731
UpdateWindowModeWhenSupportTypeChange(uint32_t windowModeSupportType)3732 void WindowSceneSessionImpl::UpdateWindowModeWhenSupportTypeChange(uint32_t windowModeSupportType)
3733 {
3734 bool onlySupportFullScreen =
3735 WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
3736 !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING);
3737 bool disableFullScreen = property_->IsFullScreenDisabled();
3738 if (onlySupportFullScreen && !property_->IsLayoutFullScreen() && !disableFullScreen) {
3739 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "onlySupportFullScreen:%{public}d IsLayoutFullScreen:%{public}d",
3740 onlySupportFullScreen, property_->IsLayoutFullScreen());
3741 Maximize(MaximizePresentation::ENTER_IMMERSIVE);
3742 return;
3743 }
3744
3745 bool onlySupportFloating =
3746 !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
3747 WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING);
3748 if (onlySupportFloating) {
3749 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "onlySupportFloating:%{public}d", onlySupportFloating);
3750 Recover(REASON_MAXIMIZE_MODE_CHANGE);
3751 }
3752 }
3753
SetSupportedWindowModesInner(const std::vector<AppExecFwk::SupportWindowMode> & supportedWindowModes)3754 WMError WindowSceneSessionImpl::SetSupportedWindowModesInner(
3755 const std::vector<AppExecFwk::SupportWindowMode>& supportedWindowModes)
3756 {
3757 auto size = supportedWindowModes.size();
3758 if (size <= 0 || size > WINDOW_SUPPORT_MODE_MAX_SIZE) {
3759 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is invalid");
3760 return WMError::WM_ERROR_INVALID_PARAM;
3761 }
3762
3763 uint32_t windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(supportedWindowModes);
3764 if (windowModeSupportType == 0) {
3765 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is 0");
3766 return WMError::WM_ERROR_INVALID_PARAM;
3767 }
3768 bool onlySupportSplit = (windowModeSupportType ==
3769 (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
3770 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY));
3771 if (onlySupportSplit) {
3772 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "mode param is only support split");
3773 return WMError::WM_ERROR_INVALID_PARAM;
3774 }
3775 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId: %{public}u, windowModeSupportType: %{public}u",
3776 GetWindowId(), windowModeSupportType);
3777
3778 // update windowModeSupportType to server
3779 auto hostSession = GetHostSession();
3780 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
3781 hostSession->NotifySupportWindowModesChange(supportedWindowModes);
3782 if (!IsPcOrPadFreeMultiWindowMode()) {
3783 pendingWindowModeSupportType_ = windowModeSupportType;
3784 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "pending update, winId: %{public}u, windowModeSupportType: %{public}u",
3785 GetWindowId(), windowModeSupportType);
3786 return WMError::WM_OK;
3787 }
3788
3789 haveSetSupportedWindowModes_ = true;
3790 property_->SetWindowModeSupportType(windowModeSupportType);
3791 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
3792 UpdateTitleButtonVisibility();
3793 UpdateWindowModeWhenSupportTypeChange(windowModeSupportType);
3794 return WMError::WM_OK;
3795 }
3796
SetImageForRecent(uint32_t imgResourceId,ImageFit imageFit)3797 WMError WindowSceneSessionImpl::SetImageForRecent(uint32_t imgResourceId, ImageFit imageFit)
3798 {
3799 int32_t persistentId = GetPersistentId();
3800 return SingletonContainer::Get<WindowAdapter>().SetImageForRecent(imgResourceId, imageFit, persistentId);
3801 }
3802
3803 /** @note @window.drag */
StartMove()3804 void WindowSceneSessionImpl::StartMove()
3805 {
3806 WLOGFI("id: %{public}d", GetPersistentId());
3807 if (IsWindowSessionInvalid()) {
3808 WLOGFE("session is invalid");
3809 return;
3810 }
3811 WindowType windowType = GetType();
3812 bool isMainWindow = WindowHelper::IsMainWindow(windowType);
3813 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
3814 bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
3815 bool isDecorDialog = isDialogWindow && property_->IsDecorEnable();
3816 bool isValidWindow = isMainWindow || (IsPcOrFreeMultiWindowCapabilityEnabled() && (isSubWindow || isDecorDialog));
3817 auto hostSession = GetHostSession();
3818 if (isValidWindow && hostSession) {
3819 hostSession->OnSessionEvent(SessionEvent::EVENT_START_MOVE);
3820 }
3821 }
3822
IsStartMoving()3823 bool WindowSceneSessionImpl::IsStartMoving()
3824 {
3825 bool isMoving = false;
3826 if (auto hostSession = GetHostSession()) {
3827 isMoving = hostSession->IsStartMoving();
3828 }
3829 TLOGI(WmsLogTag::WMS_LAYOUT, "id: %{public}d, isMoving: %{public}d", GetPersistentId(), isMoving);
3830 return isMoving;
3831 }
3832
CalcWindowShouldMove()3833 bool WindowSceneSessionImpl::CalcWindowShouldMove()
3834 {
3835 if ((windowSystemConfig_.IsPhoneWindow() ||
3836 (windowSystemConfig_.IsPadWindow() && !IsFreeMultiWindowMode())) &&
3837 GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
3838 return true;
3839 }
3840
3841 if (IsPcOrFreeMultiWindowCapabilityEnabled()) {
3842 return true;
3843 }
3844 return false;
3845 }
3846
CheckCanMoveWindowType()3847 bool WindowSceneSessionImpl::CheckCanMoveWindowType()
3848 {
3849 WindowType windowType = GetType();
3850 if (!WindowHelper::IsSystemWindow(windowType) &&
3851 !WindowHelper::IsMainWindow(windowType) &&
3852 !WindowHelper::IsSubWindow(windowType)) {
3853 return false;
3854 }
3855 return true;
3856 }
3857
CheckCanMoveWindowTypeByDevice()3858 bool WindowSceneSessionImpl::CheckCanMoveWindowTypeByDevice()
3859 {
3860 WindowType windowType = GetType();
3861 bool isPcOrFreeMultiWindowCanMove = IsPcOrFreeMultiWindowCapabilityEnabled() &&
3862 (WindowHelper::IsSystemWindow(windowType) ||
3863 WindowHelper::IsMainWindow(windowType) ||
3864 WindowHelper::IsSubWindow(windowType));
3865 bool isPhoneWindowCanMove = (windowSystemConfig_.IsPhoneWindow() ||
3866 (windowSystemConfig_.IsPadWindow() && !IsFreeMultiWindowMode())) &&
3867 (WindowHelper::IsSystemWindow(windowType) || WindowHelper::IsSubWindow(windowType));
3868 if (isPcOrFreeMultiWindowCanMove || isPhoneWindowCanMove) {
3869 return true;
3870 }
3871 return false;
3872 }
3873
CheckIsPcAppInPadFullScreenOnMobileWindowMode()3874 bool WindowSceneSessionImpl::CheckIsPcAppInPadFullScreenOnMobileWindowMode()
3875 {
3876 if (property_->GetIsPcAppInPad() &&
3877 property_->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
3878 !IsFreeMultiWindowMode()) {
3879 return true;
3880 }
3881 return false;
3882 }
3883
StartMoveWindow()3884 WmErrorCode WindowSceneSessionImpl::StartMoveWindow()
3885 {
3886 if (!CheckCanMoveWindowTypeByDevice()) {
3887 TLOGE(WmsLogTag::WMS_LAYOUT, "invalid window type:%{public}u", GetType());
3888 return WmErrorCode::WM_ERROR_INVALID_CALLING;
3889 }
3890 if (!CalcWindowShouldMove()) {
3891 TLOGE(WmsLogTag::WMS_LAYOUT, "The device is not supported");
3892 return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
3893 }
3894 if (CheckIsPcAppInPadFullScreenOnMobileWindowMode()) {
3895 return WmErrorCode::WM_OK;
3896 }
3897 if (auto hostSession = GetHostSession()) {
3898 WSError errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_START_MOVE);
3899 TLOGD(WmsLogTag::WMS_LAYOUT, "id:%{public}d, errorCode:%{public}d",
3900 GetPersistentId(), static_cast<int>(errorCode));
3901 switch (errorCode) {
3902 case WSError::WS_ERROR_REPEAT_OPERATION: {
3903 return WmErrorCode::WM_ERROR_REPEAT_OPERATION;
3904 }
3905 case WSError::WS_ERROR_NULLPTR: {
3906 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3907 }
3908 default: {
3909 return WmErrorCode::WM_OK;
3910 }
3911 }
3912 } else {
3913 TLOGE(WmsLogTag::WMS_LAYOUT, "hostSession is nullptr");
3914 return WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY;
3915 }
3916 }
3917
StartMoveWindowWithCoordinate(int32_t offsetX,int32_t offsetY)3918 WmErrorCode WindowSceneSessionImpl::StartMoveWindowWithCoordinate(int32_t offsetX, int32_t offsetY)
3919 {
3920 if (!CheckCanMoveWindowType()) {
3921 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "invalid window type:%{public}u", GetType());
3922 return WmErrorCode::WM_ERROR_INVALID_CALLING;
3923 }
3924 if (!IsPcOrFreeMultiWindowCapabilityEnabled()) {
3925 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3926 return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
3927 }
3928 if (CheckIsPcAppInPadFullScreenOnMobileWindowMode()) {
3929 return WmErrorCode::WM_OK;
3930 }
3931 if (IsWindowSessionInvalid()) {
3932 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3933 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3934 }
3935 const auto& windowRect = GetRect();
3936 if (offsetX < 0 || offsetX > static_cast<int32_t>(windowRect.width_) ||
3937 offsetY < 0 || offsetY > static_cast<int32_t>(windowRect.height_)) {
3938 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "offset not in window");
3939 return WmErrorCode::WM_ERROR_INVALID_PARAM;
3940 }
3941 auto hostSession = GetHostSession();
3942 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY);
3943 WSError errorCode;
3944 MMI::PointerEvent::PointerItem pointerItem;
3945 if (lastPointerEvent_ != nullptr &&
3946 lastPointerEvent_->GetPointerItem(lastPointerEvent_->GetPointerId(), pointerItem)) {
3947 int32_t lastDisplayX = pointerItem.GetDisplayX();
3948 int32_t lastDisplayY = pointerItem.GetDisplayY();
3949 int32_t lastDisplayId = lastPointerEvent_->GetTargetDisplayId();
3950 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "offset:[%{public}d,%{public}d] lastEvent:[%{private}d,%{private}d]"
3951 " lastDisplayId:%{public}d", offsetX, offsetY, lastDisplayX, lastDisplayY, lastDisplayId);
3952 errorCode = hostSession->StartMovingWithCoordinate(offsetX, offsetY, lastDisplayX, lastDisplayY, lastDisplayId);
3953 } else {
3954 errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_START_MOVE);
3955 }
3956 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "id:%{public}d, errorCode:%{public}d",
3957 GetPersistentId(), static_cast<int>(errorCode));
3958 switch (errorCode) {
3959 case WSError::WS_ERROR_REPEAT_OPERATION: {
3960 return WmErrorCode::WM_ERROR_REPEAT_OPERATION;
3961 }
3962 case WSError::WS_ERROR_NULLPTR: {
3963 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3964 }
3965 default: {
3966 return WmErrorCode::WM_OK;
3967 }
3968 }
3969 }
3970
StopMoveWindow()3971 WmErrorCode WindowSceneSessionImpl::StopMoveWindow()
3972 {
3973 if (!CheckCanMoveWindowType()) {
3974 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "invalid window type:%{public}u", GetType());
3975 return WmErrorCode::WM_ERROR_INVALID_CALLING;
3976 }
3977 if (!IsPcOrFreeMultiWindowCapabilityEnabled()) {
3978 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "The device is not supported");
3979 return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT;
3980 }
3981 if (IsWindowSessionInvalid()) {
3982 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
3983 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3984 }
3985 auto hostSession = GetHostSession();
3986 if (!hostSession) {
3987 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "hostSession is nullptr");
3988 return WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY;
3989 }
3990 WSError errorCode = hostSession->SyncSessionEvent(SessionEvent::EVENT_END_MOVE);
3991 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "id:%{public}d, errorCode:%{public}d",
3992 GetPersistentId(), static_cast<int>(errorCode));
3993 return errorCode == WSError::WS_ERROR_NULLPTR ? WmErrorCode::WM_ERROR_STATE_ABNORMALLY : WmErrorCode::WM_OK;
3994 }
3995
MainWindowCloseInner()3996 WMError WindowSceneSessionImpl::MainWindowCloseInner()
3997 {
3998 auto hostSession = GetHostSession();
3999 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
4000 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(GetContext());
4001 if (!abilityContext) {
4002 return Destroy(true);
4003 }
4004 bool terminateCloseProcess = false;
4005 WMError res = NotifyMainWindowClose(terminateCloseProcess);
4006 if (res == WMError::WM_OK) {
4007 TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d, not close: %{public}d", GetPersistentId(),
4008 terminateCloseProcess);
4009 if (!terminateCloseProcess) {
4010 hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
4011 }
4012 return res;
4013 }
4014 auto handler = sptr<WindowPrepareTerminateHandler>::MakeSptr();
4015 PrepareTerminateFunc func = [hostSessionWptr = wptr<ISession>(hostSession)] {
4016 auto hostSession = hostSessionWptr.promote();
4017 if (hostSession == nullptr) {
4018 TLOGNE(WmsLogTag::WMS_LIFE, "this session is nullptr");
4019 return;
4020 }
4021 hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
4022 };
4023 handler->SetPrepareTerminateFun(func);
4024 if (AAFwk::AbilityManagerClient::GetInstance()->PrepareTerminateAbility(abilityContext->GetToken(),
4025 handler) != ERR_OK) {
4026 TLOGE(WmsLogTag::WMS_LIFE, "PrepareTerminateAbility failed, do close window");
4027 hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
4028 }
4029 return WMError::WM_OK;
4030 }
4031
Close()4032 WMError WindowSceneSessionImpl::Close()
4033 {
4034 TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d", GetPersistentId());
4035 if (IsWindowSessionInvalid()) {
4036 TLOGE(WmsLogTag::WMS_DECOR, "session is invalid");
4037 return WMError::WM_ERROR_INVALID_WINDOW;
4038 }
4039 WindowType windowType = GetType();
4040 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
4041 bool isSystemSubWindow = WindowHelper::IsSystemSubWindow(windowType);
4042 bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
4043 if (WindowHelper::IsMainWindow(windowType) || isSubWindow) {
4044 WMError res = NotifyWindowWillClose(this);
4045 if (res == WMError::WM_OK) {
4046 TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d will close", GetPersistentId());
4047 return res;
4048 }
4049 }
4050 if (WindowHelper::IsMainWindow(windowType)) {
4051 return MainWindowCloseInner();
4052 } else if (isSubWindow || isSystemSubWindow || isDialogWindow) {
4053 TLOGI(WmsLogTag::WMS_DECOR, "subwindow or dialog");
4054 bool terminateCloseProcess = false;
4055 NotifySubWindowClose(terminateCloseProcess);
4056 if (!terminateCloseProcess || isDialogWindow) {
4057 return Destroy(true);
4058 }
4059 }
4060 return WMError::WM_OK;
4061 }
4062
CloseDirectly()4063 WMError WindowSceneSessionImpl::CloseDirectly()
4064 {
4065 if (IsWindowSessionInvalid()) {
4066 TLOGE(WmsLogTag::WMS_DECOR, "session is invalid");
4067 return WMError::WM_ERROR_INVALID_WINDOW;
4068 }
4069 TLOGI(WmsLogTag::WMS_DECOR, "id: %{public}d", GetPersistentId());
4070 if (WindowHelper::IsMainWindow(GetType())) {
4071 auto hostSession = GetHostSession();
4072 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
4073 hostSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
4074 return WMError::WM_OK;
4075 }
4076 return Destroy(true);
4077 }
4078
DisableAppWindowDecor()4079 WMError WindowSceneSessionImpl::DisableAppWindowDecor()
4080 {
4081 if (IsWindowSessionInvalid()) {
4082 return WMError::WM_ERROR_INVALID_WINDOW;
4083 }
4084 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4085 TLOGE(WmsLogTag::WMS_DECOR, "disable app window decor permission denied!");
4086 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4087 }
4088 if (!WindowHelper::IsMainWindow(GetType())) {
4089 TLOGE(WmsLogTag::WMS_DECOR, "window decoration is invalid on sub window");
4090 return WMError::WM_ERROR_INVALID_OPERATION;
4091 }
4092 TLOGI(WmsLogTag::WMS_DECOR, "disable app window decoration.");
4093 windowSystemConfig_.isSystemDecorEnable_ = false;
4094 UpdateDecorEnable(true);
4095 return WMError::WM_OK;
4096 }
4097
PerformBack()4098 void WindowSceneSessionImpl::PerformBack()
4099 {
4100 if (!WindowHelper::IsMainWindow(GetType())) {
4101 WLOGFI("PerformBack is not MainWindow, return");
4102 return;
4103 }
4104 if (auto hostSession = GetHostSession()) {
4105 bool needMoveToBackground = false;
4106 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(GetContext());
4107 if (abilityContext != nullptr) {
4108 abilityContext->OnBackPressedCallBack(needMoveToBackground);
4109 }
4110 TLOGI(WmsLogTag::DEFAULT, "%{public}d", needMoveToBackground);
4111 hostSession->RequestSessionBack(needMoveToBackground);
4112 }
4113 }
4114
SetGlobalMaximizeMode(MaximizeMode mode)4115 WMError WindowSceneSessionImpl::SetGlobalMaximizeMode(MaximizeMode mode)
4116 {
4117 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "mode %{public}u", static_cast<uint32_t>(mode));
4118 if (IsWindowSessionInvalid()) {
4119 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "session is invalid");
4120 return WMError::WM_ERROR_INVALID_WINDOW;
4121 }
4122 auto hostSession = GetHostSession();
4123 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
4124 if (WindowHelper::IsMainWindow(GetType())) {
4125 hostSession->SetGlobalMaximizeMode(mode);
4126 return WMError::WM_OK;
4127 } else {
4128 TLOGW(WmsLogTag::WMS_LAYOUT_PC, "fail, not main window");
4129 return WMError::WM_ERROR_INVALID_PARAM;
4130 }
4131 }
4132
GetGlobalMaximizeMode() const4133 MaximizeMode WindowSceneSessionImpl::GetGlobalMaximizeMode() const
4134 {
4135 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "in");
4136 MaximizeMode mode = MaximizeMode::MODE_RECOVER;
4137 if (auto hostSession = GetHostSession()) {
4138 hostSession->GetGlobalMaximizeMode(mode);
4139 }
4140 return mode;
4141 }
4142
SetWindowMode(WindowMode mode)4143 WMError WindowSceneSessionImpl::SetWindowMode(WindowMode mode)
4144 {
4145 TLOGD(WmsLogTag::WMS_LAYOUT, "%{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
4146 if (IsWindowSessionInvalid()) {
4147 TLOGE(WmsLogTag::WMS_LAYOUT, "Session is invalid");
4148 return WMError::WM_ERROR_INVALID_WINDOW;
4149 }
4150 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), mode)) {
4151 TLOGE(WmsLogTag::WMS_LAYOUT, "window %{public}u do not support mode: %{public}u",
4152 GetWindowId(), static_cast<uint32_t>(mode));
4153 return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
4154 }
4155 WMError ret = UpdateWindowModeImmediately(mode);
4156 if (ret != WMError::WM_OK) {
4157 TLOGE(WmsLogTag::WMS_LAYOUT, "Update window mode fail, ret:%{public}u", ret);
4158 return ret;
4159 }
4160 auto hostSession = GetHostSession();
4161 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
4162 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
4163 hostSession->OnSessionEvent(SessionEvent::EVENT_SPLIT_PRIMARY);
4164 } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
4165 hostSession->OnSessionEvent(SessionEvent::EVENT_SPLIT_SECONDARY);
4166 }
4167 return WMError::WM_OK;
4168 }
4169
SetGrayScale(float grayScale)4170 WMError WindowSceneSessionImpl::SetGrayScale(float grayScale)
4171 {
4172 if (IsWindowSessionInvalid()) {
4173 WLOGFE("session is invalid");
4174 return WMError::WM_ERROR_INVALID_WINDOW;
4175 }
4176 constexpr float eps = 1e-6f;
4177 if (grayScale < (MIN_GRAY_SCALE - eps) || grayScale > (MAX_GRAY_SCALE + eps)) {
4178 WLOGFE("invalid grayScale value: %{public}f", grayScale);
4179 return WMError::WM_ERROR_INVALID_PARAM;
4180 }
4181 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
4182 if (uiContent == nullptr) {
4183 WLOGFE("uicontent is empty");
4184 return WMError::WM_ERROR_NULLPTR;
4185 }
4186 uiContent->SetContentNodeGrayScale(grayScale);
4187 WLOGI("Set window gray scale success, grayScale: %{public}f", grayScale);
4188 return WMError::WM_OK;
4189 }
4190
GetWindowMode() const4191 WindowMode WindowSceneSessionImpl::GetWindowMode() const
4192 {
4193 return property_->GetWindowMode();
4194 }
4195
IsTransparent() const4196 bool WindowSceneSessionImpl::IsTransparent() const
4197 {
4198 if (IsWindowSessionInvalid()) {
4199 return false;
4200 }
4201 WSColorParam backgroundColor;
4202 backgroundColor.value = GetBackgroundColor();
4203 WLOGFD("color: %{public}u, alpha: %{public}u", backgroundColor.value, backgroundColor.argb.alpha);
4204 return backgroundColor.argb.alpha == 0x00; // 0x00: completely transparent
4205 }
4206
SetTransparent(bool isTransparent)4207 WMError WindowSceneSessionImpl::SetTransparent(bool isTransparent)
4208 {
4209 if (IsWindowSessionInvalid()) {
4210 WLOGFE("session is invalid");
4211 return WMError::WM_ERROR_INVALID_WINDOW;
4212 }
4213 WSColorParam backgroundColor;
4214 backgroundColor.value = GetBackgroundColor();
4215 if (isTransparent) {
4216 backgroundColor.argb.alpha = 0x00; // 0x00: completely transparent
4217 return SetBackgroundColor(backgroundColor.value);
4218 } else {
4219 backgroundColor.value = GetBackgroundColor();
4220 if (backgroundColor.argb.alpha == 0x00) {
4221 backgroundColor.argb.alpha = 0xff; // 0xff: completely opaque
4222 return SetBackgroundColor(backgroundColor.value);
4223 }
4224 }
4225 return WMError::WM_OK;
4226 }
4227
AddWindowFlag(WindowFlag flag)4228 WMError WindowSceneSessionImpl::AddWindowFlag(WindowFlag flag)
4229 {
4230 if (IsWindowSessionInvalid()) {
4231 return WMError::WM_ERROR_INVALID_WINDOW;
4232 }
4233 auto context = GetContext();
4234 if (flag == WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED && context && context->GetApplicationInfo() &&
4235 context->GetApplicationInfo()->apiCompatibleVersion >= 9 && // 9: api version
4236 !SessionPermission::IsSystemCalling()) {
4237 TLOGI(WmsLogTag::DEFAULT, "Can not set show when locked, PersistentId: %{public}u", GetPersistentId());
4238 return WMError::WM_ERROR_INVALID_PERMISSION;
4239 }
4240 if (flag == WindowFlag::WINDOW_FLAG_HANDWRITING && !SessionPermission::IsSystemCalling()) {
4241 TLOGI(WmsLogTag::DEFAULT, "Can not set handwritting, PersistentId: %{public}u", GetPersistentId());
4242 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4243 }
4244 if (flag == WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE && !SessionPermission::IsSystemCalling()) {
4245 TLOGI(WmsLogTag::DEFAULT, "Can not set forbid split move, PersistentId: %{public}u", GetPersistentId());
4246 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4247 }
4248 uint32_t updateFlags = property_->GetWindowFlags() | (static_cast<uint32_t>(flag));
4249 return SetWindowFlags(updateFlags);
4250 }
4251
RemoveWindowFlag(WindowFlag flag)4252 WMError WindowSceneSessionImpl::RemoveWindowFlag(WindowFlag flag)
4253 {
4254 if (IsWindowSessionInvalid()) {
4255 return WMError::WM_ERROR_INVALID_WINDOW;
4256 }
4257 uint32_t updateFlags = property_->GetWindowFlags() & (~(static_cast<uint32_t>(flag)));
4258 return SetWindowFlags(updateFlags);
4259 }
4260
SetWindowFlags(uint32_t flags)4261 WMError WindowSceneSessionImpl::SetWindowFlags(uint32_t flags)
4262 {
4263 TLOGI(WmsLogTag::DEFAULT, "Session %{public}u flags %{public}u", GetWindowId(), flags);
4264 if (IsWindowSessionInvalid()) {
4265 TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
4266 return WMError::WM_ERROR_INVALID_WINDOW;
4267 }
4268 if (property_->GetWindowFlags() == flags) {
4269 TLOGI(WmsLogTag::DEFAULT, "Session %{public}u set same flags %{public}u", GetWindowId(), flags);
4270 return WMError::WM_OK;
4271 }
4272 auto oriFlags = property_->GetWindowFlags();
4273 property_->SetWindowFlags(flags);
4274 WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_FLAGS);
4275 if (ret != WMError::WM_OK) {
4276 TLOGE(WmsLogTag::DEFAULT, "SetWindowFlags errCode:%{public}d winId:%{public}u",
4277 static_cast<int32_t>(ret), GetWindowId());
4278 property_->SetWindowFlags(oriFlags);
4279 }
4280 return ret;
4281 }
4282
GetWindowFlags() const4283 uint32_t WindowSceneSessionImpl::GetWindowFlags() const
4284 {
4285 return property_->GetWindowFlags();
4286 }
4287
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)4288 void WindowSceneSessionImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
4289 {
4290 if (auto uiContent = GetUIContentSharedPtr()) {
4291 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace scene win=%{public}u, display=%{public}" PRIu64,
4292 GetWindowId(), GetDisplayId());
4293 uiContent->UpdateConfiguration(configuration);
4294 } else {
4295 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, scene win=%{public}u, display=%{public}" PRIu64,
4296 GetWindowId(), GetDisplayId());
4297 }
4298 UpdateDefaultStatusBarColor();
4299 std::vector<sptr<WindowSessionImpl>> subWindows;
4300 GetSubWindows(GetPersistentId(), subWindows);
4301 for (auto& subWindowSession : subWindows) {
4302 if (subWindowSession != nullptr) {
4303 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene subWin=%{public}u, display=%{public}" PRIu64,
4304 subWindowSession->GetWindowId(), subWindowSession->GetDisplayId());
4305 subWindowSession->UpdateConfiguration(configuration);
4306 }
4307 }
4308 }
4309
UpdateConfigurationForSpecified(const std::shared_ptr<AppExecFwk::Configuration> & configuration,const std::shared_ptr<Global::Resource::ResourceManager> & resourceManager)4310 void WindowSceneSessionImpl::UpdateConfigurationForSpecified(
4311 const std::shared_ptr<AppExecFwk::Configuration>& configuration,
4312 const std::shared_ptr<Global::Resource::ResourceManager>& resourceManager)
4313 {
4314 if (auto uiContent = GetUIContentSharedPtr()) {
4315 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace scene win=%{public}u, display=%{public}" PRIu64,
4316 GetWindowId(), GetDisplayId());
4317 uiContent->UpdateConfiguration(configuration, resourceManager);
4318 } else {
4319 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, scene win=%{public}u, display=%{public}" PRIu64,
4320 GetWindowId(), GetDisplayId());
4321 }
4322 if (configuration != nullptr) {
4323 specifiedColorMode_ = configuration->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
4324 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "scene win=%{public}u, colorMode=%{public}s, display=%{public}" PRIu64,
4325 GetWindowId(), specifiedColorMode_.c_str(), GetDisplayId());
4326 }
4327 UpdateDefaultStatusBarColor();
4328 std::vector<sptr<WindowSessionImpl>> subWindows;
4329 GetSubWindows(GetPersistentId(), subWindows);
4330 if (subWindows.empty()) {
4331 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "no subSession, scene win=%{public}u, display=%{public}" PRIu64,
4332 GetWindowId(), GetDisplayId());
4333 return;
4334 }
4335 for (auto& subWindowSession : subWindows) {
4336 if (subWindowSession != nullptr) {
4337 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene subWin=%{public}u, display=%{public}" PRIu64,
4338 subWindowSession->GetWindowId(), subWindowSession->GetDisplayId());
4339 subWindowSession->UpdateConfigurationForSpecified(configuration, resourceManager);
4340 }
4341 }
4342 }
4343
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration,const std::vector<std::shared_ptr<AbilityRuntime::Context>> & ignoreWindowContexts)4344 void WindowSceneSessionImpl::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration,
4345 const std::vector<std::shared_ptr<AbilityRuntime::Context>>& ignoreWindowContexts)
4346 {
4347 std::unordered_set<std::shared_ptr<AbilityRuntime::Context>> ignoreWindowCtxSet(
4348 ignoreWindowContexts.begin(), ignoreWindowContexts.end());
4349 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene map size: %{public}u", static_cast<uint32_t>(windowSessionMap_.size()));
4350 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4351 for (const auto& winPair : windowSessionMap_) {
4352 auto window = winPair.second.second;
4353 if (window == nullptr) {
4354 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "scene window is null");
4355 continue;
4356 }
4357 if (ignoreWindowCtxSet.count(window->GetContext()) == 0) {
4358 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene win=%{public}u, display=%{public}" PRIu64,
4359 window->GetWindowId(), window->GetDisplayId());
4360 window->UpdateConfiguration(configuration);
4361 } else {
4362 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "skip scene win=%{public}u, display=%{public}" PRIu64,
4363 window->GetWindowId(), window->GetDisplayId());
4364 }
4365 }
4366 }
4367
UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration> & configuration)4368 void WindowSceneSessionImpl::UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
4369 {
4370 if (auto uiContent = GetUIContentSharedPtr()) {
4371 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "notify ace scene win=%{public}u, display=%{public}" PRIu64,
4372 GetWindowId(), GetDisplayId());
4373 uiContent->UpdateConfigurationSyncForAll(configuration);
4374 } else {
4375 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent null, scene win=%{public}u, display=%{public}" PRIu64,
4376 GetWindowId(), GetDisplayId());
4377 }
4378 std::vector<sptr<WindowSessionImpl>> subWindows;
4379 GetSubWindows(GetPersistentId(), subWindows);
4380 if (subWindows.empty()) {
4381 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "no subSession, scene win=%{public}u, display=%{public}" PRIu64,
4382 GetWindowId(), GetDisplayId());
4383 return;
4384 }
4385 for (auto& subWindowSession : subWindows) {
4386 if (subWindowSession != nullptr) {
4387 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene subWin=%{public}u, display=%{public}" PRIu64,
4388 subWindowSession->GetWindowId(), subWindowSession->GetDisplayId());
4389 subWindowSession->UpdateConfigurationSync(configuration);
4390 }
4391 }
4392 }
4393
UpdateConfigurationSyncForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)4394 void WindowSceneSessionImpl::UpdateConfigurationSyncForAll(
4395 const std::shared_ptr<AppExecFwk::Configuration>& configuration)
4396 {
4397 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4398 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene map size: %{public}u", static_cast<uint32_t>(windowSessionMap_.size()));
4399 for (const auto& winPair : windowSessionMap_) {
4400 if (auto window = winPair.second.second) {
4401 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "scene win=%{public}u, display=%{public}" PRIu64,
4402 window->GetWindowId(), window->GetDisplayId());
4403 window->UpdateConfigurationSync(configuration);
4404 }
4405 }
4406 }
4407
4408 /** @note @window.hierarchy */
GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context> & context)4409 sptr<Window> WindowSceneSessionImpl::GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context>& context)
4410 {
4411 uint32_t mainWinId = INVALID_WINDOW_ID;
4412 {
4413 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4414 if (windowSessionMap_.empty()) {
4415 TLOGE(WmsLogTag::WMS_HIERARCHY, "Please create mainWindow First!");
4416 return nullptr;
4417 }
4418 for (const auto& winPair : windowSessionMap_) {
4419 auto win = winPair.second.second;
4420 if (win && WindowHelper::IsMainWindow(win->GetType()) && context.get() == win->GetContext().get()) {
4421 mainWinId = win->GetWindowId();
4422 TLOGD(WmsLogTag::WMS_HIERARCHY, "Find MainWinId:%{public}u.", mainWinId);
4423 break;
4424 }
4425 }
4426 }
4427 TLOGI(WmsLogTag::WMS_HIERARCHY, "mainId:%{public}u!", mainWinId);
4428 if (mainWinId == INVALID_WINDOW_ID) {
4429 TLOGE(WmsLogTag::WMS_HIERARCHY, "Cannot find topWindow!");
4430 return nullptr;
4431 }
4432 uint32_t topWinId = INVALID_WINDOW_ID;
4433 WMError ret = SingletonContainer::Get<WindowAdapter>().GetTopWindowId(mainWinId, topWinId);
4434 if (ret != WMError::WM_OK) {
4435 TLOGE(WmsLogTag::WMS_HIERARCHY, "failed with errCode:%{public}d", static_cast<int32_t>(ret));
4436 return nullptr;
4437 }
4438 return FindWindowById(topWinId);
4439 }
4440
4441 /** @note @window.hierarchy */
GetTopWindowWithId(uint32_t mainWinId)4442 sptr<Window> WindowSceneSessionImpl::GetTopWindowWithId(uint32_t mainWinId)
4443 {
4444 TLOGI(WmsLogTag::WMS_HIERARCHY, "mainId:%{public}u", mainWinId);
4445 uint32_t topWinId = INVALID_WINDOW_ID;
4446 WMError ret = SingletonContainer::Get<WindowAdapter>().GetTopWindowId(mainWinId, topWinId);
4447 if (ret != WMError::WM_OK) {
4448 WLOGFE("[GetTopWin] failed with errCode:%{public}d", static_cast<int32_t>(ret));
4449 return nullptr;
4450 }
4451 return FindWindowById(topWinId);
4452 }
4453
GetMainWindowWithContext(const std::shared_ptr<AbilityRuntime::Context> & context)4454 sptr<Window> WindowSceneSessionImpl::GetMainWindowWithContext(const std::shared_ptr<AbilityRuntime::Context>& context)
4455 {
4456 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4457 if (windowSessionMap_.empty()) {
4458 TLOGE(WmsLogTag::WMS_MAIN, "Please create mainWindow First!");
4459 return nullptr;
4460 }
4461 for (const auto& winPair : windowSessionMap_) {
4462 auto win = winPair.second.second;
4463 if (win && WindowHelper::IsMainWindow(win->GetType()) && context.get() == win->GetContext().get()) {
4464 TLOGI(WmsLogTag::WMS_MAIN, "Find MainWinId:%{public}u.", win->GetWindowId());
4465 return win;
4466 }
4467 }
4468 TLOGE(WmsLogTag::WMS_MAIN, "Cannot find Window!");
4469 return nullptr;
4470 }
4471
GetMainWindowWithId(uint32_t mainWinId)4472 sptr<WindowSessionImpl> WindowSceneSessionImpl::GetMainWindowWithId(uint32_t mainWinId)
4473 {
4474 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4475 if (windowSessionMap_.empty()) {
4476 WLOGFE("Please create mainWindow First!");
4477 return nullptr;
4478 }
4479 for (const auto& winPair : windowSessionMap_) {
4480 auto win = winPair.second.second;
4481 if (win && WindowHelper::IsMainWindow(win->GetType()) && mainWinId == win->GetWindowId()) {
4482 WLOGI("GetTopWindow Find MainWinId:%{public}u.", mainWinId);
4483 return win;
4484 }
4485 }
4486 WLOGFE("Cannot find Window!");
4487 return nullptr;
4488 }
4489
GetParentMainWindowIdInner(WindowSessionImplMap & sessionMap,int32_t windowId,int32_t & mainWindowId)4490 static WMError GetParentMainWindowIdInner(WindowSessionImplMap& sessionMap, int32_t windowId, int32_t& mainWindowId)
4491 {
4492 for (const auto& [_, pair] : sessionMap) {
4493 const auto& window = pair.second;
4494 if (window == nullptr) {
4495 return WMError::WM_ERROR_NULLPTR;
4496 }
4497 if (window->GetPersistentId() != windowId) {
4498 continue;
4499 }
4500
4501 if (WindowHelper::IsMainWindow(window->GetType())) {
4502 TLOGI(WmsLogTag::WMS_SUB, "find main window, id:%{public}u", window->GetPersistentId());
4503 mainWindowId = window->GetPersistentId();
4504 return WMError::WM_OK;
4505 }
4506 if (WindowHelper::IsSubWindow(window->GetType()) || WindowHelper::IsDialogWindow(window->GetType())) {
4507 return GetParentMainWindowIdInner(sessionMap, window->GetParentId(), mainWindowId);
4508 }
4509 // not main window, sub window, dialog, set invalid id
4510 mainWindowId = INVALID_SESSION_ID;
4511 return WMError::WM_OK;
4512 }
4513 return WMError::WM_ERROR_INVALID_PARENT;
4514 }
4515
GetParentMainWindowId(int32_t windowId)4516 int32_t WindowSceneSessionImpl::GetParentMainWindowId(int32_t windowId)
4517 {
4518 if (windowId == INVALID_SESSION_ID) {
4519 TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
4520 return INVALID_SESSION_ID;
4521 }
4522 int32_t mainWindowId = INVALID_SESSION_ID;
4523 {
4524 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
4525 WMError findRet = GetParentMainWindowIdInner(windowSessionMap_, windowId, mainWindowId);
4526 if (findRet == WMError::WM_OK) {
4527 return mainWindowId;
4528 }
4529 }
4530 // can't find in client, need to find in server find
4531 WMError ret = SingletonContainer::Get<WindowAdapter>().GetParentMainWindowId(windowId, mainWindowId);
4532 if (ret != WMError::WM_OK) {
4533 TLOGE(WmsLogTag::WMS_SUB, "cant't find main window id, err:%{public}d", static_cast<uint32_t>(ret));
4534 return INVALID_SESSION_ID;
4535 }
4536 return mainWindowId;
4537 }
4538
GetAndVerifyWindowTypeForArkUI(uint32_t parentId,const std::string & windowName,WindowType parentWindowType,WindowType & windowType)4539 WMError WindowSceneSessionImpl::GetAndVerifyWindowTypeForArkUI(uint32_t parentId, const std::string& windowName,
4540 WindowType parentWindowType, WindowType& windowType)
4541 {
4542 auto window = WindowSceneSessionImpl::Find(windowName);
4543 if (window != nullptr) {
4544 TLOGE(WmsLogTag::WMS_SUB, "WindowName(%{public}s) already exists.", windowName.c_str());
4545 return WMError::WM_ERROR_REPEAT_OPERATION;
4546 }
4547 TLOGI(WmsLogTag::WMS_SUB, "parentWindowId:%{public}d, parentWindowType:%{public}d", parentId, parentWindowType);
4548 if (parentWindowType == WindowType::WINDOW_TYPE_SCENE_BOARD ||
4549 parentWindowType == WindowType::WINDOW_TYPE_DESKTOP) {
4550 windowType = WindowType::WINDOW_TYPE_SYSTEM_FLOAT;
4551 } else if (WindowHelper::IsUIExtensionWindow(parentWindowType)) {
4552 windowType = WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
4553 } else if (WindowHelper::IsSystemSubWindow(parentWindowType)) {
4554 TLOGE(WmsLogTag::WMS_SUB, "parent is system sub window, id: %{public}d, type: %{public}d",
4555 parentId, parentWindowType);
4556 return WMError::WM_ERROR_INVALID_TYPE;
4557 } else if (WindowHelper::IsSystemWindow(parentWindowType)) {
4558 windowType = WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW;
4559 } else {
4560 auto parentWindow = WindowSceneSessionImpl::GetWindowWithId(parentId);
4561 if (parentWindow == nullptr) {
4562 TLOGE(WmsLogTag::WMS_SUB, "parentWindow is null, windowId:%{public}d", parentId);
4563 return WMError::WM_ERROR_INVALID_WINDOW;
4564 }
4565 if (parentWindowType != parentWindow->GetType()) {
4566 TLOGE(WmsLogTag::WMS_SUB, "parentWindow does match type");
4567 return WMError::WM_ERROR_INVALID_WINDOW;
4568 }
4569 auto ret = WindowSceneSessionImpl::VerifySubWindowLevel(false, parentWindow);
4570 if (ret != WMError::WM_OK) {
4571 return ret;
4572 }
4573 windowType = WindowType::WINDOW_TYPE_APP_SUB_WINDOW;
4574 }
4575 return WMError::WM_OK;
4576 }
4577
SetNeedDefaultAnimation(bool needDefaultAnimation)4578 void WindowSceneSessionImpl::SetNeedDefaultAnimation(bool needDefaultAnimation)
4579 {
4580 enableDefaultAnimation_= needDefaultAnimation;
4581 auto hostSession = GetHostSession();
4582 CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
4583 hostSession->UpdateWindowAnimationFlag(needDefaultAnimation);
4584 }
4585
ConvertRadiusToSigma(float radius)4586 static float ConvertRadiusToSigma(float radius)
4587 {
4588 return radius > 0.0f ? 0.57735f * radius + SK_ScalarHalf : 0.0f; // 0.57735f is blur sigma scale
4589 }
4590
CheckParmAndPermission()4591 WMError WindowSceneSessionImpl::CheckParmAndPermission()
4592 {
4593 if (surfaceNode_ == nullptr) {
4594 WLOGFE("RSSurface node is null");
4595 return WMError::WM_ERROR_NULLPTR;
4596 }
4597
4598 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4599 WLOGFE("Check failed, permission denied");
4600 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4601 }
4602
4603 return WMError::WM_OK;
4604 }
4605
SetCornerRadius(float cornerRadius)4606 WMError WindowSceneSessionImpl::SetCornerRadius(float cornerRadius)
4607 {
4608 if (surfaceNode_ == nullptr) {
4609 WLOGFE("RSSurface node is null");
4610 return WMError::WM_ERROR_NULLPTR;
4611 }
4612
4613 WLOGFI("Set window %{public}s corner radius %{public}f", GetWindowName().c_str(), cornerRadius);
4614 surfaceNode_->SetCornerRadius(cornerRadius);
4615 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4616 return WMError::WM_OK;
4617 }
4618
SetWindowCornerRadius(float cornerRadius)4619 WMError WindowSceneSessionImpl::SetWindowCornerRadius(float cornerRadius)
4620 {
4621 if (IsWindowSessionInvalid()) {
4622 return WMError::WM_ERROR_INVALID_WINDOW;
4623 }
4624 if (!windowSystemConfig_.IsPcWindow() && !windowSystemConfig_.IsPadWindow() &&
4625 !windowSystemConfig_.IsPhoneWindow()) {
4626 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not pc, pad or phone, not supported.");
4627 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
4628 }
4629 if (!WindowHelper::IsFloatOrSubWindow(GetType())) {
4630 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not sub window or float window.");
4631 return WMError::WM_ERROR_INVALID_CALLING;
4632 }
4633
4634 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Set id %{public}u corner radius %{public}f.", GetWindowId(), cornerRadius);
4635 if (MathHelper::LessNotEqual(cornerRadius, 0.0f)) {
4636 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The corner radius is less than zero.");
4637 return WMError::WM_ERROR_INVALID_PARAM;
4638 }
4639
4640 property_->SetWindowCornerRadius(cornerRadius);
4641
4642 auto hostSession = GetHostSession();
4643 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
4644 hostSession->SetWindowCornerRadius(cornerRadius);
4645 return WMError::WM_OK;
4646 }
4647
GetWindowCornerRadius(float & cornerRadius)4648 WMError WindowSceneSessionImpl::GetWindowCornerRadius(float& cornerRadius)
4649 {
4650 if (IsWindowSessionInvalid()) {
4651 return WMError::WM_ERROR_INVALID_WINDOW;
4652 }
4653 if (!IsPcOrFreeMultiWindowCapabilityEnabled()) {
4654 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not PC or Pad, not supported.");
4655 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
4656 }
4657 if (!WindowHelper::IsFloatOrSubWindow(GetType())) {
4658 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not sub window or float window.");
4659 return WMError::WM_ERROR_INVALID_CALLING;
4660 }
4661
4662 cornerRadius = property_->GetWindowCornerRadius();
4663 if (MathHelper::LessNotEqual(cornerRadius, 0.0f)) {
4664 // Invalid corner radius means app has not set corner radius of the window, return the default corner radius
4665 TLOGI(WmsLogTag::WMS_ANIMATION, "System config radius: %{public}f, property radius: %{public}f, id: %{public}d",
4666 windowSystemConfig_.defaultCornerRadius_, cornerRadius, GetPersistentId());
4667 cornerRadius = MathHelper::LessNotEqual(windowSystemConfig_.defaultCornerRadius_, 0.0f) ?
4668 0.0f : windowSystemConfig_.defaultCornerRadius_;
4669 }
4670 return WMError::WM_OK;
4671 }
4672
SetShadowRadius(float radius)4673 WMError WindowSceneSessionImpl::SetShadowRadius(float radius)
4674 {
4675 WMError ret = CheckParmAndPermission();
4676 if (ret != WMError::WM_OK) {
4677 return ret;
4678 }
4679
4680 WLOGFI("Set window %{public}s shadow radius %{public}f", GetWindowName().c_str(), radius);
4681 if (MathHelper::LessNotEqual(radius, 0.0)) {
4682 return WMError::WM_ERROR_INVALID_PARAM;
4683 }
4684
4685 surfaceNode_->SetShadowRadius(ConvertRadiusToSigma(radius));
4686 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4687 return WMError::WM_OK;
4688 }
4689
SyncShadowsToComponent(const ShadowsInfo & shadowsInfo)4690 WMError WindowSceneSessionImpl::SyncShadowsToComponent(const ShadowsInfo& shadowsInfo)
4691 {
4692 if (IsWindowSessionInvalid()) {
4693 return WMError::WM_ERROR_INVALID_WINDOW;
4694 }
4695
4696 TLOGI(WmsLogTag::WMS_ANIMATION, "Sync Shadows To Component %{public}s shadow radius: %{public}f,"
4697 " color: %{public}s, offsetX: %{public}f, offsetY: %{public}f", GetWindowName().c_str(),
4698 shadowsInfo.radius_, shadowsInfo.color_.c_str(), shadowsInfo.offsetX_, shadowsInfo.offsetY_);
4699 if (MathHelper::LessNotEqual(shadowsInfo.radius_, 0.0)) {
4700 return WMError::WM_ERROR_INVALID_PARAM;
4701 }
4702
4703 property_->SetWindowShadows(shadowsInfo);
4704 auto hostSession = GetHostSession();
4705
4706 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_SYSTEM_ABNORMALLY);
4707 hostSession->SetWindowShadows(shadowsInfo);
4708 return WMError::WM_OK;
4709 }
4710
SetWindowShadowRadius(float radius)4711 WMError WindowSceneSessionImpl::SetWindowShadowRadius(float radius)
4712 {
4713 if (IsWindowSessionInvalid()) {
4714 return WMError::WM_ERROR_INVALID_WINDOW;
4715 }
4716 if (!windowSystemConfig_.IsPcWindow() && !windowSystemConfig_.IsPadWindow() &&
4717 !IsDeviceFeatureCapableForFreeMultiWindow()) {
4718 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not PC or Pad, not supported.");
4719 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
4720 }
4721 if (!WindowHelper::IsFloatOrSubWindow(GetType())) {
4722 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is not sub window or float window.");
4723 return WMError::WM_ERROR_INVALID_CALLING;
4724 }
4725
4726 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Set id %{public}u shadow radius %{public}f.", GetWindowId(), radius);
4727 if (MathHelper::LessNotEqual(radius, 0.0f)) {
4728 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The shadow radius is less than zero.");
4729 return WMError::WM_ERROR_INVALID_PARAM;
4730 }
4731
4732 if (surfaceNode_ == nullptr) {
4733 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "RSSurface node is nullptr.");
4734 return WMError::WM_ERROR_NULLPTR;
4735 }
4736 surfaceNode_->SetShadowRadius(ConvertRadiusToSigma(radius));
4737 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4738 return WMError::WM_OK;
4739 }
4740
SetShadowColor(std::string color)4741 WMError WindowSceneSessionImpl::SetShadowColor(std::string color)
4742 {
4743 WMError ret = CheckParmAndPermission();
4744 if (ret != WMError::WM_OK) {
4745 return ret;
4746 }
4747
4748 WLOGFI("Set window %{public}s shadow color %{public}s", GetWindowName().c_str(), color.c_str());
4749 uint32_t colorValue = 0;
4750 if (!ColorParser::Parse(color, colorValue)) {
4751 return WMError::WM_ERROR_INVALID_PARAM;
4752 }
4753
4754 surfaceNode_->SetShadowColor(colorValue);
4755 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4756 return WMError::WM_OK;
4757 }
4758
SetShadowOffsetX(float offsetX)4759 WMError WindowSceneSessionImpl::SetShadowOffsetX(float offsetX)
4760 {
4761 WMError ret = CheckParmAndPermission();
4762 if (ret != WMError::WM_OK) {
4763 return ret;
4764 }
4765
4766 WLOGFI("Set window %{public}s shadow offsetX %{public}f", GetWindowName().c_str(), offsetX);
4767 surfaceNode_->SetShadowOffsetX(offsetX);
4768 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4769 return WMError::WM_OK;
4770 }
4771
SetShadowOffsetY(float offsetY)4772 WMError WindowSceneSessionImpl::SetShadowOffsetY(float offsetY)
4773 {
4774 WMError ret = CheckParmAndPermission();
4775 if (ret != WMError::WM_OK) {
4776 return ret;
4777 }
4778
4779 WLOGFI("Set window %{public}s shadow offsetY %{public}f", GetWindowName().c_str(), offsetY);
4780 surfaceNode_->SetShadowOffsetY(offsetY);
4781 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4782 return WMError::WM_OK;
4783 }
4784
SetBlur(float radius)4785 WMError WindowSceneSessionImpl::SetBlur(float radius)
4786 {
4787 WMError ret = CheckParmAndPermission();
4788 if (ret != WMError::WM_OK) {
4789 return ret;
4790 }
4791
4792 WLOGFI("Set window %{public}s blur radius %{public}f", GetWindowName().c_str(), radius);
4793 if (MathHelper::LessNotEqual(radius, 0.0)) {
4794 return WMError::WM_ERROR_INVALID_PARAM;
4795 }
4796
4797 radius = ConvertRadiusToSigma(radius);
4798 WLOGFI("Set window %{public}s blur radius after conversion %{public}f", GetWindowName().c_str(), radius);
4799 surfaceNode_->SetFilter(RSFilter::CreateBlurFilter(radius, radius));
4800 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4801 return WMError::WM_OK;
4802 }
4803
SetBackdropBlur(float radius)4804 WMError WindowSceneSessionImpl::SetBackdropBlur(float radius)
4805 {
4806 WMError ret = CheckParmAndPermission();
4807 if (ret != WMError::WM_OK) {
4808 return ret;
4809 }
4810
4811 WLOGFI("Set window %{public}s backdrop blur radius %{public}f", GetWindowName().c_str(), radius);
4812 if (MathHelper::LessNotEqual(radius, 0.0)) {
4813 return WMError::WM_ERROR_INVALID_PARAM;
4814 }
4815
4816 radius = ConvertRadiusToSigma(radius);
4817 WLOGFI("Set window %{public}s backdrop blur radius after conversion %{public}f", GetWindowName().c_str(), radius);
4818 surfaceNode_->SetBackgroundFilter(RSFilter::CreateBlurFilter(radius, radius));
4819 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4820 return WMError::WM_OK;
4821 }
4822
SetBackdropBlurStyle(WindowBlurStyle blurStyle)4823 WMError WindowSceneSessionImpl::SetBackdropBlurStyle(WindowBlurStyle blurStyle)
4824 {
4825 WMError ret = CheckParmAndPermission();
4826 if (ret != WMError::WM_OK) {
4827 return ret;
4828 }
4829
4830 WLOGFI("Set window %{public}s backdrop blur style %{public}u", GetWindowName().c_str(), blurStyle);
4831 if (blurStyle < WindowBlurStyle::WINDOW_BLUR_OFF || blurStyle > WindowBlurStyle::WINDOW_BLUR_THICK) {
4832 return WMError::WM_ERROR_INVALID_PARAM;
4833 }
4834
4835 if (blurStyle == WindowBlurStyle::WINDOW_BLUR_OFF) {
4836 surfaceNode_->SetBackgroundFilter(nullptr);
4837 } else {
4838 auto display = SingletonContainer::IsDestroyed() ? nullptr :
4839 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
4840 if (display == nullptr) {
4841 WLOGFE("get display failed displayId:%{public}" PRIu64, property_->GetDisplayId());
4842 return WMError::WM_ERROR_INVALID_PARAM;
4843 }
4844 auto displayInfo = display->GetDisplayInfo();
4845 if (displayInfo == nullptr) {
4846 WLOGFE("get displayInfo failed displayId:%{public}" PRIu64, property_->GetDisplayId());
4847 return WMError::WM_ERROR_INVALID_PARAM;
4848 }
4849 surfaceNode_->SetBackgroundFilter(RSFilter::CreateMaterialFilter(
4850 static_cast<int>(blurStyle), GetVirtualPixelRatio(displayInfo)));
4851 }
4852
4853 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
4854 return WMError::WM_OK;
4855 }
4856
SetPrivacyMode(bool isPrivacyMode)4857 WMError WindowSceneSessionImpl::SetPrivacyMode(bool isPrivacyMode)
4858 {
4859 if (IsWindowSessionInvalid()) {
4860 return WMError::WM_ERROR_INVALID_WINDOW;
4861 }
4862 WLOGFD("id : %{public}u, %{public}u", GetWindowId(), isPrivacyMode);
4863 property_->SetPrivacyMode(isPrivacyMode);
4864 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE);
4865 }
4866
IsPrivacyMode() const4867 bool WindowSceneSessionImpl::IsPrivacyMode() const
4868 {
4869 if (IsWindowSessionInvalid()) {
4870 return false;
4871 }
4872 return property_->GetPrivacyMode();
4873 }
4874
SetSystemPrivacyMode(bool isSystemPrivacyMode)4875 void WindowSceneSessionImpl::SetSystemPrivacyMode(bool isSystemPrivacyMode)
4876 {
4877 WLOGFD("id : %{public}u, %{public}u", GetWindowId(), isSystemPrivacyMode);
4878 property_->SetSystemPrivacyMode(isSystemPrivacyMode);
4879 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE);
4880 }
4881
SetSnapshotSkip(bool isSkip)4882 WMError WindowSceneSessionImpl::SetSnapshotSkip(bool isSkip)
4883 {
4884 if (IsWindowSessionInvalid()) {
4885 return WMError::WM_ERROR_INVALID_WINDOW;
4886 }
4887 bool oldSkipValue = property_->GetSnapshotSkip();
4888 property_->SetSnapshotSkip(isSkip);
4889 auto resError = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP);
4890 if (resError != WMError::WM_OK) {
4891 property_->SetSnapshotSkip(oldSkipValue);
4892 }
4893 return resError;
4894 }
4895
Snapshot()4896 std::shared_ptr<Media::PixelMap> WindowSceneSessionImpl::Snapshot()
4897 {
4898 if (IsWindowSessionInvalid()) {
4899 return nullptr;
4900 }
4901 std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
4902 auto isSucceeded = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
4903 if (!isSucceeded) {
4904 WLOGFE("Failed to TakeSurfaceCapture!");
4905 return nullptr;
4906 }
4907 std::shared_ptr<Media::PixelMap> pixelMap = callback->GetResult(SNAPSHOT_TIMEOUT);
4908 if (pixelMap != nullptr) {
4909 WLOGFD("Snapshot succeed, save WxH=%{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
4910 } else {
4911 WLOGFE("Failed to get pixelmap, return nullptr!");
4912 }
4913 return pixelMap;
4914 }
4915
Snapshot(std::shared_ptr<Media::PixelMap> & pixelMap)4916 WMError WindowSceneSessionImpl::Snapshot(std::shared_ptr<Media::PixelMap>& pixelMap)
4917 {
4918 if (IsWindowSessionInvalid()) {
4919 return WMError::WM_ERROR_INVALID_WINDOW;
4920 }
4921 if (state_ < WindowState::STATE_SHOWN) {
4922 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d bounds not init, state: %{public}u",
4923 GetPersistentId(), state_);
4924 return WMError::WM_ERROR_INVALID_WINDOW;
4925 }
4926 std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
4927 auto isSucceeded = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
4928 if (!isSucceeded) {
4929 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, Failed to TakeSurfaceCapture", GetPersistentId());
4930 return WMError::WM_ERROR_INVALID_OPERATION;
4931 }
4932 pixelMap = callback->GetResult(SNAPSHOT_TIMEOUT);
4933 if (pixelMap == nullptr) {
4934 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, Failed to get pixelmap", GetPersistentId());
4935 return WMError::WM_ERROR_TIMEOUT;
4936 }
4937 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d snapshot end, WxH=%{public}dx%{public}d",
4938 GetPersistentId(), pixelMap->GetWidth(), pixelMap->GetHeight());
4939 return WMError::WM_OK;
4940 }
4941
SnapshotIgnorePrivacy(std::shared_ptr<Media::PixelMap> & pixelMap)4942 WMError WindowSceneSessionImpl::SnapshotIgnorePrivacy(std::shared_ptr<Media::PixelMap>& pixelMap)
4943 {
4944 if (IsWindowSessionInvalid()) {
4945 return WMError::WM_ERROR_INVALID_WINDOW;
4946 }
4947 std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
4948 auto isSucceeded = RSInterfaces::GetInstance().TakeSelfSurfaceCapture(surfaceNode_, callback);
4949 if (!isSucceeded) {
4950 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "windowId:%{public}u, Failed to TakeSelfSurfaceCapture!", GetWindowId());
4951 return WMError::WM_ERROR_INVALID_OPERATION;
4952 }
4953 pixelMap = callback->GetResult(SNAPSHOT_TIMEOUT);
4954 if (pixelMap == nullptr) {
4955 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Failed to get pixelmap, windowId:%{public}u", GetWindowId());
4956 return WMError::WM_ERROR_NULLPTR;
4957 }
4958 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "succeed, windowId:%{public}u, WxH=%{public}dx%{public}d",
4959 GetWindowId(), pixelMap->GetWidth(), pixelMap->GetHeight());
4960 return WMError::WM_OK;
4961 }
4962
NotifyMemoryLevel(int32_t level)4963 WMError WindowSceneSessionImpl::NotifyMemoryLevel(int32_t level)
4964 {
4965 TLOGI(WmsLogTag::DEFAULT, "id: %{public}u, level: %{public}d", GetWindowId(), level);
4966 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
4967 if (uiContent == nullptr) {
4968 WLOGFE("Window %{public}s notify failed, uiContent is null.", GetWindowName().c_str());
4969 return WMError::WM_ERROR_NULLPTR;
4970 }
4971 // notify memory level
4972 uiContent->NotifyMemoryLevel(level);
4973 WLOGFD("End!");
4974 return WMError::WM_OK;
4975 }
4976
SetTurnScreenOn(bool turnScreenOn)4977 WMError WindowSceneSessionImpl::SetTurnScreenOn(bool turnScreenOn)
4978 {
4979 if (IsWindowSessionInvalid()) {
4980 return WMError::WM_ERROR_INVALID_WINDOW;
4981 }
4982 property_->SetTurnScreenOn(turnScreenOn);
4983 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON);
4984 }
4985
IsTurnScreenOn() const4986 bool WindowSceneSessionImpl::IsTurnScreenOn() const
4987 {
4988 return property_->IsTurnScreenOn();
4989 }
4990
SetKeepScreenOn(bool keepScreenOn)4991 WMError WindowSceneSessionImpl::SetKeepScreenOn(bool keepScreenOn)
4992 {
4993 if (IsWindowSessionInvalid()) {
4994 WLOGFE("session is invalid");
4995 return WMError::WM_ERROR_INVALID_WINDOW;
4996 }
4997 property_->SetKeepScreenOn(keepScreenOn);
4998 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON);
4999 }
5000
IsKeepScreenOn() const5001 bool WindowSceneSessionImpl::IsKeepScreenOn() const
5002 {
5003 return property_->IsKeepScreenOn();
5004 }
5005
SetViewKeepScreenOn(bool keepScreenOn)5006 WMError WindowSceneSessionImpl::SetViewKeepScreenOn(bool keepScreenOn)
5007 {
5008 if (IsWindowSessionInvalid()) {
5009 return WMError::WM_ERROR_INVALID_WINDOW;
5010 }
5011 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, enabled: %{public}u", GetPersistentId(), keepScreenOn);
5012 property_->SetViewKeepScreenOn(keepScreenOn);
5013 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_VIEW_KEEP_SCREEN_ON);
5014 }
5015
IsViewKeepScreenOn() const5016 bool WindowSceneSessionImpl::IsViewKeepScreenOn() const
5017 {
5018 return property_->IsViewKeepScreenOn();
5019 }
5020
SetWindowShadowEnabled(bool isEnabled)5021 WMError WindowSceneSessionImpl::SetWindowShadowEnabled(bool isEnabled)
5022 {
5023 if (property_->GetPcAppInpadCompatibleMode()) {
5024 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "This is PcAppInPad, not supported");
5025 return WMError::WM_OK;
5026 }
5027 if (!windowSystemConfig_.IsPcWindow()) {
5028 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
5029 }
5030 if (IsWindowSessionInvalid()) {
5031 return WMError::WM_ERROR_INVALID_WINDOW;
5032 }
5033 property_->SetWindowShadowEnabled(isEnabled);
5034 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_SHADOW_ENABLED);
5035 }
5036
GetWindowShadowEnabled() const5037 bool WindowSceneSessionImpl::GetWindowShadowEnabled() const
5038 {
5039 return property_->GetWindowShadowEnabled();
5040 }
5041
SetTransform(const Transform & trans)5042 WMError WindowSceneSessionImpl::SetTransform(const Transform& trans)
5043 {
5044 TLOGI(WmsLogTag::DEFAULT, "Id: %{public}d", property_->GetPersistentId());
5045 if (IsWindowSessionInvalid()) {
5046 TLOGE(WmsLogTag::DEFAULT, "Session is invalid");
5047 return WMError::WM_ERROR_INVALID_WINDOW;
5048 }
5049 Transform oriTrans = property_->GetTransform();
5050 property_->SetTransform(trans);
5051 TransformSurfaceNode(trans);
5052 return WMError::WM_OK;
5053 }
5054
GetTransform() const5055 const Transform& WindowSceneSessionImpl::GetTransform() const
5056 {
5057 return property_->GetTransform();
5058 }
5059
TransformSurfaceNode(const Transform & trans)5060 void WindowSceneSessionImpl::TransformSurfaceNode(const Transform& trans)
5061 {
5062 if (surfaceNode_ == nullptr) {
5063 return;
5064 }
5065 surfaceNode_->SetPivotX(trans.pivotX_);
5066 surfaceNode_->SetPivotY(trans.pivotY_);
5067 surfaceNode_->SetScaleX(trans.scaleX_);
5068 surfaceNode_->SetScaleY(trans.scaleY_);
5069 surfaceNode_->SetTranslateX(trans.translateX_);
5070 surfaceNode_->SetTranslateY(trans.translateY_);
5071 surfaceNode_->SetTranslateZ(trans.translateZ_);
5072 surfaceNode_->SetRotationX(trans.rotationX_);
5073 surfaceNode_->SetRotationY(trans.rotationY_);
5074 surfaceNode_->SetRotation(trans.rotationZ_);
5075 uint32_t animationFlag = property_->GetAnimationFlag();
5076 if (animationFlag != static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
5077 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
5078 }
5079 }
5080
RegisterAnimationTransitionController(const sptr<IAnimationTransitionController> & listener)5081 WMError WindowSceneSessionImpl::RegisterAnimationTransitionController(
5082 const sptr<IAnimationTransitionController>& listener)
5083 {
5084 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5085 TLOGE(WmsLogTag::WMS_SYSTEM, "permission denied!");
5086 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5087 }
5088 if (listener == nullptr) {
5089 TLOGE(WmsLogTag::WMS_SYSTEM, "listener is nullptr");
5090 return WMError::WM_ERROR_NULLPTR;
5091 }
5092 animationTransitionController_ = listener;
5093 wptr<WindowSessionProperty> propertyWeak(property_);
5094 wptr<IAnimationTransitionController> animationTransitionControllerWeak(animationTransitionController_);
5095
5096 if (auto uiContent = GetUIContentSharedPtr()) {
5097 uiContent->SetNextFrameLayoutCallback([propertyWeak, animationTransitionControllerWeak]() {
5098 auto property = propertyWeak.promote();
5099 auto animationTransitionController = animationTransitionControllerWeak.promote();
5100 if (!property || !animationTransitionController) {
5101 TLOGE(WmsLogTag::WMS_SYSTEM, "property or animation transition controller is nullptr");
5102 return;
5103 }
5104 uint32_t animationFlag = property->GetAnimationFlag();
5105 if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
5106 // CustomAnimation is enabled when animationTransitionController_ exists
5107 animationTransitionController->AnimationForShown();
5108 }
5109 TLOGI(WmsLogTag::WMS_SYSTEM, "AnimationForShown excute sucess %{public}d!", property->GetPersistentId());
5110 });
5111 }
5112 TLOGI(WmsLogTag::WMS_SYSTEM, "%{public}d!", property_->GetPersistentId());
5113 return WMError::WM_OK;
5114 }
5115
UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)5116 WMError WindowSceneSessionImpl::UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)
5117 {
5118 TLOGI(WmsLogTag::WMS_SYSTEM, "id:%{public}d, isAdd:%{public}u", property_->GetPersistentId(), isAdd);
5119 if (IsWindowSessionInvalid()) {
5120 return WMError::WM_ERROR_INVALID_WINDOW;
5121 }
5122 if (!WindowHelper::IsSystemWindow(property_->GetWindowType())) {
5123 TLOGE(WmsLogTag::WMS_SYSTEM, "only system window can set");
5124 return WMError::WM_ERROR_INVALID_OPERATION;
5125 }
5126 // set no custom after customAnimation
5127 WMError ret = UpdateAnimationFlagProperty(false);
5128 if (ret != WMError::WM_OK) {
5129 TLOGE(WmsLogTag::WMS_SYSTEM, "UpdateAnimationFlagProperty failed!");
5130 return ret;
5131 }
5132 auto hostSession = GetHostSession();
5133 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5134 ret = static_cast<WMError>(hostSession->UpdateWindowSceneAfterCustomAnimation(isAdd));
5135 return ret;
5136 }
5137
AdjustWindowAnimationFlag(bool withAnimation)5138 void WindowSceneSessionImpl::AdjustWindowAnimationFlag(bool withAnimation)
5139 {
5140 if (IsWindowSessionInvalid()) {
5141 WLOGFW("session invalid!");
5142 return;
5143 }
5144 // when show/hide with animation
5145 // use custom animation when transitionController exists; else use default animation
5146 WindowType winType = property_->GetWindowType();
5147 bool isAppWindow = WindowHelper::IsAppWindow(winType);
5148 if (withAnimation && !isAppWindow && animationTransitionController_) {
5149 // use custom animation
5150 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
5151 } else if ((isAppWindow && enableDefaultAnimation_) || (withAnimation && !animationTransitionController_)) {
5152 // use default animation
5153 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::DEFAULT));
5154 } else {
5155 // with no animation
5156 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
5157 }
5158 }
5159
UpdateAnimationFlagProperty(bool withAnimation)5160 WMError WindowSceneSessionImpl::UpdateAnimationFlagProperty(bool withAnimation)
5161 {
5162 if (!WindowHelper::IsSystemWindow(GetType())) {
5163 return WMError::WM_OK;
5164 }
5165 AdjustWindowAnimationFlag(withAnimation);
5166 // when show(true) with default, hide() with None, to adjust animationFlag to disabled default animation
5167 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG);
5168 }
5169
SetAlpha(float alpha)5170 WMError WindowSceneSessionImpl::SetAlpha(float alpha)
5171 {
5172 WLOGFI("%{public}d alpha %{public}f", property_->GetPersistentId(), alpha);
5173 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
5174 WLOGFE("permission denied!");
5175 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5176 }
5177 if (IsWindowSessionInvalid()) {
5178 return WMError::WM_ERROR_INVALID_WINDOW;
5179 }
5180 surfaceNode_->SetAlpha(alpha);
5181 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
5182 return WMError::WM_OK;
5183 }
5184
BindDialogTarget(sptr<IRemoteObject> targetToken)5185 WMError WindowSceneSessionImpl::BindDialogTarget(sptr<IRemoteObject> targetToken)
5186 {
5187 if (IsWindowSessionInvalid()) {
5188 TLOGE(WmsLogTag::WMS_DIALOG, "session is invalid");
5189 return WMError::WM_ERROR_INVALID_WINDOW;
5190 }
5191 auto persistentId = property_->GetPersistentId();
5192 TLOGI(WmsLogTag::WMS_DIALOG, "id: %{public}d", persistentId);
5193 WMError ret = SingletonContainer::Get<WindowAdapter>().BindDialogSessionTarget(persistentId, targetToken);
5194 if (ret != WMError::WM_OK) {
5195 TLOGE(WmsLogTag::WMS_DIALOG, "bind window failed with errCode:%{public}d", static_cast<int32_t>(ret));
5196 }
5197 return ret;
5198 }
5199
SetDialogBackGestureEnabled(bool isEnabled)5200 WMError WindowSceneSessionImpl::SetDialogBackGestureEnabled(bool isEnabled)
5201 {
5202 WindowType windowType = GetType();
5203 if (windowType != WindowType::WINDOW_TYPE_DIALOG) {
5204 TLOGE(WmsLogTag::WMS_DIALOG, "windowType not support. WinId:%{public}u, WindowType:%{public}u",
5205 GetWindowId(), static_cast<uint32_t>(windowType));
5206 return WMError::WM_ERROR_INVALID_CALLING;
5207 }
5208 auto hostSession = GetHostSession();
5209 if (hostSession == nullptr) {
5210 TLOGE(WmsLogTag::WMS_DIALOG, "set window failed because of nullptr");
5211 return WMError::WM_ERROR_NULLPTR;
5212 }
5213 WMError ret = static_cast<WMError>(hostSession->SetDialogSessionBackGestureEnabled(isEnabled));
5214 dialogSessionBackGestureEnabled_ = isEnabled;
5215 if (ret != WMError::WM_OK) {
5216 TLOGE(WmsLogTag::WMS_DIALOG, "set window failed with errCode:%{public}d", static_cast<int32_t>(ret));
5217 }
5218 return ret;
5219 }
5220
SetTouchHotAreas(const std::vector<Rect> & rects)5221 WMError WindowSceneSessionImpl::SetTouchHotAreas(const std::vector<Rect>& rects)
5222 {
5223 std::vector<Rect> lastTouchHotAreas;
5224 property_->GetTouchHotAreas(lastTouchHotAreas);
5225 property_->SetTouchHotAreas(rects);
5226 WMError result = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA);
5227 if (result != WMError::WM_OK) {
5228 property_->SetTouchHotAreas(lastTouchHotAreas);
5229 WLOGFE("errCode:%{public}d", static_cast<int32_t>(result));
5230 return result;
5231 }
5232 for (uint32_t i = 0; i < rects.size(); i++) {
5233 TLOGD(WmsLogTag::WMS_EVENT, "id:%{public}u xywh:[%{public}d %{public}d %{public}u %{public}u]",
5234 i, rects[i].posX_, rects[i].posY_, rects[i].width_, rects[i].height_);
5235 }
5236 return result;
5237 }
5238
SetKeyboardTouchHotAreas(const KeyboardTouchHotAreas & hotAreas)5239 WMError WindowSceneSessionImpl::SetKeyboardTouchHotAreas(const KeyboardTouchHotAreas& hotAreas)
5240 {
5241 if (GetType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
5242 return WMError::WM_ERROR_INVALID_TYPE;
5243 }
5244 KeyboardTouchHotAreas lastKeyboardTouchHotAreas = property_->GetKeyboardTouchHotAreas();
5245 property_->SetKeyboardTouchHotAreas(hotAreas);
5246 WMError result = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_KEYBOARD_TOUCH_HOT_AREA);
5247 if (result != WMError::WM_OK) {
5248 property_->SetKeyboardTouchHotAreas(lastKeyboardTouchHotAreas);
5249 TLOGE(WmsLogTag::WMS_EVENT, "errCode:%{public}d", static_cast<int32_t>(result));
5250 }
5251 return result;
5252 }
5253
KeepKeyboardOnFocus(bool keepKeyboardFlag)5254 WmErrorCode WindowSceneSessionImpl::KeepKeyboardOnFocus(bool keepKeyboardFlag)
5255 {
5256 property_->KeepKeyboardOnFocus(keepKeyboardFlag);
5257 return WmErrorCode::WM_OK;
5258 }
5259
SetCallingWindow(uint32_t callingSessionId)5260 WMError WindowSceneSessionImpl::SetCallingWindow(uint32_t callingSessionId)
5261 {
5262 if (IsWindowSessionInvalid()) {
5263 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is invalid!");
5264 return WMError::WM_ERROR_INVALID_WINDOW;
5265 }
5266 if (callingSessionId != property_->GetCallingSessionId()) {
5267 TLOGI(WmsLogTag::WMS_KEYBOARD, "from %{public}d to: %{public}d",
5268 property_->GetCallingSessionId(), callingSessionId);
5269 }
5270 if (auto hostSession = GetHostSession()) {
5271 hostSession->SetCallingSessionId(callingSessionId);
5272 }
5273 property_->SetCallingSessionId(callingSessionId);
5274 return WMError::WM_OK;
5275 }
5276
ChangeKeyboardEffectOption(KeyboardEffectOption effectOption)5277 WMError WindowSceneSessionImpl::ChangeKeyboardEffectOption(KeyboardEffectOption effectOption)
5278 {
5279 TLOGI(WmsLogTag::WMS_KEYBOARD, "effect option: %{public}s",
5280 effectOption.ToString().c_str());
5281 if (effectOption.viewMode_ >= KeyboardViewMode::VIEW_MODE_END ||
5282 effectOption.flowLightMode_ >= KeyboardFlowLightMode::END ||
5283 effectOption.gradientMode_ >= KeyboardGradientMode::END) {
5284 TLOGE(WmsLogTag::WMS_KEYBOARD, "Invalid view or effect mode! effectOption: %{public}s",
5285 effectOption.ToString().c_str());
5286 return WMError::WM_ERROR_INVALID_PARAM;
5287 }
5288
5289 auto lastOption = property_->GetKeyboardEffectOption();
5290 if (effectOption == lastOption) {
5291 TLOGI(WmsLogTag::WMS_KEYBOARD, "Is same option: %{public}s", lastOption.ToString().c_str());
5292 return WMError::WM_DO_NOTHING;
5293 }
5294
5295 if (IsWindowSessionInvalid()) {
5296 TLOGE(WmsLogTag::WMS_KEYBOARD, "Session is invalid!");
5297 return WMError::WM_ERROR_INVALID_WINDOW;
5298 }
5299
5300 if (state_ != WindowState::STATE_SHOWN) {
5301 TLOGE(WmsLogTag::WMS_KEYBOARD, "The keyboard is not show status.");
5302 return WMError::WM_ERROR_INVALID_WINDOW;
5303 }
5304
5305 property_->SetKeyboardEffectOption(effectOption);
5306 auto hostSession = GetHostSession();
5307 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5308 return static_cast<WMError>(hostSession->ChangeKeyboardEffectOption(effectOption));
5309 }
5310
DumpSessionElementInfo(const std::vector<std::string> & params)5311 void WindowSceneSessionImpl::DumpSessionElementInfo(const std::vector<std::string>& params)
5312 {
5313 WLOGFD("in");
5314 std::vector<std::string> info;
5315 if (params.size() == 1 && params[0] == PARAM_DUMP_HELP) { // 1: params num
5316 WLOGFD("Dump ArkUI help Info");
5317 Ace::UIContent::ShowDumpHelp(info);
5318 SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
5319 return;
5320 }
5321
5322 WLOGFD("ArkUI:DumpInfo");
5323 if (auto uiContent = GetUIContentSharedPtr()) {
5324 uiContent->DumpInfo(params, info);
5325 }
5326
5327 for (auto iter = info.begin(); iter != info.end();) {
5328 if ((*iter).size() == 0) {
5329 iter = info.erase(iter);
5330 continue;
5331 }
5332 WLOGFD("ElementInfo size: %{public}u", static_cast<uint32_t>((*iter).size()));
5333 iter++;
5334 }
5335 if (info.size() == 0) {
5336 WLOGFD("ElementInfo is empty");
5337 return;
5338 }
5339 SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
5340 }
5341
NotifyLayoutFinishAfterWindowModeChange(WindowMode mode)5342 WSError WindowSceneSessionImpl::NotifyLayoutFinishAfterWindowModeChange(WindowMode mode)
5343 {
5344 NotifyWindowStatusDidChange(mode);
5345 return WSError::WS_OK;
5346 }
5347
UpdateWindowMode(WindowMode mode)5348 WSError WindowSceneSessionImpl::UpdateWindowMode(WindowMode mode)
5349 {
5350 WLOGFI("%{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
5351 if (IsWindowSessionInvalid()) {
5352 return WSError::WS_ERROR_INVALID_WINDOW;
5353 }
5354 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), mode)) {
5355 WLOGFE("%{public}u do not support mode: %{public}u",
5356 GetWindowId(), static_cast<uint32_t>(mode));
5357 return WSError::WS_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
5358 }
5359 WMError ret = UpdateWindowModeImmediately(mode);
5360
5361 if (windowSystemConfig_.IsPcWindow()) {
5362 if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
5363 ret = SetLayoutFullScreenByApiVersion(true);
5364 if (ret != WMError::WM_OK) {
5365 TLOGE(WmsLogTag::WMS_IMMS, "SetLayoutFullScreenByApiVersion errCode:%{public}d winId:%{public}u",
5366 static_cast<int32_t>(ret), GetWindowId());
5367 }
5368 SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
5369 statusProperty.enable_ = false;
5370 ret = SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
5371 if (ret != WMError::WM_OK) {
5372 WLOGFE("SetSystemBarProperty errCode:%{public}d winId:%{public}u",
5373 static_cast<int32_t>(ret), GetWindowId());
5374 }
5375 }
5376 }
5377 return static_cast<WSError>(ret);
5378 }
5379
GetTopNavDestinationName(std::string & topNavDestName)5380 WSError WindowSceneSessionImpl::GetTopNavDestinationName(std::string& topNavDestName)
5381 {
5382 auto uiContent = GetUIContentSharedPtr();
5383 if (uiContent == nullptr) {
5384 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "uiContent is null: winId=%{public}u", GetWindowId());
5385 return WSError::WS_DO_NOTHING;
5386 }
5387 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "call uicontent: winId=%{public}u", GetWindowId());
5388 std::string navDestInfoJsonStr = uiContent->GetTopNavDestinationInfo(false, false);
5389 if (navDestInfoJsonStr.empty()) {
5390 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, empty navDestInfoJsonStr", GetWindowId());
5391 return WSError::WS_OK;
5392 }
5393 nlohmann::json navDestInfoJson = nlohmann::json::parse(navDestInfoJsonStr, nullptr, false);
5394 if (navDestInfoJson.is_discarded()) {
5395 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "parse json error: winId=%{public}u, navDestInfoJsonStr=%{public}s",
5396 GetWindowId(), navDestInfoJsonStr.c_str());
5397 return WSError::WS_DO_NOTHING;
5398 }
5399 if (navDestInfoJson.contains("name")) {
5400 navDestInfoJson["name"].get_to(topNavDestName);
5401 }
5402 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, navDestInfoJsonStr=%{public}s, topNavDestName=%{public}s",
5403 GetWindowId(), navDestInfoJsonStr.c_str(), topNavDestName.c_str());
5404 return WSError::WS_OK;
5405 }
5406
UpdateWindowModeImmediately(WindowMode mode)5407 WMError WindowSceneSessionImpl::UpdateWindowModeImmediately(WindowMode mode)
5408 {
5409 if (state_ == WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
5410 property_->SetWindowMode(mode);
5411 UpdateTitleButtonVisibility();
5412 UpdateDecorEnable(true);
5413 } else if (state_ == WindowState::STATE_SHOWN) {
5414 // set client window mode if success.
5415 property_->SetWindowMode(mode);
5416 UpdateTitleButtonVisibility();
5417 UpdateDecorEnable(true, mode);
5418 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
5419 property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
5420 }
5421 }
5422 NotifyWindowStatusChange(mode);
5423 return WMError::WM_OK;
5424 }
5425
UpdateMaximizeMode(MaximizeMode mode)5426 WSError WindowSceneSessionImpl::UpdateMaximizeMode(MaximizeMode mode)
5427 {
5428 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "%{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
5429 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
5430 if (uiContent == nullptr) {
5431 TLOGE(WmsLogTag::WMS_LAYOUT_PC, "uiContent is null");
5432 return WSError::WS_ERROR_INVALID_PARAM;
5433 }
5434 uiContent->UpdateMaximizeMode(mode);
5435 property_->SetMaximizeMode(mode);
5436 if (mode == MaximizeMode::MODE_RECOVER && enableImmersiveMode_.load()) {
5437 enableImmersiveMode_.store(false);
5438 property_->SetIsLayoutFullScreen(false);
5439 if (auto hostSession = GetHostSession()) {
5440 hostSession->OnLayoutFullScreenChange(false);
5441 }
5442 }
5443 return WSError::WS_OK;
5444 }
5445
NotifySessionFullScreen(bool fullScreen)5446 void WindowSceneSessionImpl::NotifySessionFullScreen(bool fullScreen)
5447 {
5448 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "winId: %{public}u", GetWindowId());
5449 Maximize(fullScreen ? MaximizePresentation::ENTER_IMMERSIVE : MaximizePresentation::EXIT_IMMERSIVE);
5450 }
5451
UpdateTitleInTargetPos(bool isShow,int32_t height)5452 WSError WindowSceneSessionImpl::UpdateTitleInTargetPos(bool isShow, int32_t height)
5453 {
5454 TLOGI(WmsLogTag::WMS_DECOR, "%{public}u isShow %{public}u, height %{public}u", GetWindowId(), isShow, height);
5455 if (IsWindowSessionInvalid()) {
5456 return WSError::WS_ERROR_INVALID_WINDOW;
5457 }
5458 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
5459 if (uiContent == nullptr) {
5460 TLOGE(WmsLogTag::WMS_DECOR, "uiContent is null");
5461 return WSError::WS_ERROR_INVALID_PARAM;
5462 }
5463 uiContent->UpdateTitleInTargetPos(isShow, height);
5464 return WSError::WS_OK;
5465 }
5466
UpdateSupportWindowModesWhenSwitchFreeMultiWindow()5467 void WindowSceneSessionImpl::UpdateSupportWindowModesWhenSwitchFreeMultiWindow()
5468 {
5469 if (haveSetSupportedWindowModes_) {
5470 TLOGI(WmsLogTag::WMS_LAYOUT, "SupportedWindowMode is already set, id: %{public}d", GetPersistentId());
5471 return;
5472 }
5473 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
5474 if (abilityContext == nullptr) {
5475 TLOGE(WmsLogTag::WMS_LAYOUT, "abilityContext is nullptr");
5476 return;
5477 }
5478 auto abilityInfo = abilityContext->GetAbilityInfo();
5479 std::vector<AppExecFwk::SupportWindowMode> updateWindowModes =
5480 ExtractSupportWindowModeFromMetaData(abilityInfo);
5481 if (auto hostSession = GetHostSession()) {
5482 hostSession->NotifySupportWindowModesChange(updateWindowModes);
5483 };
5484 auto windowModeSupportType = WindowHelper::ConvertSupportModesToSupportType(updateWindowModes);
5485 property_->SetWindowModeSupportType(windowModeSupportType);
5486 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
5487 }
5488
SwitchFreeMultiWindow(bool enable)5489 WSError WindowSceneSessionImpl::SwitchFreeMultiWindow(bool enable)
5490 {
5491 if (IsWindowSessionInvalid()) {
5492 return WSError::WS_ERROR_INVALID_WINDOW;
5493 }
5494 if (windowSystemConfig_.freeMultiWindowEnable_ == enable) {
5495 UpdateSupportWindowModesWhenSwitchFreeMultiWindow();
5496 return WSError::WS_ERROR_REPEAT_OPERATION;
5497 }
5498 NotifySwitchFreeMultiWindow(enable);
5499 // Switch process finish, update system config
5500 SetFreeMultiWindowMode(enable);
5501 if (enable) {
5502 PendingUpdateSupportWindowModesWhenSwitchMultiWindow();
5503 }
5504 UpdateSupportWindowModesWhenSwitchFreeMultiWindow();
5505 UpdateEnableDragWhenSwitchMultiWindow(enable);
5506 if (!enable && !WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
5507 WindowMode::WINDOW_MODE_FULLSCREEN)) {
5508 UpdateDecorEnable(true);
5509 }
5510 auto mainWindow = FindMainWindowWithContext();
5511 bool isAnco = mainWindow != nullptr && mainWindow->IsAnco();
5512 if (WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(), WindowMode::WINDOW_MODE_FLOATING) &&
5513 !isAnco) {
5514 UpdateImmersiveBySwitchMode(enable);
5515 }
5516 SwitchSubWindow(enable, GetPersistentId());
5517 return WSError::WS_OK;
5518 }
5519
PendingUpdateSupportWindowModesWhenSwitchMultiWindow()5520 void WindowSceneSessionImpl::PendingUpdateSupportWindowModesWhenSwitchMultiWindow()
5521 {
5522 if (pendingWindowModeSupportType_ == WindowModeSupport::WINDOW_MODE_SUPPORT_ALL) {
5523 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "pending data has not set, id: %{public}d", GetPersistentId());
5524 return;
5525 }
5526
5527 uint32_t windowModeSupportType = pendingWindowModeSupportType_;
5528 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "id: %{public}d, windowModeSupportType: %{public}u",
5529 GetPersistentId(), windowModeSupportType);
5530
5531 pendingWindowModeSupportType_ = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
5532 property_->SetWindowModeSupportType(windowModeSupportType);
5533
5534 // update windowModeSupportType to server
5535 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE_SUPPORT_INFO);
5536 UpdateTitleButtonVisibility();
5537 haveSetSupportedWindowModes_ = true;
5538
5539 // update window mode immediately when pending window support type take effect
5540 bool onlySupportFullScreen =
5541 WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FULLSCREEN) &&
5542 !WindowHelper::IsWindowModeSupported(windowModeSupportType, WindowMode::WINDOW_MODE_FLOATING);
5543 bool disableFullScreen = property_->IsFullScreenDisabled();
5544 if (onlySupportFullScreen && !disableFullScreen) {
5545 TLOGI(WmsLogTag::WMS_LAYOUT_PC, "only support fullscreen, enter immersive");
5546 Maximize(MaximizePresentation::ENTER_IMMERSIVE);
5547 }
5548 }
5549
UpdateImmersiveBySwitchMode(bool freeMultiWindowEnable)5550 void WindowSceneSessionImpl::UpdateImmersiveBySwitchMode(bool freeMultiWindowEnable)
5551 {
5552 if (freeMultiWindowEnable && enableImmersiveMode_) {
5553 cacheEnableImmersiveMode_.store(true);
5554 enableImmersiveMode_.store(false);
5555 property_->SetIsLayoutFullScreen(enableImmersiveMode_);
5556 if (auto hostSession = GetHostSession()) {
5557 hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
5558 } else {
5559 TLOGE(WmsLogTag::WMS_LAYOUT, "host session is nullptr, id: %{public}d", GetPersistentId());
5560 }
5561 }
5562 if (!freeMultiWindowEnable && cacheEnableImmersiveMode_) {
5563 enableImmersiveMode_.store(true);
5564 cacheEnableImmersiveMode_.store(false);
5565 property_->SetIsLayoutFullScreen(enableImmersiveMode_);
5566 if (auto hostSession = GetHostSession()) {
5567 hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
5568 } else {
5569 TLOGE(WmsLogTag::WMS_LAYOUT, "host session is nullptr, id: %{public}d", GetPersistentId());
5570 }
5571 }
5572 }
5573
GetFreeMultiWindowModeEnabledState()5574 bool WindowSceneSessionImpl::GetFreeMultiWindowModeEnabledState()
5575 {
5576 return windowSystemConfig_.freeMultiWindowEnable_ &&
5577 windowSystemConfig_.freeMultiWindowSupport_;
5578 }
5579
PcAppInPadNormalClose()5580 WSError WindowSceneSessionImpl::PcAppInPadNormalClose()
5581 {
5582 if (IsWindowSessionInvalid()) {
5583 TLOGE(WmsLogTag::WMS_COMPAT, "window session invalid!");
5584 return WSError::WS_ERROR_INVALID_WINDOW;
5585 }
5586 if (!property_->GetIsPcAppInPad()) {
5587 TLOGE(WmsLogTag::WMS_COMPAT, "is not pcAppInPad, can not Close");
5588 return WSError::WS_ERROR_INVALID_WINDOW;
5589 }
5590 Close();
5591 return WSError::WS_OK;
5592 }
5593
NotifyCompatibleModePropertyChange(const sptr<CompatibleModeProperty> property)5594 WSError WindowSceneSessionImpl::NotifyCompatibleModePropertyChange(const sptr<CompatibleModeProperty> property)
5595 {
5596 if (IsWindowSessionInvalid()) {
5597 TLOGE(WmsLogTag::WMS_COMPAT, "window session invalid!");
5598 return WSError::WS_ERROR_INVALID_WINDOW;
5599 }
5600 property_->SetCompatibleModeProperty(property);
5601 return WSError::WS_OK;
5602 }
5603
NotifySessionForeground(uint32_t reason,bool withAnimation)5604 void WindowSceneSessionImpl::NotifySessionForeground(uint32_t reason, bool withAnimation)
5605 {
5606 TLOGI(WmsLogTag::WMS_LIFE, "in");
5607 if (!handler_) {
5608 TLOGE(WmsLogTag::WMS_LIFE, "handler is nullptr");
5609 return;
5610 }
5611 handler_->PostTask([weakThis = wptr(this), reason, withAnimation] {
5612 auto window = weakThis.promote();
5613 if (!window) {
5614 TLOGNE(WmsLogTag::WMS_LIFE, "window is nullptr");
5615 return;
5616 }
5617 window->Show(reason, withAnimation);
5618 }, __func__);
5619 }
5620
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)5621 void WindowSceneSessionImpl::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
5622 {
5623 TLOGI(WmsLogTag::WMS_LIFE, "in");
5624 if (!handler_) {
5625 TLOGE(WmsLogTag::WMS_LIFE, "handler is nullptr");
5626 return;
5627 }
5628 handler_->PostTask([weakThis = wptr(this), reason, withAnimation, isFromInnerkits] {
5629 auto window = weakThis.promote();
5630 if (!window) {
5631 TLOGNE(WmsLogTag::WMS_LIFE, "window is nullptr");
5632 return;
5633 }
5634 window->Hide(reason, withAnimation, isFromInnerkits);
5635 }, __func__);
5636 }
5637
NotifyPrepareClosePiPWindow()5638 WMError WindowSceneSessionImpl::NotifyPrepareClosePiPWindow()
5639 {
5640 TLOGI(WmsLogTag::WMS_PIP, "type: %{public}u", GetType());
5641 if (!WindowHelper::IsPipWindow(GetType())) {
5642 return WMError::WM_DO_NOTHING;
5643 }
5644 auto hostSession = GetHostSession();
5645 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5646 hostSession->NotifyPiPWindowPrepareClose();
5647 return WMError::WM_OK;
5648 }
5649
GetWindowLimits(WindowLimits & windowLimits)5650 WMError WindowSceneSessionImpl::GetWindowLimits(WindowLimits& windowLimits)
5651 {
5652 if (IsWindowSessionInvalid()) {
5653 WLOGFE("session is invalid");
5654 return WMError::WM_ERROR_INVALID_WINDOW;
5655 }
5656 const auto& customizedLimits = property_->GetWindowLimits();
5657 windowLimits.minWidth_ = customizedLimits.minWidth_;
5658 windowLimits.minHeight_ = customizedLimits.minHeight_;
5659 windowLimits.maxWidth_ = customizedLimits.maxWidth_;
5660 windowLimits.maxHeight_ = customizedLimits.maxHeight_;
5661 windowLimits.vpRatio_ = customizedLimits.vpRatio_;
5662 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
5663 "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", GetWindowId(), windowLimits.minWidth_,
5664 windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
5665 return WMError::WM_OK;
5666 }
5667
UpdateNewSize()5668 void WindowSceneSessionImpl::UpdateNewSize()
5669 {
5670 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING || property_->IsWindowLimitDisabled()) {
5671 TLOGI(WmsLogTag::WMS_LAYOUT, "Fullscreen couldnot update new size, Id: %{public}u", GetWindowId());
5672 return;
5673 }
5674 bool needResize = false;
5675 Rect windowRect = GetRequestRect();
5676 if (windowRect.IsUninitializedSize()) {
5677 windowRect = GetRect();
5678 if (windowRect.IsUninitializedSize()) {
5679 TLOGW(WmsLogTag::WMS_LAYOUT, "The sizes of requestRect and rect are uninitialized. winId: %{public}u",
5680 GetWindowId());
5681 return;
5682 }
5683 }
5684
5685 uint32_t width = windowRect.width_;
5686 uint32_t height = windowRect.height_;
5687 const auto& newLimits = property_->GetWindowLimits();
5688 if (width < newLimits.minWidth_) {
5689 width = newLimits.minWidth_;
5690 needResize = true;
5691 }
5692 if (height < newLimits.minHeight_) {
5693 height = newLimits.minHeight_;
5694 needResize = true;
5695 }
5696 if (width > newLimits.maxWidth_) {
5697 width = newLimits.maxWidth_;
5698 needResize = true;
5699 }
5700 if (height > newLimits.maxHeight_) {
5701 height = newLimits.maxHeight_;
5702 needResize = true;
5703 }
5704 if (needResize) {
5705 if (IsPcOrPadFreeMultiWindowMode()) {
5706 isResizedByLimit_ = true;
5707 }
5708 Resize(width, height);
5709 TLOGI(WmsLogTag::WMS_LAYOUT, "Resize window by limits. Id: %{public}u, width: %{public}u,"
5710 " height: %{public}u", GetWindowId(), width, height);
5711 }
5712 }
5713
SetWindowLimits(WindowLimits & windowLimits,bool isForcible)5714 WMError WindowSceneSessionImpl::SetWindowLimits(WindowLimits& windowLimits, bool isForcible)
5715 {
5716 TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
5717 "maxWidth:%{public}u, maxHeight:%{public}u, isForcible:%{public}u", GetWindowId(), windowLimits.minWidth_,
5718 windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, isForcible);
5719 if (IsWindowSessionInvalid()) {
5720 TLOGE(WmsLogTag::WMS_LAYOUT, "session is invalid");
5721 return WMError::WM_ERROR_INVALID_WINDOW;
5722 }
5723
5724 WindowType windowType = GetType();
5725 bool isDraggableSystemWin = WindowHelper::IsSystemWindow(windowType) && IsWindowDraggable();
5726 if (!WindowHelper::IsMainWindow(windowType) && !WindowHelper::IsSubWindow(windowType) &&
5727 windowType != WindowType::WINDOW_TYPE_DIALOG && !isDraggableSystemWin) {
5728 TLOGE(WmsLogTag::WMS_LAYOUT, "type not support. Id:%{public}u, type:%{public}u",
5729 GetWindowId(), static_cast<uint32_t>(windowType));
5730 return WMError::WM_ERROR_INVALID_CALLING;
5731 }
5732
5733 const auto& customizedLimits = property_->GetWindowLimits();
5734 uint32_t minWidth = windowLimits.minWidth_ ? windowLimits.minWidth_ : customizedLimits.minWidth_;
5735 uint32_t minHeight = windowLimits.minHeight_ ? windowLimits.minHeight_ : customizedLimits.minHeight_;
5736 uint32_t maxWidth = windowLimits.maxWidth_ ? windowLimits.maxWidth_ : customizedLimits.maxWidth_;
5737 uint32_t maxHeight = windowLimits.maxHeight_ ? windowLimits.maxHeight_ : customizedLimits.maxHeight_;
5738
5739 property_->SetUserWindowLimits({
5740 maxWidth, maxHeight, minWidth, minHeight, customizedLimits.maxRatio_, customizedLimits.minRatio_
5741 });
5742 forceLimits_ = isForcible;
5743 userLimitsSet_ = true;
5744 UpdateWindowSizeLimits();
5745 WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
5746 if (ret != WMError::WM_OK) {
5747 TLOGE(WmsLogTag::WMS_LAYOUT, "update window proeprty failed! id: %{public}u.", GetWindowId());
5748 return ret;
5749 }
5750 UpdateNewSize();
5751
5752 fillWindowLimits(windowLimits);
5753 return WMError::WM_OK;
5754 }
5755
fillWindowLimits(WindowLimits & windowLimits)5756 void WindowSceneSessionImpl::fillWindowLimits(WindowLimits& windowLimits)
5757 {
5758 const auto& newLimits = property_->GetWindowLimits();
5759 windowLimits.minWidth_ = newLimits.minWidth_;
5760 windowLimits.minHeight_ = newLimits.minHeight_;
5761 windowLimits.maxWidth_ = newLimits.maxWidth_;
5762 windowLimits.maxHeight_ = newLimits.maxHeight_;
5763 WLOGFI("success! Id:%{public}u, minWidth:%{public}u, minHeight:%{public}u, "
5764 "maxWidth:%{public}u, maxHeight:%{public}u", GetWindowId(), windowLimits.minWidth_,
5765 windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_);
5766 }
5767
NotifyDialogStateChange(bool isForeground)5768 WSError WindowSceneSessionImpl::NotifyDialogStateChange(bool isForeground)
5769 {
5770 const auto type = GetType();
5771 TLOGI(WmsLogTag::WMS_DIALOG, "state change [name:%{public}s, id:%{public}d, type:%{public}u], state:%{public}u,"
5772 " requestState:%{public}u, isForeground:%{public}d", property_->GetWindowName().c_str(), GetPersistentId(),
5773 type, state_, requestState_, static_cast<int32_t>(isForeground));
5774 if (IsWindowSessionInvalid()) {
5775 TLOGE(WmsLogTag::WMS_DIALOG, "session is invalid, id:%{public}d", GetPersistentId());
5776 return WSError::WS_ERROR_INVALID_WINDOW;
5777 }
5778
5779 if (isForeground) {
5780 if (state_ == WindowState::STATE_SHOWN) {
5781 return WSError::WS_OK;
5782 }
5783 if (state_ == WindowState::STATE_HIDDEN && requestState_ == WindowState::STATE_SHOWN) {
5784 state_ = WindowState::STATE_SHOWN;
5785 NotifyAfterForeground();
5786 }
5787 } else {
5788 if (state_ == WindowState::STATE_HIDDEN) {
5789 return WSError::WS_OK;
5790 }
5791 if (state_ == WindowState::STATE_SHOWN) {
5792 state_ = WindowState::STATE_HIDDEN;
5793 NotifyAfterBackground();
5794 }
5795 }
5796 TLOGI(WmsLogTag::WMS_DIALOG, "success [name:%{public}s, id:%{public}d, type:%{public}u],"
5797 " state:%{public}u, requestState:%{public}u", property_->GetWindowName().c_str(), property_->GetPersistentId(),
5798 type, state_, requestState_);
5799 return WSError::WS_OK;
5800 }
5801
SetDefaultDensityEnabled(bool enabled)5802 WMError WindowSceneSessionImpl::SetDefaultDensityEnabled(bool enabled)
5803 {
5804 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Id=%{public}d, enabled=%{public}d", GetWindowId(), enabled);
5805 if (IsWindowSessionInvalid()) {
5806 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "window is invalid");
5807 return WMError::WM_ERROR_INVALID_WINDOW;
5808 }
5809
5810 if (!WindowHelper::IsMainWindow(GetType())) {
5811 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "must be app main window");
5812 return WMError::WM_ERROR_INVALID_CALLING;
5813 }
5814
5815 if (defaultDensityEnabledGlobalConfig_ == enabled) {
5816 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "defaultDensityEnabledGlobalConfig not change");
5817 return WMError::WM_OK;
5818 }
5819
5820 if (auto hostSession = GetHostSession()) {
5821 hostSession->OnDefaultDensityEnabled(enabled);
5822 }
5823
5824 defaultDensityEnabledGlobalConfig_ = enabled;
5825 SetDefaultDensityEnabledValue(enabled);
5826
5827 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
5828 for (const auto& winPair : windowSessionMap_) {
5829 auto window = winPair.second.second;
5830 if (window == nullptr) {
5831 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "window is nullptr");
5832 continue;
5833 }
5834 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Id=%{public}d UpdateDensity", window->GetWindowId());
5835 window->SetDefaultDensityEnabledValue(enabled);
5836 window->UpdateDensity();
5837 }
5838 return WMError::WM_OK;
5839 }
5840
GetDefaultDensityEnabled()5841 bool WindowSceneSessionImpl::GetDefaultDensityEnabled()
5842 {
5843 return isDefaultDensityEnabled_.load();
5844 }
5845
GetVirtualPixelRatio(const sptr<DisplayInfo> & displayInfo)5846 float WindowSceneSessionImpl::GetVirtualPixelRatio(const sptr<DisplayInfo>& displayInfo)
5847 {
5848 if (displayInfo == nullptr) {
5849 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "displayInfo is nullptr");
5850 return INVALID_DEFAULT_DENSITY;
5851 }
5852 if (IsDefaultDensityEnabled()) {
5853 return displayInfo->GetDefaultVirtualPixelRatio();
5854 }
5855 if (useUniqueDensity_) {
5856 return virtualPixelRatio_;
5857 }
5858 auto vpr = GetMainWindowCustomDensity();
5859 return vpr >= MINIMUM_CUSTOM_DENSITY && vpr <= MAXIMUM_CUSTOM_DENSITY ? vpr : displayInfo->GetVirtualPixelRatio();
5860 }
5861
HideNonSecureWindows(bool shouldHide)5862 WMError WindowSceneSessionImpl::HideNonSecureWindows(bool shouldHide)
5863 {
5864 return SingletonContainer::Get<WindowAdapter>().AddOrRemoveSecureSession(property_->GetPersistentId(), shouldHide);
5865 }
5866
SetTextFieldAvoidInfo(double textFieldPositionY,double textFieldHeight)5867 WMError WindowSceneSessionImpl::SetTextFieldAvoidInfo(double textFieldPositionY, double textFieldHeight)
5868 {
5869 TLOGI(WmsLogTag::WMS_KEYBOARD, "textFieldPositionY: %{public}f, textFieldHeight:%{public}f",
5870 textFieldPositionY, textFieldHeight);
5871 property_->SetTextFieldPositionY(textFieldPositionY);
5872 property_->SetTextFieldHeight(textFieldHeight);
5873 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO);
5874 return WMError::WM_OK;
5875 }
5876
HandleWindowMask(const std::vector<std::vector<uint32_t>> & windowMask)5877 std::unique_ptr<Media::PixelMap> WindowSceneSessionImpl::HandleWindowMask(
5878 const std::vector<std::vector<uint32_t>>& windowMask)
5879 {
5880 const Rect& windowRect = GetRequestRect();
5881 uint32_t maskHeight = windowMask.size();
5882 if (maskHeight == 0) {
5883 WLOGFE("WindowMask is invalid");
5884 return nullptr;
5885 }
5886 uint32_t maskWidth = windowMask[0].size();
5887 if ((windowRect.height_ > 0 && windowRect.height_ != maskHeight) ||
5888 (windowRect.width_ > 0 && windowRect.width_ != maskWidth)) {
5889 WLOGFE("WindowMask is invalid");
5890 return nullptr;
5891 }
5892 constexpr uint32_t bgraChannel = 4;
5893 Media::InitializationOptions opts;
5894 opts.size.width = static_cast<int32_t>(maskWidth);
5895 opts.size.height = static_cast<int32_t>(maskHeight);
5896 uint32_t length = maskWidth * maskHeight * bgraChannel;
5897 uint8_t* data = static_cast<uint8_t*>(malloc(length));
5898 if (data == nullptr) {
5899 WLOGFE("data is nullptr");
5900 return nullptr;
5901 }
5902 constexpr uint32_t fullChannel = 255;
5903 constexpr uint32_t greenChannel = 1;
5904 constexpr uint32_t redChannel = 2;
5905 constexpr uint32_t alphaChannel = 3;
5906 for (uint32_t i = 0; i < maskHeight; i++) {
5907 for (uint32_t j = 0; j < maskWidth; j++) {
5908 uint32_t idx = i * maskWidth + j;
5909 uint32_t channel = windowMask[i][j] > 0 ? fullChannel : 0;
5910 uint32_t channelIndex = idx * bgraChannel;
5911 data[channelIndex] = channel; // blue channel
5912 data[channelIndex + greenChannel] = channel; // green channel
5913 data[channelIndex + redChannel] = fullChannel; // red channel
5914 data[channelIndex + alphaChannel] = channel; // alpha channel
5915 }
5916 }
5917 std::unique_ptr<Media::PixelMap> mask = Media::PixelMap::Create(reinterpret_cast<uint32_t*>(data), length, opts);
5918 free(data);
5919 return mask;
5920 }
5921
SetWindowMask(const std::vector<std::vector<uint32_t>> & windowMask)5922 WMError WindowSceneSessionImpl::SetWindowMask(const std::vector<std::vector<uint32_t>>& windowMask)
5923 {
5924 TLOGI(WmsLogTag::WMS_PC, "WindowId: %{public}u", GetWindowId());
5925 if (IsWindowSessionInvalid()) {
5926 WLOGFE("session is invalid");
5927 return WMError::WM_ERROR_INVALID_WINDOW;
5928 }
5929
5930 std::shared_ptr<Media::PixelMap> mask = HandleWindowMask(windowMask);
5931 if (mask == nullptr) {
5932 TLOGE(WmsLogTag::WMS_PC, "Failed to create pixelMap of window mask");
5933 return WMError::WM_ERROR_INVALID_WINDOW;
5934 }
5935
5936 auto rsMask = RSMask::CreatePixelMapMask(mask);
5937 surfaceNode_->SetCornerRadius(0.0f);
5938 surfaceNode_->SetShadowRadius(0.0f);
5939 surfaceNode_->SetAbilityBGAlpha(0);
5940 surfaceNode_->SetMask(rsMask); // RS interface to set mask
5941 RSTransactionAdapter::FlushImplicitTransaction(surfaceNode_);
5942
5943 property_->SetWindowMask(mask);
5944 property_->SetIsShaped(true);
5945 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK);
5946 }
5947
SetFollowParentMultiScreenPolicy(bool enabled)5948 WMError WindowSceneSessionImpl::SetFollowParentMultiScreenPolicy(bool enabled)
5949 {
5950 if (IsWindowSessionInvalid()) {
5951 return WMError::WM_ERROR_INVALID_WINDOW;
5952 }
5953 if (IsPadAndNotFreeMutiWindowCompatibleMode()) {
5954 TLOGE(WmsLogTag::WMS_SUB, "This is PcAppInpad, not Suppored");
5955 return WMError::WM_OK;
5956 }
5957 if (!IsPcOrPadFreeMultiWindowMode()) {
5958 TLOGE(WmsLogTag::WMS_SUB, "device not support");
5959 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
5960 }
5961 if (!WindowHelper::IsSubWindow(GetType())) {
5962 TLOGE(WmsLogTag::WMS_SUB, "called by invalid window type, type:%{public}d", GetType());
5963 return WMError::WM_ERROR_INVALID_CALLING;
5964 }
5965 auto hostSession = GetHostSession();
5966 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5967 hostSession->NotifyFollowParentMultiScreenPolicy(enabled);
5968 property_->EditSessionInfo().isFollowParentMultiScreenPolicy = enabled;
5969 return WMError::WM_OK;
5970 }
5971
UseImplicitAnimation(bool useImplicit)5972 WMError WindowSceneSessionImpl::UseImplicitAnimation(bool useImplicit)
5973 {
5974 TLOGI(WmsLogTag::WMS_PC, "WindowId: %{public}u", GetWindowId());
5975 if (IsWindowSessionInvalid()) {
5976 TLOGE(WmsLogTag::WMS_PC, "session is invalid");
5977 return WMError::WM_ERROR_INVALID_WINDOW;
5978 }
5979 auto hostSession = GetHostSession();
5980 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
5981 return static_cast<WMError>(hostSession->UseImplicitAnimation(useImplicit));
5982 }
5983
UpdateDensity()5984 void WindowSceneSessionImpl::UpdateDensity()
5985 {
5986 UpdateDensityInner(nullptr);
5987 }
5988
UpdateDensityInner(const sptr<DisplayInfo> & info)5989 void WindowSceneSessionImpl::UpdateDensityInner(const sptr<DisplayInfo>& info)
5990 {
5991 if (!userLimitsSet_) {
5992 UpdateWindowSizeLimits();
5993 UpdateNewSize();
5994 WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
5995 if (ret != WMError::WM_OK) {
5996 WLOGFE("update window proeprty failed! id: %{public}u.", GetWindowId());
5997 return;
5998 }
5999 }
6000
6001 NotifyDisplayInfoChange(info);
6002
6003 auto preRect = GetRect();
6004 UpdateViewportConfig(preRect, WindowSizeChangeReason::UNDEFINED, nullptr, info);
6005 TLOGD(WmsLogTag::DEFAULT, "[%{public}d, %{public}d, %{public}u, %{public}u]",
6006 preRect.posX_, preRect.posY_, preRect.width_, preRect.height_);
6007 }
6008
RegisterKeyboardPanelInfoChangeListener(const sptr<IKeyboardPanelInfoChangeListener> & listener)6009 WMError WindowSceneSessionImpl::RegisterKeyboardPanelInfoChangeListener(
6010 const sptr<IKeyboardPanelInfoChangeListener>& listener)
6011 {
6012 std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
6013 if (keyboardPanelInfoChangeListeners_ == nullptr) {
6014 TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d",
6015 GetPersistentId());
6016 keyboardPanelInfoChangeListeners_ = listener;
6017 } else {
6018 TLOGE(WmsLogTag::WMS_KEYBOARD, "listener already registered");
6019 return WMError::WM_ERROR_INVALID_OPERATION;
6020 }
6021
6022 return WMError::WM_OK;
6023 }
6024
RegisterWindowAttachStateChangeListener(const sptr<IWindowAttachStateChangeListner> & listener)6025 WMError WindowSceneSessionImpl::RegisterWindowAttachStateChangeListener(
6026 const sptr<IWindowAttachStateChangeListner>& listener)
6027 {
6028 if (listener == nullptr) {
6029 TLOGE(WmsLogTag::WMS_SUB, "id: %{public}d, listener is null", GetPersistentId());
6030 return WMError::WM_ERROR_NULLPTR;
6031 }
6032 {
6033 std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
6034 windowAttachStateChangeListener_ = listener;
6035 }
6036 TLOGD(WmsLogTag::WMS_SUB, "id: %{public}d listener registered", GetPersistentId());
6037 auto hostSession = GetHostSession();
6038 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6039 hostSession->NotifyWindowAttachStateListenerRegistered(true);
6040 return WMError::WM_OK;
6041 }
6042
UnregisterWindowAttachStateChangeListener()6043 WMError WindowSceneSessionImpl::UnregisterWindowAttachStateChangeListener()
6044 {
6045 {
6046 std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
6047 windowAttachStateChangeListener_ = nullptr;
6048 }
6049 TLOGD(WmsLogTag::WMS_SUB, "id: %{public}d listener unregistered", GetPersistentId());
6050 auto hostSession = GetHostSession();
6051 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6052 hostSession->NotifyWindowAttachStateListenerRegistered(false);
6053 return WMError::WM_OK;
6054 }
6055
NotifyWindowAttachStateChange(bool isAttach)6056 WSError WindowSceneSessionImpl::NotifyWindowAttachStateChange(bool isAttach)
6057 {
6058 TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", GetPersistentId());
6059 if (lifecycleCallback_) {
6060 TLOGI(WmsLogTag::WMS_SUB, "notifyAttachState id: %{public}d", GetPersistentId());
6061 lifecycleCallback_->OnNotifyAttachState(isAttach);
6062 }
6063 std::lock_guard<std::mutex> lockListener(windowAttachStateChangeListenerMutex_);
6064 if (!windowAttachStateChangeListener_) {
6065 TLOGW(WmsLogTag::WMS_SUB, "listener is null");
6066 return WSError::WS_ERROR_NULLPTR;
6067 }
6068 if (isAttach) {
6069 windowAttachStateChangeListener_->AfterAttached();
6070 } else {
6071 windowAttachStateChangeListener_->AfterDetached();
6072 }
6073 return WSError::WS_OK;
6074 }
6075
UnregisterKeyboardPanelInfoChangeListener(const sptr<IKeyboardPanelInfoChangeListener> & listener)6076 WMError WindowSceneSessionImpl::UnregisterKeyboardPanelInfoChangeListener(
6077 const sptr<IKeyboardPanelInfoChangeListener>& listener)
6078 {
6079 std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
6080 keyboardPanelInfoChangeListeners_ = nullptr;
6081 TLOGI(WmsLogTag::WMS_KEYBOARD, "id: %{public}d", GetPersistentId());
6082
6083 return WMError::WM_OK;
6084 }
6085
NotifyKeyboardPanelInfoChange(const KeyboardPanelInfo & keyboardPanelInfo)6086 void WindowSceneSessionImpl::NotifyKeyboardPanelInfoChange(const KeyboardPanelInfo& keyboardPanelInfo)
6087 {
6088 TLOGI(WmsLogTag::WMS_KEYBOARD, "isShown: %{public}d, gravity: %{public}d"
6089 ", rect_: [%{public}d, %{public}d, %{public}d, %{public}d]", keyboardPanelInfo.isShowing_,
6090 keyboardPanelInfo.gravity_, keyboardPanelInfo.rect_.posX_, keyboardPanelInfo.rect_.posY_,
6091 keyboardPanelInfo.rect_.width_, keyboardPanelInfo.rect_.height_);
6092 std::lock_guard<std::mutex> lockListener(keyboardPanelInfoChangeListenerMutex_);
6093 if (keyboardPanelInfoChangeListeners_ && keyboardPanelInfoChangeListeners_.GetRefPtr()) {
6094 keyboardPanelInfoChangeListeners_.GetRefPtr()->OnKeyboardPanelInfoChanged(keyboardPanelInfo);
6095 } else {
6096 TLOGI(WmsLogTag::WMS_KEYBOARD, "listener is unRegistered");
6097 }
6098 }
6099
UpdateDisplayId(DisplayId displayId)6100 WSError WindowSceneSessionImpl::UpdateDisplayId(DisplayId displayId)
6101 {
6102 bool displayIdChanged = property_->GetDisplayId() != displayId;
6103 property_->SetDisplayId(displayId);
6104 NotifyDisplayInfoChange();
6105 if (displayIdChanged) {
6106 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, displayId: %{public}" PRIu64, GetPersistentId(), displayId);
6107 NotifyDisplayIdChange(displayId);
6108 }
6109 return WSError::WS_OK;
6110 }
6111
UpdateOrientation()6112 WSError WindowSceneSessionImpl::UpdateOrientation()
6113 {
6114 TLOGD(WmsLogTag::DMS, "id: %{public}d", GetPersistentId());
6115 NotifyDisplayInfoChange();
6116 return WSError::WS_OK;
6117 }
6118
NotifyDisplayInfoChange(const sptr<DisplayInfo> & info)6119 void WindowSceneSessionImpl::NotifyDisplayInfoChange(const sptr<DisplayInfo>& info)
6120 {
6121 TLOGD(WmsLogTag::DMS, "id: %{public}d", GetPersistentId());
6122 sptr<DisplayInfo> displayInfo = nullptr;
6123 DisplayId displayId = 0;
6124 if (info == nullptr) {
6125 displayId = property_->GetDisplayId();
6126 auto display = SingletonContainer::IsDestroyed() ? nullptr :
6127 SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
6128 if (display == nullptr) {
6129 TLOGE(WmsLogTag::DMS, "get display by displayId %{public}" PRIu64 " failed.", displayId);
6130 return;
6131 }
6132 displayInfo = display->GetDisplayInfo();
6133 } else {
6134 displayInfo = info;
6135 }
6136 if (displayInfo == nullptr) {
6137 TLOGE(WmsLogTag::DMS, "get display info %{public}" PRIu64 " failed.", displayId);
6138 return;
6139 }
6140 if (IsSystemDensityChanged(displayInfo)) {
6141 lastSystemDensity_ = displayInfo->GetVirtualPixelRatio();
6142 NotifySystemDensityChange(displayInfo->GetVirtualPixelRatio());
6143 }
6144 float density = GetVirtualPixelRatio(displayInfo);
6145 DisplayOrientation orientation = displayInfo->GetDisplayOrientation();
6146
6147 // skip scb process
6148 auto context = GetContext();
6149 if (context == nullptr || context->GetBundleName() == AppExecFwk::Constants::SCENE_BOARD_BUNDLE_NAME) {
6150 TLOGE(WmsLogTag::DMS, "id:%{public}d failed, context is null.", GetPersistentId());
6151 return;
6152 }
6153 auto token = context->GetToken();
6154 if (token == nullptr) {
6155 TLOGE(WmsLogTag::DMS, "get token window:%{public}d failed.", GetPersistentId());
6156 return;
6157 }
6158 SingletonContainer::Get<WindowManager>().NotifyDisplayInfoChange(token, displayId, density, orientation);
6159 }
6160
MoveAndResizeKeyboard(const KeyboardLayoutParams & params)6161 WMError WindowSceneSessionImpl::MoveAndResizeKeyboard(const KeyboardLayoutParams& params)
6162 {
6163 int32_t displayWidth = 0;
6164 int32_t displayHeight = 0;
6165 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
6166 if (display != nullptr) {
6167 displayWidth = display->GetWidth();
6168 displayHeight = display->GetHeight();
6169 } else {
6170 auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
6171 if (defaultDisplayInfo != nullptr) {
6172 displayWidth = defaultDisplayInfo->GetWidth();
6173 displayHeight = defaultDisplayInfo->GetHeight();
6174 } else {
6175 TLOGE(WmsLogTag::WMS_KEYBOARD, "display is null, name: %{public}s, id: %{public}d",
6176 property_->GetWindowName().c_str(), GetPersistentId());
6177 return WMError::WM_ERROR_NULLPTR;
6178 }
6179 }
6180 bool isLandscape = displayWidth > displayHeight ? true : false;
6181 Rect newRect = isLandscape ? params.LandscapeKeyboardRect_ : params.PortraitKeyboardRect_;
6182 property_->SetRequestRect(newRect);
6183 TLOGI(WmsLogTag::WMS_KEYBOARD, "Id: %{public}d, newRect: %{public}s, isLandscape: %{public}d, "
6184 "displayWidth: %{public}d, displayHeight: %{public}d", GetPersistentId(), newRect.ToString().c_str(),
6185 isLandscape, displayWidth, displayHeight);
6186 return WMError::WM_OK;
6187 }
6188
AdjustKeyboardLayout(const KeyboardLayoutParams params)6189 WMError WindowSceneSessionImpl::AdjustKeyboardLayout(const KeyboardLayoutParams params)
6190 {
6191 property_->SetKeyboardLayoutParams(params);
6192 auto ret = MoveAndResizeKeyboard(params);
6193 if (ret != WMError::WM_OK) {
6194 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboard move and resize failed");
6195 return ret;
6196 }
6197 if (auto hostSession = GetHostSession()) {
6198 return static_cast<WMError>(hostSession->AdjustKeyboardLayout(params));
6199 }
6200 return WMError::WM_OK;
6201 }
6202
SetImmersiveModeEnabledState(bool enable)6203 WMError WindowSceneSessionImpl::SetImmersiveModeEnabledState(bool enable)
6204 {
6205 TLOGD(WmsLogTag::WMS_IMMS, "id: %{public}u, enable: %{public}u", GetWindowId(), enable);
6206 if (IsWindowSessionInvalid()) {
6207 return WMError::WM_ERROR_INVALID_WINDOW;
6208 }
6209 auto hostSession = GetHostSession();
6210 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6211 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
6212 WindowMode::WINDOW_MODE_FULLSCREEN)) {
6213 return WMError::WM_ERROR_INVALID_WINDOW;
6214 }
6215 const WindowType curWindowType = GetType();
6216 if (!WindowHelper::IsMainWindow(curWindowType) && !WindowHelper::IsSubWindow(curWindowType)) {
6217 return WMError::WM_ERROR_INVALID_WINDOW;
6218 }
6219
6220 enableImmersiveMode_ = enable;
6221 hostSession->OnLayoutFullScreenChange(enableImmersiveMode_);
6222 AAFwk::Want want;
6223 want.SetParam(Extension::IMMERSIVE_MODE_ENABLED, enable);
6224 if (auto uiContent = GetUIContentSharedPtr()) {
6225 uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_IMMERSIVE_MODE_ENABLED),
6226 want, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
6227 }
6228 WindowMode mode = GetWindowMode();
6229 if (!windowSystemConfig_.IsPcWindow() || mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
6230 return SetLayoutFullScreen(enableImmersiveMode_);
6231 }
6232 return WMError::WM_OK;
6233 }
6234
GetImmersiveModeEnabledState() const6235 bool WindowSceneSessionImpl::GetImmersiveModeEnabledState() const
6236 {
6237 TLOGD(WmsLogTag::WMS_IMMS, "id: %{public}u, enableImmersiveMode=%{public}u",
6238 GetWindowId(), enableImmersiveMode_.load());
6239 if (IsWindowSessionInvalid()) {
6240 return false;
6241 }
6242 return enableImmersiveMode_;
6243 }
6244
IsImmersiveLayout(bool & isImmersiveLayout) const6245 WMError WindowSceneSessionImpl::IsImmersiveLayout(bool& isImmersiveLayout) const
6246 {
6247 if (IsWindowSessionInvalid()) {
6248 return WMError::WM_ERROR_INVALID_WINDOW;
6249 }
6250 isImmersiveLayout = isIgnoreSafeArea_;
6251 return WMError::WM_OK;
6252 }
6253
6254 template <typename K, typename V>
GetValueByKey(const std::unordered_map<K,V> & map,K key)6255 static V GetValueByKey(const std::unordered_map<K, V>& map, K key)
6256 {
6257 auto it = map.find(key);
6258 return it != map.end() ? it->second : V{};
6259 }
6260
HandleEventForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6261 void WindowSceneSessionImpl::HandleEventForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6262 MMI::PointerEvent::PointerItem& pointerItem)
6263 {
6264 int32_t action = pointerEvent->GetPointerAction();
6265 switch (action) {
6266 case MMI::PointerEvent::POINTER_ACTION_DOWN:
6267 HandleDownForCompatibleMode(pointerEvent, pointerItem);
6268 break;
6269 case MMI::PointerEvent::POINTER_ACTION_MOVE:
6270 HandleMoveForCompatibleMode(pointerEvent, pointerItem);
6271 break;
6272 case MMI::PointerEvent::POINTER_ACTION_UP:
6273 HandleUpForCompatibleMode(pointerEvent, pointerItem);
6274 break;
6275 default:
6276 break;
6277 }
6278 }
6279
HandleDownForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6280 void WindowSceneSessionImpl::HandleDownForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6281 MMI::PointerEvent::PointerItem& pointerItem)
6282 {
6283 int32_t displayX = pointerItem.GetDisplayX();
6284 int32_t displayY = pointerItem.GetDisplayY();
6285 int32_t displayId = property_->GetDisplayId();
6286 int32_t pointerCount = pointerEvent->GetPointerCount();
6287 if (pointerCount == 1) {
6288 eventMapTriggerByDisplay_[displayId] = std::vector<bool>(MAX_POINTERS);
6289 eventMapDeltaXByDisplay_[displayId] = std::vector<int32_t>(MAX_POINTERS);
6290 downPointerByDisplay_[displayId] = std::vector<PointInfo>(MAX_POINTERS);
6291 isOverTouchSlop_ = false;
6292 isDown_ = true;
6293 }
6294
6295 if (IsInMappingRegionForCompatibleMode(displayX, displayY)) {
6296 int32_t pointerId = pointerEvent->GetPointerId();
6297 if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
6298 pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size() ||
6299 pointerId >= GetValueByKey(downPointerByDisplay_, displayId).size()) {
6300 TLOGE(WmsLogTag::DEFAULT, "pointerId: %{public}d out of range", pointerId);
6301 return;
6302 }
6303 eventMapTriggerByDisplay_[displayId][pointerId] = true;
6304 downPointerByDisplay_[displayId][pointerId] = {displayX, displayY};
6305 const auto& windowRect = GetRect();
6306 float xMappingScale = 1.0f;
6307 if (windowRect.posX_ != 0) {
6308 xMappingScale = static_cast<float>(windowRect.width_) / windowRect.posX_;
6309 }
6310 int32_t windowLeft = windowRect.posX_;
6311 int32_t windowRight = windowRect.posX_ + windowRect.width_;
6312 int32_t transferX;
6313 if (displayX <= windowLeft) {
6314 transferX = windowRight - xMappingScale * (windowLeft - displayX);
6315 } else {
6316 transferX = windowLeft + xMappingScale * (displayX - windowRight);
6317 }
6318 if (transferX < 0) {
6319 transferX = 0;
6320 }
6321 TLOGD(WmsLogTag::DEFAULT, "DOWN in mapping region, displayX: %{private}d, transferX: %{public}d, "
6322 "pointerId: %{public}d", displayX, transferX, pointerId);
6323 eventMapDeltaXByDisplay_[displayId][pointerId] = transferX - displayX;
6324 ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
6325 }
6326 }
6327
HandleMoveForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6328 void WindowSceneSessionImpl::HandleMoveForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6329 MMI::PointerEvent::PointerItem& pointerItem)
6330 {
6331 if (!isDown_) {
6332 TLOGW(WmsLogTag::WMS_COMPAT, "receive move before down, skip");
6333 return;
6334 }
6335 int32_t displayId = property_->GetDisplayId();
6336 int32_t pointerId = pointerEvent->GetPointerId();
6337 if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
6338 pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size() ||
6339 !GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId]) {
6340 return;
6341 }
6342
6343 int32_t displayX = pointerItem.GetDisplayX();
6344 int32_t displayY = pointerItem.GetDisplayY();
6345 const auto& windowRect = GetRect();
6346 if (!isOverTouchSlop_ && CheckTouchSlop(pointerId, displayX, displayY, windowRect.width_ / TOUCH_SLOP_RATIO)) {
6347 TLOGD(WmsLogTag::WMS_COMPAT, "reach touch slop, threshold: %{public}d", windowRect.width_ / TOUCH_SLOP_RATIO);
6348 isOverTouchSlop_ = true;
6349 }
6350 int32_t transferX = displayX + GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId];
6351 TLOGD(WmsLogTag::WMS_COMPAT, "MOVE, displayX: %{private}d, transferX: %{public}d, pointerId: %{public}d",
6352 displayX, transferX, pointerId);
6353 ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
6354 }
6355
HandleUpForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6356 void WindowSceneSessionImpl::HandleUpForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6357 MMI::PointerEvent::PointerItem& pointerItem)
6358 {
6359 if (!isDown_) {
6360 TLOGW(WmsLogTag::WMS_COMPAT, "receive up before down, skip");
6361 return;
6362 }
6363 int32_t displayId = property_->GetDisplayId();
6364 int32_t pointerId = pointerEvent->GetPointerId();
6365 if (pointerId >= GetValueByKey(eventMapTriggerByDisplay_, displayId).size() ||
6366 pointerId >= GetValueByKey(eventMapDeltaXByDisplay_, displayId).size()) {
6367 return;
6368 }
6369 if (GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId]) {
6370 int32_t displayX = pointerItem.GetDisplayX();
6371 int32_t transferX = displayX + GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId];
6372 ConvertPointForCompatibleMode(pointerEvent, pointerItem, transferX);
6373 TLOGD(WmsLogTag::WMS_COMPAT, "UP, displayX: %{private}d, transferX: %{public}d, pointerId: %{public}d",
6374 displayX, transferX, pointerId);
6375 GetValueByKey(eventMapDeltaXByDisplay_, displayId)[pointerId] = 0;
6376 GetValueByKey(eventMapTriggerByDisplay_, displayId)[pointerId] = false;
6377 IgnoreClickEvent(pointerEvent);
6378 }
6379 int32_t pointerCount = pointerEvent->GetPointerCount();
6380 if (pointerCount == 1) {
6381 eventMapDeltaXByDisplay_.erase(displayId);
6382 eventMapTriggerByDisplay_.erase(displayId);
6383 downPointerByDisplay_.erase(displayId);
6384 isDown_ = false;
6385 }
6386 }
6387
ConvertPointForCompatibleMode(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem,int32_t transferX)6388 void WindowSceneSessionImpl::ConvertPointForCompatibleMode(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6389 MMI::PointerEvent::PointerItem& pointerItem, int32_t transferX)
6390 {
6391 const auto& windowRect = GetRect();
6392 int32_t pointerId = pointerEvent->GetPointerId();
6393
6394 pointerItem.SetDisplayX(transferX);
6395 pointerItem.SetDisplayXPos(static_cast<double>(transferX));
6396 pointerItem.SetWindowX(transferX - windowRect.posX_);
6397 pointerItem.SetWindowXPos(static_cast<double>(transferX - windowRect.posX_));
6398 pointerEvent->UpdatePointerItem(pointerId, pointerItem);
6399 }
6400
IsInMappingRegionForCompatibleMode(int32_t displayX,int32_t displayY)6401 bool WindowSceneSessionImpl::IsInMappingRegionForCompatibleMode(int32_t displayX, int32_t displayY)
6402 {
6403 const auto& windowRect = GetRect();
6404 Rect pointerRect = { displayX, displayY, 0, 0 };
6405 return !pointerRect.IsInsideOf(windowRect);
6406 }
6407
CheckTouchSlop(int32_t pointerId,int32_t displayX,int32_t displayY,int32_t threshold)6408 bool WindowSceneSessionImpl::CheckTouchSlop(int32_t pointerId, int32_t displayX, int32_t displayY, int32_t threshold)
6409 {
6410 int32_t displayId = property_->GetDisplayId();
6411 if (downPointerByDisplay_.find(displayId) == downPointerByDisplay_.end()) {
6412 return false;
6413 }
6414 std::vector<PointInfo> downPointers = downPointerByDisplay_[displayId];
6415 return pointerId < downPointers.size() &&
6416 (std::abs(displayX - downPointers[pointerId].x) >= threshold ||
6417 std::abs(displayY - downPointers[pointerId].y) >= threshold);
6418 }
6419
IgnoreClickEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)6420 void WindowSceneSessionImpl::IgnoreClickEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
6421 {
6422 int32_t action = pointerEvent->GetPointerAction();
6423 if (action != MMI::PointerEvent::POINTER_ACTION_UP) {
6424 return;
6425 }
6426 if (isOverTouchSlop_) {
6427 if (pointerEvent->GetPointerCount() == 1) {
6428 isOverTouchSlop_ = false;
6429 }
6430 } else {
6431 pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
6432 TLOGI(WmsLogTag::DEFAULT, "transfer UP to CANCEL for not over touch slop");
6433 }
6434 }
6435
GetWindowStatus(WindowStatus & windowStatus)6436 WMError WindowSceneSessionImpl::GetWindowStatus(WindowStatus& windowStatus)
6437 {
6438 if (IsWindowSessionInvalid()) {
6439 TLOGE(WmsLogTag::WMS_PC, "session is invalid");
6440 return WMError::WM_ERROR_INVALID_WINDOW;
6441 }
6442 windowStatus = GetWindowStatusInner(GetWindowMode());
6443 TLOGD(WmsLogTag::WMS_PC, "Id:%{public}u, WindowStatus:%{public}u", GetWindowId(), windowStatus);
6444 return WMError::WM_OK;
6445 }
6446
GetIsUIExtFirstSubWindow() const6447 bool WindowSceneSessionImpl::GetIsUIExtFirstSubWindow() const
6448 {
6449 return property_->GetIsUIExtFirstSubWindow();
6450 }
6451
GetIsUIExtAnySubWindow() const6452 bool WindowSceneSessionImpl::GetIsUIExtAnySubWindow() const
6453 {
6454 return property_->GetIsUIExtAnySubWindow();
6455 }
6456
SetGestureBackEnabled(bool enable)6457 WMError WindowSceneSessionImpl::SetGestureBackEnabled(bool enable)
6458 {
6459 if (windowSystemConfig_.IsPcWindow()) {
6460 TLOGI(WmsLogTag::WMS_IMMS, "device is not support");
6461 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6462 }
6463 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u, enable %{public}u", GetWindowId(), enable);
6464 gestureBackEnabled_ = enable;
6465 AAFwk::Want want;
6466 want.SetParam(Extension::GESTURE_BACK_ENABLED, enable);
6467 if (auto uiContent = GetUIContentSharedPtr()) {
6468 uiContent->SendUIExtProprty(static_cast<uint32_t>(Extension::Businesscode::SYNC_HOST_GESTURE_BACK_ENABLED),
6469 want, static_cast<uint8_t>(SubSystemId::WM_UIEXT));
6470 }
6471 auto hostSession = GetHostSession();
6472 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6473 return hostSession->SetGestureBackEnabled(enable);
6474 }
6475
GetGestureBackEnabled(bool & enable) const6476 WMError WindowSceneSessionImpl::GetGestureBackEnabled(bool& enable) const
6477 {
6478 if (windowSystemConfig_.IsPcWindow()) {
6479 TLOGI(WmsLogTag::WMS_IMMS, "device not support");
6480 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6481 }
6482 enable = gestureBackEnabled_;
6483 TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u enable %{public}u", GetWindowId(), enable);
6484 return WMError::WM_OK;
6485 }
6486
SetFullScreenWaterfallMode(bool isWaterfallMode)6487 WSError WindowSceneSessionImpl::SetFullScreenWaterfallMode(bool isWaterfallMode)
6488 {
6489 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "prev: %{public}d, curr: %{public}d, winId: %{public}u",
6490 isFullScreenWaterfallMode_.load(), isWaterfallMode, GetWindowId());
6491 NotifyAcrossDisplaysChange(isWaterfallMode);
6492 if (isValidWaterfallMode_.load() && isFullScreenWaterfallMode_.load() == isWaterfallMode) {
6493 return WSError::WS_DO_NOTHING;
6494 }
6495 isFullScreenWaterfallMode_.store(isWaterfallMode);
6496 if (isWaterfallMode) {
6497 lastWindowModeBeforeWaterfall_.store(property_->GetWindowMode());
6498 } else {
6499 lastWindowModeBeforeWaterfall_.store(WindowMode::WINDOW_MODE_UNDEFINED);
6500 }
6501 isValidWaterfallMode_.store(true);
6502 NotifyWaterfallModeChange(isWaterfallMode);
6503 return WSError::WS_OK;
6504 }
6505
SetSupportEnterWaterfallMode(bool isSupportEnter)6506 WSError WindowSceneSessionImpl::SetSupportEnterWaterfallMode(bool isSupportEnter)
6507 {
6508 handler_->PostTask([weakThis = wptr(this), isSupportEnter, where = __func__] {
6509 auto window = weakThis.promote();
6510 if (!window) {
6511 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s window is null", where);
6512 return;
6513 }
6514 if (window->supportEnterWaterfallMode_ == isSupportEnter) {
6515 return;
6516 }
6517 TLOGNI(WmsLogTag::WMS_LAYOUT_PC, "%{public}s prev: %{public}d, curr: %{public}d",
6518 where, window->supportEnterWaterfallMode_, isSupportEnter);
6519 window->supportEnterWaterfallMode_ = isSupportEnter;
6520 std::shared_ptr<Ace::UIContent> uiContent = window->GetUIContentSharedPtr();
6521 if (uiContent == nullptr || !window->IsDecorEnable()) {
6522 TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s uiContent unavailable", where);
6523 return;
6524 }
6525 uiContent->OnContainerModalEvent(WINDOW_WATERFALL_VISIBILITY_EVENT, isSupportEnter ? "true" : "false");
6526 }, __func__);
6527 return WSError::WS_OK;
6528 }
6529
OnContainerModalEvent(const std::string & eventName,const std::string & value)6530 WMError WindowSceneSessionImpl::OnContainerModalEvent(const std::string& eventName, const std::string& value)
6531 {
6532 TLOGI(WmsLogTag::WMS_LAYOUT, "windowId: %{public}d, name: %{public}s, value: %{public}s",
6533 GetPersistentId(), eventName.c_str(), value.c_str());
6534 if (IsWindowSessionInvalid()) {
6535 TLOGE(WmsLogTag::WMS_LAYOUT, "session is invalid");
6536 return WMError::WM_ERROR_INVALID_WINDOW;
6537 }
6538 auto hostSession = GetHostSession();
6539 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
6540 hostSession->OnContainerModalEvent(eventName, value);
6541 if (eventName == WINDOW_WATERFALL_EVENT) {
6542 bool lastFullScreenWaterfallMode = isFullScreenWaterfallMode_.load();
6543 SetFullScreenWaterfallMode(true);
6544 auto ret = Maximize();
6545 if (ret != WMError::WM_OK) {
6546 TLOGE(WmsLogTag::WMS_LAYOUT, "maximize failed");
6547 SetFullScreenWaterfallMode(lastFullScreenWaterfallMode);
6548 }
6549 return ret;
6550 } else if (eventName == BACK_WINDOW_EVENT) {
6551 HandleBackEvent();
6552 return WMError::WM_OK;
6553 } else if (eventName == COMPATIBLE_MAX_WINDOW_EVENT) {
6554 MaximizeForCompatibleMode();
6555 return WMError::WM_OK;
6556 } else if (eventName == COMPATIBLE_RECOVER_WINDOW_EVENT) {
6557 RecoverForCompatibleMode();
6558 return WMError::WM_OK;
6559 }
6560 return WMError::WM_DO_NOTHING;
6561 }
6562
IsSystemDensityChanged(const sptr<DisplayInfo> & displayInfo)6563 bool WindowSceneSessionImpl::IsSystemDensityChanged(const sptr<DisplayInfo>& displayInfo)
6564 {
6565 if (MathHelper::NearZero(lastSystemDensity_ - displayInfo->GetVirtualPixelRatio())) {
6566 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "System density not change");
6567 return false;
6568 }
6569 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "windowId: %{public}d, lastDensity: %{public}f, currDensity: %{public}f",
6570 GetPersistentId(), lastSystemDensity_, displayInfo->GetVirtualPixelRatio());
6571 return true;
6572 }
6573
IsDefaultDensityEnabled()6574 bool WindowSceneSessionImpl::IsDefaultDensityEnabled()
6575 {
6576 if (WindowHelper::IsMainWindow(GetType())) {
6577 return GetDefaultDensityEnabled();
6578 }
6579 if (isEnableDefaultDensityWhenCreate_) {
6580 return true;
6581 }
6582 if (auto mainWindow = FindMainWindowWithContext()) {
6583 CopyUniqueDensityParameter(mainWindow);
6584 }
6585 return GetDefaultDensityEnabled();
6586 }
6587
GetMainWindowCustomDensity()6588 float WindowSceneSessionImpl::GetMainWindowCustomDensity()
6589 {
6590 if (WindowHelper::IsMainWindow(GetType())) {
6591 return GetCustomDensity();
6592 }
6593 auto mainWindow = FindMainWindowWithContext();
6594 return mainWindow ? mainWindow->GetCustomDensity() : UNDEFINED_DENSITY;
6595 }
6596
GetCustomDensity() const6597 float WindowSceneSessionImpl::GetCustomDensity() const
6598 {
6599 return customDensity_;
6600 }
6601
SetWindowAnchorInfo(const WindowAnchorInfo & windowAnchorInfo)6602 WMError WindowSceneSessionImpl::SetWindowAnchorInfo(const WindowAnchorInfo& windowAnchorInfo)
6603 {
6604 if (IsWindowSessionInvalid()) {
6605 return WMError::WM_ERROR_INVALID_WINDOW;
6606 }
6607 const auto& property = GetProperty();
6608 if (!WindowHelper::IsSubWindow(property->GetWindowType())) {
6609 TLOGE(WmsLogTag::WMS_SUB, "only sub window is valid");
6610 return WMError::WM_ERROR_INVALID_CALLING;
6611 }
6612 if (WindowHelper::IsFullScreenWindow(property->GetWindowMode())) {
6613 TLOGE(WmsLogTag::WMS_SUB, "not support fullscreen sub window");
6614 return WMError::WM_ERROR_INVALID_CALLING;
6615 }
6616 if (property->GetSubWindowLevel() > 1) {
6617 TLOGI(WmsLogTag::WMS_SUB, "not support more than 1 level window");
6618 return WMError::WM_ERROR_INVALID_CALLING;
6619 }
6620 if (!windowSystemConfig_.supportFollowRelativePositionToParent_) {
6621 TLOGI(WmsLogTag::WMS_SUB, "not support device");
6622 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6623 }
6624 auto hostSession = GetHostSession();
6625 if (!hostSession) {
6626 TLOGI(WmsLogTag::WMS_SUB, "session is nullptr");
6627 return WMError::WM_ERROR_INVALID_SESSION;
6628 }
6629 WSError ret = hostSession->SetWindowAnchorInfo(windowAnchorInfo);
6630 if (ret == WSError::WS_ERROR_DEVICE_NOT_SUPPORT) {
6631 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6632 }
6633 if (ret == WSError::WS_OK) {
6634 property->SetWindowAnchorInfo(windowAnchorInfo);
6635 }
6636 return ret != WSError::WS_OK ? WMError::WM_ERROR_SYSTEM_ABNORMALLY : WMError::WM_OK;
6637 }
6638
SetFollowParentWindowLayoutEnabled(bool isFollow)6639 WMError WindowSceneSessionImpl::SetFollowParentWindowLayoutEnabled(bool isFollow)
6640 {
6641 if (IsWindowSessionInvalid()) {
6642 return WMError::WM_ERROR_INVALID_WINDOW;
6643 }
6644 const auto& property = GetProperty();
6645 if (!WindowHelper::IsSubWindow(property->GetWindowType()) &&
6646 !WindowHelper::IsDialogWindow(property->GetWindowType())) {
6647 TLOGE(WmsLogTag::WMS_SUB, "only sub window and dialog is valid");
6648 return WMError::WM_ERROR_INVALID_OPERATION;
6649 }
6650 if (property->GetSubWindowLevel() > 1) {
6651 TLOGI(WmsLogTag::WMS_SUB, "not support more than 1 level window");
6652 return WMError::WM_ERROR_INVALID_OPERATION;
6653 }
6654 if (!windowSystemConfig_.supportFollowParentWindowLayout_) {
6655 TLOGI(WmsLogTag::WMS_SUB, "not support device");
6656 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6657 }
6658 if (!GetHostSession()) {
6659 TLOGI(WmsLogTag::WMS_SUB, "session is nullptr");
6660 return WMError::WM_ERROR_INVALID_SESSION;
6661 }
6662 WSError ret = GetHostSession()->SetFollowParentWindowLayoutEnabled(isFollow);
6663 if (ret == WSError::WS_ERROR_DEVICE_NOT_SUPPORT) {
6664 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6665 }
6666 return ret != WSError::WS_OK ? WMError::WM_ERROR_SYSTEM_ABNORMALLY : WMError::WM_OK;
6667 }
6668
SetWindowTransitionAnimation(WindowTransitionType transitionType,const TransitionAnimation & animation)6669 WMError WindowSceneSessionImpl::SetWindowTransitionAnimation(WindowTransitionType transitionType,
6670 const TransitionAnimation& animation)
6671 {
6672 if (IsWindowSessionInvalid()) {
6673 return WMError::WM_ERROR_INVALID_WINDOW;
6674 }
6675 if (!IsPcOrPadFreeMultiWindowMode()) {
6676 return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
6677 }
6678 if (!WindowHelper::IsMainWindow(GetType())) {
6679 return WMError::WM_ERROR_INVALID_CALLING;
6680 }
6681 WSError ret = WSError::WS_DO_NOTHING;
6682 auto hostSession = GetHostSession();
6683 if (!hostSession) {
6684 TLOGI(WmsLogTag::WMS_ANIMATION, "session is nullptr");
6685 return WMError::WM_ERROR_INVALID_SESSION;
6686 }
6687 ret = hostSession->SetWindowTransitionAnimation(transitionType, animation);
6688 if (ret == WSError::WS_OK) {
6689 std::lock_guard<std::mutex> lockListener(transitionAnimationConfigMutex_);
6690 property_->SetTransitionAnimationConfig(transitionType, animation);
6691 }
6692 return ret != WSError::WS_OK ? WMError::WM_ERROR_SYSTEM_ABNORMALLY : WMError::WM_OK;
6693 }
6694
GetWindowTransitionAnimation(WindowTransitionType transitionType)6695 std::shared_ptr<TransitionAnimation> WindowSceneSessionImpl::GetWindowTransitionAnimation(WindowTransitionType
6696 transitionType)
6697 {
6698 if (IsWindowSessionInvalid()) {
6699 return nullptr;
6700 }
6701 if (!IsPcOrPadFreeMultiWindowMode()) {
6702 return nullptr;
6703 }
6704 if (!WindowHelper::IsMainWindow(GetType())) {
6705 return nullptr;
6706 }
6707 std::lock_guard<std::mutex> lockListener(transitionAnimationConfigMutex_);
6708 auto transitionAnimationConfig = property_->GetTransitionAnimationConfig();
6709 if (transitionAnimationConfig.find(transitionType) != transitionAnimationConfig.end()) {
6710 return transitionAnimationConfig[transitionType];
6711 } else {
6712 return nullptr;
6713 }
6714 }
6715
SetCustomDensity(float density,bool applyToSubWindow)6716 WMError WindowSceneSessionImpl::SetCustomDensity(float density, bool applyToSubWindow)
6717 {
6718 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, density=%{public}f", GetWindowId(), density);
6719 if (IsWindowSessionInvalid()) {
6720 return WMError::WM_ERROR_INVALID_WINDOW;
6721 }
6722 if ((density < MINIMUM_CUSTOM_DENSITY && !MathHelper::NearZero(density - UNDEFINED_DENSITY)) ||
6723 density > MAXIMUM_CUSTOM_DENSITY) {
6724 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u set invalid density=%{public}f", GetWindowId(), density);
6725 return WMError::WM_ERROR_INVALID_PARAM;
6726 }
6727 if (!WindowHelper::IsMainWindow(GetType())) {
6728 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, must be app main window", GetWindowId());
6729 return WMError::WM_ERROR_INVALID_CALLING;
6730 }
6731 if (MathHelper::NearZero(customDensity_ - density) && !applyToSubWindow) {
6732 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u set density not change", GetWindowId());
6733 return WMError::WM_OK;
6734 }
6735 defaultDensityEnabledGlobalConfig_ = false;
6736 SetDefaultDensityEnabledValue(false);
6737 customDensity_ = density;
6738 UpdateDensity();
6739 std::shared_lock<std::shared_mutex> lock(windowSessionMutex_);
6740 for (const auto& winPair : windowSessionMap_) {
6741 auto window = winPair.second.second;
6742 if (window == nullptr) {
6743 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "window is nullptr");
6744 continue;
6745 }
6746 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Id=%{public}d UpdateDensity", window->GetWindowId());
6747 window->SetDefaultDensityEnabledValue(false);
6748 if (applyToSubWindow) {
6749 window->UpdateDensity();
6750 }
6751 }
6752 return WMError::WM_OK;
6753 }
6754
GetWindowDensityInfo(WindowDensityInfo & densityInfo)6755 WMError WindowSceneSessionImpl::GetWindowDensityInfo(WindowDensityInfo& densityInfo)
6756 {
6757 if (IsWindowSessionInvalid()) {
6758 return WMError::WM_ERROR_INVALID_WINDOW;
6759 }
6760 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
6761 if (display == nullptr) {
6762 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "display is null, winId=%{public}u", GetWindowId());
6763 return WMError::WM_ERROR_NULLPTR;
6764 }
6765 auto displayInfo = display->GetDisplayInfo();
6766 if (displayInfo == nullptr) {
6767 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "displayInfo is null, winId=%{public}u", GetWindowId());
6768 return WMError::WM_ERROR_NULLPTR;
6769 }
6770 densityInfo.systemDensity = displayInfo->GetVirtualPixelRatio();
6771 densityInfo.defaultDensity = displayInfo->GetDefaultVirtualPixelRatio();
6772 auto customDensity = UNDEFINED_DENSITY;
6773 if (IsDefaultDensityEnabled()) {
6774 customDensity = displayInfo->GetDefaultVirtualPixelRatio();
6775 } else {
6776 customDensity = GetCustomDensity();
6777 customDensity = MathHelper::NearZero(customDensity - UNDEFINED_DENSITY) ? displayInfo->GetVirtualPixelRatio()
6778 : customDensity;
6779 }
6780 densityInfo.customDensity = customDensity;
6781 return WMError::WM_OK;
6782 }
6783
IsMainWindowFullScreenAcrossDisplays(bool & isAcrossDisplays)6784 WMError WindowSceneSessionImpl::IsMainWindowFullScreenAcrossDisplays(bool& isAcrossDisplays)
6785 {
6786 if (IsWindowSessionInvalid()) {
6787 return WMError::WM_ERROR_INVALID_WINDOW;
6788 }
6789 auto hostSession = GetHostSession();
6790 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6791 return hostSession->IsMainWindowFullScreenAcrossDisplays(isAcrossDisplays);
6792 }
6793
IsFullScreenEnable() const6794 bool WindowSceneSessionImpl::IsFullScreenEnable() const
6795 {
6796 if (!WindowHelper::IsWindowModeSupported(property_->GetWindowModeSupportType(),
6797 WindowMode::WINDOW_MODE_FULLSCREEN)) {
6798 return false;
6799 }
6800 const auto& sizeLimits = property_->GetWindowLimits();
6801 uint32_t displayWidth = 0;
6802 uint32_t displayHeight = 0;
6803 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
6804 if (display == nullptr) {
6805 TLOGE(WmsLogTag::WMS_PC, "display is null, winId=%{public}u", GetWindowId());
6806 return false;
6807 }
6808 displayWidth = static_cast<uint32_t>(display->GetWidth());
6809 displayHeight = static_cast<uint32_t>(display->GetHeight());
6810 if (property_->GetDragEnabled() && (sizeLimits.maxWidth_ < displayWidth || sizeLimits.maxHeight_ < displayHeight)) {
6811 return false;
6812 }
6813 return true;
6814 }
6815
GetWindowPropertyInfo(WindowPropertyInfo & windowPropertyInfo)6816 WMError WindowSceneSessionImpl::GetWindowPropertyInfo(WindowPropertyInfo& windowPropertyInfo)
6817 {
6818 if (IsWindowSessionInvalid()) {
6819 return WMError::WM_ERROR_INVALID_WINDOW;
6820 }
6821 windowPropertyInfo.windowRect = GetRect();
6822 auto uicontent = GetUIContentSharedPtr();
6823 if (uicontent == nullptr) {
6824 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "uicontent is nullptr");
6825 } else {
6826 uicontent->GetWindowPaintSize(windowPropertyInfo.drawableRect);
6827 }
6828 windowPropertyInfo.globalDisplayRect = property_->GetGlobalDisplayRect();
6829 windowPropertyInfo.type = GetType();
6830 windowPropertyInfo.isLayoutFullScreen = IsLayoutFullScreen();
6831 windowPropertyInfo.isFullScreen = IsFullScreen();
6832 windowPropertyInfo.isTouchable = GetTouchable();
6833 windowPropertyInfo.isFocusable = GetFocusable();
6834 windowPropertyInfo.name = GetWindowName();
6835 windowPropertyInfo.isPrivacyMode = IsPrivacyMode();
6836 windowPropertyInfo.isKeepScreenOn = IsKeepScreenOn();
6837 windowPropertyInfo.brightness = GetBrightness();
6838 windowPropertyInfo.isTransparent = IsTransparent();
6839 windowPropertyInfo.id = GetWindowId();
6840 windowPropertyInfo.displayId = GetDisplayId();
6841 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "winId=%{public}u, globalDisplayRect=%{public}s", GetWindowId(),
6842 windowPropertyInfo.globalDisplayRect.ToString().c_str());
6843 HookWindowSizeByHookWindowInfo(windowPropertyInfo.windowRect);
6844 HookWindowSizeByHookWindowInfo(windowPropertyInfo.globalDisplayRect);
6845 return WMError::WM_OK;
6846 }
6847
SetHookTargetElementInfo(const AppExecFwk::ElementName & elementName)6848 WMError WindowSceneSessionImpl::SetHookTargetElementInfo(const AppExecFwk::ElementName& elementName)
6849 {
6850 auto context = GetContext();
6851 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
6852 if (!abilityContext) {
6853 TLOGE(WmsLogTag::WMS_LIFE, "abilityContext is nullptr");
6854 return WMError::WM_ERROR_NULLPTR;
6855 }
6856 if (abilityContext->IsHook() && !abilityContext->GetHookOff()) {
6857 property_->EditSessionInfo().bundleName_ = elementName.GetBundleName();
6858 property_->EditSessionInfo().moduleName_ = elementName.GetModuleName();
6859 property_->EditSessionInfo().abilityName_ = elementName.GetAbilityName();
6860 }
6861 return WMError::WM_OK;
6862 }
6863
GetAppForceLandscapeConfig(AppForceLandscapeConfig & config)6864 WMError WindowSceneSessionImpl::GetAppForceLandscapeConfig(AppForceLandscapeConfig& config)
6865 {
6866 if (IsWindowSessionInvalid()) {
6867 TLOGE(WmsLogTag::DEFAULT, "HostSession is invalid");
6868 return WMError::WM_ERROR_INVALID_WINDOW;
6869 }
6870 auto hostSession = GetHostSession();
6871 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6872 return hostSession->GetAppForceLandscapeConfig(config);
6873 }
6874
NotifyAppForceLandscapeConfigUpdated()6875 WSError WindowSceneSessionImpl::NotifyAppForceLandscapeConfigUpdated()
6876 {
6877 TLOGI(WmsLogTag::DEFAULT, "in");
6878 WindowType winType = GetType();
6879 AppForceLandscapeConfig config = {};
6880 if (WindowHelper::IsMainWindow(winType) && GetAppForceLandscapeConfig(config) == WMError::WM_OK &&
6881 config.supportSplit_ > 0) {
6882 SetForceSplitEnable(config);
6883 return WSError::WS_OK;
6884 }
6885 return WSError::WS_DO_NOTHING;
6886 }
6887
GetAppHookWindowInfoFromServer(HookWindowInfo & hookWindowInfo)6888 WMError WindowSceneSessionImpl::GetAppHookWindowInfoFromServer(HookWindowInfo& hookWindowInfo)
6889 {
6890 auto hostSession = GetHostSession();
6891 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
6892 return hostSession->GetAppHookWindowInfoFromServer(hookWindowInfo);
6893 }
6894
NotifyAppHookWindowInfoUpdated()6895 WSError WindowSceneSessionImpl::NotifyAppHookWindowInfoUpdated()
6896 {
6897 TLOGI(WmsLogTag::WMS_LAYOUT, "in");
6898 const WindowType windowType = GetType();
6899 if (!WindowHelper::IsMainWindow(windowType)) {
6900 return WSError::WS_DO_NOTHING;
6901 }
6902
6903 HookWindowInfo hookWindowInfo{};
6904 if (GetAppHookWindowInfoFromServer(hookWindowInfo) != WMError::WM_OK) {
6905 return WSError::WS_DO_NOTHING;
6906 }
6907
6908 SetAppHookWindowInfo(hookWindowInfo);
6909 return WSError::WS_OK;
6910 }
6911
SetSubWindowSource(SubWindowSource source)6912 WMError WindowSceneSessionImpl::SetSubWindowSource(SubWindowSource source)
6913 {
6914 if (IsWindowSessionInvalid()) {
6915 return WMError::WM_ERROR_INVALID_WINDOW;
6916 }
6917 const auto& property = GetProperty();
6918 if (!WindowHelper::IsSubWindow(property->GetWindowType()) &&
6919 !WindowHelper::IsDialogWindow(property->GetWindowType())) {
6920 TLOGE(WmsLogTag::WMS_SUB, "only sub window and dialog is valid");
6921 return WMError::WM_ERROR_INVALID_OPERATION;
6922 }
6923 auto hostSession = GetHostSession();
6924 if (!hostSession) {
6925 TLOGI(WmsLogTag::WMS_SUB, "session is nullptr");
6926 return WMError::WM_ERROR_INVALID_SESSION;
6927 }
6928 WSError ret = hostSession->SetSubWindowSource(source);
6929 if (ret == WSError::WS_ERROR_INVALID_WINDOW) {
6930 return WMError::WM_ERROR_INVALID_WINDOW;
6931 }
6932 return ret != WSError::WS_OK ? WMError::WM_ERROR_SYSTEM_ABNORMALLY : WMError::WM_OK;
6933 }
6934
CloseSpecificScene()6935 WSError WindowSceneSessionImpl::CloseSpecificScene()
6936 {
6937 if (!property_->IsDecorEnable()) {
6938 TLOGW(WmsLogTag::WMS_SUB, "specific scene can not close id: %{public}d, decor is not enable.",
6939 GetPersistentId());
6940 return WSError::WS_ERROR_INVALID_OPERATION;
6941 }
6942 TLOGI(WmsLogTag::WMS_SUB, "close specific scene id: %{public}d", GetPersistentId());
6943 handler_->PostTask([weakThis = wptr(this)] {
6944 auto window = weakThis.promote();
6945 if (!window) {
6946 TLOGNE(WmsLogTag::WMS_SUB, "window is nullptr");
6947 return;
6948 }
6949 window->Close();
6950 }, __func__);
6951 return WSError::WS_OK;
6952 }
6953 } // namespace Rosen
6954 } // namespace OHOS
6955