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