1 /*
2 * Copyright (c) 2021 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 <vector>
19
20 #include <ipc_skeleton.h>
21
22 #include "display_manager_service_inner.h"
23 #include "dm_common.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 }
31
UpdateInputWindow(uint32_t windowId)32 void InputWindowMonitor::UpdateInputWindow(uint32_t windowId)
33 {
34 if (windowRoot_ == nullptr) {
35 WLOGFE("windowRoot is null.");
36 return;
37 }
38 sptr<WindowNode> windowNode = windowRoot_->GetWindowNode(windowId);
39 if (windowNode == nullptr) {
40 WLOGFE("window node could not be found.");
41 return;
42 }
43 if (windowTypeSkipped_.find(windowNode->GetWindowProperty()->GetWindowType()) != windowTypeSkipped_.end()) {
44 return;
45 }
46 DisplayId displayId = windowNode->GetDisplayId();
47 UpdateInputWindowByDisplayId(displayId);
48 }
49
UpdateInputWindowByDisplayId(DisplayId displayId)50 void InputWindowMonitor::UpdateInputWindowByDisplayId(DisplayId displayId)
51 {
52 if (displayId == DISPLAY_ID_INVALID) {
53 return;
54 }
55 auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId);
56 if (container == nullptr) {
57 WLOGFE("can not get window node container.");
58 return;
59 }
60 UpdateDisplaysInfo(container, displayId);
61 std::vector<sptr<WindowNode>> windowNodes;
62 container->TraverseContainer(windowNodes);
63 auto iter = std::find_if(logicalDisplays_.begin(), logicalDisplays_.end(),
64 [displayId](MMI::LogicalDisplayInfo& logicalDisplay) {
65 return logicalDisplay.id == static_cast<int32_t>(displayId);
66 });
67 if (iter != logicalDisplays_.end()) {
68 TraverseWindowNodes(windowNodes, iter);
69 if (!iter->windowsInfo_.empty()) {
70 iter->focusWindowId = static_cast<int32_t>(container->GetFocusWindow());
71 }
72 } else {
73 WLOGFE("There is no display for this window action.");
74 return;
75 }
76 WLOGFI("update display info to IMS.");
77 MMI::InputManager::GetInstance()->UpdateDisplayInfo(physicalDisplays_, logicalDisplays_);
78 }
79
UpdateDisplaysInfo(const sptr<WindowNodeContainer> & container,DisplayId displayId)80 void InputWindowMonitor::UpdateDisplaysInfo(const sptr<WindowNodeContainer>& container, DisplayId displayId)
81 {
82 sptr<SupportedScreenModes> screenMode =
83 DisplayManagerServiceInner::GetInstance().GetScreenModesByDisplayId(displayId);
84 if (screenMode == nullptr) {
85 return;
86 }
87 MMI::PhysicalDisplayInfo physicalDisplayInfo = {
88 .id = static_cast<int32_t>(container->GetScreenId()),
89 .leftDisplayId = static_cast<int32_t>(DISPLAY_ID_INVALID),
90 .upDisplayId = static_cast<int32_t>(DISPLAY_ID_INVALID),
91 .topLeftX = 0,
92 .topLeftY = 0,
93 .width = static_cast<int32_t>(screenMode->width_),
94 .height = static_cast<int32_t>(screenMode->height_),
95 .name = "physical_display0",
96 .seatId = "seat0",
97 .seatName = "default0",
98 .logicWidth = static_cast<int32_t>(screenMode->width_),
99 .logicHeight = static_cast<int32_t>(screenMode->height_),
100 };
101 UpdateDisplayDirection(physicalDisplayInfo, displayId);
102 auto physicalDisplayIter = std::find_if(physicalDisplays_.begin(), physicalDisplays_.end(),
103 [&physicalDisplayInfo](MMI::PhysicalDisplayInfo& physicalDisplay) {
104 return physicalDisplay.id == physicalDisplayInfo.id;
105 });
106 if (physicalDisplayIter != physicalDisplays_.end()) {
107 *physicalDisplayIter = physicalDisplayInfo;
108 } else {
109 physicalDisplays_.emplace_back(physicalDisplayInfo);
110 }
111
112 MMI::LogicalDisplayInfo logicalDisplayInfo = {
113 .id = static_cast<int32_t>(container->GetScreenId()),
114 .topLeftX = container->GetDisplayRect().posX_,
115 .topLeftY = container->GetDisplayRect().posY_,
116 .width = static_cast<int32_t>(container->GetDisplayRect().width_),
117 .height = static_cast<int32_t>(container->GetDisplayRect().height_),
118 .name = "logical_display0",
119 .seatId = "seat0",
120 .seatName = "default0",
121 .focusWindowId = INVALID_WINDOW_ID,
122 .windowsInfo_ = {},
123 };
124 auto logicalDisplayIter = std::find_if(logicalDisplays_.begin(), logicalDisplays_.end(),
125 [&logicalDisplayInfo](MMI::LogicalDisplayInfo& logicalDisplay) {
126 return logicalDisplay.id == logicalDisplayInfo.id;
127 });
128 if (logicalDisplayIter != logicalDisplays_.end()) {
129 *logicalDisplayIter = logicalDisplayInfo;
130 } else {
131 logicalDisplays_.emplace_back(logicalDisplayInfo);
132 }
133 }
134
TraverseWindowNodes(const std::vector<sptr<WindowNode>> & windowNodes,std::vector<MMI::LogicalDisplayInfo>::iterator & iter)135 void InputWindowMonitor::TraverseWindowNodes(const std::vector<sptr<WindowNode>> &windowNodes,
136 std::vector<MMI::LogicalDisplayInfo>::iterator& iter)
137 {
138 iter->windowsInfo_.clear();
139 for (auto& windowNode: windowNodes) {
140 if (windowTypeSkipped_.find(windowNode->GetWindowProperty()->GetWindowType()) != windowTypeSkipped_.end()) {
141 WLOGFI("window has been skipped. [id: %{public}d, type: %{public}d]", windowNode->GetWindowId(),
142 windowNode->GetWindowProperty()->GetWindowType());
143 continue;
144 }
145 Rect hotZone = windowNode->GetHotZoneRect();
146
147 MMI::WindowInfo windowInfo = {
148 .id = static_cast<int32_t>(windowNode->GetWindowId()),
149 .pid = windowNode->GetCallingPid(),
150 .uid = windowNode->GetCallingUid(),
151 .hotZoneTopLeftX = hotZone.posX_,
152 .hotZoneTopLeftY = hotZone.posY_,
153 .hotZoneWidth = static_cast<int32_t>(hotZone.width_),
154 .hotZoneHeight = static_cast<int32_t>(hotZone.height_),
155 .winTopLeftX = windowNode->GetLayoutRect().posX_,
156 .winTopLeftY = windowNode->GetLayoutRect().posY_,
157 .displayId = static_cast<int32_t>(windowNode->GetDisplayId()),
158 .agentWindowId = static_cast<int32_t>(windowNode->GetWindowId()),
159 };
160 if (!windowNode->GetWindowProperty()->GetTouchable()) {
161 WLOGFI("window is not touchable: %{public}u", windowNode->GetWindowId());
162 windowInfo.flags |= MMI::WindowInfo::FLAG_BIT_UNTOUCHABLE;
163 }
164 iter->windowsInfo_.emplace_back(windowInfo);
165 }
166 }
167
UpdateDisplayDirection(MMI::PhysicalDisplayInfo & physicalDisplayInfo,DisplayId displayId)168 void InputWindowMonitor::UpdateDisplayDirection(MMI::PhysicalDisplayInfo& physicalDisplayInfo, DisplayId displayId)
169 {
170 Rotation rotation = DisplayManagerServiceInner::GetInstance().GetScreenInfoByDisplayId(displayId)->GetRotation();
171 switch (rotation) {
172 case Rotation::ROTATION_0:
173 physicalDisplayInfo.direction = MMI::Direction0;
174 break;
175 case Rotation::ROTATION_90:
176 physicalDisplayInfo.direction = MMI::Direction90;
177 break;
178 case Rotation::ROTATION_180:
179 physicalDisplayInfo.direction = MMI::Direction180;
180 break;
181 case Rotation::ROTATION_270:
182 physicalDisplayInfo.direction = MMI::Direction270;
183 break;
184 default:
185 break;
186 }
187 }
188 }
189 }