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