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