1 /*
2 * Copyright (c) 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 "scene_input_manager.h"
17
18 #include <hitrace_meter.h>
19 #include "input_manager.h"
20 #include "scene_session_dirty_manager.h"
21 #include "screen_session_manager/include/screen_session_manager_client.h"
22 #include "session/host/include/scene_session.h"
23 #include "session_manager/include/scene_session_manager.h"
24 #include "session_manager/include/screen_session_manager.h"
25 #include "window_manager_hilog.h"
26
27 namespace OHOS {
28 namespace Rosen {
29
30 namespace {
31 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneInputManager" };
32 const std::string SCENE_INPUT_MANAGER_THREAD = "SceneInputManager";
33 const std::string FLUSH_DISPLAY_INFO_THREAD = "OS_FlushDisplayInfoThread";
34 std::recursive_mutex g_instanceMutex;
35
36 constexpr float DIRECTION0 = 0;
37 constexpr float DIRECTION90 = 90;
38 constexpr float DIRECTION180 = 180;
39 constexpr float DIRECTION270 = 270;
40 constexpr int MAX_WINDOWINFO_NUM = 15;
41 constexpr int DEFALUT_DISPLAYID = 0;
42
ConvertDegreeToMMIRotation(float degree,MMI::DisplayMode displayMode)43 MMI::Direction ConvertDegreeToMMIRotation(float degree, MMI::DisplayMode displayMode)
44 {
45 MMI::Direction rotation = MMI::DIRECTION0;
46 if (NearEqual(degree, DIRECTION0)) {
47 rotation = MMI::DIRECTION0;
48 }
49 if (NearEqual(degree, DIRECTION90)) {
50 rotation = MMI::DIRECTION90;
51 }
52 if (NearEqual(degree, DIRECTION180)) {
53 rotation = MMI::DIRECTION180;
54 }
55 if (NearEqual(degree, DIRECTION270)) {
56 rotation = MMI::DIRECTION270;
57 }
58 if (displayMode == MMI::DisplayMode::FULL) {
59 switch (rotation) {
60 case MMI::DIRECTION0:
61 rotation = MMI::DIRECTION90;
62 break;
63 case MMI::DIRECTION90:
64 rotation = MMI::DIRECTION180;
65 break;
66 case MMI::DIRECTION180:
67 rotation = MMI::DIRECTION270;
68 break;
69 case MMI::DIRECTION270:
70 rotation = MMI::DIRECTION0;
71 break;
72 default:
73 rotation = MMI::DIRECTION0;
74 break;
75 }
76 }
77 return rotation;
78 }
79
DumpRect(const std::vector<MMI::Rect> & rects)80 std::string DumpRect(const std::vector<MMI::Rect>& rects)
81 {
82 std::string rectStr = "";
83 for (const auto& rect : rects) {
84 rectStr = rectStr + " hot : [ " + std::to_string(rect.x) +" , " + std::to_string(rect.y) +
85 " , " + std::to_string(rect.width) + " , " + std::to_string(rect.height) + "]";
86 }
87 return rectStr;
88 }
89
DumpWindowInfo(const MMI::WindowInfo & info)90 std::string DumpWindowInfo(const MMI::WindowInfo& info)
91 {
92 std::string infoStr = "windowInfo:";
93 infoStr = infoStr + "windowId: " + std::to_string(info.id) + " pid : " + std::to_string(info.pid) +
94 " uid: " + std::to_string(info.uid) + " area: [ " + std::to_string(info.area.x) + " , " +
95 std::to_string(info.area.y) + " , " + std::to_string(info.area.width) + " , " +
96 std::to_string(info.area.height) + "] agentWindowId:" + std::to_string(info.agentWindowId) + " flags:" +
97 std::to_string(info.flags) +" displayId: " + std::to_string(info.displayId) +
98 " action: " + std::to_string(static_cast<int>(info.action)) + " zOrder: " + std::to_string(info.zOrder);
99 return infoStr + DumpRect(info.defaultHotAreas);
100 }
101
DumpDisplayInfo(const MMI::DisplayInfo & info)102 std::string DumpDisplayInfo(const MMI::DisplayInfo& info)
103 {
104 std::string infoStr = "DisplayInfo: ";
105 infoStr = infoStr + " id: " + std::to_string(info.id) + " x: " + std::to_string(info.x) +
106 "y: " + std::to_string(info.y) + " width: " + std::to_string(info.width) +
107 "height: " + std::to_string(info.height) + " dpi: " + std::to_string(info.dpi) + " name:" + info.name +
108 " uniq: " + info.uniq + " displayMode: " + std::to_string(static_cast<int>(info.displayMode)) +
109 " direction : " + std::to_string( static_cast<int>(info.direction));
110 return infoStr;
111 }
112 } //namespace
113
GetInstance()114 SceneInputManager& SceneInputManager::GetInstance()
115 {
116 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
117 static SceneInputManager *instance = nullptr;
118 if (instance == nullptr) {
119 instance = new SceneInputManager();
120 instance->Init();
121 }
122 return *instance;
123 }
124
Init()125 void SceneInputManager::Init()
126 {
127 sceneSessionDirty_ = std::make_shared<SceneSessionDirtyManager>();
128 eventLoop_ = AppExecFwk::EventRunner::Create(FLUSH_DISPLAY_INFO_THREAD);
129 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
130 if (sceneSessionDirty_) {
131 auto callback = [this]() {
132 FlushDisplayInfoToMMI();
133 };
134 sceneSessionDirty_->RegisterFlushWindowInfoCallback(callback);
135 }
136 }
137
ConstructDisplayInfos(std::vector<MMI::DisplayInfo> & displayInfos)138 void SceneInputManager::ConstructDisplayInfos(std::vector<MMI::DisplayInfo>& displayInfos)
139 {
140 std::unordered_map<ScreenId, ScreenProperty> screensProperties =
141 Rosen::ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
142 auto displayMode = Rosen::ScreenSessionManagerClient::GetInstance().GetFoldDisplayMode();
143 for (auto& iter: screensProperties) {
144 auto screenId = iter.first;
145 auto& screenProperty = iter.second;
146 auto screenSession = Rosen::ScreenSessionManagerClient::GetInstance().GetScreenSessionById(screenId);
147 MMI::Direction displayRotation;
148 if (screenSession && screenSession->GetDisplayNode()) {
149 displayRotation = ConvertDegreeToMMIRotation(
150 screenSession->GetDisplayNode()->GetStagingProperties().GetRotation(),
151 static_cast<MMI::DisplayMode>(displayMode));
152 } else {
153 displayRotation = ConvertDegreeToMMIRotation(screenProperty.GetRotation(),
154 static_cast<MMI::DisplayMode>(displayMode));
155 }
156 MMI::DisplayInfo displayInfo = {
157 .id = screenId,
158 .x = screenProperty.GetOffsetX(),
159 .y = screenProperty.GetOffsetY(),
160 .width = screenProperty.GetBounds().rect_.GetWidth(),
161 .height = screenProperty.GetBounds().rect_.GetHeight(),
162 .dpi = screenProperty.GetDensity() * DOT_PER_INCH,
163 .name = "display" + std::to_string(screenId),
164 .uniq = "default" + std::to_string(screenId),
165 .direction = ConvertDegreeToMMIRotation(screenProperty.GetRotation(),
166 static_cast<MMI::DisplayMode>(displayMode)),
167 .displayDirection = displayRotation,
168 .displayMode = static_cast<MMI::DisplayMode>(displayMode)};
169 displayInfos.emplace_back(displayInfo);
170 }
171 }
172
FlushFullInfoToMMI(const std::vector<MMI::WindowInfo> & windowInfoList)173 void SceneInputManager::FlushFullInfoToMMI(const std::vector<MMI::WindowInfo>& windowInfoList)
174 {
175 std::vector<MMI::DisplayInfo> displayInfos;
176 ConstructDisplayInfos(displayInfos);
177 int mainScreenWidth = 0;
178 int mainScreenHeight = 0;
179 if (!displayInfos.empty()) {
180 mainScreenWidth = displayInfos[0].width;
181 mainScreenHeight = displayInfos[0].height;
182 }
183 if (sceneSessionDirty_ == nullptr) {
184 WLOG_E("scene session dirty is null");
185 return;
186 }
187
188 int32_t focusId = Rosen::SceneSessionManager::GetInstance().GetFocusedSession();
189 MMI::DisplayGroupInfo displayGroupInfo = {
190 .width = mainScreenWidth,
191 .height = mainScreenHeight,
192 .focusWindowId = focusId,
193 .windowsInfo = windowInfoList,
194 .displaysInfo = displayInfos};
195 for (const auto& displayInfo : displayGroupInfo.displaysInfo) {
196 WLOG_D("[EventDispatch] - %s", DumpDisplayInfo(displayInfo).c_str());
197 }
198 for (const auto& windowInfo : displayGroupInfo.windowsInfo) {
199 WLOG_D("[EventDispatch] - %s", DumpWindowInfo(windowInfo).c_str());
200 }
201 MMI::InputManager::GetInstance()->UpdateDisplayInfo(displayGroupInfo);
202 }
203
NotifyWindowInfoChange(const sptr<SceneSession> & sceneSession,const WindowUpdateType & type)204 void SceneInputManager::NotifyWindowInfoChange(const sptr<SceneSession>& sceneSession, const WindowUpdateType& type)
205 {
206 if (sceneSessionDirty_) {
207 sceneSessionDirty_->NotifyWindowInfoChange(sceneSession, type);
208 }
209 }
210
NotifyMMIWindowPidChange(const sptr<SceneSession> & sceneSession,const bool startMoving)211 void SceneInputManager::NotifyMMIWindowPidChange(const sptr<SceneSession>& sceneSession, const bool startMoving)
212 {
213 if (sceneSessionDirty_) {
214 sceneSessionDirty_->NotifyWindowInfoChange(sceneSession,
215 WindowUpdateType::WINDOW_UPDATE_PROPERTY, startMoving);
216 if (sceneSession == nullptr) {
217 return;
218 }
219 sceneSession->SetIsStartMoving(startMoving);
220 }
221 }
222
NotifyWindowInfoChangeFromSession(const sptr<SceneSession> & sceneSesion)223 void SceneInputManager::NotifyWindowInfoChangeFromSession(const sptr<SceneSession>& sceneSesion)
224 {
225 if (sceneSessionDirty_) {
226 sceneSessionDirty_->NotifyWindowInfoChange(sceneSesion, WindowUpdateType::WINDOW_UPDATE_PROPERTY);
227 }
228 }
229
FlushChangeInfoToMMI(const std::map<uint64_t,std::vector<MMI::WindowInfo>> & screenId2Windows)230 void SceneInputManager::FlushChangeInfoToMMI(const std::map<uint64_t, std::vector<MMI::WindowInfo>>& screenId2Windows)
231 {
232 for (auto& iter : screenId2Windows) {
233 auto displayId = iter.first;
234 auto& windowInfos = iter.second;
235 for (auto& windowInfo : windowInfos) {
236 WLOG_D("[EventDispatch] --- %s", DumpWindowInfo(windowInfo).c_str());
237 }
238
239 int32_t focusId = Rosen::SceneSessionManager::GetInstance().GetFocusedSession();
240 MMI::WindowGroupInfo windowGroup = {focusId, displayId, windowInfos};
241 MMI::InputManager::GetInstance()->UpdateWindowInfo(windowGroup);
242 }
243 }
244
FlushDisplayInfoToMMI()245 void SceneInputManager::FlushDisplayInfoToMMI()
246 {
247 auto task = [this]() {
248 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "FlushDisplayInfoToMMI");
249 if (sceneSessionDirty_ == nullptr) {
250 return;
251 }
252 sceneSessionDirty_->ResetSessionDirty();
253
254 std::vector<MMI::WindowInfo> windowInfoList = sceneSessionDirty_->GetFullWindowInfoList();
255 WLOG_D("[EventDispatch] - windowInfo:windowList = %{public}d", static_cast<int>(windowInfoList.size()));
256 if (windowInfoList.size() == 0) {
257 FlushFullInfoToMMI(windowInfoList);
258 return;
259 }
260 windowInfoList.back().action = MMI::WINDOW_UPDATE_ACTION::ADD_END;
261 if (windowInfoList.size() <= MAX_WINDOWINFO_NUM) {
262 FlushFullInfoToMMI(windowInfoList);
263 return;
264 }
265
266 auto iterBegin = windowInfoList.begin();
267 auto iterEnd = windowInfoList.end();
268 auto iterNext = std::next(iterBegin, MAX_WINDOWINFO_NUM);
269 FlushFullInfoToMMI(std::vector<MMI::WindowInfo>(iterBegin, iterNext));
270 while (iterNext != iterEnd) {
271 auto iterNewBegin = iterNext;
272 if (std::distance(iterNewBegin, iterEnd) <= MAX_WINDOWINFO_NUM) {
273 iterNext = iterEnd;
274 } else {
275 iterNext = std::next(iterNewBegin, MAX_WINDOWINFO_NUM);
276 }
277 std::map<uint64_t, std::vector<MMI::WindowInfo>> screenToWindowInfoList;
278 screenToWindowInfoList.emplace(DEFALUT_DISPLAYID, std::vector<MMI::WindowInfo>(iterNewBegin, iterNext));
279 FlushChangeInfoToMMI(screenToWindowInfoList);
280 }
281 };
282 if (eventHandler_) {
283 eventHandler_->PostTask(task);
284 }
285 }
286 }
287 } // namespace OHOS::Rosen