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