1 /*
2 * Copyright (c) 2021-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_impl.h"
17
18 #include <ability_manager_client.h>
19 #include <common/rs_common_def.h>
20 #include <filesystem>
21 #include <fstream>
22 #include <hisysevent.h>
23 #include <parameters.h>
24 #include <ipc_skeleton.h>
25 #include <transaction/rs_interfaces.h>
26 #include <transaction/rs_transaction.h>
27 #include <ui/rs_node.h>
28
29 #include "permission.h"
30 #include "color_parser.h"
31 #include "display_manager.h"
32 #include "display_info.h"
33 #include "ressched_report.h"
34 #include "singleton_container.h"
35 #include "surface_capture_future.h"
36 #include "sys_cap_util.h"
37 #include "window_adapter.h"
38 #include "window_agent.h"
39 #include "window_helper.h"
40 #include "window_manager_hilog.h"
41 #include "wm_common.h"
42 #include "wm_common_inner.h"
43 #include "wm_math.h"
44 #include "perform_reporter.h"
45 #include "hitrace_meter.h"
46 #include <hisysevent.h>
47
48 namespace OHOS {
49 namespace Rosen {
50 namespace {
51 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowImpl"};
52 const std::string PARAM_DUMP_HELP = "-h";
53 }
54
55 WM_IMPLEMENT_SINGLE_INSTANCE(ResSchedReport);
56
57 const WindowImpl::ColorSpaceConvertMap WindowImpl::colorSpaceConvertMap[] = {
58 { ColorSpace::COLOR_SPACE_DEFAULT, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB },
59 { ColorSpace::COLOR_SPACE_WIDE_GAMUT, GraphicColorGamut::GRAPHIC_COLOR_GAMUT_DCI_P3 },
60 };
61
62 std::map<std::string, std::pair<uint32_t, sptr<Window>>> WindowImpl::windowMap_;
63 std::map<uint32_t, std::vector<sptr<WindowImpl>>> WindowImpl::subWindowMap_;
64 std::map<uint32_t, std::vector<sptr<WindowImpl>>> WindowImpl::appFloatingWindowMap_;
65 std::map<uint32_t, std::vector<sptr<WindowImpl>>> WindowImpl::appDialogWindowMap_;
66 std::map<uint32_t, std::vector<sptr<IScreenshotListener>>> WindowImpl::screenshotListeners_;
67 std::map<uint32_t, std::vector<sptr<ITouchOutsideListener>>> WindowImpl::touchOutsideListeners_;
68 std::map<uint32_t, std::vector<sptr<IDialogTargetTouchListener>>> WindowImpl::dialogTargetTouchListeners_;
69 std::map<uint32_t, std::vector<sptr<IWindowLifeCycle>>> WindowImpl::lifecycleListeners_;
70 std::map<uint32_t, std::vector<sptr<IWindowChangeListener>>> WindowImpl::windowChangeListeners_;
71 std::map<uint32_t, std::vector<sptr<IAvoidAreaChangedListener>>> WindowImpl::avoidAreaChangeListeners_;
72 std::map<uint32_t, std::vector<sptr<IOccupiedAreaChangeListener>>> WindowImpl::occupiedAreaChangeListeners_;
73 std::map<uint32_t, sptr<IDialogDeathRecipientListener>> WindowImpl::dialogDeathRecipientListener_;
74 std::recursive_mutex WindowImpl::globalMutex_;
75 int g_constructorCnt = 0;
76 int g_deConstructorCnt = 0;
WindowImpl(const sptr<WindowOption> & option)77 WindowImpl::WindowImpl(const sptr<WindowOption>& option)
78 {
79 property_ = new (std::nothrow) WindowProperty();
80 if (property_ == nullptr) {
81 WLOGFE("Property is null");
82 return;
83 }
84 InitWindowProperty(option);
85
86 windowTag_ = option->GetWindowTag();
87 isMainHandlerAvailable_ = option->GetMainHandlerAvailable();
88 AdjustWindowAnimationFlag();
89 UpdateDecorEnable();
90 auto& sysBarPropMap = option->GetSystemBarProperty();
91 for (auto it : sysBarPropMap) {
92 property_->SetSystemBarProperty(it.first, it.second);
93 }
94 name_ = option->GetWindowName();
95
96 surfaceNode_ = CreateSurfaceNode(property_->GetWindowName(), option->GetWindowType());
97 if (surfaceNode_ != nullptr) {
98 vsyncStation_ = std::make_shared<VsyncStation>(surfaceNode_->GetId());
99 }
100
101 moveDragProperty_ = new (std::nothrow) MoveDragProperty();
102 if (moveDragProperty_ == nullptr) {
103 WLOGFE("MoveDragProperty is null");
104 }
105 WLOGFD("g_constructorCnt: %{public}d name: %{public}s",
106 ++g_constructorCnt, property_->GetWindowName().c_str());
107 }
108
InitWindowProperty(const sptr<WindowOption> & option)109 void WindowImpl::InitWindowProperty(const sptr<WindowOption>& option)
110 {
111 if (option == nullptr) {
112 TLOGE(WmsLogTag::WMS_MAIN, "Init window property failed, option is nullptr.");
113 return;
114 }
115 property_->SetWindowName(option->GetWindowName());
116 property_->SetRequestRect(option->GetWindowRect());
117 property_->SetWindowType(option->GetWindowType());
118 if (WindowHelper::IsAppFloatingWindow(option->GetWindowType())) {
119 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
120 } else {
121 property_->SetWindowMode(option->GetWindowMode());
122 }
123 property_->SetFullScreen(option->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN);
124 property_->SetFocusable(option->GetFocusable());
125 property_->SetTouchable(option->GetTouchable());
126 property_->SetDisplayId(option->GetDisplayId());
127 property_->SetCallingWindow(option->GetCallingWindow());
128 property_->SetWindowFlags(option->GetWindowFlags());
129 property_->SetHitOffset(option->GetHitOffset());
130 property_->SetRequestedOrientation(option->GetRequestedOrientation());
131 property_->SetTurnScreenOn(option->IsTurnScreenOn());
132 property_->SetKeepScreenOn(option->IsKeepScreenOn());
133 property_->SetBrightness(option->GetBrightness());
134 }
135
CreateSurfaceNode(std::string name,WindowType type)136 RSSurfaceNode::SharedPtr WindowImpl::CreateSurfaceNode(std::string name, WindowType type)
137 {
138 struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
139 rsSurfaceNodeConfig.SurfaceNodeName = name;
140 RSSurfaceNodeType rsSurfaceNodeType = RSSurfaceNodeType::DEFAULT;
141 switch (type) {
142 case WindowType::WINDOW_TYPE_BOOT_ANIMATION:
143 case WindowType::WINDOW_TYPE_POINTER:
144 rsSurfaceNodeType = RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
145 break;
146 case WindowType::WINDOW_TYPE_APP_MAIN_WINDOW:
147 rsSurfaceNodeType = RSSurfaceNodeType::APP_WINDOW_NODE;
148 break;
149 case WindowType::WINDOW_TYPE_PIP:
150 rsSurfaceNodeType = RSSurfaceNodeType::APP_WINDOW_NODE;
151 break;
152 default:
153 rsSurfaceNodeType = RSSurfaceNodeType::DEFAULT;
154 break;
155 }
156
157 auto isPhone = windowSystemConfig_.uiType_ == UI_TYPE_PHONE;
158 if (isPhone && WindowHelper::IsWindowFollowParent(type)) {
159 rsSurfaceNodeType = RSSurfaceNodeType::ABILITY_COMPONENT_NODE;
160 }
161 return RSSurfaceNode::Create(rsSurfaceNodeConfig, rsSurfaceNodeType);
162 }
163
~WindowImpl()164 WindowImpl::~WindowImpl()
165 {
166 WLOGI("windowName: %{public}s, windowId: %{public}d, g_deConstructorCnt: %{public}d, surfaceNode:%{public}d",
167 GetWindowName().c_str(), GetWindowId(), ++g_deConstructorCnt, static_cast<uint32_t>(surfaceNode_.use_count()));
168 Destroy(true, false);
169 }
170
Find(const std::string & name)171 sptr<Window> WindowImpl::Find(const std::string& name)
172 {
173 auto iter = windowMap_.find(name);
174 if (iter == windowMap_.end()) {
175 return nullptr;
176 }
177 return iter->second.second;
178 }
179
GetContext() const180 const std::shared_ptr<AbilityRuntime::Context> WindowImpl::GetContext() const
181 {
182 return context_;
183 }
184
FindWindowById(uint32_t WinId)185 sptr<Window> WindowImpl::FindWindowById(uint32_t WinId)
186 {
187 if (windowMap_.empty()) {
188 WLOGFE("Please create mainWindow First!");
189 return nullptr;
190 }
191 for (auto iter = windowMap_.begin(); iter != windowMap_.end(); iter++) {
192 if (WinId == iter->second.first) {
193 WLOGI("FindWindow id: %{public}u", WinId);
194 return iter->second.second;
195 }
196 }
197 WLOGFE("Cannot find Window!");
198 return nullptr;
199 }
200
GetTopWindowWithId(uint32_t mainWinId)201 sptr<Window> WindowImpl::GetTopWindowWithId(uint32_t mainWinId)
202 {
203 uint32_t topWinId = INVALID_WINDOW_ID;
204 WMError ret = SingletonContainer::Get<WindowAdapter>().GetTopWindowId(mainWinId, topWinId);
205 if (ret != WMError::WM_OK) {
206 WLOGFE("GetTopWindowId failed with errCode:%{public}d", static_cast<int32_t>(ret));
207 return nullptr;
208 }
209 return FindWindowById(topWinId);
210 }
211
GetWindowWithId(uint32_t WinId)212 sptr<Window> WindowImpl::GetWindowWithId(uint32_t WinId)
213 {
214 return FindWindowById(WinId);
215 }
216
GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context> & context)217 sptr<Window> WindowImpl::GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context>& context)
218 {
219 if (windowMap_.empty()) {
220 WLOGFE("Please create mainWindow First!");
221 return nullptr;
222 }
223 uint32_t mainWinId = INVALID_WINDOW_ID;
224 for (auto iter = windowMap_.begin(); iter != windowMap_.end(); iter++) {
225 auto win = iter->second.second;
226 if (context.get() == win->GetContext().get() && WindowHelper::IsMainWindow(win->GetType())) {
227 mainWinId = win->GetWindowId();
228 WLOGI("GetTopWindow Find MainWinId:%{public}u.", mainWinId);
229 break;
230 }
231 }
232 WLOGI("GetTopWindowfinal winId:%{public}u!", mainWinId);
233 if (mainWinId == INVALID_WINDOW_ID) {
234 WLOGFE("Cannot find topWindow!");
235 return nullptr;
236 }
237 uint32_t topWinId = INVALID_WINDOW_ID;
238 WMError ret = SingletonContainer::Get<WindowAdapter>().GetTopWindowId(mainWinId, topWinId);
239 if (ret != WMError::WM_OK) {
240 WLOGFE("GetTopWindowId failed with errCode:%{public}d", static_cast<int32_t>(ret));
241 return nullptr;
242 }
243 return FindWindowById(topWinId);
244 }
245
GetSubWindow(uint32_t parentId)246 std::vector<sptr<Window>> WindowImpl::GetSubWindow(uint32_t parentId)
247 {
248 if (subWindowMap_.find(parentId) == subWindowMap_.end()) {
249 WLOGFE("Cannot parentWindow with id: %{public}u!", parentId);
250 return std::vector<sptr<Window>>();
251 }
252 return std::vector<sptr<Window>>(subWindowMap_[parentId].begin(), subWindowMap_[parentId].end());
253 }
254
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)255 void WindowImpl::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
256 {
257 for (const auto& winPair : windowMap_) {
258 auto window = winPair.second.second;
259 window->UpdateConfiguration(configuration);
260 }
261 }
262
GetSurfaceNode() const263 std::shared_ptr<RSSurfaceNode> WindowImpl::GetSurfaceNode() const
264 {
265 return surfaceNode_;
266 }
267
GetRect() const268 Rect WindowImpl::GetRect() const
269 {
270 return property_->GetWindowRect();
271 }
272
GetRequestRect() const273 Rect WindowImpl::GetRequestRect() const
274 {
275 return property_->GetRequestRect();
276 }
277
GetType() const278 WindowType WindowImpl::GetType() const
279 {
280 return property_->GetWindowType();
281 }
282
GetMode() const283 WindowMode WindowImpl::GetMode() const
284 {
285 return property_->GetWindowMode();
286 }
287
GetAlpha() const288 float WindowImpl::GetAlpha() const
289 {
290 return property_->GetAlpha();
291 }
292
GetWindowState() const293 WindowState WindowImpl::GetWindowState() const
294 {
295 return state_;
296 }
297
SetFocusable(bool isFocusable)298 WMError WindowImpl::SetFocusable(bool isFocusable)
299 {
300 if (!IsWindowValid()) {
301 return WMError::WM_ERROR_INVALID_WINDOW;
302 }
303 property_->SetFocusable(isFocusable);
304 if (state_ == WindowState::STATE_SHOWN) {
305 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_FOCUSABLE);
306 }
307 return WMError::WM_OK;
308 }
309
GetFocusable() const310 bool WindowImpl::GetFocusable() const
311 {
312 return property_->GetFocusable();
313 }
314
SetTouchable(bool isTouchable)315 WMError WindowImpl::SetTouchable(bool isTouchable)
316 {
317 if (!IsWindowValid()) {
318 return WMError::WM_ERROR_INVALID_WINDOW;
319 }
320 property_->SetTouchable(isTouchable);
321 if (state_ == WindowState::STATE_SHOWN) {
322 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_TOUCHABLE);
323 }
324 return WMError::WM_OK;
325 }
326
GetTouchable() const327 bool WindowImpl::GetTouchable() const
328 {
329 return property_->GetTouchable();
330 }
331
GetWindowName() const332 const std::string& WindowImpl::GetWindowName() const
333 {
334 return name_;
335 }
336
GetWindowId() const337 uint32_t WindowImpl::GetWindowId() const
338 {
339 return property_->GetWindowId();
340 }
341
GetDisplayId() const342 uint64_t WindowImpl::GetDisplayId() const
343 {
344 return property_->GetDisplayId();
345 }
346
GetWindowFlags() const347 uint32_t WindowImpl::GetWindowFlags() const
348 {
349 return property_->GetWindowFlags();
350 }
351
GetRequestModeSupportInfo() const352 uint32_t WindowImpl::GetRequestModeSupportInfo() const
353 {
354 return property_->GetRequestModeSupportInfo();
355 }
356
GetModeSupportInfo() const357 uint32_t WindowImpl::GetModeSupportInfo() const
358 {
359 return property_->GetModeSupportInfo();
360 }
361
IsMainHandlerAvailable() const362 bool WindowImpl::IsMainHandlerAvailable() const
363 {
364 return isMainHandlerAvailable_;
365 }
366
GetSystemBarPropertyByType(WindowType type) const367 SystemBarProperty WindowImpl::GetSystemBarPropertyByType(WindowType type) const
368 {
369 auto curProperties = property_->GetSystemBarProperty();
370 return curProperties[type];
371 }
372
GetAvoidAreaByType(AvoidAreaType type,AvoidArea & avoidArea)373 WMError WindowImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea)
374 {
375 if (!IsWindowValid()) {
376 return WMError::WM_ERROR_INVALID_WINDOW;
377 }
378 WLOGI("GetAvoidAreaByType Search Type: %{public}u", static_cast<uint32_t>(type));
379 uint32_t windowId = property_->GetWindowId();
380 WMError ret = SingletonContainer::Get<WindowAdapter>().GetAvoidAreaByType(windowId, type, avoidArea);
381 if (ret != WMError::WM_OK) {
382 WLOGFE("GetAvoidAreaByType errCode:%{public}d winId:%{public}u Type is :%{public}u.",
383 static_cast<int32_t>(ret), property_->GetWindowId(), static_cast<uint32_t>(type));
384 }
385 return ret;
386 }
387
SetWindowType(WindowType type)388 WMError WindowImpl::SetWindowType(WindowType type)
389 {
390 WLOGFD("window id: %{public}u, type:%{public}u.", property_->GetWindowId(), static_cast<uint32_t>(type));
391 if (type != WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW && !Permission::IsSystemCalling() &&
392 !Permission::IsStartByHdcd()) {
393 WLOGFE("set window type permission denied!");
394 return WMError::WM_ERROR_NOT_SYSTEM_APP;
395 }
396 if (!IsWindowValid()) {
397 return WMError::WM_ERROR_INVALID_WINDOW;
398 }
399 if (state_ == WindowState::STATE_CREATED) {
400 if (!(WindowHelper::IsAppWindow(type) || WindowHelper::IsSystemWindow(type))) {
401 WLOGFE("window type is invalid %{public}u.", type);
402 return WMError::WM_ERROR_INVALID_PARAM;
403 }
404 property_->SetWindowType(type);
405 UpdateDecorEnable();
406 AdjustWindowAnimationFlag();
407 return WMError::WM_OK;
408 }
409 if (property_->GetWindowType() != type) {
410 return WMError::WM_ERROR_INVALID_PARAM;
411 }
412 return WMError::WM_OK;
413 }
414
SetWindowMode(WindowMode mode)415 WMError WindowImpl::SetWindowMode(WindowMode mode)
416 {
417 WLOGI("Window %{public}u mode %{public}u", property_->GetWindowId(), static_cast<uint32_t>(mode));
418 if (!IsWindowValid()) {
419 return WMError::WM_ERROR_INVALID_WINDOW;
420 }
421 if (!WindowHelper::IsWindowModeSupported(GetModeSupportInfo(), mode)) {
422 WLOGE("window %{public}u do not support mode: %{public}u",
423 property_->GetWindowId(), static_cast<uint32_t>(mode));
424 return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
425 }
426 if (state_ == WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
427 UpdateMode(mode);
428 } else if (state_ == WindowState::STATE_SHOWN) {
429 WindowMode lastMode = property_->GetWindowMode();
430 property_->SetWindowMode(mode);
431 UpdateDecorEnable();
432 WMError ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_MODE);
433 if (ret != WMError::WM_OK) {
434 property_->SetWindowMode(lastMode);
435 return ret;
436 }
437 // set client window mode if success.
438 UpdateMode(mode);
439 }
440 if (property_->GetWindowMode() != mode) {
441 WLOGFE("set window mode filed! id: %{public}u.", property_->GetWindowId());
442 return WMError::WM_ERROR_INVALID_PARAM;
443 }
444 return WMError::WM_OK;
445 }
446
SetAlpha(float alpha)447 WMError WindowImpl::SetAlpha(float alpha)
448 {
449 WLOGI("Window %{public}u alpha %{public}f", property_->GetWindowId(), alpha);
450 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
451 WLOGFE("set alpha permission denied!");
452 return WMError::WM_ERROR_NOT_SYSTEM_APP;
453 }
454 if (!IsWindowValid()) {
455 return WMError::WM_ERROR_INVALID_WINDOW;
456 }
457 property_->SetAlpha(alpha);
458 surfaceNode_->SetAlpha(alpha);
459 RSTransaction::FlushImplicitTransaction();
460 return WMError::WM_OK;
461 }
462
SetTransform(const Transform & trans)463 WMError WindowImpl::SetTransform(const Transform& trans)
464 {
465 WLOGI("Window %{public}u", property_->GetWindowId());
466 if (!IsWindowValid()) {
467 return WMError::WM_ERROR_INVALID_WINDOW;
468 }
469 Transform oriTrans = property_->GetTransform();
470 property_->SetTransform(trans);
471 WMError ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_TRANSFORM_PROPERTY);
472 if (ret != WMError::WM_OK) {
473 WLOGFE("SetTransform errCode:%{public}d winId:%{public}u",
474 static_cast<int32_t>(ret), property_->GetWindowId());
475 property_->SetTransform(oriTrans); // reset to ori transform when update failed
476 }
477 if (property_->IsDisplayZoomOn()) {
478 TransformSurfaceNode(property_->GetZoomTransform());
479 } else {
480 TransformSurfaceNode(trans);
481 }
482 return ret;
483 }
484
GetTransform() const485 const Transform& WindowImpl::GetTransform() const
486 {
487 return property_->GetTransform();
488 }
489
GetZoomTransform() const490 const Transform& WindowImpl::GetZoomTransform() const
491 {
492 return property_->GetZoomTransform();
493 }
494
AddWindowFlag(WindowFlag flag)495 WMError WindowImpl::AddWindowFlag(WindowFlag flag)
496 {
497 if (!IsWindowValid()) {
498 return WMError::WM_ERROR_INVALID_WINDOW;
499 }
500 if (flag == WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED && state_ != WindowState::STATE_CREATED) {
501 WLOGFE("Only support add show when locked when window create, id: %{public}u", property_->GetWindowId());
502 return WMError::WM_ERROR_INVALID_WINDOW;
503 }
504 if (flag == WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE && !Permission::IsSystemCalling()) {
505 WLOGFE("set forbid split move permission denied!");
506 return WMError::WM_ERROR_NOT_SYSTEM_APP;
507 }
508 uint32_t updateFlags = property_->GetWindowFlags() | (static_cast<uint32_t>(flag));
509 return SetWindowFlags(updateFlags);
510 }
511
RemoveWindowFlag(WindowFlag flag)512 WMError WindowImpl::RemoveWindowFlag(WindowFlag flag)
513 {
514 if (!IsWindowValid()) {
515 return WMError::WM_ERROR_INVALID_WINDOW;
516 }
517 if (flag == WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED && state_ != WindowState::STATE_CREATED) {
518 WLOGFE("Only support remove show when locked when window create, id: %{public}u", property_->GetWindowId());
519 return WMError::WM_ERROR_INVALID_WINDOW;
520 }
521 if (flag == WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE && !Permission::IsSystemCalling()) {
522 WLOGFE("set forbid split move permission denied!");
523 return WMError::WM_ERROR_NOT_SYSTEM_APP;
524 }
525 uint32_t updateFlags = property_->GetWindowFlags() & (~(static_cast<uint32_t>(flag)));
526 return SetWindowFlags(updateFlags);
527 }
528
SetWindowFlags(uint32_t flags)529 WMError WindowImpl::SetWindowFlags(uint32_t flags)
530 {
531 WLOGI("Window %{public}u flags %{public}u", property_->GetWindowId(), flags);
532 if (!IsWindowValid()) {
533 return WMError::WM_ERROR_INVALID_WINDOW;
534 }
535 if (property_->GetWindowFlags() == flags) {
536 return WMError::WM_OK;
537 }
538 auto oriFlags = property_->GetWindowFlags();
539 property_->SetWindowFlags(flags);
540 if (state_ == WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
541 return WMError::WM_OK;
542 }
543 WMError ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_FLAGS);
544 if (ret != WMError::WM_OK) {
545 WLOGFE("SetWindowFlags errCode:%{public}d winId:%{public}u",
546 static_cast<int32_t>(ret), property_->GetWindowId());
547 property_->SetWindowFlags(oriFlags);
548 }
549 return ret;
550 }
551
OnNewWant(const AAFwk::Want & want)552 void WindowImpl::OnNewWant(const AAFwk::Want& want)
553 {
554 WLOGI("Window [name:%{public}s, id:%{public}u]", name_.c_str(), property_->GetWindowId());
555 if (uiContent_ != nullptr) {
556 uiContent_->OnNewWant(want);
557 }
558 }
559
NapiSetUIContent(const std::string & contentInfo,napi_env env,napi_value storage,bool isdistributed,sptr<IRemoteObject> token,AppExecFwk::Ability * ability)560 WMError WindowImpl::NapiSetUIContent(const std::string& contentInfo, napi_env env, napi_value storage,
561 bool isdistributed, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
562 {
563 return SetUIContentInner(contentInfo, env, storage,
564 isdistributed ? WindowSetUIContentType::DISTRIBUTE : WindowSetUIContentType::DEFAULT, ability);
565 }
566
SetUIContentByName(const std::string & contentInfo,napi_env env,napi_value storage,AppExecFwk::Ability * ability)567 WMError WindowImpl::SetUIContentByName(
568 const std::string& contentInfo, napi_env env, napi_value storage, AppExecFwk::Ability* ability)
569 {
570 return SetUIContentInner(contentInfo, env, storage, WindowSetUIContentType::BY_NAME, ability);
571 }
572
SetUIContentByAbc(const std::string & contentInfo,napi_env env,napi_value storage,AppExecFwk::Ability * ability)573 WMError WindowImpl::SetUIContentByAbc(
574 const std::string& contentInfo, napi_env env, napi_value storage, AppExecFwk::Ability* ability)
575 {
576 return SetUIContentInner(contentInfo, env, storage, WindowSetUIContentType::BY_ABC, ability);
577 }
578
SetUIContentInner(const std::string & contentInfo,napi_env env,napi_value storage,WindowSetUIContentType type,AppExecFwk::Ability * ability)579 WMError WindowImpl::SetUIContentInner(const std::string& contentInfo, napi_env env, napi_value storage,
580 WindowSetUIContentType type, AppExecFwk::Ability* ability)
581 {
582 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "loadContent");
583 if (!IsWindowValid()) {
584 WLOGFD("interrupt set uicontent because window is invalid! window state: %{public}d", state_);
585 return WMError::WM_ERROR_INVALID_WINDOW;
586 }
587 WLOGFD("NapiSetUIContent: %{public}s", contentInfo.c_str());
588 if (uiContent_) {
589 uiContent_->Destroy();
590 }
591 std::unique_ptr<Ace::UIContent> uiContent;
592 if (ability != nullptr) {
593 uiContent = Ace::UIContent::Create(ability);
594 } else {
595 uiContent = Ace::UIContent::Create(context_.get(), reinterpret_cast<NativeEngine*>(env));
596 }
597 if (uiContent == nullptr) {
598 WLOGFE("fail to NapiSetUIContent id: %{public}u", property_->GetWindowId());
599 return WMError::WM_ERROR_NULLPTR;
600 }
601
602 OHOS::Ace::UIContentErrorCode aceRet = OHOS::Ace::UIContentErrorCode::NO_ERRORS;
603 switch (type) {
604 default:
605 case WindowSetUIContentType::DEFAULT:
606 aceRet = uiContent->Initialize(this, contentInfo, storage);
607 break;
608 case WindowSetUIContentType::DISTRIBUTE:
609 aceRet = uiContent->Restore(this, contentInfo, storage);
610 break;
611 case WindowSetUIContentType::BY_NAME:
612 aceRet = uiContent->InitializeByName(this, contentInfo, storage);
613 break;
614 case WindowSetUIContentType::BY_ABC:
615 auto abcContent = GetAbcContent(contentInfo);
616 aceRet = uiContent->Initialize(this, abcContent, storage, contentInfo);
617 break;
618 }
619 // make uiContent available after Initialize/Restore
620 {
621 std::lock_guard<std::recursive_mutex> lock(mutex_);
622 uiContent_ = std::move(uiContent);
623 }
624
625 if (isIgnoreSafeAreaNeedNotify_) {
626 uiContent_->SetIgnoreViewSafeArea(isIgnoreSafeArea_);
627 }
628 UpdateDecorEnable(true);
629
630 if (state_ == WindowState::STATE_SHOWN) {
631 // UIContent may be nullptr when show window, need to notify again when window is shown
632 uiContent_->Foreground();
633 UpdateTitleButtonVisibility();
634 Ace::ViewportConfig config;
635 Rect rect = GetRect();
636 config.SetSize(rect.width_, rect.height_);
637 config.SetPosition(rect.posX_, rect.posY_);
638 auto display = SingletonContainer::IsDestroyed() ? nullptr :
639 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
640 if (display == nullptr) {
641 WLOGFE("get display failed displayId:%{public}" PRIu64", window id:%{public}u", property_->GetDisplayId(),
642 property_->GetWindowId());
643 return WMError::WM_ERROR_NULLPTR;
644 }
645 float virtualPixelRatio = display->GetVirtualPixelRatio();
646 config.SetDensity(virtualPixelRatio);
647 auto displayInfo = display->GetDisplayInfo();
648 if (displayInfo != nullptr) {
649 config.SetOrientation(static_cast<int32_t>(displayInfo->GetDisplayOrientation()));
650 TLOGI(WmsLogTag::WMS_LIFE, "notify window orientation change end.");
651 }
652 uiContent_->UpdateViewportConfig(config, WindowSizeChangeReason::UNDEFINED, nullptr);
653 WLOGFD("notify uiContent window size change end");
654 }
655 if (aceRet != OHOS::Ace::UIContentErrorCode::NO_ERRORS) {
656 WLOGFE("failed to init or restore uicontent with file %{public}s. errorCode: %{public}d",
657 contentInfo.c_str(), static_cast<uint16_t>(aceRet));
658 return WMError::WM_ERROR_INVALID_PARAM;
659 }
660 return WMError::WM_OK;
661 }
662
GetVirtualPixelRatio()663 float WindowImpl::GetVirtualPixelRatio()
664 {
665 float vpr = 1.0f; // This is an abnormal value, which is used to identify abnormal scenarios.
666 auto display = SingletonContainer::IsDestroyed() ? nullptr :
667 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
668 if (display == nullptr) {
669 TLOGE(WmsLogTag::WMS_LAYOUT, "get display failed displayId:%{public}" PRIu64 ", window id:%{public}u",
670 property_->GetDisplayId(), property_->GetWindowId());
671 return vpr;
672 }
673 return display->GetVirtualPixelRatio();
674 }
675
GetAbcContent(const std::string & abcPath)676 std::shared_ptr<std::vector<uint8_t>> WindowImpl::GetAbcContent(const std::string& abcPath)
677 {
678 std::filesystem::path abcFile { abcPath };
679 if (abcFile.empty() || !abcFile.is_absolute() || !std::filesystem::exists(abcFile)) {
680 WLOGFE("abc file path is not valid");
681 return nullptr;
682 }
683 int begin, end;
684 std::fstream file(abcFile, std::ios::in | std::ios::binary);
685 if (!file) {
686 WLOGFE("abc file is not valid");
687 return nullptr;
688 }
689 begin = file.tellg();
690 file.seekg(0, std::ios::end);
691 end = file.tellg();
692 int len = end - begin;
693 WLOGFD("abc file: %{public}s, size: %{public}d", abcPath.c_str(), len);
694
695 if (len <= 0) {
696 WLOGFE("abc file size is 0");
697 return nullptr;
698 }
699 std::vector<uint8_t> abcBytes(len);
700 file.seekg(0, std::ios::beg);
701 file.read(reinterpret_cast<char *>(abcBytes.data()), len);
702 return std::make_shared<std::vector<uint8_t>>(abcBytes);
703 }
704
GetUIContent() const705 Ace::UIContent* WindowImpl::GetUIContent() const
706 {
707 return uiContent_.get();
708 }
709
GetUIContentWithId(uint32_t winId) const710 Ace::UIContent* WindowImpl::GetUIContentWithId(uint32_t winId) const
711 {
712 return nullptr;
713 }
714
GetContentInfo()715 std::string WindowImpl::GetContentInfo()
716 {
717 WLOGFD("GetContentInfo");
718 if (uiContent_ == nullptr) {
719 WLOGFE("fail to GetContentInfo id: %{public}u", property_->GetWindowId());
720 return "";
721 }
722 return uiContent_->GetContentInfo();
723 }
724
GetColorSpaceFromSurfaceGamut(GraphicColorGamut colorGamut)725 ColorSpace WindowImpl::GetColorSpaceFromSurfaceGamut(GraphicColorGamut colorGamut)
726 {
727 for (auto item: colorSpaceConvertMap) {
728 if (item.surfaceColorGamut == colorGamut) {
729 return item.colorSpace;
730 }
731 }
732 return ColorSpace::COLOR_SPACE_DEFAULT;
733 }
734
GetSurfaceGamutFromColorSpace(ColorSpace colorSpace)735 GraphicColorGamut WindowImpl::GetSurfaceGamutFromColorSpace(ColorSpace colorSpace)
736 {
737 for (auto item: colorSpaceConvertMap) {
738 if (item.colorSpace == colorSpace) {
739 return item.surfaceColorGamut;
740 }
741 }
742 return GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
743 }
744
IsSupportWideGamut()745 bool WindowImpl::IsSupportWideGamut()
746 {
747 return true;
748 }
749
SetColorSpace(ColorSpace colorSpace)750 void WindowImpl::SetColorSpace(ColorSpace colorSpace)
751 {
752 if (!IsWindowValid()) {
753 return;
754 }
755 if (surfaceNode_ == nullptr) {
756 TLOGE(WmsLogTag::DEFAULT, "surface node is nullptr, winId: %{public}u", GetWindowId());
757 return;
758 }
759 auto surfaceGamut = GetSurfaceGamutFromColorSpace(colorSpace);
760 surfaceNode_->SetColorSpace(surfaceGamut);
761 }
762
GetColorSpace()763 ColorSpace WindowImpl::GetColorSpace()
764 {
765 if (!IsWindowValid()) {
766 return ColorSpace::COLOR_SPACE_DEFAULT;
767 }
768 if (surfaceNode_ == nullptr) {
769 TLOGE(WmsLogTag::DEFAULT, "surface node is nullptr, winId: %{public}u", GetWindowId());
770 return ColorSpace::COLOR_SPACE_DEFAULT;
771 }
772 auto surfaceGamut = surfaceNode_->GetColorSpace();
773 return GetColorSpaceFromSurfaceGamut(surfaceGamut);
774 }
775
Snapshot()776 std::shared_ptr<Media::PixelMap> WindowImpl::Snapshot()
777 {
778 if (!IsWindowValid()) {
779 return nullptr;
780 }
781 std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
782 auto isSucceeded = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
783 std::shared_ptr<Media::PixelMap> pixelMap;
784 if (isSucceeded) {
785 pixelMap = callback->GetResult(2000); // wait for <= 2000ms
786 } else {
787 pixelMap = SingletonContainer::Get<WindowAdapter>().GetSnapshot(property_->GetWindowId());
788 }
789 if (pixelMap != nullptr) {
790 WLOGFD("WMS-Client Save WxH = %{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
791 } else {
792 WLOGFE("Failed to get pixelmap, return nullptr!");
793 }
794 return pixelMap;
795 }
796
DumpInfo(const std::vector<std::string> & params,std::vector<std::string> & info)797 void WindowImpl::DumpInfo(const std::vector<std::string>& params, std::vector<std::string>& info)
798 {
799 if (params.size() == 1 && params[0] == PARAM_DUMP_HELP) { // 1: params num
800 WLOGFD("Dump ArkUI help Info");
801 Ace::UIContent::ShowDumpHelp(info);
802 SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
803 return;
804 }
805 WLOGFD("ArkUI:DumpInfo");
806 if (uiContent_ != nullptr) {
807 uiContent_->DumpInfo(params, info);
808 }
809 SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
810 }
811
SetSystemBarProperty(WindowType type,const SystemBarProperty & property)812 WMError WindowImpl::SetSystemBarProperty(WindowType type, const SystemBarProperty& property)
813 {
814 WLOGI("Window %{public}u type %{public}u enable:%{public}u, bgColor:%{public}x, Color:%{public}x ",
815 property_->GetWindowId(), static_cast<uint32_t>(type), property.enable_,
816 property.backgroundColor_, property.contentColor_);
817 if (!IsWindowValid()) {
818 return WMError::WM_ERROR_INVALID_WINDOW;
819 }
820 if (GetSystemBarPropertyByType(type) == property) {
821 return WMError::WM_OK;
822 }
823 property_->SetSystemBarProperty(type, property);
824 if (state_ == WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
825 return WMError::WM_OK;
826 }
827 WMError ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_OTHER_PROPS);
828 if (ret != WMError::WM_OK) {
829 WLOGFE("SetSystemBarProperty errCode:%{public}d winId:%{public}u",
830 static_cast<int32_t>(ret), property_->GetWindowId());
831 }
832 return ret;
833 }
834
SetSystemBarProperties(const std::map<WindowType,SystemBarProperty> & properties,const std::map<WindowType,SystemBarPropertyFlag> & propertyFlags)835 WMError WindowImpl::SetSystemBarProperties(const std::map<WindowType, SystemBarProperty>& properties,
836 const std::map<WindowType, SystemBarPropertyFlag>& propertyFlags)
837 {
838 SystemBarProperty current = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
839 auto flagIter = propertyFlags.find(WindowType::WINDOW_TYPE_STATUS_BAR);
840 auto propertyIter = properties.find(WindowType::WINDOW_TYPE_STATUS_BAR);
841 if ((flagIter != propertyFlags.end() && flagIter->second.contentColorFlag) &&
842 (propertyIter != properties.end() && current.contentColor_ != propertyIter->second.contentColor_)) {
843 current.contentColor_ = propertyIter->second.contentColor_;
844 current.settingFlag_ = static_cast<SystemBarSettingFlag>(
845 static_cast<uint32_t>(propertyIter->second.settingFlag_) |
846 static_cast<uint32_t>(SystemBarSettingFlag::COLOR_SETTING));
847 WLOGI("Window:%{public}u %{public}s set status bar content color %{public}u",
848 GetWindowId(), GetWindowName().c_str(), current.contentColor_);
849 return SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, current);
850 }
851 return WMError::WM_OK;
852 }
853
GetSystemBarProperties(std::map<WindowType,SystemBarProperty> & properties)854 WMError WindowImpl::GetSystemBarProperties(std::map<WindowType, SystemBarProperty>& properties)
855 {
856 if (property_ != nullptr) {
857 WLOGI("Window:%{public}u", GetWindowId());
858 properties[WindowType::WINDOW_TYPE_STATUS_BAR] = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
859 } else {
860 WLOGFE("inner property is null");
861 }
862 return WMError::WM_OK;
863 }
864
SetSpecificBarProperty(WindowType type,const SystemBarProperty & property)865 WMError WindowImpl::SetSpecificBarProperty(WindowType type, const SystemBarProperty& property)
866 {
867 return WMError::WM_OK;
868 }
869
UpdateSystemBarProperty(bool status)870 WMError WindowImpl::UpdateSystemBarProperty(bool status)
871 {
872 if (!IsWindowValid()) {
873 WLOGFE("PutSystemBarProperty errCode:%{public}d winId:%{public}u",
874 static_cast<int32_t>(WMError::WM_ERROR_INVALID_WINDOW), property_->GetWindowId());
875 return WMError::WM_ERROR_INVALID_WINDOW;
876 }
877
878 SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
879 SystemBarProperty naviProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
880 if (status) {
881 statusProperty.enable_ = false;
882 naviProperty.enable_ = false;
883 } else {
884 statusProperty.enable_ = true;
885 naviProperty.enable_ = true;
886 }
887
888 if ((GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR) == statusProperty) &&
889 (GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_BAR) == naviProperty)) {
890 return WMError::WM_OK;
891 }
892 if (!(GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR) == statusProperty)) {
893 property_->SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
894 }
895 if (!(GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_BAR) == naviProperty)) {
896 property_->SetSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, naviProperty);
897 }
898 if (state_ == WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
899 return WMError::WM_OK;
900 }
901
902 WMError ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_OTHER_PROPS);
903 if (ret != WMError::WM_OK) {
904 WLOGFE("SetSystemBarProperty errCode:%{public}d winId:%{public}u",
905 static_cast<int32_t>(ret), property_->GetWindowId());
906 }
907 return ret;
908 }
909
SetLayoutFullScreen(bool status)910 WMError WindowImpl::SetLayoutFullScreen(bool status)
911 {
912 WLOGI("Window %{public}u status: %{public}u", property_->GetWindowId(), status);
913 if (!IsWindowValid() ||
914 !WindowHelper::IsWindowModeSupported(GetModeSupportInfo(), WindowMode::WINDOW_MODE_FULLSCREEN)) {
915 WLOGFE("invalid window or fullscreen mode is not be supported, winId:%{public}u", property_->GetWindowId());
916 return WMError::WM_ERROR_INVALID_WINDOW;
917 }
918 WMError ret = WMError::WM_OK;
919 uint32_t version = 0;
920 if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
921 version = context_->GetApplicationInfo()->apiCompatibleVersion;
922 }
923 ret = SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
924 if (ret != WMError::WM_OK) {
925 WLOGFE("SetWindowMode errCode:%{public}d winId:%{public}u",
926 static_cast<int32_t>(ret), property_->GetWindowId());
927 return ret;
928 }
929 isIgnoreSafeArea_ = status;
930 // 10 ArkUI new framework support after API10
931 if (version >= 10) {
932 if (uiContent_ != nullptr) {
933 uiContent_->SetIgnoreViewSafeArea(status);
934 }
935 isIgnoreSafeAreaNeedNotify_ = true;
936 } else {
937 if (status) {
938 ret = RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
939 if (ret != WMError::WM_OK) {
940 WLOGFE("RemoveWindowFlag errCode:%{public}d winId:%{public}u",
941 static_cast<int32_t>(ret), property_->GetWindowId());
942 return ret;
943 }
944 } else {
945 ret = AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
946 if (ret != WMError::WM_OK) {
947 WLOGFE("AddWindowFlag errCode:%{public}d winId:%{public}u",
948 static_cast<int32_t>(ret), property_->GetWindowId());
949 return ret;
950 }
951 }
952 }
953 enableImmersiveMode_ = status;
954 return ret;
955 }
956
SetFullScreen(bool status)957 WMError WindowImpl::SetFullScreen(bool status)
958 {
959 WLOGI("Window %{public}u status: %{public}d", property_->GetWindowId(), status);
960 if (!IsWindowValid() ||
961 !WindowHelper::IsWindowModeSupported(GetModeSupportInfo(), WindowMode::WINDOW_MODE_FULLSCREEN)) {
962 WLOGFE("invalid window or fullscreen mode is not be supported, winId:%{public}u", property_->GetWindowId());
963 return WMError::WM_ERROR_INVALID_WINDOW;
964 }
965 WMError ret = UpdateSystemBarProperty(status);
966 if (ret != WMError::WM_OK) {
967 WLOGFE("UpdateSystemBarProperty errCode:%{public}d winId:%{public}u",
968 static_cast<int32_t>(ret), property_->GetWindowId());
969 }
970 ret = SetLayoutFullScreen(status);
971 if (ret != WMError::WM_OK) {
972 WLOGFE("SetLayoutFullScreen errCode:%{public}d winId:%{public}u",
973 static_cast<int32_t>(ret), property_->GetWindowId());
974 }
975 return ret;
976 }
977
SetFloatingMaximize(bool isEnter)978 WMError WindowImpl::SetFloatingMaximize(bool isEnter)
979 {
980 WLOGFI("id:%{public}d SetFloatingMaximize status: %{public}d", property_->GetWindowId(), isEnter);
981 if (!IsWindowValid() ||
982 !WindowHelper::IsWindowModeSupported(GetModeSupportInfo(), WindowMode::WINDOW_MODE_FULLSCREEN)) {
983 WLOGFE("invalid window or maximize mode is not be supported, winId:%{public}u", property_->GetWindowId());
984 return WMError::WM_ERROR_INVALID_WINDOW;
985 }
986
987 if (isEnter && GetGlobalMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
988 WMError ret = SetFullScreen(true);
989 if (ret == WMError::WM_OK) {
990 property_->SetMaximizeMode(MaximizeMode::MODE_FULL_FILL);
991 }
992 return ret;
993 }
994
995 if (isEnter && GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
996 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
997 SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
998 }
999 }
1000 property_->SetMaximizeMode(isEnter ? MaximizeMode::MODE_AVOID_SYSTEM_BAR : MaximizeMode::MODE_RECOVER);
1001 property_->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
1002 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
1003 }
1004
SetAspectRatio(float ratio)1005 WMError WindowImpl::SetAspectRatio(float ratio)
1006 {
1007 WLOGFI("windowId: %{public}u, ratio: %{public}f", GetWindowId(), ratio);
1008 if (!WindowHelper::IsMainWindow(GetType())) {
1009 WLOGFE("Invalid operation, windowId: %{public}u", GetWindowId());
1010 return WMError::WM_ERROR_INVALID_OPERATION;
1011 }
1012 if (MathHelper::NearZero(ratio) || ratio < 0.0f) {
1013 WLOGFE("Invalid param, ratio: %{public}f", ratio);
1014 return WMError::WM_ERROR_INVALID_PARAM;
1015 }
1016 property_->SetAspectRatio(ratio);
1017 if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
1018 WLOGFD("window is hidden or created! id: %{public}u, ratio: %{public}f ", property_->GetWindowId(), ratio);
1019 return WMError::WM_OK;
1020 }
1021 auto ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_ASPECT_RATIO);
1022 if (ret != WMError::WM_OK) {
1023 WLOGFE("Set AspectRatio failed. errorCode: %{public}u", ret);
1024 }
1025 return ret;
1026 }
1027
ResetAspectRatio()1028 WMError WindowImpl::ResetAspectRatio()
1029 {
1030 if (!IsWindowValid()) {
1031 TLOGE(WmsLogTag::DEFAULT, "Window is invalid");
1032 return WMError::WM_ERROR_INVALID_OPERATION;
1033 }
1034
1035 WLOGFI("windowId: %{public}u", GetWindowId());
1036 if (!WindowHelper::IsMainWindow(GetType())) {
1037 WLOGFE("Invalid operation, windowId: %{public}u", GetWindowId());
1038 return WMError::WM_ERROR_INVALID_OPERATION;
1039 }
1040 property_->SetAspectRatio(0.0);
1041 if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
1042 WLOGFD("window is hidden or created! id: %{public}u", property_->GetWindowId());
1043 return WMError::WM_OK;
1044 }
1045 UpdateProperty(PropertyChangeAction::ACTION_UPDATE_ASPECT_RATIO);
1046 return WMError::WM_OK;
1047 }
1048
MapFloatingWindowToAppIfNeeded()1049 void WindowImpl::MapFloatingWindowToAppIfNeeded()
1050 {
1051 if (!WindowHelper::IsAppFloatingWindow(GetType()) || context_.get() == nullptr) {
1052 return;
1053 }
1054
1055 WLOGFI("In");
1056 for (const auto& winPair : windowMap_) {
1057 auto win = winPair.second.second;
1058 if (win->GetType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
1059 context_.get() == win->GetContext().get()) {
1060 sptr<WindowImpl> selfImpl(this);
1061 appFloatingWindowMap_[win->GetWindowId()].push_back(selfImpl);
1062 WLOGFD("Map FloatingWindow %{public}u to AppMainWindow %{public}u, type is %{public}u",
1063 GetWindowId(), win->GetWindowId(), GetType());
1064 return;
1065 }
1066 }
1067 }
1068
MapDialogWindowToAppIfNeeded()1069 void WindowImpl::MapDialogWindowToAppIfNeeded()
1070 {
1071 if (GetType() != WindowType::WINDOW_TYPE_DIALOG) {
1072 return;
1073 }
1074
1075 for (const auto& winPair : windowMap_) {
1076 auto win = winPair.second.second;
1077 if (win->GetType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
1078 context_.get() == win->GetContext().get()) {
1079 sptr<WindowImpl> selfImpl(this);
1080 appDialogWindowMap_[win->GetWindowId()].push_back(selfImpl);
1081 WLOGFD("Map DialogWindow %{public}u to AppMainWindow %{public}u", GetWindowId(), win->GetWindowId());
1082 return;
1083 }
1084 }
1085 }
1086
UpdateProperty(PropertyChangeAction action)1087 WMError WindowImpl::UpdateProperty(PropertyChangeAction action)
1088 {
1089 return SingletonContainer::Get<WindowAdapter>().UpdateProperty(property_, action);
1090 }
1091
GetConfigurationFromAbilityInfo()1092 void WindowImpl::GetConfigurationFromAbilityInfo()
1093 {
1094 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
1095 if (abilityContext == nullptr) {
1096 WLOGFE("id:%{public}u is not ability Window", property_->GetWindowId());
1097 return;
1098 }
1099 auto abilityInfo = abilityContext->GetAbilityInfo();
1100 if (abilityInfo == nullptr) {
1101 WLOGFE("id:%{public}u Ability window get ability info failed", property_->GetWindowId());
1102 return;
1103 }
1104
1105 // get support modes configuration
1106 uint32_t modeSupportInfo = WindowHelper::ConvertSupportModesToSupportInfo(abilityInfo->windowModes);
1107 if (modeSupportInfo == 0) {
1108 WLOGFD("mode config param is 0, all modes is supported");
1109 modeSupportInfo = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
1110 }
1111 WLOGFD("winId: %{public}u, modeSupportInfo: %{public}u", GetWindowId(), modeSupportInfo);
1112 SetRequestModeSupportInfo(modeSupportInfo);
1113
1114 // get window size limits configuration
1115 WindowLimits sizeLimits;
1116 sizeLimits.maxWidth_ = abilityInfo->maxWindowWidth;
1117 sizeLimits.maxHeight_ = abilityInfo->maxWindowHeight;
1118 sizeLimits.minWidth_ = abilityInfo->minWindowWidth;
1119 sizeLimits.minHeight_ = abilityInfo->minWindowHeight;
1120 sizeLimits.maxRatio_ = static_cast<float>(abilityInfo->maxWindowRatio);
1121 sizeLimits.minRatio_ = static_cast<float>(abilityInfo->minWindowRatio);
1122 property_->SetSizeLimits(sizeLimits);
1123
1124 // get orientation configuration
1125 OHOS::AppExecFwk::DisplayOrientation displayOrientation =
1126 static_cast<OHOS::AppExecFwk::DisplayOrientation>(
1127 static_cast<uint32_t>(abilityInfo->orientation));
1128 if (ABILITY_TO_WMS_ORIENTATION_MAP.count(displayOrientation) == 0) {
1129 WLOGFE("id:%{public}u Do not support this Orientation type", property_->GetWindowId());
1130 return;
1131 }
1132 Orientation orientation = ABILITY_TO_WMS_ORIENTATION_MAP.at(displayOrientation);
1133 if (orientation < Orientation::BEGIN || orientation > Orientation::END) {
1134 WLOGFE("Set orientation from ability failed");
1135 return;
1136 }
1137 property_->SetRequestedOrientation(orientation);
1138 }
1139
UpdateTitleButtonVisibility()1140 void WindowImpl::UpdateTitleButtonVisibility()
1141 {
1142 WLOGFD("[Client] UpdateTitleButtonVisibility");
1143 std::lock_guard<std::recursive_mutex> lock(mutex_);
1144 if (uiContent_ == nullptr || !IsDecorEnable()) {
1145 return;
1146 }
1147 auto modeSupportInfo = GetModeSupportInfo();
1148 bool hideSplitButton = !(modeSupportInfo & WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY);
1149 // not support fullscreen in split and floating mode, or not support float in fullscreen mode
1150 bool hideMaximizeButton = (!(modeSupportInfo & WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN) &&
1151 (GetMode() == WindowMode::WINDOW_MODE_FLOATING || WindowHelper::IsSplitWindowMode(GetMode()))) ||
1152 (!(modeSupportInfo & WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING) &&
1153 GetMode() == WindowMode::WINDOW_MODE_FULLSCREEN);
1154 WLOGD("[Client] [hideSplit, hideMaximize]: [%{public}d, %{public}d]", hideSplitButton, hideMaximizeButton);
1155 uiContent_->HideWindowTitleButton(hideSplitButton, hideMaximizeButton, false);
1156 }
1157
IsAppMainOrSubOrFloatingWindow()1158 bool WindowImpl::IsAppMainOrSubOrFloatingWindow()
1159 {
1160 // App main window need decor config, stretchable config and effect config
1161 // App sub window and float window need effect config
1162 if (WindowHelper::IsAppWindow(GetType())) {
1163 return true;
1164 }
1165
1166 if (WindowHelper::IsAppFloatingWindow(GetType())) {
1167 for (const auto& winPair : windowMap_) {
1168 auto win = winPair.second.second;
1169 if (win != nullptr && win->GetType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
1170 context_.get() == win->GetContext().get()) {
1171 isAppFloatingWindow_ = true;
1172 return true;
1173 }
1174 }
1175 }
1176 return false;
1177 }
1178
SetSystemConfig()1179 void WindowImpl::SetSystemConfig()
1180 {
1181 if (!IsAppMainOrSubOrFloatingWindow()) {
1182 return;
1183 }
1184 if (SingletonContainer::Get<WindowAdapter>().GetSystemConfig(windowSystemConfig_) == WMError::WM_OK) {
1185 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
1186 WLOGFD("get system decor enable:%{public}d", windowSystemConfig_.isSystemDecorEnable_);
1187 property_->SetDecorEnable(windowSystemConfig_.isSystemDecorEnable_);
1188 WLOGFD("get stretchable enable:%{public}d", windowSystemConfig_.isStretchable_);
1189 property_->SetStretchable(windowSystemConfig_.isStretchable_);
1190 // if window mode is undefined, set it from configuration
1191 if (property_->GetWindowMode() == WindowMode::WINDOW_MODE_UNDEFINED) {
1192 WLOGFD("get default window mode:%{public}u", windowSystemConfig_.defaultWindowMode_);
1193 property_->SetWindowMode(windowSystemConfig_.defaultWindowMode_);
1194 }
1195 if (property_->GetLastWindowMode() == WindowMode::WINDOW_MODE_UNDEFINED) {
1196 property_->SetLastWindowMode(windowSystemConfig_.defaultWindowMode_);
1197 }
1198 }
1199 }
1200 }
1201
GetKeyboardAnimationConfig()1202 KeyboardAnimationConfig WindowImpl::GetKeyboardAnimationConfig()
1203 {
1204 return { windowSystemConfig_.animationIn_, windowSystemConfig_.animationOut_ };
1205 }
1206
WindowCreateCheck(uint32_t parentId)1207 WMError WindowImpl::WindowCreateCheck(uint32_t parentId)
1208 {
1209 if (vsyncStation_ == nullptr || !vsyncStation_->IsVsyncReceiverCreated()) {
1210 return WMError::WM_ERROR_NULLPTR;
1211 }
1212 // check window name, same window names are forbidden
1213 if (windowMap_.find(name_) != windowMap_.end()) {
1214 WLOGFE("WindowName(%{public}s) already exists.", name_.c_str());
1215 return WMError::WM_ERROR_REPEAT_OPERATION;
1216 }
1217 if (CheckCameraFloatingWindowMultiCreated(property_->GetWindowType())) {
1218 WLOGFE("Camera Floating Window already exists.");
1219 return WMError::WM_ERROR_REPEAT_OPERATION;
1220 }
1221 if (parentId == INVALID_WINDOW_ID) {
1222 if (WindowHelper::IsSystemSubWindow(property_->GetWindowType()) ||
1223 WindowHelper::IsSubWindow(property_->GetWindowType())) {
1224 return WMError::WM_ERROR_INVALID_PARENT;
1225 }
1226 return WMError::WM_OK;
1227 }
1228
1229 if (property_->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
1230 property_->SetParentId(parentId);
1231 } else {
1232 sptr<Window> parentWindow = nullptr;
1233 for (const auto& winPair : windowMap_) {
1234 if (winPair.second.first == parentId) {
1235 property_->SetParentId(parentId);
1236 parentWindow = winPair.second.second;
1237 break;
1238 }
1239 }
1240 if (WindowHelper::IsSystemSubWindow(property_->GetWindowType())) {
1241 if (parentWindow == nullptr) {
1242 return WMError::WM_ERROR_INVALID_PARENT;
1243 }
1244 if (!parentWindow->IsAllowHaveSystemSubWindow()) {
1245 return WMError::WM_ERROR_INVALID_PARENT;
1246 }
1247 }
1248 }
1249 if (property_->GetParentId() != parentId) {
1250 WLOGFE("Parent Window does not exist. ParentId is %{public}u", parentId);
1251 return WMError::WM_ERROR_INVALID_PARENT;
1252 }
1253
1254 return WMError::WM_OK;
1255 }
1256
ChangePropertyByApiVersion()1257 void WindowImpl::ChangePropertyByApiVersion()
1258 {
1259 uint32_t version = 0;
1260 if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
1261 version = context_->GetApplicationInfo()->apiCompatibleVersion;
1262 }
1263 // 10 ArkUI new framework support after API10
1264 if (version >= 10) {
1265 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
1266 SystemBarProperty statusSystemBarProperty(true, 0x00FFFFFF, 0xFF000000);
1267 SystemBarProperty navigationSystemBarProperty(true, 0x00FFFFFF, 0xFF000000);
1268 property_->SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusSystemBarProperty);
1269 property_->SetSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, navigationSystemBarProperty);
1270 }
1271 }
1272 }
1273
SetDefaultDisplayIdIfNeed()1274 void WindowImpl::SetDefaultDisplayIdIfNeed()
1275 {
1276 auto displayId = property_->GetDisplayId();
1277 if (displayId == DISPLAY_ID_INVALID) {
1278 auto defaultDisplayId = SingletonContainer::IsDestroyed() ? DISPLAY_ID_INVALID :
1279 SingletonContainer::Get<DisplayManager>().GetDefaultDisplayId();
1280 defaultDisplayId = (defaultDisplayId == DISPLAY_ID_INVALID) ? 0 : defaultDisplayId;
1281 property_->SetDisplayId(defaultDisplayId);
1282 TLOGI(WmsLogTag::WMS_LIFE, "Reset displayId: %{public}" PRIu64, defaultDisplayId);
1283 }
1284 }
1285
Create(uint32_t parentId,const std::shared_ptr<AbilityRuntime::Context> & context)1286 WMError WindowImpl::Create(uint32_t parentId, const std::shared_ptr<AbilityRuntime::Context>& context)
1287 {
1288 WLOGFD("Window[%{public}s] Create", name_.c_str());
1289 WMError ret = WindowCreateCheck(parentId);
1290 if (ret != WMError::WM_OK) {
1291 return ret;
1292 }
1293 SetDefaultDisplayIdIfNeed();
1294 context_ = context;
1295 sptr<WindowImpl> window(this);
1296 sptr<IWindow> windowAgent(new WindowAgent(window));
1297 static std::atomic<uint32_t> tempWindowId = 0;
1298 uint32_t windowId = tempWindowId++; // for test
1299 sptr<IRemoteObject> token = context_ ? context_->GetToken() : nullptr;
1300 if (token) {
1301 property_->SetTokenState(true);
1302 }
1303 ChangePropertyByApiVersion();
1304 InitAbilityInfo();
1305 SetSystemConfig();
1306
1307 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
1308 GetConfigurationFromAbilityInfo();
1309 } else if (property_->GetWindowMode() == WindowMode::WINDOW_MODE_UNDEFINED) {
1310 property_->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
1311 }
1312
1313 if (property_->GetWindowType() == WindowType::WINDOW_TYPE_VOLUME_OVERLAY && surfaceNode_) {
1314 surfaceNode_->SetFrameGravity(Gravity::TOP_LEFT);
1315 }
1316
1317 ret = SingletonContainer::Get<WindowAdapter>().CreateWindow(windowAgent, property_, surfaceNode_,
1318 windowId, token);
1319 RecordLifeCycleExceptionEvent(LifeCycleEvent::CREATE_EVENT, ret);
1320 if (ret != WMError::WM_OK) {
1321 WLOGFE("create window failed with errCode:%{public}d", static_cast<int32_t>(ret));
1322 return ret;
1323 }
1324 property_->SetWindowId(windowId);
1325 if (surfaceNode_) {
1326 surfaceNode_->SetWindowId(windowId);
1327 }
1328 sptr<Window> self(this);
1329 windowMap_.insert(std::make_pair(name_, std::pair<uint32_t, sptr<Window>>(windowId, self)));
1330 if (parentId != INVALID_WINDOW_ID) {
1331 subWindowMap_[property_->GetParentId()].push_back(window);
1332 }
1333
1334 MapFloatingWindowToAppIfNeeded();
1335 MapDialogWindowToAppIfNeeded();
1336 UpdateDecorEnable();
1337
1338 state_ = WindowState::STATE_CREATED;
1339 InputTransferStation::GetInstance().AddInputWindow(self);
1340 needRemoveWindowInputChannel_ = true;
1341 return ret;
1342 }
1343
PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)1344 bool WindowImpl::PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
1345 {
1346 if (uiContent_ != nullptr) {
1347 return uiContent_->ProcessKeyEvent(keyEvent, true);
1348 }
1349 return false;
1350 }
1351
InitAbilityInfo()1352 void WindowImpl::InitAbilityInfo()
1353 {
1354 AbilityInfo info;
1355 info.bundleName_ = SysCapUtil::GetBundleName();
1356 auto originalAbilityInfo = GetOriginalAbilityInfo();
1357 if (originalAbilityInfo != nullptr) {
1358 info.abilityName_ = originalAbilityInfo->name;
1359 } else {
1360 WLOGFD("original ability info is null %{public}s", name_.c_str());
1361 }
1362 property_->SetAbilityInfo(info);
1363 }
1364
GetOriginalAbilityInfo() const1365 std::shared_ptr<AppExecFwk::AbilityInfo> WindowImpl::GetOriginalAbilityInfo() const
1366 {
1367 if (context_ == nullptr) {
1368 WLOGFD("context is null %{public}s", name_.c_str());
1369 return nullptr;
1370 }
1371
1372 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
1373 if (abilityContext == nullptr) {
1374 WLOGFD("abilityContext is null %{public}s", name_.c_str());
1375 return nullptr;
1376 }
1377 return abilityContext->GetAbilityInfo();
1378 }
1379
BindDialogTarget(sptr<IRemoteObject> targetToken)1380 WMError WindowImpl::BindDialogTarget(sptr<IRemoteObject> targetToken)
1381 {
1382 if (!IsWindowValid()) {
1383 TLOGE(WmsLogTag::WMS_DIALOG, "window is invalid");
1384 return WMError::WM_ERROR_INVALID_WINDOW;
1385 }
1386 uint32_t windowId = property_->GetWindowId();
1387 WMError ret = SingletonContainer::Get<WindowAdapter>().BindDialogTarget(windowId, targetToken);
1388 if (ret != WMError::WM_OK) {
1389 WLOGFE("bind window failed with errCode:%{public}d", static_cast<int32_t>(ret));
1390 }
1391
1392 return ret;
1393 }
1394
DestroyDialogWindow()1395 void WindowImpl::DestroyDialogWindow()
1396 {
1397 // remove from appDialogWindowMap_
1398 for (auto& dialogWindows: appDialogWindowMap_) {
1399 for (auto iter = dialogWindows.second.begin(); iter != dialogWindows.second.end(); ++iter) {
1400 if ((*iter) == nullptr) {
1401 continue;
1402 }
1403 if ((*iter)->GetWindowId() == GetWindowId()) {
1404 dialogWindows.second.erase(iter);
1405 break;
1406 }
1407 }
1408 }
1409
1410 // Destroy app dialog window if exist
1411 if (appDialogWindowMap_.count(GetWindowId()) > 0) {
1412 auto& dialogWindows = appDialogWindowMap_.at(GetWindowId());
1413 for (auto iter = dialogWindows.begin(); iter != dialogWindows.end(); iter = dialogWindows.begin()) {
1414 if ((*iter) == nullptr) {
1415 dialogWindows.erase(iter);
1416 continue;
1417 }
1418 (*iter)->Destroy(false);
1419 }
1420 appDialogWindowMap_.erase(GetWindowId());
1421 }
1422 }
1423
DestroyFloatingWindow()1424 void WindowImpl::DestroyFloatingWindow()
1425 {
1426 // remove from appFloatingWindowMap_
1427 TLOGI(WmsLogTag::WMS_LIFE, "Remove from appFloatingWindowMap_");
1428 for (auto& floatingWindows: appFloatingWindowMap_) {
1429 for (auto iter = floatingWindows.second.begin(); iter != floatingWindows.second.end(); ++iter) {
1430 if ((*iter) == nullptr) {
1431 continue;
1432 }
1433 if ((*iter)->GetWindowId() == GetWindowId()) {
1434 floatingWindows.second.erase(iter);
1435 break;
1436 }
1437 }
1438 }
1439
1440 // Destroy app floating window if exist
1441 TLOGI(WmsLogTag::WMS_LIFE, "Destroy app floating window if exist");
1442 if (appFloatingWindowMap_.count(GetWindowId()) > 0) {
1443 auto& floatingWindows = appFloatingWindowMap_.at(GetWindowId());
1444 for (auto iter = floatingWindows.begin(); iter != floatingWindows.end(); iter = floatingWindows.begin()) {
1445 if ((*iter) == nullptr) {
1446 floatingWindows.erase(iter);
1447 continue;
1448 }
1449 (*iter)->Destroy();
1450 }
1451 appFloatingWindowMap_.erase(GetWindowId());
1452 }
1453 }
1454
DestroySubWindow()1455 void WindowImpl::DestroySubWindow()
1456 {
1457 if (subWindowMap_.count(property_->GetParentId()) > 0) { // remove from subWindowMap_
1458 auto& subWindows = subWindowMap_.at(property_->GetParentId());
1459 for (auto iter = subWindows.begin(); iter < subWindows.end(); ++iter) {
1460 if ((*iter) == nullptr) {
1461 continue;
1462 }
1463 if ((*iter)->GetWindowId() == GetWindowId()) {
1464 subWindows.erase(iter);
1465 break;
1466 }
1467 }
1468 }
1469
1470 if (subWindowMap_.count(GetWindowId()) > 0) { // remove from subWindowMap_ and windowMap_
1471 auto& subWindows = subWindowMap_.at(GetWindowId());
1472 for (auto iter = subWindows.begin(); iter != subWindows.end(); iter = subWindows.begin()) {
1473 if ((*iter) == nullptr) {
1474 subWindows.erase(iter);
1475 continue;
1476 }
1477 (*iter)->Destroy(false);
1478 }
1479 subWindowMap_[GetWindowId()].clear();
1480 subWindowMap_.erase(GetWindowId());
1481 }
1482 }
1483
ClearVsyncStation()1484 void WindowImpl::ClearVsyncStation()
1485 {
1486 std::lock_guard<std::recursive_mutex> lock(mutex_);
1487 if (vsyncStation_ != nullptr) {
1488 vsyncStation_.reset();
1489 }
1490 }
1491
Destroy()1492 WMError WindowImpl::Destroy()
1493 {
1494 return Destroy(true);
1495 }
1496
Destroy(bool needNotifyServer,bool needClearListener)1497 WMError WindowImpl::Destroy(bool needNotifyServer, bool needClearListener)
1498 {
1499 if (!IsWindowValid()) {
1500 return WMError::WM_OK;
1501 }
1502
1503 WLOGI("Window %{public}u Destroy", property_->GetWindowId());
1504 WMError ret = WMError::WM_OK;
1505 if (needNotifyServer) {
1506 NotifyBeforeDestroy(GetWindowName());
1507 if (subWindowMap_.count(GetWindowId()) > 0) {
1508 for (auto& subWindow : subWindowMap_.at(GetWindowId())) {
1509 NotifyBeforeSubWindowDestroy(subWindow);
1510 }
1511 }
1512 ret = SingletonContainer::Get<WindowAdapter>().DestroyWindow(property_->GetWindowId());
1513 RecordLifeCycleExceptionEvent(LifeCycleEvent::DESTROY_EVENT, ret);
1514 if (ret != WMError::WM_OK) {
1515 WLOGFE("destroy window failed with errCode:%{public}d", static_cast<int32_t>(ret));
1516 if (GetType() != WindowType::WINDOW_TYPE_DIALOG) {
1517 return ret;
1518 }
1519 }
1520 } else {
1521 WLOGI("no need to destroy");
1522 }
1523
1524 if (needRemoveWindowInputChannel_) {
1525 InputTransferStation::GetInstance().RemoveInputWindow(property_->GetWindowId());
1526 }
1527 windowMap_.erase(GetWindowName());
1528 if (needClearListener) {
1529 ClearListenersById(GetWindowId());
1530 }
1531 DestroySubWindow();
1532 DestroyFloatingWindow();
1533 DestroyDialogWindow();
1534 ClearVsyncStation();
1535 {
1536 std::lock_guard<std::recursive_mutex> lock(mutex_);
1537 state_ = WindowState::STATE_DESTROYED;
1538 }
1539 return ret;
1540 }
1541
NeedToStopShowing()1542 bool WindowImpl::NeedToStopShowing()
1543 {
1544 if (!WindowHelper::IsMainWindow(property_->GetWindowType())) {
1545 return false;
1546 }
1547 // show failed when current mode is not support or window only supports split mode and can show when locked
1548 bool isShowWhenLocked = GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
1549 if (!WindowHelper::IsWindowModeSupported(GetModeSupportInfo(), GetMode()) ||
1550 WindowHelper::IsOnlySupportSplitAndShowWhenLocked(isShowWhenLocked, GetModeSupportInfo())) {
1551 WLOGFE("current mode is not supported, windowId: %{public}u, modeSupportInfo: %{public}u, winMode: %{public}u",
1552 property_->GetWindowId(), GetModeSupportInfo(), GetMode());
1553 return true;
1554 }
1555 return false;
1556 }
1557
UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)1558 WMError WindowImpl::UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)
1559 {
1560 WLOGI("id: %{public}u UpdateRsTree, isAdd:%{public}u",
1561 property_->GetWindowId(), isAdd);
1562 if (!IsWindowValid()) {
1563 return WMError::WM_ERROR_INVALID_WINDOW;
1564 }
1565 if (!WindowHelper::IsSystemWindow(property_->GetWindowType())) {
1566 WLOGFE("only system window can set");
1567 return WMError::WM_ERROR_INVALID_OPERATION;
1568 }
1569 AdjustWindowAnimationFlag(false); // false means update rs tree with default option
1570 // need time out check
1571 WMError ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG);
1572 if (ret != WMError::WM_OK) {
1573 WLOGFE("UpdateProperty failed with errCode:%{public}d", static_cast<int32_t>(ret));
1574 return ret;
1575 }
1576 ret = SingletonContainer::Get<WindowAdapter>().UpdateRsTree(property_->GetWindowId(), isAdd);
1577 if (ret != WMError::WM_OK) {
1578 WLOGFE("UpdateRsTree failed with errCode:%{public}d", static_cast<int32_t>(ret));
1579 return ret;
1580 }
1581 return WMError::WM_OK;
1582 }
1583
AdjustWindowAnimationFlag(bool withAnimation)1584 void WindowImpl::AdjustWindowAnimationFlag(bool withAnimation)
1585 {
1586 // when show/hide with animation
1587 // use custom animation when transitionController exists; else use default animation
1588 WindowType winType = property_->GetWindowType();
1589 bool isAppWindow = WindowHelper::IsAppWindow(winType);
1590 if (withAnimation && !isAppWindow && animationTransitionController_) {
1591 // use custom animation
1592 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
1593 } else if ((isAppWindow && needDefaultAnimation_) || (withAnimation && !animationTransitionController_)) {
1594 // use default animation
1595 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::DEFAULT));
1596 } else if (winType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1597 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::INPUTE));
1598 } else {
1599 // with no animation
1600 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
1601 }
1602 }
1603
PreProcessShow(uint32_t reason,bool withAnimation)1604 WMError WindowImpl::PreProcessShow(uint32_t reason, bool withAnimation)
1605 {
1606 if (state_ == WindowState::STATE_FROZEN) {
1607 WLOGFE("window is frozen, can not be shown, windowId: %{public}u", property_->GetWindowId());
1608 return WMError::WM_ERROR_INVALID_OPERATION;
1609 }
1610 SetDefaultOption();
1611 SetModeSupportInfo(GetRequestModeSupportInfo());
1612 AdjustWindowAnimationFlag(withAnimation);
1613
1614 if (NeedToStopShowing()) { // true means stop showing
1615 return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
1616 }
1617
1618 // update title button visibility when show
1619 UpdateTitleButtonVisibility();
1620 return WMError::WM_OK;
1621 }
1622
Show(uint32_t reason,bool withAnimation,bool withFocus)1623 WMError WindowImpl::Show(uint32_t reason, bool withAnimation, bool withFocus)
1624 {
1625 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, __PRETTY_FUNCTION__);
1626 WLOGFD("Window Show [name:%{public}s, id:%{public}u, mode: %{public}u], reason:%{public}u, "
1627 "withAnimation:%{public}d", name_.c_str(), property_->GetWindowId(), GetMode(), reason, withAnimation);
1628 if (!IsWindowValid()) {
1629 return WMError::WM_ERROR_INVALID_WINDOW;
1630 }
1631 UpdateDecorEnable(true);
1632 if (static_cast<WindowStateChangeReason>(reason) == WindowStateChangeReason::KEYGUARD ||
1633 static_cast<WindowStateChangeReason>(reason) == WindowStateChangeReason::TOGGLING) {
1634 state_ = WindowState::STATE_SHOWN;
1635 NotifyAfterForeground();
1636 return WMError::WM_OK;
1637 }
1638 if (state_ == WindowState::STATE_SHOWN) {
1639 if (property_->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
1640 SingletonContainer::Get<WindowAdapter>().MinimizeAllAppWindows(property_->GetDisplayId());
1641 } else {
1642 WLOGI("window is already shown id: %{public}u", property_->GetWindowId());
1643 SingletonContainer::Get<WindowAdapter>().ProcessPointDown(property_->GetWindowId(), false);
1644 }
1645 // when show sub window, check its parent state
1646 sptr<Window> parent = FindWindowById(property_->GetParentId());
1647 if (parent != nullptr && parent->GetWindowState() == WindowState::STATE_HIDDEN) {
1648 WLOGFD("sub window can not show, because main window hide");
1649 return WMError::WM_OK;
1650 } else {
1651 NotifyAfterForeground(true, false);
1652 }
1653 return WMError::WM_OK;
1654 }
1655 WMError ret = PreProcessShow(reason, withAnimation);
1656 if (ret != WMError::WM_OK) {
1657 NotifyForegroundFailed(ret);
1658 return ret;
1659 }
1660 // this lock solves the multithreading problem when reading WindowState
1661 std::lock_guard<std::recursive_mutex> lock(windowStateMutex_);
1662 ret = SingletonContainer::Get<WindowAdapter>().AddWindow(property_);
1663 RecordLifeCycleExceptionEvent(LifeCycleEvent::SHOW_EVENT, ret);
1664 if (ret == WMError::WM_OK) {
1665 UpdateWindowStateWhenShow();
1666 } else {
1667 NotifyForegroundFailed(ret);
1668 WLOGFE("show window id:%{public}u errCode:%{public}d", property_->GetWindowId(), static_cast<int32_t>(ret));
1669 }
1670 // systemui make startbar resident, when refactor immersive, this code can delete
1671 if (property_->GetRequestedOrientation() == Orientation::HORIZONTAL
1672 || property_->GetRequestedOrientation() == Orientation::REVERSE_HORIZONTAL) {
1673 RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
1674 }
1675 needNotifyFocusLater_ = false;
1676 return ret;
1677 }
1678
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)1679 WMError WindowImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
1680 {
1681 WLOGD("id:%{public}u Hide, reason:%{public}u, Animation:%{public}d",
1682 property_->GetWindowId(), reason, withAnimation);
1683 if (!IsWindowValid()) {
1684 return WMError::WM_ERROR_INVALID_WINDOW;
1685 }
1686 WindowStateChangeReason stateChangeReason = static_cast<WindowStateChangeReason>(reason);
1687 if (stateChangeReason == WindowStateChangeReason::KEYGUARD ||
1688 stateChangeReason == WindowStateChangeReason::TOGGLING) {
1689 state_ = stateChangeReason == WindowStateChangeReason::KEYGUARD ?
1690 WindowState::STATE_FROZEN : WindowState::STATE_HIDDEN;
1691 NotifyAfterBackground();
1692 return WMError::WM_OK;
1693 }
1694 if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
1695 WLOGI("already hidden, id: %{public}u", property_->GetWindowId());
1696 NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
1697 return WMError::WM_OK;
1698 }
1699 WMError ret = WMError::WM_OK;
1700 if (WindowHelper::IsSystemWindow(property_->GetWindowType())) {
1701 AdjustWindowAnimationFlag(withAnimation);
1702 // when show(true) with default, hide() with None, to adjust animationFlag to disabled default animation
1703 ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG);
1704 if (ret != WMError::WM_OK) {
1705 WLOGFE("UpdateProperty failed with errCode:%{public}d", static_cast<int32_t>(ret));
1706 return ret;
1707 }
1708 }
1709 ret = SingletonContainer::Get<WindowAdapter>().RemoveWindow(property_->GetWindowId(), isFromInnerkits);
1710 RecordLifeCycleExceptionEvent(LifeCycleEvent::HIDE_EVENT, ret);
1711 if (ret != WMError::WM_OK) {
1712 WLOGFE("hide errCode:%{public}d for winId:%{public}u", static_cast<int32_t>(ret), property_->GetWindowId());
1713 return ret;
1714 }
1715 UpdateWindowStateWhenHide();
1716 uint32_t animationFlag = property_->GetAnimationFlag();
1717 if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
1718 animationTransitionController_->AnimationForHidden();
1719 }
1720 ResetMoveOrDragState();
1721 escKeyEventTriggered_ = false;
1722 return ret;
1723 }
1724
MoveTo(int32_t x,int32_t y,bool isMoveToGlobal)1725 WMError WindowImpl::MoveTo(int32_t x, int32_t y, bool isMoveToGlobal)
1726 {
1727 WLOGFD("id:%{public}d MoveTo %{public}d %{public}d",
1728 property_->GetWindowId(), x, y);
1729 if (!IsWindowValid()) {
1730 return WMError::WM_ERROR_INVALID_WINDOW;
1731 }
1732
1733 Rect rect = (WindowHelper::IsMainFloatingWindow(GetType(), GetMode())) ?
1734 GetRect() : property_->GetRequestRect();
1735 Rect moveRect = { x, y, rect.width_, rect.height_ }; // must keep w/h, which may maintain stashed resize info
1736 property_->SetRequestRect(moveRect);
1737 {
1738 // this lock solves the multithreading problem when reading WindowState
1739 std::lock_guard<std::recursive_mutex> lock(windowStateMutex_);
1740 if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
1741 WLOGFD("window is hidden or created! id: %{public}u, oriPos: [%{public}d, %{public}d, "
1742 "movePos: [%{public}d, %{public}d]", property_->GetWindowId(), rect.posX_, rect.posY_, x, y);
1743 return WMError::WM_OK;
1744 }
1745 }
1746
1747 if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
1748 WLOGFE("fullscreen window could not moveto, winId: %{public}u", GetWindowId());
1749 return WMError::WM_ERROR_INVALID_OPERATION;
1750 }
1751 property_->SetWindowSizeChangeReason(WindowSizeChangeReason::MOVE);
1752 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_RECT);
1753 }
1754
Resize(uint32_t width,uint32_t height)1755 WMError WindowImpl::Resize(uint32_t width, uint32_t height)
1756 {
1757 WLOGFD("id:%{public}d Resize %{public}u %{public}u",
1758 property_->GetWindowId(), width, height);
1759 if (!IsWindowValid()) {
1760 return WMError::WM_ERROR_INVALID_WINDOW;
1761 }
1762
1763 Rect rect = (WindowHelper::IsMainFloatingWindow(GetType(), GetMode())) ?
1764 GetRect() : property_->GetRequestRect();
1765 Rect resizeRect = { rect.posX_, rect.posY_, width, height };
1766 property_->SetRequestRect(resizeRect);
1767 property_->SetDecoStatus(false);
1768 {
1769 // this lock solves the multithreading problem when reading WindowState
1770 std::lock_guard<std::recursive_mutex> lock(windowStateMutex_);
1771 if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
1772 WLOGFD("window is hidden or created! id: %{public}u, oriRect: [%{public}u, %{public}u], "
1773 "resizeRect: [%{public}u, %{public}u]", property_->GetWindowId(), rect.width_,
1774 rect.height_, width, height);
1775 return WMError::WM_OK;
1776 }
1777 }
1778
1779 if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
1780 WLOGFE("fullscreen window could not resize, winId: %{public}u", GetWindowId());
1781 return WMError::WM_ERROR_INVALID_OPERATION;
1782 }
1783 property_->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
1784 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_RECT);
1785 }
1786
SetWindowGravity(WindowGravity gravity,uint32_t percent)1787 WMError WindowImpl::SetWindowGravity(WindowGravity gravity, uint32_t percent)
1788 {
1789 WLOGFD("id:%{public}d SetWindowGravity %{public}u %{public}u",
1790 property_->GetWindowId(), gravity, percent);
1791
1792 return SingletonContainer::Get<WindowAdapter>().SetWindowGravity(property_->GetWindowId(), gravity, percent);
1793 }
1794
SetKeepScreenOn(bool keepScreenOn)1795 WMError WindowImpl::SetKeepScreenOn(bool keepScreenOn)
1796 {
1797 if (!IsWindowValid()) {
1798 return WMError::WM_ERROR_INVALID_WINDOW;
1799 }
1800 property_->SetKeepScreenOn(keepScreenOn);
1801 if (state_ == WindowState::STATE_SHOWN) {
1802 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON);
1803 }
1804 return WMError::WM_OK;
1805 }
1806
IsKeepScreenOn() const1807 bool WindowImpl::IsKeepScreenOn() const
1808 {
1809 if (!IsWindowValid()) {
1810 return false;
1811 }
1812 return property_->IsKeepScreenOn();
1813 }
1814
SetTurnScreenOn(bool turnScreenOn)1815 WMError WindowImpl::SetTurnScreenOn(bool turnScreenOn)
1816 {
1817 if (!IsWindowValid()) {
1818 return WMError::WM_ERROR_INVALID_WINDOW;
1819 }
1820 property_->SetTurnScreenOn(turnScreenOn);
1821 if (state_ == WindowState::STATE_SHOWN) {
1822 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON);
1823 }
1824 return WMError::WM_OK;
1825 }
1826
IsTurnScreenOn() const1827 bool WindowImpl::IsTurnScreenOn() const
1828 {
1829 if (!IsWindowValid()) {
1830 return false;
1831 }
1832 return property_->IsTurnScreenOn();
1833 }
1834
SetBackgroundColor(uint32_t color)1835 WMError WindowImpl::SetBackgroundColor(uint32_t color)
1836 {
1837 // 0xff000000: ARGB style, means Opaque color.
1838 const bool isAlphaZero = !(color & 0xff000000);
1839 auto abilityInfo = property_->GetAbilityInfo();
1840 if (isAlphaZero && WindowHelper::IsMainWindow(property_->GetWindowType())) {
1841 auto& reportInstance = SingletonContainer::Get<WindowInfoReporter>();
1842 reportInstance.ReportZeroOpacityInfoImmediately(abilityInfo.bundleName_,
1843 abilityInfo.abilityName_);
1844 }
1845
1846 if (uiContent_ != nullptr) {
1847 uiContent_->SetBackgroundColor(color);
1848 return WMError::WM_OK;
1849 }
1850 WLOGI("ace is null, Id: %{public}u", GetWindowId());
1851 if (aceAbilityHandler_ != nullptr) {
1852 aceAbilityHandler_->SetBackgroundColor(color);
1853 return WMError::WM_OK;
1854 }
1855 WLOGFE("FA mode could not set bg color: %{public}u", GetWindowId());
1856 return WMError::WM_ERROR_INVALID_OPERATION;
1857 }
1858
GetBackgroundColor() const1859 uint32_t WindowImpl::GetBackgroundColor() const
1860 {
1861 if (uiContent_ != nullptr) {
1862 return uiContent_->GetBackgroundColor();
1863 }
1864 WLOGD("uiContent is nullptr, windowId: %{public}u, use FA mode", GetWindowId());
1865 if (aceAbilityHandler_ != nullptr) {
1866 return aceAbilityHandler_->GetBackgroundColor();
1867 }
1868 WLOGFE("FA mode does not get bg color: %{public}u", GetWindowId());
1869 return 0xffffffff; // means no background color been set, default color is white
1870 }
1871
SetBackgroundColor(const std::string & color)1872 WMError WindowImpl::SetBackgroundColor(const std::string& color)
1873 {
1874 if (!IsWindowValid()) {
1875 return WMError::WM_ERROR_INVALID_WINDOW;
1876 }
1877 uint32_t colorValue;
1878 if (ColorParser::Parse(color, colorValue)) {
1879 WLOGD("SetBackgroundColor: window: %{public}s, value: [%{public}s, %{public}u]",
1880 name_.c_str(), color.c_str(), colorValue);
1881 return SetBackgroundColor(colorValue);
1882 }
1883 WLOGFE("invalid color string: %{public}s", color.c_str());
1884 return WMError::WM_ERROR_INVALID_PARAM;
1885 }
1886
SetTransparent(bool isTransparent)1887 WMError WindowImpl::SetTransparent(bool isTransparent)
1888 {
1889 if (!IsWindowValid()) {
1890 return WMError::WM_ERROR_INVALID_WINDOW;
1891 }
1892 ColorParam backgroundColor;
1893 backgroundColor.value = GetBackgroundColor();
1894 if (isTransparent) {
1895 backgroundColor.argb.alpha = 0x00; // 0x00: completely transparent
1896 return SetBackgroundColor(backgroundColor.value);
1897 } else {
1898 backgroundColor.value = GetBackgroundColor();
1899 if (backgroundColor.argb.alpha == 0x00) {
1900 backgroundColor.argb.alpha = 0xff; // 0xff: completely opaque
1901 return SetBackgroundColor(backgroundColor.value);
1902 }
1903 }
1904 return WMError::WM_OK;
1905 }
1906
IsTransparent() const1907 bool WindowImpl::IsTransparent() const
1908 {
1909 if (!IsWindowValid()) {
1910 return false;
1911 }
1912 ColorParam backgroundColor;
1913 backgroundColor.value = GetBackgroundColor();
1914 WLOGFD("color: %{public}u, alpha: %{public}u", backgroundColor.value, backgroundColor.argb.alpha);
1915 return backgroundColor.argb.alpha == 0x00; // 0x00: completely transparent
1916 }
1917
SetBrightness(float brightness)1918 WMError WindowImpl::SetBrightness(float brightness)
1919 {
1920 if (!IsWindowValid()) {
1921 return WMError::WM_ERROR_INVALID_WINDOW;
1922 }
1923 if ((brightness < MINIMUM_BRIGHTNESS &&
1924 std::fabs(brightness - UNDEFINED_BRIGHTNESS) >= std::numeric_limits<float>::min()) ||
1925 brightness > MAXIMUM_BRIGHTNESS) {
1926 WLOGFE("invalid brightness value: %{public}f", brightness);
1927 return WMError::WM_ERROR_INVALID_PARAM;
1928 }
1929 if (!WindowHelper::IsAppWindow(GetType())) {
1930 WLOGFE("non app window does not support set brightness, type: %{public}u", GetType());
1931 return WMError::WM_ERROR_INVALID_TYPE;
1932 }
1933 property_->SetBrightness(brightness);
1934 if (state_ == WindowState::STATE_SHOWN) {
1935 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS);
1936 }
1937 return WMError::WM_OK;
1938 }
1939
GetBrightness() const1940 float WindowImpl::GetBrightness() const
1941 {
1942 return property_->GetBrightness();
1943 }
1944
SetCallingWindow(uint32_t windowId)1945 WMError WindowImpl::SetCallingWindow(uint32_t windowId)
1946 {
1947 if (!IsWindowValid()) {
1948 return WMError::WM_ERROR_INVALID_WINDOW;
1949 }
1950 property_->SetCallingWindow(windowId);
1951 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_CALLING_WINDOW);
1952 }
1953
RecordLifeCycleExceptionEvent(LifeCycleEvent event,WMError errCode) const1954 void WindowImpl::RecordLifeCycleExceptionEvent(LifeCycleEvent event, WMError errCode) const
1955 {
1956 if (!(errCode > WMError::WM_ERROR_NEED_REPORT_BASE && errCode < WMError::WM_ERROR_NEED_REPORT_END)) {
1957 return;
1958 }
1959 std::ostringstream oss;
1960 oss << "life cycle is abnormal: " << "window_name: " << name_
1961 << ", id:" << GetWindowId() << ", event: " << TransferLifeCycleEventToString(event)
1962 << ", errCode: " << static_cast<int32_t>(errCode) << ";";
1963 std::string info = oss.str();
1964 WLOGI("window life cycle exception: %{public}s", info.c_str());
1965 int32_t ret = HiSysEventWrite(
1966 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
1967 "WINDOW_LIFE_CYCLE_EXCEPTION",
1968 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
1969 "PID", getpid(),
1970 "UID", getuid(),
1971 "MSG", info);
1972 if (ret != 0) {
1973 WLOGFE("Write HiSysEvent error, ret:%{public}d", ret);
1974 }
1975 }
1976
TransferLifeCycleEventToString(LifeCycleEvent type) const1977 std::string WindowImpl::TransferLifeCycleEventToString(LifeCycleEvent type) const
1978 {
1979 std::string event;
1980 switch (type) {
1981 case LifeCycleEvent::CREATE_EVENT:
1982 event = "CREATE";
1983 break;
1984 case LifeCycleEvent::SHOW_EVENT:
1985 event = "SHOW";
1986 break;
1987 case LifeCycleEvent::HIDE_EVENT:
1988 event = "HIDE";
1989 break;
1990 case LifeCycleEvent::DESTROY_EVENT:
1991 event = "DESTROY";
1992 break;
1993 default:
1994 event = "UNDEFINE";
1995 break;
1996 }
1997 return event;
1998 }
1999
SetPrivacyMode(bool isPrivacyMode)2000 WMError WindowImpl::SetPrivacyMode(bool isPrivacyMode)
2001 {
2002 if (!IsWindowValid()) {
2003 return WMError::WM_ERROR_INVALID_WINDOW;
2004 }
2005 WLOGFD("id : %{public}u, SetPrivacyMode, %{public}u", GetWindowId(), isPrivacyMode);
2006 property_->SetPrivacyMode(isPrivacyMode);
2007 return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE);
2008 }
2009
IsPrivacyMode() const2010 bool WindowImpl::IsPrivacyMode() const
2011 {
2012 if (!IsWindowValid()) {
2013 return false;
2014 }
2015 return property_->GetPrivacyMode();
2016 }
2017
SetSystemPrivacyMode(bool isSystemPrivacyMode)2018 void WindowImpl::SetSystemPrivacyMode(bool isSystemPrivacyMode)
2019 {
2020 WLOGFD("id : %{public}u, SetSystemPrivacyMode, %{public}u", GetWindowId(), isSystemPrivacyMode);
2021 property_->SetSystemPrivacyMode(isSystemPrivacyMode);
2022 UpdateProperty(PropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE);
2023 }
2024
SetSnapshotSkip(bool isSkip)2025 WMError WindowImpl::SetSnapshotSkip(bool isSkip)
2026 {
2027 if (!IsWindowValid()) {
2028 return WMError::WM_ERROR_INVALID_WINDOW;
2029 }
2030 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
2031 WLOGFE("set snapshot skip permission denied!");
2032 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2033 }
2034 property_->SetSnapshotSkip(isSkip);
2035 auto ret = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_SNAPSHOT_SKIP);
2036 WLOGFD("id : %{public}u, set snapshot skip end. isSkip:%{public}u, systemPrivacyMode:%{public}u, ret:%{public}u",
2037 GetWindowId(), isSkip, property_->GetSystemPrivacyMode(), ret);
2038 return WMError::WM_OK;
2039 }
2040
2041 /** @note @window.hierarchy */
RaiseToAppTop()2042 WMError WindowImpl::RaiseToAppTop()
2043 {
2044 if (!IsWindowValid()) {
2045 TLOGE(WmsLogTag::DEFAULT, "Window is invalid");
2046 return WMError::WM_ERROR_INVALID_WINDOW;
2047 }
2048
2049 auto parentId = property_->GetParentId();
2050 if (parentId == INVALID_WINDOW_ID) {
2051 WLOGFE("Only the children of the main window can be raised!");
2052 return WMError::WM_ERROR_INVALID_PARENT;
2053 }
2054
2055 if (!WindowHelper::IsSubWindow(property_->GetWindowType())) {
2056 WLOGFE("Must be app sub window window!");
2057 return WMError::WM_ERROR_INVALID_CALLING;
2058 }
2059
2060 if (state_ != WindowState::STATE_SHOWN) {
2061 WLOGFE("The sub window must be shown!");
2062 return WMError::WM_DO_NOTHING;
2063 }
2064
2065 return SingletonContainer::Get<WindowAdapter>().RaiseToAppTop(GetWindowId());
2066 }
2067
DisableAppWindowDecor()2068 WMError WindowImpl::DisableAppWindowDecor()
2069 {
2070 if (!IsWindowValid()) {
2071 return WMError::WM_ERROR_INVALID_WINDOW;
2072 }
2073 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
2074 WLOGFE("disable app window decor permission denied!");
2075 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2076 }
2077 if (!WindowHelper::IsMainWindow(property_->GetWindowType())) {
2078 WLOGFE("window decoration is invalid on sub window");
2079 return WMError::WM_ERROR_INVALID_OPERATION;
2080 }
2081 WLOGI("disable app window decoration.");
2082 windowSystemConfig_.isSystemDecorEnable_ = false;
2083 UpdateDecorEnable(true);
2084 return WMError::WM_OK;
2085 }
2086
IsDecorEnable() const2087 bool WindowImpl::IsDecorEnable() const
2088 {
2089 bool enable = windowSystemConfig_.isSystemDecorEnable_ &&
2090 WindowHelper::IsMainWindow(property_->GetWindowType());
2091 WLOGFD("get decor enable %{public}d", enable);
2092 return enable;
2093 }
2094
Maximize()2095 WMError WindowImpl::Maximize()
2096 {
2097 WLOGI("id: %{public}u Maximize", property_->GetWindowId());
2098 if (!IsWindowValid()) {
2099 return WMError::WM_ERROR_INVALID_WINDOW;
2100 }
2101 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
2102 return SetFullScreen(true);
2103 } else {
2104 WLOGI("Maximize fail, not main window");
2105 return WMError::WM_ERROR_INVALID_PARAM;
2106 }
2107 }
2108
MaximizeFloating()2109 WMError WindowImpl::MaximizeFloating()
2110 {
2111 WLOGI("id: %{public}u MaximizeFloating", property_->GetWindowId());
2112 if (!IsWindowValid()) {
2113 return WMError::WM_ERROR_INVALID_WINDOW;
2114 }
2115 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
2116 return SetFloatingMaximize(true);
2117 } else {
2118 WLOGI("MaximizeFloating fail, not main window");
2119 return WMError::WM_ERROR_INVALID_PARAM;
2120 }
2121 }
2122
SetGlobalMaximizeMode(MaximizeMode mode)2123 WMError WindowImpl::SetGlobalMaximizeMode(MaximizeMode mode)
2124 {
2125 WLOGI("id: %{public}u SetGlobalMaximizeMode: %{public}u", property_->GetWindowId(),
2126 static_cast<uint32_t>(mode));
2127 if (!IsWindowValid()) {
2128 return WMError::WM_ERROR_INVALID_WINDOW;
2129 }
2130 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
2131 SingletonContainer::Get<WindowAdapter>().SetMaximizeMode(mode);
2132 return WMError::WM_OK;
2133 } else {
2134 WLOGI("SetGlobalMaximizeMode fail, not main window");
2135 return WMError::WM_ERROR_INVALID_PARAM;
2136 }
2137 }
2138
GetGlobalMaximizeMode() const2139 MaximizeMode WindowImpl::GetGlobalMaximizeMode() const
2140 {
2141 return SingletonContainer::Get<WindowAdapter>().GetMaximizeMode();
2142 }
2143
SetImmersiveModeEnabledState(bool enable)2144 WMError WindowImpl::SetImmersiveModeEnabledState(bool enable)
2145 {
2146 TLOGD(WmsLogTag::WMS_IMMS, "WindowImpl id: %{public}u SetImmersiveModeEnabledState: %{public}u",
2147 property_->GetWindowId(), static_cast<uint32_t>(enable));
2148 if (!IsWindowValid() ||
2149 !WindowHelper::IsWindowModeSupported(GetModeSupportInfo(), WindowMode::WINDOW_MODE_FULLSCREEN)) {
2150 TLOGE(WmsLogTag::WMS_IMMS, "invalid window or fullscreen mode is not be supported, winId:%{public}u",
2151 property_->GetWindowId());
2152 return WMError::WM_ERROR_INVALID_WINDOW;
2153 }
2154 const WindowType curWindowType = GetType();
2155 if (!WindowHelper::IsMainWindow(curWindowType) && !WindowHelper::IsSubWindow(curWindowType)) {
2156 return WMError::WM_ERROR_INVALID_WINDOW;
2157 }
2158
2159 enableImmersiveMode_ = enable;
2160 const WindowMode mode = GetMode();
2161 if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
2162 return SetLayoutFullScreen(enableImmersiveMode_);
2163 }
2164 return WMError::WM_OK;
2165 }
2166
GetImmersiveModeEnabledState() const2167 bool WindowImpl::GetImmersiveModeEnabledState() const
2168 {
2169 if (!IsWindowValid()) {
2170 return false;
2171 }
2172 return enableImmersiveMode_;
2173 }
2174
NotifyWindowTransition(TransitionReason reason)2175 WMError WindowImpl::NotifyWindowTransition(TransitionReason reason)
2176 {
2177 sptr<WindowTransitionInfo> fromInfo = new(std::nothrow) WindowTransitionInfo();
2178 sptr<WindowTransitionInfo> toInfo = new(std::nothrow) WindowTransitionInfo();
2179 if (fromInfo == nullptr || toInfo == nullptr) {
2180 WLOGFE("new windowTransitionInfo failed");
2181 return WMError::WM_ERROR_NO_MEM;
2182 }
2183 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
2184 if (abilityContext == nullptr) {
2185 WLOGFE("id:%{public}d is not ability Window", property_->GetWindowId());
2186 return WMError::WM_ERROR_NO_MEM;
2187 }
2188 auto abilityInfo = abilityContext->GetAbilityInfo();
2189 if (abilityInfo == nullptr) {
2190 return WMError::WM_ERROR_NULLPTR;
2191 }
2192 fromInfo->SetBundleName(context_->GetBundleName());
2193 fromInfo->SetAbilityName(abilityInfo->name);
2194 fromInfo->SetWindowMode(property_->GetWindowMode());
2195 fromInfo->SetWindowRect(property_->GetWindowRect());
2196 fromInfo->SetAbilityToken(context_->GetToken());
2197 fromInfo->SetWindowType(property_->GetWindowType());
2198 fromInfo->SetDisplayId(property_->GetDisplayId());
2199 fromInfo->SetTransitionReason(reason);
2200 return SingletonContainer::Get<WindowAdapter>().NotifyWindowTransition(fromInfo, toInfo);
2201 }
2202
Minimize()2203 WMError WindowImpl::Minimize()
2204 {
2205 WLOGI("id: %{public}u Minimize", property_->GetWindowId());
2206 if (!IsWindowValid()) {
2207 return WMError::WM_ERROR_INVALID_WINDOW;
2208 }
2209 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
2210 if (context_ != nullptr) {
2211 WMError ret = NotifyWindowTransition(TransitionReason::MINIMIZE);
2212 if (ret != WMError::WM_OK) {
2213 WLOGI("Minimize without animation ret:%{public}u", static_cast<uint32_t>(ret));
2214 AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(context_->GetToken(), true);
2215 }
2216 } else {
2217 Hide();
2218 }
2219 }
2220 return WMError::WM_OK;
2221 }
2222
Recover()2223 WMError WindowImpl::Recover()
2224 {
2225 WLOGI("id: %{public}u Normalize", property_->GetWindowId());
2226 if (!IsWindowValid()) {
2227 return WMError::WM_ERROR_INVALID_WINDOW;
2228 }
2229 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
2230 if (property_->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
2231 property_->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
2232 SetFloatingMaximize(false);
2233 return WMError::WM_OK;
2234 }
2235 SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
2236 }
2237 return WMError::WM_OK;
2238 }
2239
Close()2240 WMError WindowImpl::Close()
2241 {
2242 WLOGI("id: %{public}u Close", property_->GetWindowId());
2243 if (!IsWindowValid()) {
2244 return WMError::WM_ERROR_INVALID_WINDOW;
2245 }
2246 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
2247 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
2248 if (!abilityContext) {
2249 return Destroy();
2250 }
2251 sptr<AAFwk::IPrepareTerminateCallback> callback = this;
2252 if (AAFwk::AbilityManagerClient::GetInstance()->PrepareTerminateAbility(abilityContext->GetToken(),
2253 callback) != ERR_OK) {
2254 WLOGFW("RegisterWindowManagerServiceHandler failed, do close window");
2255 PendingClose();
2256 return WMError::WM_OK;
2257 }
2258 }
2259 return WMError::WM_OK;
2260 }
2261
DoPrepareTerminate()2262 void WindowImpl::DoPrepareTerminate()
2263 {
2264 WLOGFI("do pending close by ability");
2265 PendingClose();
2266 }
2267
PendingClose()2268 void WindowImpl::PendingClose()
2269 {
2270 WLOGFD("begin");
2271 WMError ret = NotifyWindowTransition(TransitionReason::CLOSE_BUTTON);
2272 if (ret != WMError::WM_OK) {
2273 WLOGI("Close without animation ret:%{public}u", static_cast<uint32_t>(ret));
2274 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
2275 if (abilityContext != nullptr) {
2276 abilityContext->CloseAbility();
2277 }
2278 }
2279 }
2280
RequestFocus() const2281 WMError WindowImpl::RequestFocus() const
2282 {
2283 if (!IsWindowValid()) {
2284 return WMError::WM_ERROR_INVALID_WINDOW;
2285 }
2286 return SingletonContainer::Get<WindowAdapter>().RequestFocus(property_->GetWindowId());
2287 }
2288
SetInputEventConsumer(const std::shared_ptr<IInputEventConsumer> & inputEventConsumer)2289 void WindowImpl::SetInputEventConsumer(const std::shared_ptr<IInputEventConsumer>& inputEventConsumer)
2290 {
2291 std::lock_guard<std::recursive_mutex> lock(mutex_);
2292 inputEventConsumer_ = inputEventConsumer;
2293 }
2294
RegisterLifeCycleListener(const sptr<IWindowLifeCycle> & listener)2295 WMError WindowImpl::RegisterLifeCycleListener(const sptr<IWindowLifeCycle>& listener)
2296 {
2297 WLOGFD("Start register");
2298 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2299 return RegisterListener(lifecycleListeners_[GetWindowId()], listener);
2300 }
2301
UnregisterLifeCycleListener(const sptr<IWindowLifeCycle> & listener)2302 WMError WindowImpl::UnregisterLifeCycleListener(const sptr<IWindowLifeCycle>& listener)
2303 {
2304 WLOGFD("Start unregister");
2305 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2306 return UnregisterListener(lifecycleListeners_[GetWindowId()], listener);
2307 }
2308
RegisterWindowChangeListener(const sptr<IWindowChangeListener> & listener)2309 WMError WindowImpl::RegisterWindowChangeListener(const sptr<IWindowChangeListener>& listener)
2310 {
2311 WLOGFD("Start register");
2312 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2313 return RegisterListener(windowChangeListeners_[GetWindowId()], listener);
2314 }
2315
UnregisterWindowChangeListener(const sptr<IWindowChangeListener> & listener)2316 WMError WindowImpl::UnregisterWindowChangeListener(const sptr<IWindowChangeListener>& listener)
2317 {
2318 WLOGFD("Start unregister");
2319 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2320 return UnregisterListener(windowChangeListeners_[GetWindowId()], listener);
2321 }
2322
RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)2323 WMError WindowImpl::RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
2324 {
2325 WLOGFD("Start register");
2326 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2327 WMError ret = RegisterListener(avoidAreaChangeListeners_[GetWindowId()], listener);
2328 if (avoidAreaChangeListeners_[GetWindowId()].size() == 1) {
2329 SingletonContainer::Get<WindowAdapter>().UpdateAvoidAreaListener(property_->GetWindowId(), true);
2330 }
2331 return ret;
2332 }
2333
UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)2334 WMError WindowImpl::UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
2335 {
2336 WLOGFD("Start unregister");
2337 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2338 WMError ret = UnregisterListener(avoidAreaChangeListeners_[GetWindowId()], listener);
2339 if (avoidAreaChangeListeners_[GetWindowId()].empty()) {
2340 SingletonContainer::Get<WindowAdapter>().UpdateAvoidAreaListener(property_->GetWindowId(), false);
2341 }
2342 return ret;
2343 }
2344
RegisterDragListener(const sptr<IWindowDragListener> & listener)2345 WMError WindowImpl::RegisterDragListener(const sptr<IWindowDragListener>& listener)
2346 {
2347 WLOGFD("Start register");
2348 std::lock_guard<std::recursive_mutex> lock(mutex_);
2349 return RegisterListener(windowDragListeners_, listener);
2350 }
2351
UnregisterDragListener(const sptr<IWindowDragListener> & listener)2352 WMError WindowImpl::UnregisterDragListener(const sptr<IWindowDragListener>& listener)
2353 {
2354 WLOGFD("Start unregister");
2355 std::lock_guard<std::recursive_mutex> lock(mutex_);
2356 return UnregisterListener(windowDragListeners_, listener);
2357 }
2358
RegisterDisplayMoveListener(sptr<IDisplayMoveListener> & listener)2359 WMError WindowImpl::RegisterDisplayMoveListener(sptr<IDisplayMoveListener>& listener)
2360 {
2361 WLOGFD("Start register");
2362 std::lock_guard<std::recursive_mutex> lock(mutex_);
2363 return RegisterListener(displayMoveListeners_, listener);
2364 }
2365
UnregisterDisplayMoveListener(sptr<IDisplayMoveListener> & listener)2366 WMError WindowImpl::UnregisterDisplayMoveListener(sptr<IDisplayMoveListener>& listener)
2367 {
2368 WLOGFD("Start unregister");
2369 std::lock_guard<std::recursive_mutex> lock(mutex_);
2370 return UnregisterListener(displayMoveListeners_, listener);
2371 }
2372
RegisterWindowDestroyedListener(const NotifyNativeWinDestroyFunc & func)2373 void WindowImpl::RegisterWindowDestroyedListener(const NotifyNativeWinDestroyFunc& func)
2374 {
2375 WLOGFD("Start register");
2376 notifyNativefunc_ = std::move(func);
2377 }
2378
RegisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)2379 WMError WindowImpl::RegisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener>& listener)
2380 {
2381 WLOGFD("Start register");
2382 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2383 return RegisterListener(occupiedAreaChangeListeners_[GetWindowId()], listener);
2384 }
2385
UnregisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)2386 WMError WindowImpl::UnregisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener>& listener)
2387 {
2388 WLOGFD("Start unregister");
2389 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2390 return UnregisterListener(occupiedAreaChangeListeners_[GetWindowId()], listener);
2391 }
2392
RegisterTouchOutsideListener(const sptr<ITouchOutsideListener> & listener)2393 WMError WindowImpl::RegisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
2394 {
2395 WLOGFD("Start register");
2396 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2397 return RegisterListener(touchOutsideListeners_[GetWindowId()], listener);
2398 }
2399
UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener> & listener)2400 WMError WindowImpl::UnregisterTouchOutsideListener(const sptr<ITouchOutsideListener>& listener)
2401 {
2402 WLOGFD("Start unregister");
2403 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2404 return UnregisterListener(touchOutsideListeners_[GetWindowId()], listener);
2405 }
2406
RegisterAnimationTransitionController(const sptr<IAnimationTransitionController> & listener)2407 WMError WindowImpl::RegisterAnimationTransitionController(const sptr<IAnimationTransitionController>& listener)
2408 {
2409 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
2410 WLOGFE("register animation transition controller permission denied!");
2411 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2412 }
2413 if (listener == nullptr) {
2414 WLOGFE("listener is nullptr");
2415 return WMError::WM_ERROR_NULLPTR;
2416 }
2417 animationTransitionController_ = listener;
2418 wptr<WindowProperty> propertyToken(property_);
2419 wptr<IAnimationTransitionController> animationTransitionControllerToken(animationTransitionController_);
2420 if (uiContent_) {
2421 uiContent_->SetNextFrameLayoutCallback([propertyToken, animationTransitionControllerToken]() {
2422 auto property = propertyToken.promote();
2423 auto animationTransitionController = animationTransitionControllerToken.promote();
2424 if (!property || !animationTransitionController) {
2425 return;
2426 }
2427 uint32_t animationFlag = property->GetAnimationFlag();
2428 if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
2429 // CustomAnimation is enabled when animationTransitionController_ exists
2430 animationTransitionController->AnimationForShown();
2431 }
2432 });
2433 }
2434 return WMError::WM_OK;
2435 }
2436
RegisterScreenshotListener(const sptr<IScreenshotListener> & listener)2437 WMError WindowImpl::RegisterScreenshotListener(const sptr<IScreenshotListener>& listener)
2438 {
2439 WLOGFD("Start register");
2440 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2441 return RegisterListener(screenshotListeners_[GetWindowId()], listener);
2442 }
2443
UnregisterScreenshotListener(const sptr<IScreenshotListener> & listener)2444 WMError WindowImpl::UnregisterScreenshotListener(const sptr<IScreenshotListener>& listener)
2445 {
2446 WLOGFD("Start unregister");
2447 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2448 return UnregisterListener(screenshotListeners_[GetWindowId()], listener);
2449 }
2450
RegisterDialogTargetTouchListener(const sptr<IDialogTargetTouchListener> & listener)2451 WMError WindowImpl::RegisterDialogTargetTouchListener(const sptr<IDialogTargetTouchListener>& listener)
2452 {
2453 WLOGFD("Start register");
2454 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2455 return RegisterListener(dialogTargetTouchListeners_[GetWindowId()], listener);
2456 }
2457
UnregisterDialogTargetTouchListener(const sptr<IDialogTargetTouchListener> & listener)2458 WMError WindowImpl::UnregisterDialogTargetTouchListener(const sptr<IDialogTargetTouchListener>& listener)
2459 {
2460 WLOGFD("Start unregister");
2461 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2462 return UnregisterListener(dialogTargetTouchListeners_[GetWindowId()], listener);
2463 }
2464
RegisterDialogDeathRecipientListener(const sptr<IDialogDeathRecipientListener> & listener)2465 void WindowImpl::RegisterDialogDeathRecipientListener(const sptr<IDialogDeathRecipientListener>& listener)
2466 {
2467 WLOGFD("Start register");
2468 if (listener == nullptr) {
2469 WLOGFE("listener is nullptr");
2470 return;
2471 }
2472 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2473 dialogDeathRecipientListener_[GetWindowId()] = listener;
2474 }
2475
UnregisterDialogDeathRecipientListener(const sptr<IDialogDeathRecipientListener> & listener)2476 void WindowImpl::UnregisterDialogDeathRecipientListener(const sptr<IDialogDeathRecipientListener>& listener)
2477 {
2478 WLOGFD("Start unregister");
2479 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2480 dialogDeathRecipientListener_[GetWindowId()] = nullptr;
2481 }
2482
2483 template<typename T>
RegisterListener(std::vector<sptr<T>> & holder,const sptr<T> & listener)2484 WMError WindowImpl::RegisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
2485 {
2486 if (listener == nullptr) {
2487 WLOGFE("listener is nullptr");
2488 return WMError::WM_ERROR_NULLPTR;
2489 }
2490 if (std::find(holder.begin(), holder.end(), listener) != holder.end()) {
2491 WLOGFE("Listener already registered");
2492 return WMError::WM_OK;
2493 }
2494 holder.emplace_back(listener);
2495 return WMError::WM_OK;
2496 }
2497
2498 template<typename T>
UnregisterListener(std::vector<sptr<T>> & holder,const sptr<T> & listener)2499 WMError WindowImpl::UnregisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
2500 {
2501 if (listener == nullptr) {
2502 WLOGFE("listener could not be null");
2503 return WMError::WM_ERROR_NULLPTR;
2504 }
2505 holder.erase(std::remove_if(holder.begin(), holder.end(),
2506 [listener](sptr<T> registeredListener) {
2507 return registeredListener == listener;
2508 }), holder.end());
2509 return WMError::WM_OK;
2510 }
2511
2512 template <typename T>
GetListeners()2513 EnableIfSame<T, IWindowLifeCycle, std::vector<sptr<IWindowLifeCycle>>> WindowImpl::GetListeners()
2514 {
2515 std::vector<sptr<IWindowLifeCycle>> lifecycleListeners;
2516 {
2517 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2518 for (auto &listener : lifecycleListeners_[GetWindowId()]) {
2519 lifecycleListeners.push_back(listener);
2520 }
2521 }
2522 return lifecycleListeners;
2523 }
2524
2525 template <typename T>
GetListeners()2526 EnableIfSame<T, IWindowChangeListener, std::vector<sptr<IWindowChangeListener>>> WindowImpl::GetListeners()
2527 {
2528 std::vector<sptr<IWindowChangeListener>> windowChangeListeners;
2529 {
2530 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2531 for (auto &listener : windowChangeListeners_[GetWindowId()]) {
2532 windowChangeListeners.push_back(listener);
2533 }
2534 }
2535 return windowChangeListeners;
2536 }
2537
2538 template <typename T>
GetListeners()2539 EnableIfSame<T, IAvoidAreaChangedListener, std::vector<sptr<IAvoidAreaChangedListener>>> WindowImpl::GetListeners()
2540 {
2541 std::vector<sptr<IAvoidAreaChangedListener>> avoidAreaChangeListeners;
2542 {
2543 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2544 for (auto &listener : avoidAreaChangeListeners_[GetWindowId()]) {
2545 avoidAreaChangeListeners.push_back(listener);
2546 }
2547 }
2548 return avoidAreaChangeListeners;
2549 }
2550
2551 template <typename T>
GetListeners()2552 EnableIfSame<T, IDisplayMoveListener, std::vector<sptr<IDisplayMoveListener>>> WindowImpl::GetListeners()
2553 {
2554 std::vector<sptr<IDisplayMoveListener>> displayMoveListeners;
2555 {
2556 std::lock_guard<std::recursive_mutex> lock(mutex_);
2557 for (auto &listener : displayMoveListeners_) {
2558 displayMoveListeners.push_back(listener);
2559 }
2560 }
2561 return displayMoveListeners;
2562 }
2563
2564 template <typename T>
GetListeners()2565 EnableIfSame<T, IScreenshotListener, std::vector<sptr<IScreenshotListener>>> WindowImpl::GetListeners()
2566 {
2567 std::vector<sptr<IScreenshotListener>> screenshotListeners;
2568 {
2569 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2570 for (auto &listener : screenshotListeners_[GetWindowId()]) {
2571 screenshotListeners.push_back(listener);
2572 }
2573 }
2574 return screenshotListeners;
2575 }
2576
2577 template <typename T>
GetListeners()2578 EnableIfSame<T, ITouchOutsideListener, std::vector<sptr<ITouchOutsideListener>>> WindowImpl::GetListeners()
2579 {
2580 std::vector<sptr<ITouchOutsideListener>> touchOutsideListeners;
2581 {
2582 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2583 for (auto &listener : touchOutsideListeners_[GetWindowId()]) {
2584 touchOutsideListeners.push_back(listener);
2585 }
2586 }
2587 return touchOutsideListeners;
2588 }
2589
2590 template <typename T>
GetListeners()2591 EnableIfSame<T, IDialogTargetTouchListener, std::vector<sptr<IDialogTargetTouchListener>>> WindowImpl::GetListeners()
2592 {
2593 std::vector<sptr<IDialogTargetTouchListener>> dialogTargetTouchListeners;
2594 {
2595 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2596 for (auto &listener : dialogTargetTouchListeners_[GetWindowId()]) {
2597 dialogTargetTouchListeners.push_back(listener);
2598 }
2599 }
2600 return dialogTargetTouchListeners;
2601 }
2602
2603 template <typename T>
GetListeners()2604 EnableIfSame<T, IWindowDragListener, std::vector<sptr<IWindowDragListener>>> WindowImpl::GetListeners()
2605 {
2606 std::vector<sptr<IWindowDragListener>> windowDragListeners;
2607 {
2608 std::lock_guard<std::recursive_mutex> lock(mutex_);
2609 for (auto &listener : windowDragListeners_) {
2610 windowDragListeners.push_back(listener);
2611 }
2612 }
2613 return windowDragListeners;
2614 }
2615
2616 template <typename T>
GetListeners()2617 EnableIfSame<T, IOccupiedAreaChangeListener, std::vector<sptr<IOccupiedAreaChangeListener>>> WindowImpl::GetListeners()
2618 {
2619 std::vector<sptr<IOccupiedAreaChangeListener>> occupiedAreaChangeListeners;
2620 {
2621 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2622 for (auto &listener : occupiedAreaChangeListeners_[GetWindowId()]) {
2623 occupiedAreaChangeListeners.push_back(listener);
2624 }
2625 }
2626 return occupiedAreaChangeListeners;
2627 }
2628
2629 template <typename T>
GetListener()2630 EnableIfSame<T, IDialogDeathRecipientListener, wptr<IDialogDeathRecipientListener>> WindowImpl::GetListener()
2631 {
2632 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
2633 return dialogDeathRecipientListener_[GetWindowId()];
2634 }
2635
SetAceAbilityHandler(const sptr<IAceAbilityHandler> & handler)2636 void WindowImpl::SetAceAbilityHandler(const sptr<IAceAbilityHandler>& handler)
2637 {
2638 if (handler == nullptr) {
2639 WLOGI("ace ability handler is nullptr");
2640 }
2641 std::lock_guard<std::recursive_mutex> lock(mutex_);
2642 aceAbilityHandler_ = handler;
2643 }
2644
SetRequestModeSupportInfo(uint32_t modeSupportInfo)2645 void WindowImpl::SetRequestModeSupportInfo(uint32_t modeSupportInfo)
2646 {
2647 property_->SetRequestModeSupportInfo(modeSupportInfo);
2648 SetModeSupportInfo(modeSupportInfo);
2649 }
2650
SetModeSupportInfo(uint32_t modeSupportInfo)2651 void WindowImpl::SetModeSupportInfo(uint32_t modeSupportInfo)
2652 {
2653 property_->SetModeSupportInfo(modeSupportInfo);
2654 }
2655
UpdateRect(const struct Rect & rect,bool decoStatus,WindowSizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction)2656 void WindowImpl::UpdateRect(const struct Rect& rect, bool decoStatus, WindowSizeChangeReason reason,
2657 const std::shared_ptr<RSTransaction>& rsTransaction)
2658 {
2659 if (state_ == WindowState::STATE_DESTROYED) {
2660 WLOGFW("invalid window state");
2661 return;
2662 }
2663 auto display = SingletonContainer::IsDestroyed() ? nullptr :
2664 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
2665 if (display == nullptr) {
2666 WLOGFE("get display failed displayId:%{public}" PRIu64", window id:%{public}u", property_->GetDisplayId(),
2667 property_->GetWindowId());
2668 return;
2669 }
2670 Rect lastOriRect = property_->GetWindowRect();
2671
2672 property_->SetDecoStatus(decoStatus);
2673 if (reason == WindowSizeChangeReason::HIDE) {
2674 property_->SetRequestRect(rect);
2675 return;
2676 }
2677 property_->SetWindowRect(rect);
2678
2679 // update originRect when floating window show for the first time.
2680 if (!isOriginRectSet_ && WindowHelper::IsMainFloatingWindow(GetType(), GetMode())) {
2681 property_->SetOriginRect(rect);
2682 isOriginRectSet_ = true;
2683 }
2684 WLOGFD("winId:%{public}u, rect[%{public}d, %{public}d, %{public}u, %{public}u], reason:%{public}u",
2685 property_->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_, reason);
2686 Rect rectToAce = rect;
2687 // update rectToAce for stretchable window
2688 if (windowSystemConfig_.isStretchable_ && WindowHelper::IsMainFloatingWindow(GetType(), GetMode())) {
2689 if (IsStretchableReason(reason)) {
2690 rectToAce = property_->GetOriginRect();
2691 } else {
2692 property_->SetOriginRect(rect);
2693 }
2694 }
2695 ScheduleUpdateRectTask(rectToAce, lastOriRect, reason, rsTransaction, display);
2696 }
2697
ScheduleUpdateRectTask(const Rect & rectToAce,const Rect & lastOriRect,WindowSizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction,const sptr<class Display> & display)2698 void WindowImpl::ScheduleUpdateRectTask(const Rect& rectToAce, const Rect& lastOriRect, WindowSizeChangeReason reason,
2699 const std::shared_ptr<RSTransaction>& rsTransaction, const sptr<class Display>& display)
2700 {
2701 auto task = [weakThis = wptr(this), reason, rsTransaction, rectToAce, lastOriRect, display]() mutable {
2702 auto window = weakThis.promote();
2703 if (!window) {
2704 TLOGNE(WmsLogTag::WMS_IMMS, "window is null");
2705 return;
2706 }
2707 if (rsTransaction) {
2708 RSTransaction::FlushImplicitTransaction();
2709 rsTransaction->Begin();
2710 }
2711 RSAnimationTimingProtocol protocol;
2712 protocol.SetDuration(600);
2713 auto curve = RSAnimationTimingCurve::CreateCubicCurve(0.2, 0.0, 0.2, 1.0);
2714 RSNode::OpenImplicitAnimation(protocol, curve);
2715 if ((rectToAce != lastOriRect) || (reason != window->lastSizeChangeReason_)) {
2716 window->NotifySizeChange(rectToAce, reason, rsTransaction);
2717 window->lastSizeChangeReason_ = reason;
2718 }
2719 window->UpdateViewportConfig(rectToAce, display, reason, rsTransaction);
2720 RSNode::CloseImplicitAnimation();
2721 if (rsTransaction) {
2722 rsTransaction->Commit();
2723 }
2724 window->postTaskDone_ = true;
2725 };
2726 ResSchedReport::GetInstance().RequestPerfIfNeed(reason, GetType(), GetMode());
2727 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
2728 if (handler_ != nullptr && reason == WindowSizeChangeReason::ROTATION) {
2729 postTaskDone_ = false;
2730 handler_->PostTask(task, "wms:UpdateRect");
2731 } else {
2732 if ((rectToAce != lastOriRect) || (reason != lastSizeChangeReason_) || !postTaskDone_) {
2733 NotifySizeChange(rectToAce, reason, rsTransaction);
2734 lastSizeChangeReason_ = reason;
2735 postTaskDone_ = true;
2736 }
2737 UpdateViewportConfig(rectToAce, display, reason, rsTransaction);
2738 }
2739 }
2740
UpdateMode(WindowMode mode)2741 void WindowImpl::UpdateMode(WindowMode mode)
2742 {
2743 WLOGI("UpdateMode %{public}u", mode);
2744 property_->SetWindowMode(mode);
2745 UpdateTitleButtonVisibility();
2746 UpdateDecorEnable(true);
2747 }
2748
UpdateModeSupportInfo(uint32_t modeSupportInfo)2749 void WindowImpl::UpdateModeSupportInfo(uint32_t modeSupportInfo)
2750 {
2751 WLOGFD("modeSupportInfo: %{public}u, winId: %{public}u", modeSupportInfo, GetWindowId());
2752 SetModeSupportInfo(modeSupportInfo);
2753 UpdateTitleButtonVisibility();
2754 }
2755
HandleBackKeyPressedEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)2756 void WindowImpl::HandleBackKeyPressedEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
2757 {
2758 std::shared_ptr<IInputEventConsumer> inputEventConsumer;
2759 {
2760 std::lock_guard<std::recursive_mutex> lock(mutex_);
2761 inputEventConsumer = inputEventConsumer_;
2762 }
2763 SingletonContainer::Get<WindowInfoReporter>().ReportBackButtonInfoImmediately();
2764
2765 bool isConsumed = false;
2766 if (inputEventConsumer != nullptr) {
2767 WLOGD("Transfer back key event to inputEventConsumer");
2768 isConsumed = inputEventConsumer->OnInputEvent(keyEvent);
2769 } else if (uiContent_ != nullptr) {
2770 WLOGD("Transfer back key event to uiContent");
2771 isConsumed = uiContent_->ProcessBackPressed();
2772 } else {
2773 WLOGFE("There is no back key event consumer");
2774 }
2775 if (isConsumed) {
2776 WLOGD("Back key event is consumed");
2777 return;
2778 }
2779 PerformBack();
2780 }
2781
PerformBack()2782 void WindowImpl::PerformBack()
2783 {
2784 auto task = [weakThis = wptr(this)]() {
2785 auto window = weakThis.promote();
2786 if (!window) {
2787 TLOGNE(WmsLogTag::WMS_IMMS, "window is null");
2788 return;
2789 }
2790 if (!WindowHelper::IsMainWindow(window->property_->GetWindowType())) {
2791 WLOGD("it is not a main window");
2792 return;
2793 }
2794 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(window->context_);
2795 if (abilityContext == nullptr) {
2796 WLOGFE("abilityContext is null");
2797 return;
2798 }
2799 bool needMoveToBackground = false;
2800 int ret = abilityContext->OnBackPressedCallBack(needMoveToBackground);
2801 if (ret == ERR_OK && needMoveToBackground) {
2802 abilityContext->MoveAbilityToBackground();
2803 WLOGD("id: %{public}u closed, to move Ability: %{public}u",
2804 window->property_->GetWindowId(), needMoveToBackground);
2805 return;
2806 }
2807 // TerminateAbility will invoke last ability, CloseAbility will not.
2808 bool shouldTerminateAbility = WindowHelper::IsFullScreenWindow(window->property_->GetWindowMode());
2809 if (shouldTerminateAbility) {
2810 abilityContext->TerminateSelf();
2811 } else {
2812 abilityContext->CloseAbility();
2813 }
2814 WLOGD("id: %{public}u closed, to kill Ability: %{public}u",
2815 window->property_->GetWindowId(), static_cast<uint32_t>(shouldTerminateAbility));
2816 };
2817 handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
2818 handler_->PostTask(task, "WindowImpl::PerformBack");
2819 }
2820
ConsumeKeyEvent(std::shared_ptr<MMI::KeyEvent> & keyEvent)2821 void WindowImpl::ConsumeKeyEvent(std::shared_ptr<MMI::KeyEvent>& keyEvent)
2822 {
2823 int32_t keyCode = keyEvent->GetKeyCode();
2824 int32_t keyAction = keyEvent->GetKeyAction();
2825 WLOGFD("KeyCode: %{public}d, action: %{public}d", keyCode, keyAction);
2826 bool shouldMarkProcess = true;
2827 if (keyCode == MMI::KeyEvent::KEYCODE_BACK && keyAction == MMI::KeyEvent::KEY_ACTION_UP) {
2828 HandleBackKeyPressedEvent(keyEvent);
2829 } else {
2830 std::shared_ptr<IInputEventConsumer> inputEventConsumer;
2831 {
2832 std::lock_guard<std::recursive_mutex> lock(mutex_);
2833 inputEventConsumer = inputEventConsumer_;
2834 }
2835 if (inputEventConsumer != nullptr) {
2836 WLOGD("Transfer key event to inputEventConsumer");
2837 (void)inputEventConsumer->OnInputEvent(keyEvent);
2838 shouldMarkProcess = false;
2839 } else if (uiContent_ != nullptr) {
2840 WLOGD("Transfer key event to uiContent");
2841 bool handled = static_cast<bool>(uiContent_->ProcessKeyEvent(keyEvent));
2842 if (!handled && keyCode == MMI::KeyEvent::KEYCODE_ESCAPE &&
2843 GetMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
2844 property_->GetMaximizeMode() == MaximizeMode::MODE_FULL_FILL &&
2845 keyAction == MMI::KeyEvent::KEY_ACTION_DOWN && !escKeyEventTriggered_) {
2846 WLOGI("recover from fullscreen cause KEYCODE_ESCAPE");
2847 Recover();
2848 }
2849 if (keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_ESCAPE) {
2850 escKeyEventTriggered_ = (keyAction == MMI::KeyEvent::KEY_ACTION_UP) ? false : true;
2851 }
2852 shouldMarkProcess = !handled;
2853 } else {
2854 WLOGFE("There is no key event consumer");
2855 }
2856 }
2857 if (GetType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
2858 WLOGFI("DispatchKeyEvent: %{public}u", GetWindowId());
2859 SingletonContainer::Get<WindowAdapter>().DispatchKeyEvent(GetWindowId(), keyEvent);
2860 keyEvent->MarkProcessed();
2861 return;
2862 }
2863 if (shouldMarkProcess) {
2864 keyEvent->MarkProcessed();
2865 }
2866 }
2867
HandleModeChangeHotZones(int32_t posX,int32_t posY)2868 void WindowImpl::HandleModeChangeHotZones(int32_t posX, int32_t posY)
2869 {
2870 if (!WindowHelper::IsMainFloatingWindow(GetType(), GetMode())) {
2871 return;
2872 }
2873
2874 ModeChangeHotZones hotZones;
2875 auto res = SingletonContainer::Get<WindowAdapter>().GetModeChangeHotZones(property_->GetDisplayId(), hotZones);
2876 WLOGD("[HotZone] Window %{public}u, Pointer[%{public}d, %{public}d]", GetWindowId(), posX, posY);
2877 if (res == WMError::WM_OK) {
2878 WLOGD("[HotZone] Fullscreen [%{public}d, %{public}d, %{public}u, %{public}u]", hotZones.fullscreen_.posX_,
2879 hotZones.fullscreen_.posY_, hotZones.fullscreen_.width_, hotZones.fullscreen_.height_);
2880 WLOGD("[HotZone] Primary [%{public}d, %{public}d, %{public}u, %{public}u]", hotZones.primary_.posX_,
2881 hotZones.primary_.posY_, hotZones.primary_.width_, hotZones.primary_.height_);
2882 WLOGD("[HotZone] Secondary [%{public}d, %{public}d, %{public}u, %{public}u]", hotZones.secondary_.posX_,
2883 hotZones.secondary_.posY_, hotZones.secondary_.width_, hotZones.secondary_.height_);
2884
2885 if (WindowHelper::IsPointInTargetRectWithBound(posX, posY, hotZones.fullscreen_)) {
2886 SetFullScreen(true);
2887 } else if (WindowHelper::IsPointInTargetRectWithBound(posX, posY, hotZones.primary_)) {
2888 SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
2889 } else if (WindowHelper::IsPointInTargetRectWithBound(posX, posY, hotZones.secondary_)) {
2890 SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_SECONDARY);
2891 }
2892 }
2893 }
2894
UpdatePointerEventForStretchableWindow(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)2895 void WindowImpl::UpdatePointerEventForStretchableWindow(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
2896 {
2897 MMI::PointerEvent::PointerItem pointerItem;
2898 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
2899 WLOGFW("Point item is invalid");
2900 return;
2901 }
2902 const Rect& originRect = property_->GetOriginRect();
2903 PointInfo originPos =
2904 WindowHelper::CalculateOriginPosition(originRect, GetRect(),
2905 { pointerItem.GetDisplayX(), pointerItem.GetDisplayY() });
2906 pointerItem.SetDisplayX(originPos.x);
2907 pointerItem.SetDisplayY(originPos.y);
2908 pointerItem.SetWindowX(originPos.x - originRect.posX_);
2909 pointerItem.SetWindowY(originPos.y - originRect.posY_);
2910 pointerEvent->UpdatePointerItem(pointerEvent->GetPointerId(), pointerItem);
2911 }
2912
UpdateDragType(int32_t startPointPosX,int32_t startPointPosY)2913 void WindowImpl::UpdateDragType(int32_t startPointPosX, int32_t startPointPosY)
2914 {
2915 const auto& startRectExceptCorner = moveDragProperty_->startRectExceptCorner_;
2916 if (startPointPosX > startRectExceptCorner.posX_ &&
2917 (startPointPosX < startRectExceptCorner.posX_ +
2918 static_cast<int32_t>(startRectExceptCorner.width_))) {
2919 moveDragProperty_->dragType_ = DragType::DRAG_BOTTOM_OR_TOP;
2920 } else if (startPointPosY > startRectExceptCorner.posY_ &&
2921 (startPointPosY < startRectExceptCorner.posY_ +
2922 static_cast<int32_t>(startRectExceptCorner.height_))) {
2923 moveDragProperty_->dragType_ = DragType::DRAG_LEFT_OR_RIGHT;
2924 } else if ((startPointPosX <= startRectExceptCorner.posX_ && startPointPosY <= startRectExceptCorner.posY_) ||
2925 (startPointPosX >= startRectExceptCorner.posX_ + static_cast<int32_t>(startRectExceptCorner.width_) &&
2926 startPointPosY >= startRectExceptCorner.posY_ + static_cast<int32_t>(startRectExceptCorner.height_))) {
2927 moveDragProperty_->dragType_ = DragType::DRAG_LEFT_TOP_CORNER;
2928 } else {
2929 moveDragProperty_->dragType_ = DragType::DRAG_RIGHT_TOP_CORNER;
2930 }
2931 }
2932
CalculateStartRectExceptHotZone(float vpr)2933 void WindowImpl::CalculateStartRectExceptHotZone(float vpr)
2934 {
2935 TransformHelper::Vector2 hotZoneScale(1, 1);
2936 if (property_->isNeedComputerTransform()) {
2937 property_->ComputeTransform();
2938 hotZoneScale = WindowHelper::CalculateHotZoneScale(property_->GetTransformMat());
2939 }
2940
2941 const auto& startPointRect = GetRect();
2942 auto& startRectExceptFrame = moveDragProperty_->startRectExceptFrame_;
2943 startRectExceptFrame.posX_ = startPointRect.posX_ +
2944 static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr / hotZoneScale.x_);
2945 startRectExceptFrame.posY_ = startPointRect.posY_ +
2946 static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr / hotZoneScale.y_);
2947 startRectExceptFrame.width_ = startPointRect.width_ -
2948 static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr / hotZoneScale.x_);
2949 startRectExceptFrame.height_ = startPointRect.height_ -
2950 static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr / hotZoneScale.y_);
2951
2952 auto& startRectExceptCorner = moveDragProperty_->startRectExceptCorner_;
2953 startRectExceptCorner.posX_ = startPointRect.posX_ +
2954 static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr / hotZoneScale.x_);
2955 startRectExceptCorner.posY_ = startPointRect.posY_ +
2956 static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr / hotZoneScale.y_);
2957 startRectExceptCorner.width_ = startPointRect.width_ -
2958 static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr / hotZoneScale.x_);
2959 startRectExceptCorner.height_ = startPointRect.height_ -
2960 static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr / hotZoneScale.y_);
2961 }
2962
IsPointInDragHotZone(int32_t startPointPosX,int32_t startPointPosY,int32_t sourceType)2963 bool WindowImpl::IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY, int32_t sourceType)
2964 {
2965 // calculate rect with hotzone
2966 Rect rectWithHotzone;
2967 rectWithHotzone.posX_ = GetRect().posX_ - static_cast<int32_t>(HOTZONE_POINTER);
2968 rectWithHotzone.posY_ = GetRect().posY_ - static_cast<int32_t>(HOTZONE_POINTER);
2969 rectWithHotzone.width_ = GetRect().width_ + HOTZONE_POINTER * 2; // 2: calculate width need
2970 rectWithHotzone.height_ = GetRect().height_ + HOTZONE_POINTER * 2; // 2: calculate height need
2971
2972 if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
2973 !WindowHelper::IsPointInTargetRectWithBound(startPointPosX, startPointPosY, rectWithHotzone)) {
2974 return false;
2975 } else if ((!WindowHelper::IsPointInTargetRect(startPointPosX,
2976 startPointPosY, moveDragProperty_->startRectExceptFrame_)) ||
2977 (!WindowHelper::IsPointInWindowExceptCorner(startPointPosX,
2978 startPointPosY, moveDragProperty_->startRectExceptCorner_))) {
2979 return true;
2980 }
2981 return false;
2982 }
2983
StartMove()2984 void WindowImpl::StartMove()
2985 {
2986 if (!WindowHelper::IsMainFloatingWindow(GetType(), GetMode())) {
2987 WLOGE("[StartMove] current window can not be moved, windowId %{public}u", GetWindowId());
2988 return;
2989 }
2990 if (!moveDragProperty_->pointEventStarted_ || moveDragProperty_->startDragFlag_) {
2991 WLOGE("[StartMove] pointerEvent has not been started, or is dragging now");
2992 return;
2993 }
2994 moveDragProperty_->startMoveFlag_ = true;
2995 SingletonContainer::Get<WindowAdapter>().NotifyServerReadyToMoveOrDrag(property_->GetWindowId(),
2996 property_, moveDragProperty_);
2997 WLOGI("[StartMove] windowId %{public}u", GetWindowId());
2998 }
2999
ResetMoveOrDragState()3000 void WindowImpl::ResetMoveOrDragState()
3001 {
3002 if (!WindowHelper::IsMainWindow(GetType())) {
3003 return;
3004 }
3005 moveDragProperty_->pointEventStarted_ = false;
3006 moveDragProperty_->startDragFlag_ = false;
3007 moveDragProperty_->startMoveFlag_ = false;
3008 UpdateRect(GetRect(), property_->GetDecoStatus(), WindowSizeChangeReason::DRAG_END);
3009 }
3010
ReadyToMoveOrDragWindow(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const MMI::PointerEvent::PointerItem & pointerItem)3011 void WindowImpl::ReadyToMoveOrDragWindow(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
3012 const MMI::PointerEvent::PointerItem& pointerItem)
3013 {
3014 if (moveDragProperty_->pointEventStarted_) {
3015 return;
3016 }
3017
3018 moveDragProperty_->startPointRect_ = GetRect();
3019 moveDragProperty_->startPointPosX_ = pointerItem.GetDisplayX();
3020 moveDragProperty_->startPointPosY_ = pointerItem.GetDisplayY();
3021 moveDragProperty_->startPointerId_ = pointerEvent->GetPointerId();
3022 moveDragProperty_->targetDisplayId_ = pointerEvent->GetTargetDisplayId();
3023 moveDragProperty_->sourceType_ = pointerEvent->GetSourceType();
3024 moveDragProperty_->pointEventStarted_ = true;
3025
3026 // calculate window inner rect except frame
3027 auto display = SingletonContainer::IsDestroyed() ? nullptr :
3028 SingletonContainer::Get<DisplayManager>().GetDisplayById(moveDragProperty_->targetDisplayId_);
3029 if (display == nullptr) {
3030 WLOGFE("get display failed moveDragProperty targetDisplayId:%{public}u, window id:%{public}u",
3031 moveDragProperty_->targetDisplayId_, property_->GetWindowId());
3032 return;
3033 }
3034 auto displayInfo = display->GetDisplayInfo();
3035 if (displayInfo == nullptr) {
3036 WLOGFE("get display info failed moveDragProperty targetDisplayId:%{public}u, window id:%{public}u",
3037 moveDragProperty_->targetDisplayId_, property_->GetWindowId());
3038 return;
3039 }
3040 float vpr = display->GetVirtualPixelRatio();
3041 int32_t startPointPosX = moveDragProperty_->startPointPosX_ + displayInfo->GetOffsetX();
3042 int32_t startPointPosY = moveDragProperty_->startPointPosY_ + displayInfo->GetOffsetY();
3043
3044 CalculateStartRectExceptHotZone(vpr);
3045
3046 if (GetType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
3047 moveDragProperty_->startMoveFlag_ = true;
3048 SingletonContainer::Get<WindowAdapter>().NotifyServerReadyToMoveOrDrag(property_->GetWindowId(),
3049 property_, moveDragProperty_);
3050 } else if (IsPointInDragHotZone(startPointPosX, startPointPosY, moveDragProperty_->sourceType_)
3051 && property_->GetMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
3052 moveDragProperty_->startDragFlag_ = true;
3053 UpdateDragType(startPointPosX, startPointPosY);
3054 SingletonContainer::Get<WindowAdapter>().NotifyServerReadyToMoveOrDrag(property_->GetWindowId(),
3055 property_, moveDragProperty_);
3056 }
3057 return;
3058 }
3059
EndMoveOrDragWindow(int32_t posX,int32_t posY,int32_t pointId,int32_t sourceType)3060 void WindowImpl::EndMoveOrDragWindow(int32_t posX, int32_t posY, int32_t pointId, int32_t sourceType)
3061 {
3062 if (pointId != moveDragProperty_->startPointerId_ || sourceType != moveDragProperty_->sourceType_) {
3063 return;
3064 }
3065
3066 if (moveDragProperty_->startDragFlag_) {
3067 SingletonContainer::Get<WindowAdapter>().ProcessPointUp(GetWindowId());
3068 moveDragProperty_->startDragFlag_ = false;
3069 }
3070
3071 if (moveDragProperty_->startMoveFlag_) {
3072 SingletonContainer::Get<WindowAdapter>().ProcessPointUp(GetWindowId());
3073 moveDragProperty_->startMoveFlag_ = false;
3074 HandleModeChangeHotZones(posX, posY);
3075 }
3076 moveDragProperty_->pointEventStarted_ = false;
3077 ResSchedReport::GetInstance().StopPerfIfNeed();
3078 }
3079
ConsumeMoveOrDragEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3080 void WindowImpl::ConsumeMoveOrDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3081 {
3082 MMI::PointerEvent::PointerItem pointerItem;
3083 int32_t pointId = pointerEvent->GetPointerId();
3084 int32_t sourceType = pointerEvent->GetSourceType();
3085 if (!pointerEvent->GetPointerItem(pointId, pointerItem) ||
3086 (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
3087 pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
3088 WLOGFW("invalid pointerEvent");
3089 return;
3090 }
3091 int32_t pointDisplayX = pointerItem.GetDisplayX();
3092 int32_t pointDisplayY = pointerItem.GetDisplayY();
3093 int32_t action = pointerEvent->GetPointerAction();
3094 int32_t targetDisplayId = pointerEvent->GetTargetDisplayId();
3095 switch (action) {
3096 // Ready to move or drag
3097 case MMI::PointerEvent::POINTER_ACTION_DOWN:
3098 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN: {
3099 const auto& rect = GetRect();
3100 ReadyToMoveOrDragWindow(pointerEvent, pointerItem);
3101 if (IsPointerEventConsumed()) {
3102 ResSchedReport::GetInstance().TrigClick();
3103 }
3104 TLOGD(WmsLogTag::WMS_EVENT, "windowId:%{public}u, pointId:%{public}d, sourceType:%{public}d, "
3105 "hasPointStarted:%{public}d, startMove:%{public}d, startDrag:%{public}d, targetDisplayId:"
3106 "%{public}d, pointPos:[%{private}d, %{private}d], winRect:[%{public}d, %{public}d, %{public}u, "
3107 "%{public}u]", GetWindowId(), pointId, sourceType, moveDragProperty_->pointEventStarted_,
3108 moveDragProperty_->startMoveFlag_, moveDragProperty_->startDragFlag_, targetDisplayId,
3109 pointDisplayX, pointDisplayY, rect.posX_, rect.posY_, rect.width_, rect.height_);
3110 break;
3111 }
3112 // End move or drag
3113 case MMI::PointerEvent::POINTER_ACTION_UP:
3114 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
3115 case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
3116 EndMoveOrDragWindow(pointDisplayX, pointDisplayY, pointId, sourceType);
3117 WLOGFD("[Client Point Up/Cancel]: windowId: %{public}u, action: %{public}d, sourceType: %{public}d, "
3118 "startMove: %{public}d, startDrag: %{public}d", GetWindowId(), action, sourceType,
3119 moveDragProperty_->startMoveFlag_, moveDragProperty_->startDragFlag_);
3120 break;
3121 }
3122 default:
3123 break;
3124 }
3125 }
3126
IsPointerEventConsumed()3127 bool WindowImpl::IsPointerEventConsumed()
3128 {
3129 return moveDragProperty_->startDragFlag_ || moveDragProperty_->startMoveFlag_;
3130 }
3131
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3132 void WindowImpl::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3133 {
3134 if (pointerEvent == nullptr) {
3135 WLOGFE("The pointer event is nullptr");
3136 return;
3137 }
3138 if (windowSystemConfig_.isStretchable_ && GetMode() == WindowMode::WINDOW_MODE_FLOATING) {
3139 UpdatePointerEventForStretchableWindow(pointerEvent);
3140 }
3141 std::shared_ptr<IInputEventConsumer> inputEventConsumer;
3142 {
3143 std::lock_guard<std::recursive_mutex> lock(mutex_);
3144 inputEventConsumer = inputEventConsumer_;
3145 }
3146 if (inputEventConsumer != nullptr) {
3147 WLOGFD("Transfer pointer event to inputEventConsumer");
3148 if (!(inputEventConsumer->OnInputEvent(pointerEvent))) {
3149 WLOGFI("The Input event consumer consumes pointer event failed.");
3150 pointerEvent->MarkProcessed();
3151 }
3152 } else if (uiContent_ != nullptr) {
3153 WLOGFD("Transfer pointer event to uiContent");
3154 if (!(uiContent_->ProcessPointerEvent(pointerEvent))) {
3155 WLOGFI("The UI content consumes pointer event failed.");
3156 pointerEvent->MarkProcessed();
3157 }
3158 } else {
3159 WLOGFW("pointerEvent is not consumed, windowId: %{public}u", GetWindowId());
3160 pointerEvent->MarkProcessed();
3161 }
3162 }
3163
CalculatePointerDirection(int32_t pointerX,int32_t pointerY)3164 uint32_t WindowImpl::CalculatePointerDirection(int32_t pointerX, int32_t pointerY)
3165 {
3166 UpdateDragType(pointerX, pointerY);
3167 return STYLEID_MAP.at(moveDragProperty_->dragType_);
3168 }
3169
HandlePointerStyle(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3170 void WindowImpl::HandlePointerStyle(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3171 {
3172 MMI::PointerEvent::PointerItem pointerItem;
3173 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
3174 WLOGFE("Get pointeritem failed");
3175 pointerEvent->MarkProcessed();
3176 return;
3177 }
3178 auto action = pointerEvent->GetPointerAction();
3179 uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId());
3180 int32_t mousePointX = pointerItem.GetDisplayX();
3181 int32_t mousePointY = pointerItem.GetDisplayY();
3182 int32_t sourceType = pointerEvent->GetSourceType();
3183 uint32_t oldStyleID = mouseStyleID_;
3184 uint32_t newStyleID = 0;
3185 if (WindowHelper::IsMainFloatingWindow(GetType(), GetMode())) {
3186 auto display = SingletonContainer::IsDestroyed() ? nullptr :
3187 SingletonContainer::Get<DisplayManager>().GetDisplayById(pointerEvent->GetTargetDisplayId());
3188 if (display == nullptr || display->GetDisplayInfo() == nullptr) {
3189 WLOGFE("get display failed displayId:%{public}" PRIu64", window id:%{public}u",
3190 property_->GetDisplayId(), property_->GetWindowId());
3191 return;
3192 }
3193 float vpr = display->GetVirtualPixelRatio();
3194 CalculateStartRectExceptHotZone(vpr);
3195 if (IsPointInDragHotZone(mousePointX, mousePointY, sourceType) &&
3196 property_->GetMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
3197 newStyleID = CalculatePointerDirection(mousePointX, mousePointY);
3198 } else if (action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP) {
3199 newStyleID = MMI::MOUSE_ICON::DEFAULT;
3200 }
3201 } else if (GetType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
3202 newStyleID = (GetRect().width_ > GetRect().height_) ?
3203 MMI::MOUSE_ICON::NORTH_SOUTH : MMI::MOUSE_ICON::WEST_EAST;
3204 if (action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP) {
3205 newStyleID = MMI::MOUSE_ICON::DEFAULT; // when receive up event, set default style
3206 }
3207 }
3208 TLOGD(WmsLogTag::WMS_EVENT, "winId:%{public}u, Mouse posX:%{private}u, posY:%{private}u, action:%{public}u, "
3209 "winRect posX:%{public}u, posY:%{public}u, W:%{public}u, H:%{public}u, "
3210 "newStyle:%{public}u, oldStyle:%{public}u",
3211 windowId, mousePointX, mousePointY, action, GetRect().posX_,
3212 GetRect().posY_, GetRect().width_, GetRect().height_, newStyleID, oldStyleID);
3213 if (oldStyleID != newStyleID) {
3214 MMI::PointerStyle pointerStyle;
3215 pointerStyle.id = static_cast<int32_t>(newStyleID);
3216 int32_t res = MMI::InputManager::GetInstance()->SetPointerStyle(windowId, pointerStyle);
3217 if (res != 0) {
3218 WLOGFE("set pointer style failed, res is %{public}u", res);
3219 return;
3220 }
3221 mouseStyleID_ = newStyleID;
3222 }
3223 }
3224
PerfLauncherHotAreaIfNeed(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3225 void WindowImpl::PerfLauncherHotAreaIfNeed(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3226 {
3227 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
3228 int32_t action = pointerEvent->GetPointerAction();
3229 if (action != MMI::PointerEvent::POINTER_ACTION_CANCEL) {
3230 return;
3231 }
3232 MMI::PointerEvent::PointerItem pointerItem;
3233 int32_t pointId = pointerEvent->GetPointerId();
3234 if (!pointerEvent->GetPointerItem(pointId, pointerItem)) {
3235 WLOGFW("invalid pointerEvent");
3236 return;
3237 }
3238 auto display = SingletonContainer::IsDestroyed() ? nullptr :
3239 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
3240 if (display == nullptr) {
3241 return;
3242 }
3243 auto displayHeight = display->GetHeight();
3244 constexpr float HOT_RATE = 0.07;
3245 auto height = static_cast<int32_t>(displayHeight * HOT_RATE);
3246 int32_t pointDisplayY = pointerItem.GetDisplayY();
3247 if (pointDisplayY > displayHeight - height) {
3248 ResSchedReport::GetInstance().AnimationBoost();
3249 }
3250 #endif
3251 }
3252
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)3253 void WindowImpl::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
3254 {
3255 // If windowRect transformed, transform event back to its origin position
3256 if (property_) {
3257 property_->UpdatePointerEvent(pointerEvent);
3258 }
3259 int32_t action = pointerEvent->GetPointerAction();
3260 if (action == MMI::PointerEvent::POINTER_ACTION_MOVE || action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
3261 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
3262 ResSchedReport::GetInstance().TrigSlide(GetType(), true);
3263 }
3264 if (action == MMI::PointerEvent::POINTER_ACTION_UP || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
3265 action == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
3266 ResSchedReport::GetInstance().TrigSlide(GetType(), false);
3267 }
3268 if ((action == MMI::PointerEvent::POINTER_ACTION_MOVE || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP) &&
3269 pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
3270 HandlePointerStyle(pointerEvent);
3271 }
3272 PerfLauncherHotAreaIfNeed(pointerEvent);
3273 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
3274 WLOGFD("WMS process point down, id:%{public}u, action: %{public}d", GetWindowId(), action);
3275 if (GetType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) {
3276 MMI::PointerEvent::PointerItem pointerItem;
3277 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
3278 WLOGFW("Point item is invalid");
3279 pointerEvent->MarkProcessed();
3280 return;
3281 }
3282 if (!WindowHelper::IsPointInTargetRect(pointerItem.GetDisplayX(), pointerItem.GetDisplayY(), GetRect())) {
3283 NotifyAfterUnfocused(false);
3284 pointerEvent->MarkProcessed();
3285 return;
3286 }
3287 }
3288 if (property_ != nullptr) {
3289 SingletonContainer::Get<WindowAdapter>().ProcessPointDown(property_->GetWindowId());
3290 }
3291 }
3292
3293 // If point event type is up, should reset start move flag
3294 if (WindowHelper::IsMainFloatingWindow(GetType(), GetMode()) || GetType() == WindowType::WINDOW_TYPE_DOCK_SLICE ||
3295 (action == MMI::PointerEvent::POINTER_ACTION_UP || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
3296 action == MMI::PointerEvent::POINTER_ACTION_CANCEL)) {
3297 ConsumeMoveOrDragEvent(pointerEvent);
3298 }
3299
3300 if (IsPointerEventConsumed()) {
3301 pointerEvent->MarkProcessed();
3302 return;
3303 }
3304
3305 TransferPointerEvent(pointerEvent);
3306 }
3307
RequestVsync(const std::shared_ptr<VsyncCallback> & vsyncCallback)3308 void WindowImpl::RequestVsync(const std::shared_ptr<VsyncCallback>& vsyncCallback)
3309 {
3310 std::lock_guard<std::recursive_mutex> lock(mutex_);
3311 if (state_ == WindowState::STATE_DESTROYED) {
3312 WLOGFE("[WM] Receive Vsync Request failed, window is destroyed");
3313 return;
3314 }
3315
3316 if (!SingletonContainer::IsDestroyed() && vsyncStation_ != nullptr) {
3317 vsyncStation_->RequestVsync(vsyncCallback);
3318 }
3319 }
3320
GetVSyncPeriod()3321 int64_t WindowImpl::GetVSyncPeriod()
3322 {
3323 std::lock_guard<std::recursive_mutex> lock(mutex_);
3324 if (!SingletonContainer::IsDestroyed() && vsyncStation_ != nullptr) {
3325 return vsyncStation_->GetVSyncPeriod();
3326 }
3327 return 0;
3328 }
3329
UpdateFocusStatus(bool focused)3330 void WindowImpl::UpdateFocusStatus(bool focused)
3331 {
3332 if (!IsWindowValid()) {
3333 TLOGE(WmsLogTag::DEFAULT, "Window is invalid");
3334 return;
3335 }
3336
3337 WLOGFD("IsFocused: %{public}d, id: %{public}u", focused, property_->GetWindowId());
3338 isFocused_ = focused;
3339 if (focused) {
3340 HiSysEventWrite(
3341 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
3342 "FOCUS_WINDOW",
3343 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
3344 "PID", getpid(),
3345 "UID", getuid(),
3346 "BUNDLE_NAME", property_->GetAbilityInfo().bundleName_);
3347 if (state_ <= WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
3348 needNotifyFocusLater_ = true;
3349 return;
3350 }
3351 NotifyAfterFocused();
3352 } else {
3353 NotifyAfterUnfocused();
3354 }
3355 }
3356
IsFocused() const3357 bool WindowImpl::IsFocused() const
3358 {
3359 if (!IsWindowValid()) {
3360 TLOGE(WmsLogTag::DEFAULT, "Window is invalid");
3361 return false;
3362 }
3363
3364 return isFocused_;
3365 }
3366
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3367 void WindowImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3368 {
3369 if (uiContent_ != nullptr) {
3370 WLOGFD("notify ace winId:%{public}u", GetWindowId());
3371 uiContent_->UpdateConfiguration(configuration);
3372 }
3373 if (subWindowMap_.count(GetWindowId()) == 0) {
3374 return;
3375 }
3376 for (auto& subWindow : subWindowMap_.at(GetWindowId())) {
3377 subWindow->UpdateConfiguration(configuration);
3378 }
3379 }
3380
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)3381 void WindowImpl::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
3382 {
3383 WLOGI("Update AvoidArea, id: %{public}u", property_->GetWindowId());
3384 auto display = SingletonContainer::IsDestroyed() ? nullptr :
3385 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
3386 UpdateViewportConfig(GetRect(), display, WindowSizeChangeReason::UNDEFINED, nullptr, {{type, *avoidArea}});
3387 NotifyAvoidAreaChange(avoidArea, type);
3388 }
3389
UpdateViewportConfig(const Rect & rect,const sptr<Display> & display,WindowSizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction,const std::map<AvoidAreaType,AvoidArea> & avoidAreas)3390 void WindowImpl::UpdateViewportConfig(const Rect& rect, const sptr<Display>& display, WindowSizeChangeReason reason,
3391 const std::shared_ptr<RSTransaction>& rsTransaction,
3392 const std::map<AvoidAreaType, AvoidArea>& avoidAreas)
3393 {
3394 std::lock_guard<std::recursive_mutex> lock(mutex_);
3395 if (uiContent_ == nullptr) {
3396 return;
3397 }
3398 Ace::ViewportConfig config;
3399 config.SetSize(rect.width_, rect.height_);
3400 config.SetPosition(rect.posX_, rect.posY_);
3401 if (display) {
3402 config.SetDensity(display->GetVirtualPixelRatio());
3403 auto displayInfo = display->GetDisplayInfo();
3404 if (displayInfo != nullptr) {
3405 config.SetOrientation(static_cast<int32_t>(displayInfo->GetDisplayOrientation()));
3406 }
3407 }
3408 uiContent_->UpdateViewportConfig(config, reason, rsTransaction, avoidAreas);
3409 WLOGFD("Id:%{public}u, windowRect:[%{public}d, %{public}d, %{public}u, %{public}u]",
3410 property_->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_);
3411 }
3412
UpdateDecorEnable(bool needNotify)3413 void WindowImpl::UpdateDecorEnable(bool needNotify)
3414 {
3415 WLOGFD("Start");
3416 if (WindowHelper::IsMainWindow(property_->GetWindowType())) {
3417 bool enable = windowSystemConfig_.isSystemDecorEnable_ &&
3418 WindowHelper::IsWindowModeSupported(windowSystemConfig_.decorModeSupportInfo_, GetMode());
3419 WLOGFD("Decor enable: %{public}d", static_cast<int32_t>(enable));
3420 property_->SetDecorEnable(enable);
3421 } else {
3422 property_->SetDecorEnable(false);
3423 }
3424 if (needNotify) {
3425 if (uiContent_ != nullptr) {
3426 uiContent_->UpdateWindowMode(GetMode(), property_->GetDecorEnable());
3427 WLOGFD("Notify uiContent window mode change end");
3428 }
3429 NotifyModeChange(GetMode(), property_->GetDecorEnable());
3430 }
3431 }
3432
UpdateWindowStateUnfrozen()3433 void WindowImpl::UpdateWindowStateUnfrozen()
3434 {
3435 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
3436 if (abilityContext != nullptr && windowTag_ == WindowTag::MAIN_WINDOW) {
3437 WLOGFD("DoAbilityForeground KEYGUARD, id: %{public}u", GetWindowId());
3438 AAFwk::AbilityManagerClient::GetInstance()->DoAbilityForeground(abilityContext->GetToken(),
3439 static_cast<uint32_t>(WindowStateChangeReason::KEYGUARD));
3440 } else if (state_ != WindowState::STATE_SHOWN) {
3441 state_ = WindowState::STATE_SHOWN;
3442 NotifyAfterForeground();
3443 }
3444 }
3445
UpdateWindowState(WindowState state)3446 void WindowImpl::UpdateWindowState(WindowState state)
3447 {
3448 WLOGFI("id: %{public}u, State to set:%{public}u", GetWindowId(), state);
3449 if (!IsWindowValid()) {
3450 return;
3451 }
3452 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
3453 switch (state) {
3454 case WindowState::STATE_FROZEN: {
3455 if (abilityContext != nullptr && windowTag_ == WindowTag::MAIN_WINDOW) {
3456 WLOGFD("DoAbilityBackground KEYGUARD, id: %{public}u", GetWindowId());
3457 AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(abilityContext->GetToken(),
3458 static_cast<uint32_t>(WindowStateChangeReason::KEYGUARD));
3459 } else {
3460 state_ = WindowState::STATE_FROZEN;
3461 NotifyAfterBackground(false, true);
3462 }
3463 break;
3464 }
3465 case WindowState::STATE_UNFROZEN: {
3466 UpdateWindowStateUnfrozen();
3467 break;
3468 }
3469 case WindowState::STATE_SHOWN: {
3470 if (abilityContext != nullptr && windowTag_ == WindowTag::MAIN_WINDOW) {
3471 WLOGFD("WindowState::STATE_SHOWN, id: %{public}u", GetWindowId());
3472 AAFwk::AbilityManagerClient::GetInstance()->DoAbilityForeground(abilityContext->GetToken(),
3473 static_cast<uint32_t>(WindowStateChangeReason::TOGGLING));
3474 } else {
3475 state_ = WindowState::STATE_SHOWN;
3476 NotifyAfterForeground();
3477 }
3478 break;
3479 }
3480 case WindowState::STATE_HIDDEN: {
3481 if (abilityContext != nullptr && windowTag_ == WindowTag::MAIN_WINDOW &&
3482 state_ == WindowState::STATE_SHOWN) {
3483 WLOGFD("WindowState: STATE_SHOWN, id: %{public}u", GetWindowId());
3484 AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(abilityContext->GetToken(),
3485 static_cast<uint32_t>(WindowStateChangeReason::NORMAL));
3486 } else {
3487 Hide(static_cast<uint32_t>(WindowStateChangeReason::NORMAL), false);
3488 }
3489 break;
3490 }
3491 default: {
3492 WLOGFE("windowState to set is invalid");
3493 break;
3494 }
3495 }
3496 }
3497
UpdateWindowStateWhenShow()3498 WmErrorCode WindowImpl::UpdateWindowStateWhenShow()
3499 {
3500 state_ = WindowState::STATE_SHOWN;
3501 if (WindowHelper::IsMainWindow(property_->GetWindowType()) ||
3502 WindowHelper::IsSystemMainWindow(property_->GetWindowType())) {
3503 // update subwindow subWindowState_ and notify subwindow shown or not
3504 UpdateSubWindowStateAndNotify(GetWindowId());
3505 NotifyAfterForeground();
3506 } else if (GetType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
3507 subWindowState_ = WindowState::STATE_SHOWN;
3508 NotifyAfterForeground();
3509 } else {
3510 uint32_t parentId = property_->GetParentId();
3511 sptr<Window> parentWindow = FindWindowById(parentId);
3512 if (parentWindow == nullptr) {
3513 WLOGE("parent window is null");
3514 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3515 }
3516 if (parentWindow->GetWindowState() == WindowState::STATE_HIDDEN) {
3517 // not notify user shown and update subwindowState_
3518 subWindowState_ = WindowState::STATE_HIDDEN;
3519 } else if (parentWindow->GetWindowState() == WindowState::STATE_SHOWN) {
3520 NotifyAfterForeground();
3521 subWindowState_ = WindowState::STATE_SHOWN;
3522 }
3523 }
3524 if (needNotifyFocusLater_ && isFocused_) {
3525 UpdateFocusStatus(true);
3526 }
3527 return WmErrorCode::WM_OK;
3528 }
3529
UpdateWindowStateWhenHide()3530 WmErrorCode WindowImpl::UpdateWindowStateWhenHide()
3531 {
3532 state_ = WindowState::STATE_HIDDEN;
3533 if (WindowHelper::IsSystemMainWindow(property_->GetWindowType()) ||
3534 WindowHelper::IsMainWindow(property_->GetWindowType())) {
3535 // main window need to update subwindow subWindowState_ and notify subwindow shown or not
3536 UpdateSubWindowStateAndNotify(GetWindowId());
3537 NotifyAfterBackground();
3538 } else if (GetType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
3539 subWindowState_ = WindowState::STATE_HIDDEN;
3540 NotifyAfterBackground();
3541 } else {
3542 uint32_t parentId = property_->GetParentId();
3543 sptr<Window> parentWindow = FindWindowById(parentId);
3544 if (parentWindow == nullptr) {
3545 WLOGE("parent window is null");
3546 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
3547 }
3548 if (subWindowState_ == WindowState::STATE_SHOWN) {
3549 NotifyAfterBackground();
3550 }
3551 subWindowState_ = WindowState::STATE_HIDDEN;
3552 }
3553 return WmErrorCode::WM_OK;
3554 }
3555
UpdateSubWindowStateAndNotify(uint32_t parentId)3556 WmErrorCode WindowImpl::UpdateSubWindowStateAndNotify(uint32_t parentId)
3557 {
3558 if (subWindowMap_.find(parentId) == subWindowMap_.end()) {
3559 WLOGFD("main window: %{public}u has no child node", parentId);
3560 return WmErrorCode::WM_OK;
3561 }
3562 std::vector<sptr<WindowImpl>> subWindows = subWindowMap_[parentId];
3563 if (subWindows.empty()) {
3564 WLOGFD("main window: %{public}u, its subWindowMap is empty", parentId);
3565 return WmErrorCode::WM_OK;
3566 }
3567 // when main window hide and subwindow whose state is shown should hide and notify user
3568 if (state_ == WindowState::STATE_HIDDEN) {
3569 for (auto subwindow : subWindows) {
3570 if (subwindow->GetWindowState() == WindowState::STATE_SHOWN &&
3571 subwindow->subWindowState_ == WindowState::STATE_SHOWN) {
3572 subwindow->NotifyAfterBackground();
3573 }
3574 subwindow->subWindowState_ = WindowState::STATE_HIDDEN;
3575 }
3576 // when main window show and subwindow whose state is shown should show and notify user
3577 } else if (state_ == WindowState::STATE_SHOWN) {
3578 for (auto subwindow : subWindows) {
3579 if (subwindow->GetWindowState() == WindowState::STATE_SHOWN &&
3580 subwindow->subWindowState_ == WindowState::STATE_HIDDEN) {
3581 subwindow->NotifyAfterForeground();
3582 subwindow->subWindowState_ = WindowState::STATE_SHOWN;
3583 } else {
3584 subwindow->subWindowState_ = WindowState::STATE_HIDDEN;
3585 }
3586 }
3587 }
3588 return WmErrorCode::WM_OK;
3589 }
3590
GetWindowProperty()3591 sptr<WindowProperty> WindowImpl::GetWindowProperty()
3592 {
3593 return property_;
3594 }
3595
RestoreSplitWindowMode(uint32_t mode)3596 void WindowImpl::RestoreSplitWindowMode(uint32_t mode)
3597 {
3598 if (!IsWindowValid()) {
3599 return;
3600 }
3601 auto windowMode = static_cast<WindowMode>(mode);
3602 if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
3603 UpdateMode(windowMode);
3604 }
3605 }
3606
UpdateDragEvent(const PointInfo & point,DragEvent event)3607 void WindowImpl::UpdateDragEvent(const PointInfo& point, DragEvent event)
3608 {
3609 NotifyDragEvent(point, event);
3610 }
3611
NotifyDragEvent(const PointInfo & point,DragEvent event)3612 void WindowImpl::NotifyDragEvent(const PointInfo& point, DragEvent event)
3613 {
3614 auto windowDragListeners = GetListeners<IWindowDragListener>();
3615 Rect rect = GetRect();
3616 for (auto& listener : windowDragListeners) {
3617 if (listener != nullptr) {
3618 listener->OnDrag(point.x - rect.posX_, point.y - rect.posY_, event);
3619 }
3620 }
3621 }
3622
UpdateDisplayId(DisplayId from,DisplayId to)3623 void WindowImpl::UpdateDisplayId(DisplayId from, DisplayId to)
3624 {
3625 WLOGFD("update displayId. win %{public}u", GetWindowId());
3626 NotifyDisplayMoveChange(from, to);
3627 property_->SetDisplayId(to);
3628 }
3629
UpdateOccupiedAreaChangeInfo(const sptr<OccupiedAreaChangeInfo> & info,const std::shared_ptr<RSTransaction> & rsTransaction)3630 void WindowImpl::UpdateOccupiedAreaChangeInfo(const sptr<OccupiedAreaChangeInfo>& info,
3631 const std::shared_ptr<RSTransaction>& rsTransaction)
3632 {
3633 WLOGFD("Update OccupiedArea, id: %{public}u", property_->GetWindowId());
3634 NotifyOccupiedAreaChange(info, rsTransaction);
3635 }
3636
UpdateActiveStatus(bool isActive)3637 void WindowImpl::UpdateActiveStatus(bool isActive)
3638 {
3639 WLOGFD("window active status: %{public}d, id: %{public}u", isActive, property_->GetWindowId());
3640 if (isActive) {
3641 NotifyAfterActive();
3642 } else {
3643 NotifyAfterInactive();
3644 }
3645 }
3646
NotifyScreenshot()3647 void WindowImpl::NotifyScreenshot()
3648 {
3649 auto screenshotListeners = GetListeners<IScreenshotListener>();
3650 for (auto& screenshotListener : screenshotListeners) {
3651 if (screenshotListener != nullptr) {
3652 screenshotListener->OnScreenshot();
3653 }
3654 }
3655 }
3656
NotifyTouchOutside()3657 void WindowImpl::NotifyTouchOutside()
3658 {
3659 auto touchOutsideListeners = GetListeners<ITouchOutsideListener>();
3660 for (auto& touchOutsideListener : touchOutsideListeners) {
3661 if (touchOutsideListener != nullptr) {
3662 touchOutsideListener->OnTouchOutside();
3663 }
3664 }
3665 }
3666
NotifyTouchDialogTarget(int32_t posX,int32_t posY)3667 void WindowImpl::NotifyTouchDialogTarget(int32_t posX, int32_t posY)
3668 {
3669 SingletonContainer::Get<WindowAdapter>().ProcessPointDown(property_->GetWindowId());
3670 auto dialogTargetTouchListeners = GetListeners<IDialogTargetTouchListener>();
3671 for (auto& dialogTargetTouchListener : dialogTargetTouchListeners) {
3672 if (dialogTargetTouchListener != nullptr) {
3673 dialogTargetTouchListener->OnDialogTargetTouch();
3674 }
3675 }
3676 }
3677
NotifyDestroy()3678 void WindowImpl::NotifyDestroy()
3679 {
3680 auto dialogDeathRecipientListener = GetListener<IDialogDeathRecipientListener>();
3681 if (dialogDeathRecipientListener != nullptr) {
3682 dialogDeathRecipientListener->OnDialogDeathRecipient();
3683 }
3684 }
3685
NotifyForeground()3686 void WindowImpl::NotifyForeground()
3687 {
3688 NotifyAfterForeground();
3689 }
3690
NotifyBackground()3691 void WindowImpl::NotifyBackground()
3692 {
3693 NotifyAfterBackground();
3694 }
3695
NotifyForegroundInteractiveStatus(bool interactive)3696 void WindowImpl::NotifyForegroundInteractiveStatus(bool interactive)
3697 {
3698 WLOGFI("NotifyForegroundInteractiveStatus %{public}d", interactive);
3699 if (!IsWindowValid() || state_ != WindowState::STATE_SHOWN) {
3700 return;
3701 }
3702 if (interactive) {
3703 NotifyAfterResumed();
3704 } else {
3705 NotifyAfterPaused();
3706 }
3707 }
3708
TransformSurfaceNode(const Transform & trans)3709 void WindowImpl::TransformSurfaceNode(const Transform& trans)
3710 {
3711 if (surfaceNode_ == nullptr) {
3712 return;
3713 }
3714 surfaceNode_->SetPivotX(trans.pivotX_);
3715 surfaceNode_->SetPivotY(trans.pivotY_);
3716 surfaceNode_->SetScaleX(trans.scaleX_);
3717 surfaceNode_->SetScaleY(trans.scaleY_);
3718 surfaceNode_->SetTranslateX(trans.translateX_);
3719 surfaceNode_->SetTranslateY(trans.translateY_);
3720 surfaceNode_->SetTranslateZ(trans.translateZ_);
3721 surfaceNode_->SetRotationX(trans.rotationX_);
3722 surfaceNode_->SetRotationY(trans.rotationY_);
3723 surfaceNode_->SetRotation(trans.rotationZ_);
3724 }
3725
UpdateZoomTransform(const Transform & trans,bool isDisplayZoomOn)3726 void WindowImpl::UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn)
3727 {
3728 WLOGFD("%{public}s zoomTrans, pivotX:%{public}f, pivotY:%{public}f, scaleX:%{public}f, scaleY:%{public}f"
3729 ", transX:%{public}f, transY:%{public}f, transZ:%{public}f, rotateX:%{public}f, rotateY:%{public}f "
3730 "rotateZ:%{public}f", property_->GetWindowName().c_str(), trans.pivotX_, trans.pivotY_, trans.scaleX_,
3731 trans.scaleY_, trans.translateX_, trans.translateY_, trans.translateZ_, trans.rotationX_,
3732 trans.rotationY_, trans.rotationZ_);
3733 property_->SetZoomTransform(trans);
3734 property_->SetDisplayZoomState(isDisplayZoomOn);
3735 }
3736
ClearListenersById(uint32_t winId)3737 void WindowImpl::ClearListenersById(uint32_t winId)
3738 {
3739 std::lock_guard<std::recursive_mutex> lock(globalMutex_);
3740 ClearUselessListeners(screenshotListeners_, winId);
3741 ClearUselessListeners(touchOutsideListeners_, winId);
3742 ClearUselessListeners(dialogTargetTouchListeners_, winId);
3743 ClearUselessListeners(lifecycleListeners_, winId);
3744 ClearUselessListeners(windowChangeListeners_, winId);
3745 ClearUselessListeners(avoidAreaChangeListeners_, winId);
3746 ClearUselessListeners(occupiedAreaChangeListeners_, winId);
3747 ClearUselessListeners(dialogDeathRecipientListener_, winId);
3748 }
3749
NotifyAfterForeground(bool needNotifyListeners,bool needNotifyUiContent)3750 void WindowImpl::NotifyAfterForeground(bool needNotifyListeners, bool needNotifyUiContent)
3751 {
3752 if (needNotifyListeners) {
3753 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3754 CALL_LIFECYCLE_LISTENER(AfterForeground, lifecycleListeners);
3755 }
3756 if (needNotifyUiContent) {
3757 CALL_UI_CONTENT(Foreground);
3758 }
3759 }
3760
NotifyAfterBackground(bool needNotifyListeners,bool needNotifyUiContent)3761 void WindowImpl::NotifyAfterBackground(bool needNotifyListeners, bool needNotifyUiContent)
3762 {
3763 if (needNotifyListeners) {
3764 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3765 CALL_LIFECYCLE_LISTENER(AfterBackground, lifecycleListeners);
3766 }
3767 if (needNotifyUiContent) {
3768 CALL_UI_CONTENT(Background);
3769 }
3770 }
3771
NotifyAfterFocused()3772 void WindowImpl::NotifyAfterFocused()
3773 {
3774 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3775 CALL_LIFECYCLE_LISTENER(AfterFocused, lifecycleListeners);
3776 CALL_UI_CONTENT(Focus);
3777 }
3778
NotifyAfterUnfocused(bool needNotifyUiContent)3779 void WindowImpl::NotifyAfterUnfocused(bool needNotifyUiContent)
3780 {
3781 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3782 // use needNotifyUinContent to separate ui content callbacks
3783 CALL_LIFECYCLE_LISTENER(AfterUnfocused, lifecycleListeners);
3784 if (needNotifyUiContent) {
3785 CALL_UI_CONTENT(UnFocus);
3786 }
3787 }
3788
NotifyAfterResumed()3789 void WindowImpl::NotifyAfterResumed()
3790 {
3791 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3792 CALL_LIFECYCLE_LISTENER(AfterResumed, lifecycleListeners);
3793 }
3794
NotifyAfterPaused()3795 void WindowImpl::NotifyAfterPaused()
3796 {
3797 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3798 CALL_LIFECYCLE_LISTENER(AfterPaused, lifecycleListeners);
3799 }
3800
NotifyBeforeDestroy(std::string windowName)3801 void WindowImpl::NotifyBeforeDestroy(std::string windowName)
3802 {
3803 std::lock_guard<std::recursive_mutex> lock(mutex_);
3804 if (uiContent_ != nullptr) {
3805 auto uiContent = std::move(uiContent_);
3806 uiContent_ = nullptr;
3807 uiContent->Destroy();
3808 }
3809 if (notifyNativefunc_) {
3810 notifyNativefunc_(windowName);
3811 }
3812 }
3813
NotifyBeforeSubWindowDestroy(sptr<WindowImpl> window)3814 void WindowImpl::NotifyBeforeSubWindowDestroy(sptr<WindowImpl> window)
3815 {
3816 auto uiContent = window->GetUIContent();
3817 if (uiContent != nullptr) {
3818 uiContent->Destroy();
3819 }
3820 if (window->GetNativeDestroyCallback()) {
3821 window->GetNativeDestroyCallback()(window->GetWindowName());
3822 }
3823 }
3824
NotifyAfterActive()3825 void WindowImpl::NotifyAfterActive()
3826 {
3827 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3828 CALL_LIFECYCLE_LISTENER(AfterActive, lifecycleListeners);
3829 }
3830
NotifyAfterInactive()3831 void WindowImpl::NotifyAfterInactive()
3832 {
3833 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3834 CALL_LIFECYCLE_LISTENER(AfterInactive, lifecycleListeners);
3835 }
3836
NotifyForegroundFailed(WMError ret)3837 void WindowImpl::NotifyForegroundFailed(WMError ret)
3838 {
3839 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3840 CALL_LIFECYCLE_LISTENER_WITH_PARAM(ForegroundFailed, lifecycleListeners, static_cast<int32_t>(ret));
3841 }
3842
NotifyBackgroundFailed(WMError ret)3843 void WindowImpl::NotifyBackgroundFailed(WMError ret)
3844 {
3845 auto lifecycleListeners = GetListeners<IWindowLifeCycle>();
3846 CALL_LIFECYCLE_LISTENER_WITH_PARAM(BackgroundFailed, lifecycleListeners, static_cast<int32_t>(ret));
3847 }
3848
IsStretchableReason(WindowSizeChangeReason reason)3849 bool WindowImpl::IsStretchableReason(WindowSizeChangeReason reason)
3850 {
3851 return reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::DRAG_END ||
3852 reason == WindowSizeChangeReason::DRAG_START || reason == WindowSizeChangeReason::RECOVER ||
3853 reason == WindowSizeChangeReason::MOVE || reason == WindowSizeChangeReason::UNDEFINED;
3854 }
3855
NotifySizeChange(Rect rect,WindowSizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction)3856 void WindowImpl::NotifySizeChange(Rect rect, WindowSizeChangeReason reason,
3857 const std::shared_ptr<RSTransaction>& rsTransaction)
3858 {
3859 auto windowChangeListeners = GetListeners<IWindowChangeListener>();
3860 for (auto& listener : windowChangeListeners) {
3861 if (listener != nullptr) {
3862 listener->OnSizeChange(rect, reason, rsTransaction);
3863 }
3864 }
3865 }
3866
NotifyAvoidAreaChange(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)3867 void WindowImpl::NotifyAvoidAreaChange(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
3868 {
3869 auto avoidAreaChangeListeners = GetListeners<IAvoidAreaChangedListener>();
3870 for (auto& listener : avoidAreaChangeListeners) {
3871 if (listener != nullptr) {
3872 listener->OnAvoidAreaChanged(*avoidArea, type);
3873 }
3874 }
3875 }
3876
NotifyDisplayMoveChange(DisplayId from,DisplayId to)3877 void WindowImpl::NotifyDisplayMoveChange(DisplayId from, DisplayId to)
3878 {
3879 auto displayMoveListeners = GetListeners<IDisplayMoveListener>();
3880 for (auto& listener : displayMoveListeners) {
3881 if (listener != nullptr) {
3882 listener->OnDisplayMove(from, to);
3883 }
3884 }
3885 }
3886
NotifyModeChange(WindowMode mode,bool hasDeco)3887 void WindowImpl::NotifyModeChange(WindowMode mode, bool hasDeco)
3888 {
3889 auto windowChangeListeners = GetListeners<IWindowChangeListener>();
3890 for (auto& listener : windowChangeListeners) {
3891 if (listener != nullptr) {
3892 listener->OnModeChange(mode, hasDeco);
3893 }
3894 }
3895 }
3896
NotifyOccupiedAreaChange(const sptr<OccupiedAreaChangeInfo> & info,const std::shared_ptr<RSTransaction> & rsTransaction)3897 void WindowImpl::NotifyOccupiedAreaChange(const sptr<OccupiedAreaChangeInfo>& info,
3898 const std::shared_ptr<RSTransaction>& rsTransaction)
3899 {
3900 auto occupiedAreaChangeListeners = GetListeners<IOccupiedAreaChangeListener>();
3901 for (auto& listener : occupiedAreaChangeListeners) {
3902 if (listener != nullptr) {
3903 listener->OnSizeChange(info, rsTransaction);
3904 }
3905 }
3906 }
3907
SetNeedRemoveWindowInputChannel(bool needRemoveWindowInputChannel)3908 void WindowImpl::SetNeedRemoveWindowInputChannel(bool needRemoveWindowInputChannel)
3909 {
3910 needRemoveWindowInputChannel_ = needRemoveWindowInputChannel;
3911 }
3912
GetSystemAlarmWindowDefaultSize(Rect defaultRect)3913 Rect WindowImpl::GetSystemAlarmWindowDefaultSize(Rect defaultRect)
3914 {
3915 auto display = SingletonContainer::IsDestroyed() ? nullptr :
3916 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
3917 if (display == nullptr) {
3918 WLOGFE("get display failed displayId:%{public}" PRIu64", window id:%{public}u", property_->GetDisplayId(),
3919 property_->GetWindowId());
3920 return defaultRect;
3921 }
3922 uint32_t width = static_cast<uint32_t>(display->GetWidth());
3923 uint32_t height = static_cast<uint32_t>(display->GetHeight());
3924 WLOGFD("width:%{public}u, height:%{public}u, displayId:%{public}" PRIu64"",
3925 width, height, property_->GetDisplayId());
3926 uint32_t alarmWidth = static_cast<uint32_t>((static_cast<float>(width) *
3927 SYSTEM_ALARM_WINDOW_WIDTH_RATIO));
3928 uint32_t alarmHeight = static_cast<uint32_t>((static_cast<float>(height) *
3929 SYSTEM_ALARM_WINDOW_HEIGHT_RATIO));
3930
3931 Rect rect = { static_cast<int32_t>((width - alarmWidth) / 2), static_cast<int32_t>((height - alarmHeight) / 2),
3932 alarmWidth, alarmHeight }; // divided by 2 to middle the window
3933 return rect;
3934 }
3935
SetDefaultOption()3936 void WindowImpl::SetDefaultOption()
3937 {
3938 switch (property_->GetWindowType()) {
3939 case WindowType::WINDOW_TYPE_STATUS_BAR:
3940 case WindowType::WINDOW_TYPE_NAVIGATION_BAR:
3941 case WindowType::WINDOW_TYPE_VOLUME_OVERLAY:
3942 case WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT:
3943 case WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR: {
3944 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3945 property_->SetFocusable(false);
3946 break;
3947 }
3948 case WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW: {
3949 property_->SetRequestRect(GetSystemAlarmWindowDefaultSize(property_->GetRequestRect()));
3950 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3951 break;
3952 }
3953 case WindowType::WINDOW_TYPE_KEYGUARD: {
3954 RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
3955 property_->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
3956 break;
3957 }
3958 case WindowType::WINDOW_TYPE_DRAGGING_EFFECT: {
3959 property_->SetWindowFlags(0);
3960 break;
3961 }
3962 case WindowType::WINDOW_TYPE_APP_COMPONENT: {
3963 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3964 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
3965 break;
3966 }
3967 case WindowType::WINDOW_TYPE_TOAST:
3968 case WindowType::WINDOW_TYPE_FLOAT:
3969 case WindowType::WINDOW_TYPE_SYSTEM_FLOAT:
3970 case WindowType::WINDOW_TYPE_FLOAT_CAMERA:
3971 case WindowType::WINDOW_TYPE_VOICE_INTERACTION:
3972 case WindowType::WINDOW_TYPE_LAUNCHER_DOCK:
3973 case WindowType::WINDOW_TYPE_SEARCHING_BAR:
3974 case WindowType::WINDOW_TYPE_SCREENSHOT:
3975 case WindowType::WINDOW_TYPE_GLOBAL_SEARCH:
3976 case WindowType::WINDOW_TYPE_DIALOG: {
3977 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3978 break;
3979 }
3980 case WindowType::WINDOW_TYPE_BOOT_ANIMATION:
3981 case WindowType::WINDOW_TYPE_POINTER: {
3982 property_->SetFocusable(false);
3983 break;
3984 }
3985 case WindowType::WINDOW_TYPE_DOCK_SLICE: {
3986 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3987 property_->SetFocusable(false);
3988 break;
3989 }
3990 case WindowType::WINDOW_TYPE_SYSTEM_TOAST: {
3991 property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
3992 property_->SetTouchable(false);
3993 property_->SetFocusable(false);
3994 break;
3995 }
3996 default:
3997 break;
3998 }
3999 }
4000
IsWindowValid() const4001 bool WindowImpl::IsWindowValid() const
4002 {
4003 bool res = ((state_ > WindowState::STATE_INITIAL) && (state_ < WindowState::STATE_BOTTOM));
4004 if (!res) {
4005 WLOGW("already destroyed or not created! id: %{public}u", GetWindowId());
4006 }
4007 return res;
4008 }
4009
IsLayoutFullScreen() const4010 bool WindowImpl::IsLayoutFullScreen() const
4011 {
4012 if (!IsWindowValid()) {
4013 return false;
4014 }
4015 auto mode = GetMode();
4016 return (mode == WindowMode::WINDOW_MODE_FULLSCREEN && isIgnoreSafeArea_);
4017 }
4018
IsFullScreen() const4019 bool WindowImpl::IsFullScreen() const
4020 {
4021 if (!IsWindowValid()) {
4022 return false;
4023 }
4024 auto statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
4025 auto naviProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
4026 return (IsLayoutFullScreen() && !statusProperty.enable_ && !naviProperty.enable_);
4027 }
4028
SetRequestedOrientation(Orientation orientation)4029 void WindowImpl::SetRequestedOrientation(Orientation orientation)
4030 {
4031 if (!IsWindowValid()) {
4032 TLOGE(WmsLogTag::DEFAULT, "window is invalid");
4033 return;
4034 }
4035 if (property_->GetRequestedOrientation() == orientation) {
4036 return;
4037 }
4038 property_->SetRequestedOrientation(orientation);
4039 if (state_ == WindowState::STATE_SHOWN) {
4040 UpdateProperty(PropertyChangeAction::ACTION_UPDATE_ORIENTATION);
4041 }
4042 }
4043
GetRequestedOrientation()4044 Orientation WindowImpl::GetRequestedOrientation()
4045 {
4046 if (!IsWindowValid()) {
4047 TLOGE(WmsLogTag::DEFAULT, "window is invalid");
4048 return Orientation::UNSPECIFIED;
4049 }
4050 return property_->GetRequestedOrientation();
4051 }
4052
SetTouchHotAreas(const std::vector<Rect> & rects)4053 WMError WindowImpl::SetTouchHotAreas(const std::vector<Rect>& rects)
4054 {
4055 std::vector<Rect> lastTouchHotAreas;
4056 property_->GetTouchHotAreas(lastTouchHotAreas);
4057
4058 property_->SetTouchHotAreas(rects);
4059 WMError result = UpdateProperty(PropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA);
4060 if (result != WMError::WM_OK) {
4061 property_->SetTouchHotAreas(lastTouchHotAreas);
4062 }
4063 return result;
4064 }
4065
GetRequestedTouchHotAreas(std::vector<Rect> & rects) const4066 void WindowImpl::GetRequestedTouchHotAreas(std::vector<Rect>& rects) const
4067 {
4068 property_->GetTouchHotAreas(rects);
4069 }
4070
SetAPPWindowLabel(const std::string & label)4071 WMError WindowImpl::SetAPPWindowLabel(const std::string& label)
4072 {
4073 if (uiContent_ == nullptr) {
4074 WLOGFE("uicontent is empty");
4075 return WMError::WM_ERROR_NULLPTR;
4076 }
4077 uiContent_->SetAppWindowTitle(label);
4078 WLOGI("Set app window label success, label : %{public}s", label.c_str());
4079 return WMError::WM_OK;
4080 }
4081
SetAPPWindowIcon(const std::shared_ptr<Media::PixelMap> & icon)4082 WMError WindowImpl::SetAPPWindowIcon(const std::shared_ptr<Media::PixelMap>& icon)
4083 {
4084 if (icon == nullptr) {
4085 WLOGFE("window icon is empty");
4086 return WMError::WM_ERROR_NULLPTR;
4087 }
4088 if (uiContent_ == nullptr) {
4089 WLOGFE("uicontent is empty");
4090 return WMError::WM_ERROR_NULLPTR;
4091 }
4092 uiContent_->SetAppWindowIcon(icon);
4093 WLOGI("Set app window icon success");
4094 return WMError::WM_OK;
4095 }
4096
CheckCameraFloatingWindowMultiCreated(WindowType type)4097 bool WindowImpl::CheckCameraFloatingWindowMultiCreated(WindowType type)
4098 {
4099 if (type != WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
4100 return false;
4101 }
4102
4103 for (auto& winPair : windowMap_) {
4104 if (winPair.second.second->GetType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
4105 return true;
4106 }
4107 }
4108 uint32_t accessTokenId = static_cast<uint32_t>(IPCSkeleton::GetCallingTokenID());
4109 property_->SetAccessTokenId(accessTokenId);
4110 TLOGI(WmsLogTag::DEFAULT, "Create camera float window, TokenId = %{private}u", accessTokenId);
4111 return false;
4112 }
4113
SetCornerRadius(float cornerRadius)4114 WMError WindowImpl::SetCornerRadius(float cornerRadius)
4115 {
4116 WLOGI("Window %{public}s set corner radius %{public}f", name_.c_str(), cornerRadius);
4117 surfaceNode_->SetCornerRadius(cornerRadius);
4118 RSTransaction::FlushImplicitTransaction();
4119 return WMError::WM_OK;
4120 }
4121
SetShadowRadius(float radius)4122 WMError WindowImpl::SetShadowRadius(float radius)
4123 {
4124 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
4125 WLOGFE("set shadow radius permission denied!");
4126 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4127 }
4128 WLOGI("Window %{public}s set shadow radius %{public}f", name_.c_str(), radius);
4129 if (MathHelper::LessNotEqual(radius, 0.0)) {
4130 return WMError::WM_ERROR_INVALID_PARAM;
4131 }
4132 surfaceNode_->SetShadowRadius(radius);
4133 RSTransaction::FlushImplicitTransaction();
4134 return WMError::WM_OK;
4135 }
4136
SetShadowColor(std::string color)4137 WMError WindowImpl::SetShadowColor(std::string color)
4138 {
4139 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
4140 WLOGFE("set shadow color permission denied!");
4141 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4142 }
4143 WLOGI("Window %{public}s set shadow color %{public}s", name_.c_str(), color.c_str());
4144 uint32_t colorValue;
4145 if (!ColorParser::Parse(color, colorValue)) {
4146 return WMError::WM_ERROR_INVALID_PARAM;
4147 }
4148 surfaceNode_->SetShadowColor(colorValue);
4149 RSTransaction::FlushImplicitTransaction();
4150 return WMError::WM_OK;
4151 }
4152
SetShadowOffsetX(float offsetX)4153 WMError WindowImpl::SetShadowOffsetX(float offsetX)
4154 {
4155 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
4156 WLOGFE("set shadow offset x permission denied!");
4157 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4158 }
4159 WLOGI("Window %{public}s set shadow offsetX %{public}f", name_.c_str(), offsetX);
4160 surfaceNode_->SetShadowOffsetX(offsetX);
4161 RSTransaction::FlushImplicitTransaction();
4162 return WMError::WM_OK;
4163 }
4164
SetShadowOffsetY(float offsetY)4165 WMError WindowImpl::SetShadowOffsetY(float offsetY)
4166 {
4167 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
4168 WLOGFE("set shadow offset y permission denied!");
4169 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4170 }
4171 WLOGI("Window %{public}s set shadow offsetY %{public}f", name_.c_str(), offsetY);
4172 surfaceNode_->SetShadowOffsetY(offsetY);
4173 RSTransaction::FlushImplicitTransaction();
4174 return WMError::WM_OK;
4175 }
4176
SetBlur(float radius)4177 WMError WindowImpl::SetBlur(float radius)
4178 {
4179 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
4180 WLOGFE("set blur permission denied!");
4181 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4182 }
4183 WLOGI("Window %{public}s set blur radius %{public}f", name_.c_str(), radius);
4184 if (MathHelper::LessNotEqual(radius, 0.0)) {
4185 return WMError::WM_ERROR_INVALID_PARAM;
4186 }
4187 radius = ConvertRadiusToSigma(radius);
4188 WLOGFI("[Client] Window %{public}s set blur radius after conversion %{public}f", name_.c_str(), radius);
4189 surfaceNode_->SetFilter(RSFilter::CreateBlurFilter(radius, radius));
4190 RSTransaction::FlushImplicitTransaction();
4191 return WMError::WM_OK;
4192 }
4193
SetBackdropBlur(float radius)4194 WMError WindowImpl::SetBackdropBlur(float radius)
4195 {
4196 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
4197 WLOGFE("set backdrop blur permission denied!");
4198 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4199 }
4200 WLOGI("Window %{public}s set backdrop blur radius %{public}f", name_.c_str(), radius);
4201 if (MathHelper::LessNotEqual(radius, 0.0)) {
4202 return WMError::WM_ERROR_INVALID_PARAM;
4203 }
4204 radius = ConvertRadiusToSigma(radius);
4205 WLOGFI("[Client] Window %{public}s set backdrop blur radius after conversion %{public}f", name_.c_str(), radius);
4206 surfaceNode_->SetBackgroundFilter(RSFilter::CreateBlurFilter(radius, radius));
4207 RSTransaction::FlushImplicitTransaction();
4208 return WMError::WM_OK;
4209 }
4210
SetBackdropBlurStyle(WindowBlurStyle blurStyle)4211 WMError WindowImpl::SetBackdropBlurStyle(WindowBlurStyle blurStyle)
4212 {
4213 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
4214 WLOGFE("set backdrop blur style permission denied!");
4215 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4216 }
4217 WLOGI("Window %{public}s set backdrop blur style %{public}u", name_.c_str(), blurStyle);
4218 if (blurStyle < WindowBlurStyle::WINDOW_BLUR_OFF || blurStyle > WindowBlurStyle::WINDOW_BLUR_THICK) {
4219 return WMError::WM_ERROR_INVALID_PARAM;
4220 }
4221
4222 if (blurStyle == WindowBlurStyle::WINDOW_BLUR_OFF) {
4223 surfaceNode_->SetBackgroundFilter(nullptr);
4224 } else {
4225 auto display = SingletonContainer::IsDestroyed() ? nullptr :
4226 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
4227 if (display == nullptr) {
4228 WLOGFE("get display failed displayId:%{public}" PRIu64", window id:%{public}u", property_->GetDisplayId(),
4229 property_->GetWindowId());
4230 return WMError::WM_ERROR_INVALID_PARAM;
4231 }
4232 surfaceNode_->SetBackgroundFilter(RSFilter::CreateMaterialFilter(static_cast<int>(blurStyle),
4233 display->GetVirtualPixelRatio()));
4234 }
4235 RSTransaction::FlushImplicitTransaction();
4236 return WMError::WM_OK;
4237 }
4238
NotifyMemoryLevel(int32_t level)4239 WMError WindowImpl::NotifyMemoryLevel(int32_t level)
4240 {
4241 WLOGFD("id: %{public}u, notify memory level: %{public}d", property_->GetWindowId(), level);
4242 std::lock_guard<std::recursive_mutex> lock(mutex_);
4243 if (uiContent_ == nullptr) {
4244 WLOGFE("Window %{public}s notify memory level failed, ace is null.", name_.c_str());
4245 return WMError::WM_ERROR_NULLPTR;
4246 }
4247 // notify memory level
4248 uiContent_->NotifyMemoryLevel(level);
4249 return WMError::WM_OK;
4250 }
4251
IsAllowHaveSystemSubWindow()4252 bool WindowImpl::IsAllowHaveSystemSubWindow()
4253 {
4254 auto windowType = property_->GetWindowType();
4255 if (WindowHelper::IsSystemSubWindow(windowType) ||
4256 WindowHelper::IsSubWindow(windowType) ||
4257 windowType == WindowType::WINDOW_TYPE_DIALOG) {
4258 WLOGI("type %{public}u not allowed to add subwindow", windowType);
4259 return false;
4260 }
4261 return true;
4262 }
4263
SetNeedDefaultAnimation(bool needDefaultAnimation)4264 void WindowImpl::SetNeedDefaultAnimation(bool needDefaultAnimation)
4265 {
4266 needDefaultAnimation_= needDefaultAnimation;
4267 }
4268
SetTextFieldAvoidInfo(double textFieldPositionY,double textFieldHeight)4269 WMError WindowImpl::SetTextFieldAvoidInfo(double textFieldPositionY, double textFieldHeight)
4270 {
4271 property_->SetTextFieldPositionY(textFieldPositionY);
4272 property_->SetTextFieldHeight(textFieldHeight);
4273 UpdateProperty(PropertyChangeAction::ACTION_UPDATE_TEXTFIELD_AVOID_INFO);
4274 return WMError::WM_OK;
4275 }
4276 } // namespace Rosen
4277 } // namespace OHOS
4278