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