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