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