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