• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }