1 /*
2 * Copyright (c) 2021-2022 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 "avoid_area_controller.h"
17 #include "display_manager_service_inner.h"
18 #include "window_helper.h"
19 #include "window_manager_hilog.h"
20 #include "wm_trace.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 namespace {
25 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "AvoidAreaController"};
26 }
27
28 const int32_t AVOID_NUM = 4;
29
IsAvoidAreaNode(const sptr<WindowNode> & node) const30 bool AvoidAreaController::IsAvoidAreaNode(const sptr<WindowNode>& node) const
31 {
32 if (node == nullptr) {
33 WLOGFE("IsAvoidAreaNode Failed, node is nullprt");
34 return false;
35 }
36
37 if (!WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
38 WLOGFE("IsAvoidAreaNode Failed, node type is not avoid type");
39 return false;
40 }
41
42 return true;
43 }
44
GetAvoidPosType(const Rect & rect) const45 AvoidPosType AvoidAreaController::GetAvoidPosType(const Rect& rect) const
46 {
47 auto display = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId_);
48 if (display == nullptr) {
49 WLOGFE("GetAvoidPosType fail. Get display fail. displayId:%{public}" PRIu64"", displayId_);
50 return AvoidPosType::AVOID_POS_UNKNOWN;
51 }
52 uint32_t displayWidth = static_cast<uint32_t>(display->GetWidth());
53 uint32_t displayHeight = static_cast<uint32_t>(display->GetHeight());
54
55 return WindowHelper::GetAvoidPosType(rect, displayWidth, displayHeight);
56 }
57
AvoidControl(const sptr<WindowNode> & node,AvoidControlType type)58 WMError AvoidAreaController::AvoidControl(const sptr<WindowNode>& node, AvoidControlType type)
59 {
60 WM_FUNCTION_TRACE();
61 if (!IsAvoidAreaNode(node)) {
62 WLOGFE("AvoidControl check param Failed. Type: %{public}u", type);
63 return WMError::WM_ERROR_INVALID_PARAM;
64 }
65 uint32_t windowId = node->GetWindowId();
66 auto iter = avoidNodes_.find(windowId);
67 // do not add a exist node(the same id)
68 if (type == AvoidControlType::AVOID_NODE_ADD && iter != avoidNodes_.end()) {
69 WLOGFE("WinId:%{public}d is added. AvoidControl Add Failed. Type: %{public}u", windowId, type);
70 return WMError::WM_ERROR_INVALID_PARAM;
71 }
72 // do not update or removew a unexist node
73 if (type != AvoidControlType::AVOID_NODE_ADD && iter == avoidNodes_.end()) {
74 WLOGFE("WinId:%{public}d not exist. AvoidControl Update or Remove Failed. Type: %{public}u", windowId, type);
75 return WMError::WM_ERROR_INVALID_PARAM;
76 }
77
78 switch (type) {
79 case AvoidControlType::AVOID_NODE_ADD:
80 avoidNodes_[windowId] = node;
81 WLOGFI("WinId:%{public}d add. And the windowType is %{public}d", windowId, node->GetWindowType());
82 break;
83 case AvoidControlType::AVOID_NODE_UPDATE:
84 avoidNodes_[windowId] = node;
85 WLOGFI("WinId:%{public}d update. And the windowType is %{public}d", windowId, node->GetWindowType());
86 break;
87 case AvoidControlType::AVOID_NODE_REMOVE:
88 avoidNodes_.erase(iter);
89 WLOGFI("WinId:%{public}d remove. And the windowType is %{public}d", windowId, node->GetWindowType());
90 break;
91 default:
92 WLOGFE("invalid AvoidControlType: %{public}u", type);
93 return WMError::WM_ERROR_INVALID_PARAM;
94 }
95
96 // get all Area info and notify windowcontainer
97 std::vector<Rect> avoidAreas = GetAvoidArea();
98 DumpAvoidArea(avoidAreas);
99 UseCallbackNotifyAvoidAreaChanged(avoidAreas);
100 return WMError::WM_OK;
101 }
102
GetAvoidArea() const103 std::vector<Rect> AvoidAreaController::GetAvoidArea() const
104 {
105 std::vector<Rect> avoidArea(AVOID_NUM, {0, 0, 0, 0}); // avoid area left, top, right, bottom
106 for (auto iter = avoidNodes_.begin(); iter != avoidNodes_.end(); ++iter) {
107 Rect curRect = iter->second->GetLayoutRect();
108 auto curPos = GetAvoidPosType(curRect);
109 if (curPos == AvoidPosType::AVOID_POS_UNKNOWN) {
110 WLOGFE("GetAvoidArea AVOID_POS_UNKNOWN Rect: x : %{public}d, y: %{public}d, w: %{public}u h: %{public}u",
111 static_cast<uint32_t>(curRect.posX_), static_cast<uint32_t>(curRect.posY_),
112 static_cast<uint32_t>(curRect.width_), static_cast<uint32_t>(curRect.height_));
113 continue;
114 }
115 avoidArea[static_cast<uint32_t>(curPos)] = curRect;
116 }
117 return avoidArea;
118 }
119
GetAvoidAreaByType(AvoidAreaType avoidAreaType) const120 std::vector<Rect> AvoidAreaController::GetAvoidAreaByType(AvoidAreaType avoidAreaType) const
121 {
122 if (avoidAreaType != AvoidAreaType::TYPE_SYSTEM) {
123 WLOGFE("GetAvoidAreaByType. Support Type is AvoidAreaType::TYPE_SYSTEM. But current type is %{public}u",
124 static_cast<uint32_t>(avoidAreaType));
125 std::vector<Rect> avoidArea(AVOID_NUM, {0, 0, 0, 0});
126 return avoidArea;
127 }
128 WLOGFI("AvoidAreaController::GetAvoidAreaByType Success");
129 return GetAvoidArea();
130 }
131
UseCallbackNotifyAvoidAreaChanged(std::vector<Rect> & avoidArea) const132 void AvoidAreaController::UseCallbackNotifyAvoidAreaChanged(std::vector<Rect>& avoidArea) const
133 {
134 if (updateAvoidAreaCallBack_) {
135 updateAvoidAreaCallBack_(avoidArea);
136 }
137 }
138
DumpAvoidArea(const std::vector<Rect> & avoidArea) const139 void AvoidAreaController::DumpAvoidArea(const std::vector<Rect>& avoidArea) const
140 {
141 WLOGFI("----------------- AvoidArea Begin-----------------");
142 WLOGFI(" No [ x y w h]");
143 for (uint32_t i = 0; i < avoidArea.size(); i++) {
144 WLOGFI("%{public}4u [%{public}4d %{public}4d %{public}4u %{public}4u]", i,
145 avoidArea[i].posX_, avoidArea[i].posY_, avoidArea[i].width_, avoidArea[i].height_);
146 }
147 WLOGFI("----------------- AvoidArea End-----------------");
148 }
149 }
150 }
151