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