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 "input_window_monitor.h"
17
18 #include <ipc_skeleton.h>
19 #include <ability_manager_client.h>
20
21 #include "display_manager_service_inner.h"
22 #include "dm_common.h"
23 #include "window_helper.h"
24 #include "window_manager_hilog.h"
25
26 namespace OHOS {
27 namespace Rosen {
28 namespace {
29 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "InputWindowMonitor"};
30 }
convertRectsToMmiRects(const std::vector<Rect> & rects,std::vector<MMI::Rect> & mmiRects)31 static inline void convertRectsToMmiRects(const std::vector<Rect>& rects, std::vector<MMI::Rect>& mmiRects)
32 {
33 for (const auto& rect : rects) {
34 mmiRects.emplace_back(
35 MMI::Rect{ rect.posX_, rect.posY_, static_cast<int32_t>(rect.width_), static_cast<int32_t>(rect.height_) });
36 }
37 }
38
UpdateInputWindow(uint32_t windowId)39 void InputWindowMonitor::UpdateInputWindow(uint32_t windowId)
40 {
41 if (windowRoot_ == nullptr) {
42 WLOGFE("windowRoot is null.");
43 return;
44 }
45 sptr<WindowNode> windowNode = windowRoot_->GetWindowNode(windowId);
46 if (windowNode == nullptr) {
47 WLOGFE("window node could not be found.");
48 return;
49 }
50 if (INPUT_WINDOW_TYPE_SKIPPED.find(windowNode->GetWindowProperty()->GetWindowType()) !=
51 INPUT_WINDOW_TYPE_SKIPPED.end()) {
52 return;
53 }
54 DisplayId displayId = windowNode->GetDisplayId();
55 UpdateInputWindowByDisplayId(displayId);
56 }
57
GetDisplayInfo(uint32_t windowId)58 MMI::DisplayGroupInfo InputWindowMonitor::GetDisplayInfo(uint32_t windowId)
59 {
60 if (windowRoot_ == nullptr) {
61 WLOGFE("windowRoot is null.");
62 return displayGroupInfo_;
63 }
64 sptr<WindowNode> windowNode = windowRoot_->GetWindowNode(windowId);
65 if (windowNode == nullptr) {
66 WLOGFE("window node could not be found.");
67 return displayGroupInfo_;
68 }
69 if (INPUT_WINDOW_TYPE_SKIPPED.find(windowNode->GetWindowProperty()->GetWindowType()) !=
70 INPUT_WINDOW_TYPE_SKIPPED.end()) {
71 return displayGroupInfo_;
72 }
73 DisplayId displayId = windowNode->GetDisplayId();
74 HandleDisplayInfo(displayId);
75 return displayGroupInfo_;
76 }
77
HandleDisplayInfo(DisplayId displayId)78 void InputWindowMonitor::HandleDisplayInfo(DisplayId displayId)
79 {
80 if (displayId == DISPLAY_ID_INVALID) {
81 return;
82 }
83 auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
84 if (container == nullptr) {
85 WLOGFE("can not get window node container.");
86 return;
87 }
88
89 auto displayInfos = container->GetAllDisplayInfo();
90 if (displayInfos.empty()) {
91 return;
92 }
93
94 UpdateDisplayGroupInfo(container, displayGroupInfo_);
95 UpdateDisplayInfo(displayInfos, displayGroupInfo_.displaysInfo);
96 std::vector<sptr<WindowNode>> windowNodes;
97 container->TraverseContainer(windowNodes);
98 TraverseWindowNodes(windowNodes, displayGroupInfo_.windowsInfo);
99 }
100
UpdateInputWindowByDisplayId(DisplayId displayId)101 void InputWindowMonitor::UpdateInputWindowByDisplayId(DisplayId displayId)
102 {
103 HandleDisplayInfo(displayId);
104 WLOGFI("update display info to IMS, displayId: %{public}" PRIu64"", displayId);
105 MMI::InputManager::GetInstance()->UpdateDisplayInfo(displayGroupInfo_);
106 }
107
UpdateDisplayGroupInfo(const sptr<WindowNodeContainer> & windowNodeContainer,MMI::DisplayGroupInfo & displayGroupInfo)108 void InputWindowMonitor::UpdateDisplayGroupInfo(const sptr<WindowNodeContainer>& windowNodeContainer,
109 MMI::DisplayGroupInfo& displayGroupInfo)
110 {
111 const Rect&& rect = windowNodeContainer->GetDisplayGroupRect();
112 displayGroupInfo.width = static_cast<int32_t>(rect.width_);
113 displayGroupInfo.height = static_cast<int32_t>(rect.height_);
114 displayGroupInfo.focusWindowId = static_cast<int32_t>(windowNodeContainer->GetFocusWindow());
115 displayGroupInfo.windowsInfo.clear();
116 displayGroupInfo.displaysInfo.clear();
117 }
118
UpdateDisplayInfo(const std::vector<sptr<DisplayInfo>> & displayInfos,std::vector<MMI::DisplayInfo> & displayInfoVector)119 void InputWindowMonitor::UpdateDisplayInfo(const std::vector<sptr<DisplayInfo>>& displayInfos,
120 std::vector<MMI::DisplayInfo>& displayInfoVector)
121 {
122 for (auto& displayInfo : displayInfos) {
123 if (displayInfo == nullptr) {
124 continue;
125 }
126 uint32_t displayWidth = static_cast<uint32_t>(displayInfo->GetWidth());
127 uint32_t displayHeight = static_cast<uint32_t>(displayInfo->GetHeight());
128 int32_t offsetX = displayInfo->GetOffsetX();
129 int32_t offsetY = displayInfo->GetOffsetY();
130 if (displayInfo->GetWaterfallDisplayCompressionStatus()) {
131 displayWidth = static_cast<uint32_t>(
132 static_cast<int32_t>(displayWidth) + offsetX * 2); // 2: Get full width;
133 displayHeight = static_cast<uint32_t>(
134 static_cast<int32_t>(displayHeight) + offsetY * 2); // 2: Get full height;
135 offsetX = 0;
136 offsetY = 0;
137 }
138 if (displayInfo->GetRotation() == Rotation::ROTATION_90 ||
139 displayInfo->GetRotation() == Rotation::ROTATION_270) {
140 std::swap(displayWidth, displayHeight);
141 }
142 MMI::DisplayInfo display = {
143 .id = static_cast<int32_t>(displayInfo->GetDisplayId()),
144 .x = offsetX,
145 .y = offsetY,
146 .width = static_cast<int32_t>(displayWidth),
147 .height = static_cast<int32_t>(displayHeight),
148 .name = (std::stringstream("display ")<<displayInfo->GetDisplayId()).str(),
149 .uniq = "default" + std::to_string(displayInfo->GetDisplayId()),
150 .direction = GetDisplayDirectionForMmi(displayInfo->GetRotation()),
151 };
152 auto displayIter = std::find_if(displayInfoVector.begin(), displayInfoVector.end(),
153 [&display](MMI::DisplayInfo& displayInfoTmp) {
154 return displayInfoTmp.id == display.id;
155 });
156 if (displayIter != displayInfoVector.end()) {
157 *displayIter = display;
158 } else {
159 displayInfoVector.emplace_back(display);
160 }
161 WLOGFD("UpdateDisplayInfo, displayId: %{public}d, displayRect: "
162 "[%{public}d, %{public}d, %{public}u, %{public}u]",
163 display.id, display.x, display.y, display.width, display.height);
164 }
165 }
166
TransformWindowRects(const sptr<WindowNode> & windowNode,Rect & areaRect,std::vector<Rect> & touchHotAreas,std::vector<Rect> & pointerHotAreas)167 void InputWindowMonitor::TransformWindowRects(const sptr<WindowNode>& windowNode, Rect& areaRect,
168 std::vector<Rect>& touchHotAreas, std::vector<Rect>& pointerHotAreas)
169 {
170 if (windowNode->GetWindowProperty()->isNeedComputerTransform()) {
171 windowNode->ComputeTransform();
172 for (Rect& rect : touchHotAreas) {
173 rect = WindowHelper::TransformRect(windowNode->GetWindowProperty()->GetTransformMat(), rect);
174 }
175 for (Rect& rect : pointerHotAreas) {
176 rect = WindowHelper::TransformRect(windowNode->GetWindowProperty()->GetTransformMat(), rect);
177 }
178 WLOGFI("Area rect before tranform: [%{public}d, %{public}d, %{public}u, %{public}u]",
179 areaRect.posX_, areaRect.posY_, areaRect.width_, areaRect.height_);
180 areaRect = WindowHelper::TransformRect(windowNode->GetWindowProperty()->GetTransformMat(), areaRect);
181 WLOGFI("Area rect after tranform: [%{public}d, %{public}d, %{public}u, %{public}u]",
182 areaRect.posX_, areaRect.posY_, areaRect.width_, areaRect.height_);
183 }
184 }
185
TraverseWindowNodes(const std::vector<sptr<WindowNode>> & windowNodes,std::vector<MMI::WindowInfo> & windowsInfo)186 void InputWindowMonitor::TraverseWindowNodes(const std::vector<sptr<WindowNode>> &windowNodes,
187 std::vector<MMI::WindowInfo>& windowsInfo)
188 {
189 std::map<uint32_t, sptr<WindowNode>> dialogWindowMap;
190 for (const auto& windowNode: windowNodes) {
191 sptr<WindowNode> callerNode =
192 windowRoot_->FindDialogCallerNode(windowNode->GetWindowType(), windowNode->dialogTargetToken_);
193 if (callerNode != nullptr) {
194 dialogWindowMap.insert(std::make_pair(callerNode->GetWindowId(), windowNode));
195 }
196 }
197 for (const auto& windowNode: windowNodes) {
198 if (INPUT_WINDOW_TYPE_SKIPPED.find(windowNode->GetWindowType()) != INPUT_WINDOW_TYPE_SKIPPED.end()) {
199 WLOGFI("skip node[id:%{public}u, type:%{public}d]", windowNode->GetWindowId(), windowNode->GetWindowType());
200 continue;
201 }
202
203 std::vector<Rect> touchHotAreas;
204 std::vector<Rect> pointerHotAreas;
205 windowNode->GetTouchHotAreas(touchHotAreas);
206 windowNode->GetPointerHotAreas(pointerHotAreas);
207 Rect areaRect = windowNode->GetWindowRect();
208
209 TransformWindowRects(windowNode, areaRect, touchHotAreas, pointerHotAreas);
210
211 MMI::WindowInfo windowInfo = {
212 .id = static_cast<int32_t>(windowNode->GetWindowId()),
213 .pid = windowNode->GetInputEventCallingPid(),
214 .uid = windowNode->GetCallingUid(),
215 .area = MMI::Rect { areaRect.posX_, areaRect.posY_,
216 static_cast<int32_t>(areaRect.width_), static_cast<int32_t>(areaRect.height_) },
217 .agentWindowId = static_cast<int32_t>(windowNode->GetWindowId()),
218 };
219
220 auto iter = (windowNode->GetParentId() == INVALID_WINDOW_ID) ?
221 dialogWindowMap.find(windowNode->GetWindowId()) : dialogWindowMap.find(windowNode->GetParentId());
222 if (iter != dialogWindowMap.end()) {
223 windowInfo.pid = iter->second->GetCallingPid();
224 windowInfo.uid = iter->second->GetCallingUid();
225 windowInfo.agentWindowId = static_cast<int32_t>(iter->second->GetWindowId());
226 }
227 convertRectsToMmiRects(touchHotAreas, windowInfo.defaultHotAreas);
228 convertRectsToMmiRects(pointerHotAreas, windowInfo.pointerHotAreas);
229 if (!windowNode->GetWindowProperty()->GetTouchable()) {
230 WLOGFI("window is not touchable: %{public}u", windowNode->GetWindowId());
231 windowInfo.flags |= MMI::WindowInfo::FLAG_BIT_UNTOUCHABLE;
232 }
233 windowsInfo.emplace_back(windowInfo);
234 }
235 }
236
GetDisplayDirectionForMmi(Rotation rotation)237 MMI::Direction InputWindowMonitor::GetDisplayDirectionForMmi(Rotation rotation)
238 {
239 MMI::Direction direction = MMI::Direction0;
240 switch (rotation) {
241 case Rotation::ROTATION_0:
242 direction = MMI::Direction0;
243 break;
244 case Rotation::ROTATION_90:
245 direction = MMI::Direction90;
246 break;
247 case Rotation::ROTATION_180:
248 direction = MMI::Direction180;
249 break;
250 case Rotation::ROTATION_270:
251 direction = MMI::Direction270;
252 break;
253 default:
254 break;
255 }
256 return direction;
257 }
258 }
259 }