• 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_session_dirty_manager.h"
17 
18 #include <parameters.h>
19 #include "screen_session_manager_client/include/screen_session_manager_client.h"
20 #include "session_manager/include/scene_session_manager.h"
21 #include "window_helper.h"
22 #include "fold_screen_state_internel.h"
23 
24 namespace OHOS::Rosen {
25 namespace {
26 constexpr float DIRECTION0 = 0 ;
27 constexpr float DIRECTION90 = 90 ;
28 constexpr float DIRECTION180 = 180 ;
29 constexpr float DIRECTION270 = 270 ;
30 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionDirtyManager"};
31 constexpr unsigned int POINTER_CHANGE_AREA_COUNT = 8;
32 constexpr int POINTER_CHANGE_AREA_SIXTEEN = 16;
33 constexpr int POINTER_CHANGE_AREA_DEFAULT = 0;
34 constexpr int POINTER_CHANGE_AREA_FIVE = 5;
35 constexpr unsigned int TRANSFORM_DATA_LEN = 9;
36 constexpr int UPDATE_TASK_DURATION = 10;
37 const std::string UPDATE_WINDOW_INFO_TASK = "UpdateWindowInfoTask";
38 static int32_t g_screenRotationOffset = system::GetIntParameter<int32_t>("const.fold.screen_rotation.offset", 0);
39 constexpr float ZORDER_UIEXTENSION_INDEX = 0.1;
40 constexpr int WINDOW_NAME_TYPE_UNKNOWN = 0;
41 constexpr int WINDOW_NAME_TYPE_THUMBNAIL = 1;
42 const std::string SCREENSHOT_WINDOW_NAME_PREFIX = "ScreenShotWindow";
43 const std::string PREVIEW_WINDOW_NAME_PREFIX = "PreviewWindow";
44 } // namespace
45 
operator ==(const MMI::Rect left,const MMI::Rect right)46 static bool operator==(const MMI::Rect left, const MMI::Rect right)
47 {
48     return ((left.x == right.x) && (left.y == right.y) && (left.width == right.width) && (left.height == right.height));
49 }
50 
51 struct InputRectHash {
operator ()OHOS::Rosen::InputRectHash52     std::size_t operator()(const MMI::Rect& r) const
53     {
54         std::size_t h1 = std::hash<int32_t>{}(r.x);
55         std::size_t h2 = std::hash<int32_t>{}(r.y);
56         std::size_t h3 = std::hash<int32_t>{}(r.width);
57         std::size_t h4 = std::hash<int32_t>{}(r.height);
58         return ((h1 * 31 + h2) * 31 + h3) * 31 + h4;
59     }
60 };
61 
62 struct InputRectEqual {
operator ()OHOS::Rosen::InputRectEqual63     bool operator()(const MMI::Rect& left, const MMI::Rect& right) const
64     {
65         return left.x == right.x && left.y == right.y &&
66                left.width == right.width && left.height == right.height;
67     }
68 };
69 
ConvertDegreeToMMIRotation(float degree)70 MMI::Direction ConvertDegreeToMMIRotation(float degree)
71 {
72     MMI::Direction rotation = MMI::DIRECTION0;
73     if (NearEqual(degree, DIRECTION0)) {
74         rotation = MMI::DIRECTION0;
75     } else if (NearEqual(degree, DIRECTION90)) {
76         rotation = MMI::DIRECTION90;
77     } else if (NearEqual(degree, DIRECTION180)) {
78         rotation = MMI::DIRECTION180;
79     } else if (NearEqual(degree, DIRECTION270)) {
80         rotation = MMI::DIRECTION270;
81     }
82     return rotation;
83 }
84 
ConvertToMMIRotation(float degree)85 MMI::Rotation ConvertToMMIRotation(float degree)
86 {
87     MMI::Rotation rotation = MMI::Rotation::ROTATION_0;
88     if (NearEqual(degree, DIRECTION0)) {
89         rotation = MMI::Rotation::ROTATION_0;
90     } else if (NearEqual(degree, DIRECTION90)) {
91         rotation = MMI::Rotation::ROTATION_90;
92     } else if (NearEqual(degree, DIRECTION180)) {
93         rotation = MMI::Rotation::ROTATION_180;
94     } else if (NearEqual(degree, DIRECTION270)) {
95         rotation = MMI::Rotation::ROTATION_270;
96     }
97     return rotation;
98 }
99 
CmpMMIWindowInfo(const MMI::WindowInfo & a,const MMI::WindowInfo & b)100 bool CmpMMIWindowInfo(const MMI::WindowInfo& a, const MMI::WindowInfo& b)
101 {
102     return a.defaultHotAreas.size() > b.defaultHotAreas.size();
103 }
104 
CalRotationToTranslate(const MMI::Direction & displayRotation,float width,float height,const Vector2f & offset,float & rotate)105 Vector2f CalRotationToTranslate(const MMI::Direction& displayRotation, float width, float height,
106     const Vector2f& offset, float& rotate)
107 {
108     Vector2f translate = offset;
109     switch (displayRotation) {
110         case MMI::DIRECTION0: {
111             break;
112         }
113         case MMI::DIRECTION270: {
114             translate.x_ = offset.y_;
115             translate.y_ = height - offset.x_;
116             rotate = -M_PI_2;
117             break;
118         }
119         case MMI::DIRECTION180:
120             translate.x_ = width - offset.x_;
121             translate.y_ = height - offset.y_;
122             rotate = M_PI;
123             break;
124         case MMI::DIRECTION90: {
125             translate.x_ = width - offset.y_;
126             translate.y_ = offset.x_;
127             rotate = M_PI_2;
128             break;
129         }
130         default:
131             break;
132     }
133     return translate;
134 }
135 
GetTransformFromWindowInfo(const MMI::WindowInfo & hostWindowInfo)136 Matrix3f GetTransformFromWindowInfo(const MMI::WindowInfo& hostWindowInfo)
137 {
138     const std::vector<float>& hostTransform = hostWindowInfo.transform;
139     if (hostTransform.size() != TRANSFORM_DATA_LEN) {
140         TLOGE(WmsLogTag::WMS_EVENT, "transform data len invalid, id: %{public}d", hostWindowInfo.id);
141         return Matrix3f();
142     }
143     return Matrix3f(hostTransform[0], hostTransform[1], hostTransform[2],  // 0,1,2: matrix index
144                     hostTransform[3], hostTransform[4], hostTransform[5],  // 3,4,5: matrix index
145                     hostTransform[6], hostTransform[7], hostTransform[8]); // 6,7,8: matrix index
146 }
147 
CalNotRotateTransform(const sptr<SceneSession> & sceneSession,Matrix3f & transform,bool useUIExtension) const148 void SceneSessionDirtyManager::CalNotRotateTransform(const sptr<SceneSession>& sceneSession, Matrix3f& transform,
149     bool useUIExtension) const
150 {
151     if (sceneSession == nullptr) {
152         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
153         return;
154     }
155     auto sessionProperty = sceneSession->GetSessionProperty();
156     if (sessionProperty == nullptr) {
157         TLOGE(WmsLogTag::WMS_EVENT, "sessionProperty is nullptr");
158         return;
159     }
160     auto displayId = sessionProperty->GetDisplayId();
161     std::map<ScreenId, ScreenProperty> screensProperties =
162         Rosen::ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
163     if (screensProperties.find(displayId) == screensProperties.end()) {
164         return;
165     }
166     auto screenProperty = screensProperties[displayId];
167     MMI::Direction displayRotation = ConvertDegreeToMMIRotation(screenProperty.GetPhysicalRotation());
168     float width = screenProperty.GetBounds().rect_.GetWidth();
169     float height = screenProperty.GetBounds().rect_.GetHeight();
170     Vector2f scale(sceneSession->GetScaleX(), sceneSession->GetScaleY());
171     Vector2f offset = sceneSession->GetSessionGlobalPosition(useUIExtension);
172     float rotate = 0.0f;
173     Vector2f translate = CalRotationToTranslate(displayRotation, width, height, offset, rotate);
174     transform = transform.Translate(translate).Rotate(rotate)
175                          .Scale(scale, sceneSession->GetPivotX(), sceneSession->GetPivotY()).Inverse();
176 }
177 
CalTransform(const sptr<SceneSession> & sceneSession,Matrix3f & transform,const SingleHandData & singleHandData,bool useUIExtension) const178 void SceneSessionDirtyManager::CalTransform(const sptr<SceneSession>& sceneSession, Matrix3f& transform,
179     const SingleHandData& singleHandData, bool useUIExtension) const
180 {
181     if (sceneSession == nullptr) {
182         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
183         return;
184     }
185     transform = Matrix3f::IDENTITY;
186     bool isRotate = sceneSession->GetSessionInfo().isRotable_;
187     auto displayMode = ScreenSessionManagerClient::GetInstance().GetFoldDisplayMode();
188     if (singleHandData.mode != SingleHandMode::MIDDLE) {
189         transform = transform.Scale({singleHandData.scaleX, singleHandData.scaleY},
190                                     singleHandData.pivotX, singleHandData.pivotY);
191     }
192     if (isRotate || !sceneSession->GetSessionInfo().isSystem_ ||
193         static_cast<MMI::DisplayMode>(displayMode) == MMI::DisplayMode::FULL ||
194         displayMode == FoldDisplayMode::GLOBAL_FULL ||
195         (static_cast<MMI::DisplayMode>(displayMode) == MMI::DisplayMode::MAIN &&
196         (FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice() ||
197         FoldScreenStateInternel::IsSecondaryDisplayFoldDevice()))) {
198         Vector2f scale(sceneSession->GetScaleX(), sceneSession->GetScaleY());
199         Vector2f translate = sceneSession->GetSessionGlobalPosition(useUIExtension);
200         if (useUIExtension && UpdateModalExtensionInCompatStatus(sceneSession, transform)) {
201             TLOGD(WmsLogTag::WMS_EVENT, "sceneSession is compat mode");
202             return;
203         }
204         transform = transform.Translate(translate)
205                              .Scale(scale, sceneSession->GetPivotX(), sceneSession->GetPivotY()).Inverse();
206         return;
207     }
208     CalNotRotateTransform(sceneSession, transform, useUIExtension);
209 }
210 
UpdateModalExtensionInCompatStatus(const sptr<SceneSession> & sceneSession,Matrix3f & transform) const211 bool SceneSessionDirtyManager::UpdateModalExtensionInCompatStatus(const sptr<SceneSession>& sceneSession,
212     Matrix3f& transform) const
213 {
214     if (sceneSession == nullptr) {
215         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
216         return false;
217     }
218     if (!sceneSession->IsInCompatScaleStatus()) {
219         TLOGD(WmsLogTag::WMS_EVENT, "sceneSession not is compat scale status");
220         return false;
221     }
222     auto modalUIExtensionEventInfo = sceneSession->GetLastModalUIExtensionEventInfo();
223     if (!modalUIExtensionEventInfo) {
224         TLOGE(WmsLogTag::WMS_EVENT, "modalUIExtensionEventInfo is nullptr");
225         return false;
226     }
227     const WSRect& rect = sceneSession->GetSessionGlobalRect();
228     float heightDiff = rect.height_ - modalUIExtensionEventInfo.value().windowRect.height_;
229     Vector2f scale(sceneSession->GetScaleX(), sceneSession->GetScaleY());
230     Vector2f translate(rect.posX_, rect.posY_ + heightDiff);
231     transform = transform.Translate(translate)
232         .Scale(scale, sceneSession->GetPivotX(), sceneSession->GetPivotY()).Inverse();
233     if (!sceneSession->GetSessionProperty()->IsAdaptToImmersive()) {
234         Vector2f translateOffset(0, heightDiff * (1 - sceneSession->GetScaleY()));
235         transform = transform.Translate(translateOffset);
236     }
237     return true;
238 }
239 
UpdateDefaultHotAreas(sptr<SceneSession> sceneSession,std::vector<MMI::Rect> & touchHotAreas,std::vector<MMI::Rect> & pointerHotAreas) const240 void SceneSessionDirtyManager::UpdateDefaultHotAreas(sptr<SceneSession> sceneSession,
241     std::vector<MMI::Rect>& touchHotAreas,
242     std::vector<MMI::Rect>& pointerHotAreas) const
243 {
244     if (sceneSession == nullptr) {
245         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
246         return;
247     }
248     WSRect windowRect = sceneSession->GetSessionGlobalRectInMultiScreen();
249     uint32_t touchOffset = 0;
250     uint32_t pointerOffset = 0;
251     bool isMidScene = sceneSession->GetIsMidScene();
252     bool isAppPipWindow = sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_PIP;
253     bool isAppMainWindow = sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
254     const auto& singleHandData = GetSingleHandData(sceneSession);
255     sptr<WindowSessionProperty> windowSessionProperty = sceneSession->GetSessionProperty();
256     bool isSystemOrSubWindow = (WindowHelper::IsSystemWindow(sceneSession->GetWindowType()) ||
257         WindowHelper::IsSubWindow(sceneSession->GetWindowType()));
258     bool isDragAccessibleWindow = windowSessionProperty->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
259         sceneSession->IsDragAccessible();
260     bool isSingleHandAffectedWindow = singleHandData.mode != SingleHandMode::MIDDLE &&
261         windowSessionProperty->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN;
262     if ((isAppPipWindow || isAppMainWindow || (isSystemOrSubWindow && isDragAccessibleWindow)) &&
263         !isMidScene && !isSingleHandAffectedWindow) {
264         float vpr = 1.5f; // 1.5: default vp
265         auto sessionProperty = sceneSession->GetSessionProperty();
266         if (sessionProperty != nullptr) {
267             auto displayId = sessionProperty->GetDisplayId();
268             auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
269             if (screenSession != nullptr) {
270                 vpr = screenSession->GetScreenProperty().GetDensity();
271             }
272         }
273         touchOffset = static_cast<uint32_t>(HOTZONE_TOUCH * vpr);
274         pointerOffset = static_cast<uint32_t>(HOTZONE_POINTER * vpr);
275     }
276 
277     MMI::Rect touchRect = {
278         .x = -touchOffset,
279         .y = -touchOffset,
280         .width = windowRect.width_ + static_cast<int32_t>(touchOffset * 2),  // 2 : double touchOffset
281         .height = windowRect.height_ + static_cast<int32_t>(touchOffset * 2) // 2 : double touchOffset
282     };
283 
284     MMI::Rect pointerRect = {
285         .x = -pointerOffset,
286         .y = -pointerOffset,
287         .width = windowRect.width_ + static_cast<int32_t>(pointerOffset * 2),  // 2 : double pointerOffset
288         .height = windowRect.height_ + static_cast<int32_t>(pointerOffset * 2) // 2 : double pointerOffset
289     };
290 
291     touchHotAreas.emplace_back(touchRect);
292     pointerHotAreas.emplace_back(pointerRect);
293 }
294 
UpdateKeyboardHotAreasInner(const sptr<SceneSession> & sceneSession,std::vector<Rect> & hotAreas)295 static void UpdateKeyboardHotAreasInner(const sptr<SceneSession>& sceneSession, std::vector<Rect>& hotAreas)
296 {
297     sptr<SceneSession> session = (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) ?
298         sceneSession->GetKeyboardSession() : sceneSession;
299     auto sessionProperty = session->GetSessionProperty();
300     KeyboardTouchHotAreas keyboardTouchHotAreas = sessionProperty->GetKeyboardTouchHotAreas();
301     auto displayId = sessionProperty->GetDisplayId();
302     std::map<ScreenId, ScreenProperty> screensProperties =
303         ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
304     if (screensProperties.find(displayId) == screensProperties.end()) {
305         return;
306     }
307     const auto& screenProperty = screensProperties[displayId];
308     bool isLandscape = screenProperty.GetBounds().rect_.GetWidth() > screenProperty.GetBounds().rect_.GetHeight();
309     if (screenProperty.GetBounds().rect_.GetWidth() == screenProperty.GetBounds().rect_.GetHeight()) {
310         DisplayOrientation orientation = screenProperty.GetDisplayOrientation();
311         if (orientation == DisplayOrientation::UNKNOWN) {
312             TLOGW(WmsLogTag::WMS_KEYBOARD, "Display orientation is UNKNOWN");
313         }
314         isLandscape = (orientation == DisplayOrientation::LANDSCAPE ||
315             orientation == DisplayOrientation::LANDSCAPE_INVERTED);
316     }
317     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
318         if (keyboardTouchHotAreas.isKeyboardEmpty()) {
319             return;
320         }
321         hotAreas = isLandscape ? keyboardTouchHotAreas.landscapeKeyboardHotAreas_ :
322             keyboardTouchHotAreas.portraitKeyboardHotAreas_;
323     } else if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
324         if (keyboardTouchHotAreas.isPanelEmpty()) {
325             return;
326         }
327         hotAreas = isLandscape ? keyboardTouchHotAreas.landscapePanelHotAreas_ :
328             keyboardTouchHotAreas.portraitPanelHotAreas_;
329     }
330 }
331 
UpdateHotAreas(const sptr<SceneSession> & sceneSession,std::vector<MMI::Rect> & touchHotAreas,std::vector<MMI::Rect> & pointerHotAreas) const332 void SceneSessionDirtyManager::UpdateHotAreas(const sptr<SceneSession>& sceneSession,
333     std::vector<MMI::Rect>& touchHotAreas, std::vector<MMI::Rect>& pointerHotAreas) const
334 {
335     if (sceneSession == nullptr) {
336         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
337         return;
338     }
339     std::unordered_set<MMI::Rect, InputRectHash, InputRectEqual> hotAreaHashSet;
340     std::vector<Rect> hotAreas = sceneSession->GetTouchHotAreas();
341     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
342         sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
343         UpdateKeyboardHotAreasInner(sceneSession, hotAreas);
344     }
345     for (const auto& area : hotAreas) {
346         MMI::Rect rect;
347         rect.x = area.posX_;
348         rect.y = area.posY_;
349         rect.width = static_cast<int32_t>(area.width_);
350         rect.height = static_cast<int32_t>(area.height_);
351         if (hotAreaHashSet.count(rect)) {
352             continue;
353         }
354         hotAreaHashSet.insert(rect);
355         touchHotAreas.emplace_back(rect);
356         pointerHotAreas.emplace_back(rect);
357         if (touchHotAreas.size() == static_cast<uint32_t>(MMI::WindowInfo::MAX_HOTAREA_COUNT)) {
358             auto sessionId = sceneSession->GetWindowId();
359             TLOGE(WmsLogTag::WMS_EVENT, "id=%{public}d hotAreas size > %{public}d",
360                 sessionId, static_cast<int>(hotAreas.size()));
361             break;
362         }
363     }
364     if (touchHotAreas.empty()) {
365         return UpdateDefaultHotAreas(sceneSession, touchHotAreas, pointerHotAreas);
366     }
367 }
368 
AddDialogSessionMapItem(const sptr<SceneSession> & session,std::map<int32_t,sptr<SceneSession>> & dialogMap)369 static void AddDialogSessionMapItem(const sptr<SceneSession>& session,
370     std::map<int32_t, sptr<SceneSession>>& dialogMap)
371 {
372     const auto& mainSession = session->GetMainSession();
373     if (mainSession == nullptr) {
374         return;
375     }
376     bool isTopmostModalWindow = false;
377     const auto& property = session->GetSessionProperty();
378     if (property != nullptr && property->IsTopmost()) {
379         isTopmostModalWindow = true;
380     }
381     if (auto iter = dialogMap.find(mainSession->GetPersistentId());
382         iter != dialogMap.end() && iter->second != nullptr) {
383         auto& targetSession = iter->second;
384         if (session->IsApplicationModal() == targetSession->IsApplicationModal()) {
385             if (targetSession->GetSessionProperty() &&
386                 targetSession->GetSessionProperty()->IsTopmost() &&
387                 !isTopmostModalWindow) {
388                 return;
389             }
390             if (targetSession->GetZOrder() > session->GetZOrder()) {
391                 return;
392             }
393         } else if (!session->IsApplicationModal() && targetSession->IsApplicationModal()) {
394             return;
395         }
396     }
397     dialogMap[mainSession->GetPersistentId()] = session;
398     TLOGD(WmsLogTag::WMS_DIALOG, "Add dialog session, id: %{public}d, mainSessionId: %{public}d",
399         session->GetPersistentId(), mainSession->GetPersistentId());
400 }
401 
UpdateCallingPidMapItem(const sptr<SceneSession> & session,std::unordered_map<int32_t,sptr<SceneSession>> & callingPidMap)402 static void UpdateCallingPidMapItem(const sptr<SceneSession>& session,
403     std::unordered_map<int32_t, sptr<SceneSession>>& callingPidMap)
404 {
405     auto sessionPid = session->GetCallingPid();
406     auto parentSession = session->GetParentSession();
407     while (parentSession) {
408         auto parentSessionPid = parentSession->GetCallingPid();
409         if (sessionPid != parentSessionPid) {
410             callingPidMap[parentSessionPid] = session;
411         }
412         parentSession = parentSession->GetParentSession();
413     }
414 }
415 
AddCallingPidMapItem(const sptr<SceneSession> & session,std::unordered_map<int32_t,sptr<SceneSession>> & callingPidMap)416 static void AddCallingPidMapItem(const sptr<SceneSession>& session,
417     std::unordered_map<int32_t, sptr<SceneSession>>& callingPidMap)
418 {
419     auto sessionCallingPid = session->GetCallingPid();
420     auto iter = callingPidMap.find(sessionCallingPid);
421     if (iter == callingPidMap.end()) {
422         if (!session->IsApplicationModal()) {
423             return;
424         }
425         callingPidMap.emplace(std::make_pair(sessionCallingPid, session));
426         UpdateCallingPidMapItem(session, callingPidMap);
427         TLOGD(WmsLogTag::WMS_DIALOG,
428             "Add callingPid session, sessionCallingPid: %{public}d, sessionId: %{public}d",
429             sessionCallingPid, session->GetPersistentId());
430     } else {
431         if (iter->second->GetZOrder() < session->GetZOrder()) {
432             callingPidMap[sessionCallingPid] = session;
433             UpdateCallingPidMapItem(session, callingPidMap);
434             TLOGD(WmsLogTag::WMS_DIALOG,
435                 "Update callingPid session, sessionCallingPid: %{public}d, sessionId: %{public}d",
436                 sessionCallingPid, session->GetPersistentId());
437         }
438     }
439 }
440 
UpdateDialogSessionMap(const std::map<int32_t,sptr<SceneSession>> & sessionMap,const std::unordered_map<int32_t,sptr<SceneSession>> & callingPidMap,std::map<int32_t,sptr<SceneSession>> & dialogMap)441 static void UpdateDialogSessionMap(
442     const std::map<int32_t, sptr<SceneSession>>& sessionMap,
443     const std::unordered_map<int32_t, sptr<SceneSession>>& callingPidMap,
444     std::map<int32_t, sptr<SceneSession>>& dialogMap)
445 {
446     for (const auto& [_, session] : sessionMap) {
447         if (session == nullptr || session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
448             continue;
449         }
450         auto iter = callingPidMap.find(session->GetCallingPid());
451         if (iter != callingPidMap.end()) {
452             dialogMap[session->GetPersistentId()] = iter->second;
453             TLOGD(WmsLogTag::WMS_DIALOG,
454                 "Update dialog session, sessionId: %{public}d, callingPidSessionId: %{public}d",
455                 session->GetPersistentId(), iter->second->GetPersistentId());
456         }
457     }
458 }
459 
GetDialogSessionMap(const std::map<int32_t,sptr<SceneSession>> & sessionMap) const460 std::map<int32_t, sptr<SceneSession>> SceneSessionDirtyManager::GetDialogSessionMap(
461     const std::map<int32_t, sptr<SceneSession>>& sessionMap) const
462 {
463     std::map<int32_t, sptr<SceneSession>> dialogMap;
464     std::unordered_map<int32_t, sptr<SceneSession>> callingPidMap;
465     bool hasModalApplication = false;
466     for (const auto& [_, session] : sessionMap) {
467         if (session == nullptr || session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
468             continue;
469         }
470         if (!session->IsModal() && !session->IsDialogWindow()) {
471             continue;
472         }
473         AddDialogSessionMapItem(session, dialogMap);
474         AddCallingPidMapItem(session, callingPidMap);
475         if (session->IsApplicationModal()) {
476             hasModalApplication = true;
477         }
478     }
479     if (hasModalApplication) {
480         UpdateDialogSessionMap(sessionMap, callingPidMap, dialogMap);
481     }
482     return dialogMap;
483 }
484 
IsFilterSession(const sptr<SceneSession> & sceneSession) const485 bool SceneSessionDirtyManager::IsFilterSession(const sptr<SceneSession>& sceneSession) const
486 {
487     if (sceneSession == nullptr) {
488         return true;
489     }
490 
491     if (sceneSession->IsSystemInput()) {
492         return false;
493     } else if (sceneSession->IsSystemSession() && sceneSession->IsVisible() && sceneSession->IsSystemActive()) {
494         return false;
495     }
496     if (!SceneSessionManager::GetInstance().IsSessionVisible(sceneSession)) {
497         return true;
498     }
499     return false;
500 }
501 
NotifyWindowInfoChange(const sptr<SceneSession> & sceneSession,const WindowUpdateType & type,const bool startMoving)502 void SceneSessionDirtyManager::NotifyWindowInfoChange(const sptr<SceneSession>& sceneSession,
503     const WindowUpdateType& type, const bool startMoving)
504 {
505     if (sceneSession == nullptr) {
506         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is null");
507         return;
508     }
509 
510     if (type == WindowUpdateType::WINDOW_UPDATE_ADDED || type == WindowUpdateType::WINDOW_UPDATE_REMOVED||
511         type == WindowUpdateType::WINDOW_UPDATE_ACTIVE) {
512         TLOGD(WmsLogTag::WMS_EVENT, "[EventDispatch] wid=%{public}d, winType=%{public}d",
513             sceneSession->GetWindowId(), static_cast<int>(type));
514     }
515     ResetFlushWindowInfoTask();
516 }
517 
ResetFlushWindowInfoTask()518 void SceneSessionDirtyManager::ResetFlushWindowInfoTask()
519 {
520     sessionDirty_.store(true);
521     bool hasPostTask = false;
522     if (hasPostTask_.compare_exchange_strong(hasPostTask, true)) {
523         auto task = [this]() {
524             hasPostTask_.store(false);
525             if (!sessionDirty_.load() || flushWindowInfoCallback_ == nullptr) {
526                 return;
527             }
528             flushWindowInfoCallback_();
529         };
530         TLOGD(WmsLogTag::WMS_EVENT, "in");
531         SceneSessionManager::GetInstance().PostFlushWindowInfoTask(task,
532             UPDATE_WINDOW_INFO_TASK, UPDATE_TASK_DURATION);
533     }
534 }
535 
GetLastConstrainedModalUIExtInfo(const sptr<SceneSession> & sceneSession,SecSurfaceInfo & constrainedModalUIExtInfo)536 bool SceneSessionDirtyManager::GetLastConstrainedModalUIExtInfo(const sptr<SceneSession>& sceneSession,
537     SecSurfaceInfo& constrainedModalUIExtInfo)
538 {
539     if (sceneSession == nullptr) {
540         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
541         return false;
542     }
543     auto surfaceNodeId = sceneSession->GetSurfaceNodeId();
544     if (!surfaceNodeId) {
545         TLOGD(WmsLogTag::WMS_EVENT, "surfaceNodeId not found");
546         return false;
547     }
548     {
549         std::shared_lock<std::shared_mutex> lock(constrainedModalUIExtInfoMutex_);
550         auto iter = constrainedModalUIExtInfoMap_.find(*surfaceNodeId);
551         if (iter == constrainedModalUIExtInfoMap_.end()) {
552             return false;
553         }
554         if (!iter->second.empty()) {
555             constrainedModalUIExtInfo = iter->second.back();
556             return true;
557         }
558     }
559     return false;
560 }
561 
AddModalExtensionWindowInfo(std::vector<MMI::WindowInfo> & windowInfoList,MMI::WindowInfo windowInfo,const sptr<SceneSession> & sceneSession,const ExtensionWindowEventInfo & extensionInfo)562 void SceneSessionDirtyManager::AddModalExtensionWindowInfo(std::vector<MMI::WindowInfo>& windowInfoList,
563     MMI::WindowInfo windowInfo, const sptr<SceneSession>& sceneSession,
564     const ExtensionWindowEventInfo& extensionInfo)
565 {
566     if (sceneSession == nullptr) {
567         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
568         return;
569     }
570 
571     windowInfo.id = extensionInfo.persistentId;
572     if (extensionInfo.windowRect.width_ != 0 || extensionInfo.windowRect.height_ != 0) {
573         auto singleHandData = GetSingleHandData(sceneSession);
574         MMI::Rect windowRect = {
575             .x = ceil(singleHandData.scaleX * extensionInfo.windowRect.posX_ +
576                  singleHandData.singleHandX),
577             .y = ceil(singleHandData.scaleY * extensionInfo.windowRect.posY_ +
578                  singleHandData.singleHandY),
579             .width = extensionInfo.windowRect.width_,
580             .height = extensionInfo.windowRect.height_
581         };
582         windowInfo.area = windowRect;
583         std::vector<MMI::Rect> touchHotAreas;
584         MMI::Rect touchRect = {
585             .x = 0,
586             .y = 0,
587             .width = extensionInfo.windowRect.width_,
588             .height = extensionInfo.windowRect.height_
589         };
590         touchHotAreas.emplace_back(touchRect);
591         windowInfo.defaultHotAreas = touchHotAreas;
592         windowInfo.pointerHotAreas = std::move(touchHotAreas);
593         Matrix3f transform;
594         CalTransform(sceneSession, transform, singleHandData, true);
595         std::vector<float> transformData(transform.GetData(), transform.GetData() + TRANSFORM_DATA_LEN);
596         windowInfo.transform = std::move(transformData);
597     }
598 
599     windowInfo.agentWindowId = extensionInfo.persistentId;
600     windowInfo.pid = extensionInfo.pid;
601     std::vector<int32_t> pointerChangeAreas(POINTER_CHANGE_AREA_COUNT, 0);
602     windowInfo.pointerChangeAreas = std::move(pointerChangeAreas);
603     windowInfo.zOrder = windowInfo.zOrder + ZORDER_UIEXTENSION_INDEX;
604 
605     windowInfoList.emplace_back(windowInfo);
606 }
607 
GetModalUIExtensionInfo(std::vector<MMI::WindowInfo> & windowInfoList,const sptr<SceneSession> & sceneSession,const MMI::WindowInfo & hostWindowInfo)608 void SceneSessionDirtyManager::GetModalUIExtensionInfo(std::vector<MMI::WindowInfo>& windowInfoList,
609     const sptr<SceneSession>& sceneSession, const MMI::WindowInfo& hostWindowInfo)
610 {
611     auto modalUIExtensionEventInfo = sceneSession->GetLastModalUIExtensionEventInfo();
612     if (!modalUIExtensionEventInfo) {
613         return;
614     }
615     if (modalUIExtensionEventInfo->isConstrainedModal) {  // constrained UIExt
616         SecSurfaceInfo constrainedModalUIExtInfo;
617         if (!GetLastConstrainedModalUIExtInfo(sceneSession, constrainedModalUIExtInfo)) {
618             TLOGE(WmsLogTag::WMS_EVENT, "cannot find last constrained Modal UIExtInfo");
619             return;
620         }
621         MMI::WindowInfo windowInfo = GetSecComponentWindowInfo(constrainedModalUIExtInfo,
622             hostWindowInfo, sceneSession, GetTransformFromWindowInfo(hostWindowInfo));
623         std::vector<int32_t> pointerChangeAreas(POINTER_CHANGE_AREA_COUNT, 0);
624         windowInfo.pointerChangeAreas = std::move(pointerChangeAreas);
625         windowInfo.zOrder = hostWindowInfo.zOrder + ZORDER_UIEXTENSION_INDEX;
626         windowInfo.privacyUIFlag = false;
627         TLOGD(WmsLogTag::WMS_EVENT, "constrained Modal UIExt id: %{public}d", windowInfo.id);
628         windowInfoList.emplace_back(windowInfo);
629     } else {  // normal UIExt
630         AddModalExtensionWindowInfo(windowInfoList, hostWindowInfo, sceneSession, *modalUIExtensionEventInfo);
631     }
632 }
633 
GetFullWindowInfoList()634 auto SceneSessionDirtyManager::GetFullWindowInfoList() ->
635 std::pair<std::vector<MMI::WindowInfo>, std::vector<std::shared_ptr<Media::PixelMap>>>
636 {
637     std::vector<MMI::WindowInfo> windowInfoList;
638     std::vector<std::shared_ptr<Media::PixelMap>> pixelMapList;
639     const auto sceneSessionMap = SceneSessionManager::GetInstance().GetSceneSessionMap();
640     // all input event should trans to dialog window if dialog exists
641     const auto dialogMap = GetDialogSessionMap(sceneSessionMap);
642     uint32_t maxHotAreasNum = 0;
643     for (const auto& sceneSessionValuePair : sceneSessionMap) {
644         const auto& sceneSessionValue = sceneSessionValuePair.second;
645         if (sceneSessionValue == nullptr) {
646             continue;
647         }
648         TLOGD(WmsLogTag::WMS_EVENT,
649             "[EventDispatch] windowName=%{public}s bundleName=%{public}s"
650             " windowId=%{public}d activeStatus=%{public}d", sceneSessionValue->GetWindowName().c_str(),
651             sceneSessionValue->GetSessionInfo().bundleName_.c_str(), sceneSessionValue->GetWindowId(),
652             sceneSessionValue->GetForegroundInteractiveStatus());
653         auto [windowInfo, pixelMap] = GetWindowInfo(sceneSessionValue, WindowAction::WINDOW_ADD);
654         auto iter = (sceneSessionValue->GetMainSessionId() == INVALID_SESSION_ID) ?
655             dialogMap.find(sceneSessionValue->GetPersistentId()) :
656             dialogMap.find(sceneSessionValue->GetMainSessionId());
657         if (iter != dialogMap.end() && iter->second != nullptr &&
658             sceneSessionValue->GetPersistentId() != iter->second->GetPersistentId() &&
659             iter->second->GetZOrder() > sceneSessionValue->GetZOrder()) {
660             windowInfo.agentWindowId = static_cast<int32_t>(iter->second->GetPersistentId());
661             windowInfo.pid = static_cast<int32_t>(iter->second->GetCallingPid());
662         } else {
663             GetModalUIExtensionInfo(windowInfoList, sceneSessionValue, windowInfo);
664         }
665         TLOGD(WmsLogTag::WMS_EVENT, "windowId=%{public}d, agentWindowId=%{public}d, zOrder=%{public}f",
666             windowInfo.id, windowInfo.agentWindowId, windowInfo.zOrder);
667         windowInfoList.emplace_back(windowInfo);
668         pixelMapList.emplace_back(pixelMap);
669         // set the number of hot areas to the maximum number of hot areas when it exceeds the maximum number
670         // to avoid exceeding socket buff limits
671         if (windowInfo.defaultHotAreas.size() > maxHotAreasNum) {
672             maxHotAreasNum = windowInfo.defaultHotAreas.size();
673         }
674     }
675     if (maxHotAreasNum > MMI::WindowInfo::DEFAULT_HOTAREA_COUNT) {
676         std::sort(windowInfoList.begin(), windowInfoList.end(), CmpMMIWindowInfo);
677     }
678     return {windowInfoList, pixelMapList};
679 }
680 
UpdatePointerAreas(sptr<SceneSession> sceneSession,std::vector<int32_t> & pointerChangeAreas) const681 void SceneSessionDirtyManager::UpdatePointerAreas(sptr<SceneSession> sceneSession,
682     std::vector<int32_t>& pointerChangeAreas) const
683 {
684     if (!sceneSession) {
685         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is null");
686         return;
687     }
688     auto sessionProperty = sceneSession->GetSessionProperty();
689     if (!sessionProperty) {
690         TLOGE(WmsLogTag::WMS_EVENT, "sessionProperty is null");
691         return;
692     }
693     bool isDragAccessible = sceneSession->IsDragAccessible();
694     TLOGD(WmsLogTag::WMS_EVENT, "window %{public}s isDragAccessible: %{public}d", sceneSession->GetWindowName().c_str(),
695         isDragAccessible);
696     if (isDragAccessible) {
697         float vpr = 1.5f; // 1.5: default vp
698         auto displayId = sessionProperty->GetDisplayId();
699         auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
700         if (screenSession != nullptr) {
701             vpr = screenSession->GetScreenProperty().GetDensity();
702         }
703         int32_t pointerAreaFivePx = static_cast<int32_t>(POINTER_CHANGE_AREA_FIVE * vpr);
704         int32_t pointerAreaSixteenPx = static_cast<int32_t>(POINTER_CHANGE_AREA_SIXTEEN * vpr);
705         if (sceneSession->GetSessionInfo().isSetPointerAreas_) {
706             pointerChangeAreas = {POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT,
707                 POINTER_CHANGE_AREA_DEFAULT, pointerAreaFivePx, pointerAreaSixteenPx,
708                 pointerAreaFivePx, pointerAreaSixteenPx, pointerAreaFivePx};
709             return;
710         }
711         auto limits = sessionProperty->GetWindowLimits();
712         TLOGD(WmsLogTag::WMS_EVENT, "%{public}s [minWidth,maxWidth,minHeight,maxHeight]: %{public}d,"
713             " %{public}d, %{public}d, %{public}d", sceneSession->GetWindowName().c_str(), limits.minWidth_,
714             limits.maxWidth_, limits.minHeight_, limits.maxHeight_);
715         if (limits.minWidth_ == limits.maxWidth_ && limits.minHeight_ != limits.maxHeight_) {
716             pointerChangeAreas = {POINTER_CHANGE_AREA_DEFAULT, pointerAreaFivePx,
717                 POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT,
718                 pointerAreaFivePx, POINTER_CHANGE_AREA_DEFAULT,  POINTER_CHANGE_AREA_DEFAULT};
719         } else if (limits.minWidth_ != limits.maxWidth_ && limits.minHeight_ == limits.maxHeight_) {
720             pointerChangeAreas = {POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT,
721                 POINTER_CHANGE_AREA_DEFAULT, pointerAreaFivePx, POINTER_CHANGE_AREA_DEFAULT,
722                 POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT, pointerAreaFivePx};
723         } else if (limits.minWidth_ != limits.maxWidth_ && limits.minHeight_ != limits.maxHeight_) {
724             pointerChangeAreas = {pointerAreaSixteenPx, pointerAreaFivePx,
725                 pointerAreaSixteenPx, pointerAreaFivePx, pointerAreaSixteenPx,
726                 pointerAreaFivePx, pointerAreaSixteenPx, pointerAreaFivePx};
727         }
728     } else {
729         TLOGD(WmsLogTag::WMS_EVENT, "sceneSession is: %{public}d dragAccessible is false",
730             sceneSession->GetPersistentId());
731     }
732 }
733 
UpdatePrivacyMode(const sptr<SceneSession> & sceneSession,MMI::WindowInfo & windowInfo) const734 void SceneSessionDirtyManager::UpdatePrivacyMode(const sptr<SceneSession>& sceneSession,
735     MMI::WindowInfo& windowInfo) const
736 {
737     if (sceneSession == nullptr) {
738         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
739         return;
740     }
741     windowInfo.privacyMode = MMI::SecureFlag::DEFAULT_MODE;
742     sptr<WindowSessionProperty> windowSessionProperty = sceneSession->GetSessionProperty();
743     if (windowSessionProperty == nullptr) {
744         TLOGE(WmsLogTag::WMS_EVENT, "windowSessionProperty is nullptr");
745         return;
746     }
747     if (windowSessionProperty->GetPrivacyMode() || windowSessionProperty->GetSystemPrivacyMode() ||
748         sceneSession->GetCombinedExtWindowFlags().privacyModeFlag) {
749         windowInfo.privacyMode = MMI::SecureFlag::PRIVACY_MODE;
750     }
751 }
752 
UpdateWindowFlags(DisplayId displayId,const sptr<SceneSession> & sceneSession,MMI::WindowInfo & windowInfo) const753 void SceneSessionDirtyManager::UpdateWindowFlags(DisplayId displayId, const sptr<SceneSession>& sceneSession,
754     MMI::WindowInfo& windowInfo) const
755 {
756     windowInfo.flags = 0;
757     auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
758     if (screenSession != nullptr) {
759         if (!screenSession->IsTouchEnabled() || !sceneSession->GetSystemTouchable() ||
760             !sceneSession->GetForegroundInteractiveStatus()) {
761             windowInfo.flags |= MMI::WindowInfo::FLAG_BIT_UNTOUCHABLE;
762         }
763     }
764 }
765 
GetWindowInfo(const sptr<SceneSession> & sceneSession,const WindowAction & action) const766 std::pair<MMI::WindowInfo, std::shared_ptr<Media::PixelMap>> SceneSessionDirtyManager::GetWindowInfo(
767     const sptr<SceneSession>& sceneSession, const WindowAction& action) const
768 {
769     if (sceneSession == nullptr) {
770         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
771         return {};
772     }
773     sptr<WindowSessionProperty> windowSessionProperty = sceneSession->GetSessionProperty();
774     if (windowSessionProperty == nullptr) {
775         TLOGE(WmsLogTag::WMS_EVENT, "GetSessionProperty is nullptr");
776         return {};
777     }
778     Matrix3f transform;
779     WSRect windowRect = sceneSession->GetSessionGlobalRectInMultiScreen();
780     auto pid = sceneSession->GetCallingPid();
781     auto uid = sceneSession->GetCallingUid();
782     auto windowId = sceneSession->GetWindowId();
783     auto displayId = windowSessionProperty->GetDisplayId();
784     const auto& singleHandData = GetSingleHandData(sceneSession);
785     CalTransform(sceneSession, transform, singleHandData);
786     std::vector<float> transformData(transform.GetData(), transform.GetData() + TRANSFORM_DATA_LEN);
787 
788     auto agentWindowId = sceneSession->GetWindowId();
789     auto zOrder = sceneSession->GetZOrder();
790     std::vector<int32_t> pointerChangeAreas(POINTER_CHANGE_AREA_COUNT, 0);
791     WindowType windowType = windowSessionProperty->GetWindowType();
792     CheckIfUpdatePointAreas(windowType, sceneSession, windowSessionProperty, pointerChangeAreas);
793     std::vector<MMI::Rect> touchHotAreas;
794     std::vector<MMI::Rect> pointerHotAreas;
795     UpdateHotAreas(sceneSession, touchHotAreas, pointerHotAreas);
796     int windowNameType = WINDOW_NAME_TYPE_UNKNOWN;
797     std::string windowName = sceneSession->GetWindowNameAllType();
798     auto startsWith = [](const std::string& str, const std::string& prefix) {
799         return str.size() >= prefix.size() &&
800             std::equal(prefix.begin(), prefix.end(), str.begin());
801     };
802     if (startsWith(windowName, SCREENSHOT_WINDOW_NAME_PREFIX) || startsWith(windowName, PREVIEW_WINDOW_NAME_PREFIX)) {
803         windowNameType = WINDOW_NAME_TYPE_THUMBNAIL;
804     }
805     auto pixelMap = windowSessionProperty->GetWindowMask();
806     MMI::WindowInfo windowInfo = {
807         .id = windowId,
808         .pid = sceneSession->IsStartMoving() ? static_cast<int32_t>(getpid()) : pid,
809         .uid = uid,
810         .area = { ceil(singleHandData.scaleX * windowRect.posX_ + singleHandData.singleHandX),
811                   ceil(singleHandData.scaleX * windowRect.posY_ + singleHandData.singleHandY),
812                   windowRect.width_, windowRect.height_ },
813         .defaultHotAreas = std::move(touchHotAreas),
814         .pointerHotAreas = std::move(pointerHotAreas),
815         .agentWindowId = agentWindowId,
816         .action = static_cast<MMI::WINDOW_UPDATE_ACTION>(action),
817         .displayId = displayId,
818         .groupId = SceneSessionManager::GetInstance().GetDisplayGroupId(displayId),
819         .zOrder = zOrder,
820         .pointerChangeAreas = std::move(pointerChangeAreas),
821         .transform = transformData,
822         .pixelMap = pixelMap.get(),
823         .windowInputType = static_cast<MMI::WindowInputType>(sceneSession->GetSessionInfo().windowInputType_),
824         .windowType = static_cast<int32_t>(windowType),
825         .isSkipSelfWhenShowOnVirtualScreen = sceneSession->GetSessionProperty()->GetSkipEventOnCastPlus(),
826         .windowNameType = windowNameType,
827     };
828     UpdateWindowFlags(displayId, sceneSession, windowInfo);
829     if (windowSessionProperty->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_HANDWRITING)) {
830         windowInfo.flags |= MMI::WindowInfo::FLAG_BIT_HANDWRITING;
831     }
832     UpdatePrivacyMode(sceneSession, windowInfo);
833     windowInfo.uiExtentionWindowInfo = GetSecSurfaceWindowinfoList(sceneSession, windowInfo, transform);
834     return {windowInfo, pixelMap};
835 }
836 
GetSingleHandData(const sptr<SceneSession> & sceneSession) const837 SingleHandData SceneSessionDirtyManager::GetSingleHandData(const sptr<SceneSession>& sceneSession) const
838 {
839     SingleHandData singleHandData;
840     auto sessionProperty = sceneSession->GetSessionProperty();
841     auto displayId = sessionProperty->GetDisplayId();
842     if (displayId != ScreenSessionManagerClient::GetInstance().GetDefaultScreenId() ||
843         !sceneSession->SessionIsSingleHandMode()) {
844         return singleHandData;
845     }
846     const std::map<ScreenId, ScreenProperty>& screensProperties =
847         ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
848     const SingleHandTransform& transform = sceneSession->GetSingleHandTransform();
849     const SingleHandScreenInfo& singleHandScreenInfo = SceneSessionManager::GetInstance().GetSingleHandScreenInfo();
850     singleHandData.scaleX = transform.scaleX;
851     singleHandData.scaleY = transform.scaleY;
852     singleHandData.singleHandX = transform.posX;
853     singleHandData.singleHandY = transform.posY;
854     singleHandData.pivotX = singleHandScreenInfo.scalePivotX;
855     singleHandData.pivotY = singleHandScreenInfo.scalePivotY;
856     singleHandData.mode = singleHandScreenInfo.mode;
857     return singleHandData;
858 }
859 
CheckIfUpdatePointAreas(WindowType windowType,const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & windowSessionProperty,std::vector<int32_t> & pointerChangeAreas) const860 void SceneSessionDirtyManager::CheckIfUpdatePointAreas(WindowType windowType, const sptr<SceneSession>& sceneSession,
861     const sptr<WindowSessionProperty>& windowSessionProperty, std::vector<int32_t>& pointerChangeAreas) const
862 {
863     bool isMainWindow = WindowHelper::IsMainWindow(windowType);
864     bool isDecorEnabledDialog = WindowHelper::IsDialogWindow(windowType) && windowSessionProperty->IsDecorEnable();
865     bool isDragAccessibleSystemWindowButNotDialog = WindowHelper::IsSystemWindow(windowType) &&
866         !WindowHelper::IsDialogWindow(windowType) && sceneSession->IsDragAccessible();
867     bool isDecorEnabledSubWindow = WindowHelper::IsSubWindow(windowType) && windowSessionProperty->IsDecorEnable();
868     bool isDragAccessibleSubWindow = WindowHelper::IsSubWindow(windowType) && sceneSession->IsDragAccessible();
869     bool isUpdatePointerAreasNeeded = isMainWindow || isDecorEnabledDialog || isDecorEnabledSubWindow ||
870         isDragAccessibleSubWindow || isDragAccessibleSystemWindowButNotDialog;
871     auto windowMode = windowSessionProperty->GetWindowMode();
872     auto maximizeMode = windowSessionProperty->GetMaximizeMode();
873     if ((windowMode == WindowMode::WINDOW_MODE_FLOATING && maximizeMode != MaximizeMode::MODE_AVOID_SYSTEM_BAR &&
874          isUpdatePointerAreasNeeded) ||
875         sceneSession->GetSessionInfo().isSetPointerAreas_) {
876         UpdatePointerAreas(sceneSession, pointerChangeAreas);
877     }
878 }
879 
RegisterFlushWindowInfoCallback(FlushWindowInfoCallback && callback)880 void SceneSessionDirtyManager::RegisterFlushWindowInfoCallback(FlushWindowInfoCallback&& callback)
881 {
882     flushWindowInfoCallback_ = std::move(callback);
883 }
884 
ResetSessionDirty()885 void SceneSessionDirtyManager::ResetSessionDirty()
886 {
887     sessionDirty_.store(false);
888 }
889 
DumpRect(const std::vector<MMI::Rect> & rects)890 std::string DumpRect(const std::vector<MMI::Rect>& rects)
891 {
892     std::string rectStr = "hot:";
893     for (const auto& rect : rects) {
894         rectStr = rectStr + std::to_string(rect.x) +"," + std::to_string(rect.y) +
895         "," + std::to_string(rect.width) + "," + std::to_string(rect.height) + "|";
896     }
897     return rectStr;
898 }
899 
DumpWindowInfo(const MMI::WindowInfo & info)900 std::string DumpWindowInfo(const MMI::WindowInfo& info)
901 {
902     std::string infoStr = "wInfo:";
903     infoStr = infoStr + std::to_string(info.id) + "|" + std::to_string(info.pid) +
904         "|" + std::to_string(info.uid) + "|" + std::to_string(info.area.x) + "," +
905         std::to_string(info.area.y) + "," + std::to_string(info.area.width) + "," +
906         std::to_string(info.area.height) + "|" + std::to_string(info.agentWindowId) + "|" +
907         std::to_string(info.flags) + "|" + std::to_string(info.displayId) +
908         "|" + std::to_string(static_cast<int>(info.action)) + "|" + std::to_string(info.zOrder) + ",";
909     return infoStr + DumpRect(info.defaultHotAreas);
910 }
911 
DumpSecRectInfo(const SecRectInfo & secRectInfo)912 std::string DumpSecRectInfo(const SecRectInfo & secRectInfo)
913 {
914     std::string infoStr = "[" + std::to_string(secRectInfo.relativeCoords.GetLeft()) + "," +
915         std::to_string(secRectInfo.relativeCoords.GetTop()) +  "," +
916         std::to_string(secRectInfo.relativeCoords.GetWidth()) + "," +
917         std::to_string(secRectInfo.relativeCoords.GetHeight()) + "]" +
918         "|" + std::to_string(static_cast<int>(secRectInfo.scale[0])) +
919         "|" + std::to_string(static_cast<int>(secRectInfo.scale[1])) +
920         "|" + std::to_string(static_cast<int>(secRectInfo.anchor[0])) +
921         "|" + std::to_string(static_cast<int>(secRectInfo.anchor[1]));
922     return infoStr;
923 }
924 
DumpSecSurfaceInfo(const SecSurfaceInfo & secSurfaceInfo)925 std::string DumpSecSurfaceInfo(const SecSurfaceInfo& secSurfaceInfo)
926 {
927     std::string infoStr = std::to_string(secSurfaceInfo.hostPid) +
928         "|" + std::to_string(secSurfaceInfo.uiExtensionPid) +
929         "|" + std::to_string(secSurfaceInfo.hostNodeId) +
930         "|" + std::to_string(secSurfaceInfo.uiExtensionNodeId);
931     return infoStr;
932 }
933 
MakeWindowInfoFormHostWindow(const MMI::WindowInfo & hostWindowinfo) const934 MMI::WindowInfo SceneSessionDirtyManager::MakeWindowInfoFormHostWindow(const MMI::WindowInfo& hostWindowinfo) const
935 {
936     MMI::WindowInfo windowinfo;
937     windowinfo.id = hostWindowinfo.id;
938     windowinfo.pid = hostWindowinfo.pid;
939     windowinfo.uid = hostWindowinfo.uid;
940     windowinfo.area = hostWindowinfo.area;
941     windowinfo.agentWindowId = hostWindowinfo.agentWindowId;
942     windowinfo.action = hostWindowinfo.action;
943     windowinfo.displayId = hostWindowinfo.displayId;
944     windowinfo.flags = hostWindowinfo.flags;
945     windowinfo.privacyMode = hostWindowinfo.privacyMode;
946     windowinfo.transform = hostWindowinfo.transform;
947     return windowinfo;
948 }
949 
CoordinateSystemHostWindowToScreen(const Matrix3f hostTransform,const SecRectInfo & secRectInfo)950 Matrix3f CoordinateSystemHostWindowToScreen(const Matrix3f hostTransform, const SecRectInfo& secRectInfo)
951 {
952     Matrix3f transform = Matrix3f::IDENTITY;
953     Vector2f translate(secRectInfo.relativeCoords.GetLeft(), secRectInfo.relativeCoords.GetTop());
954     transform = transform.Translate(translate);
955     Vector2f scale(secRectInfo.scale[0], secRectInfo.scale[1]);
956     transform = transform.Scale(scale, secRectInfo.anchor[0], secRectInfo.anchor[1]);
957     transform = hostTransform.Inverse() * transform;
958     return transform;
959 }
960 
CalRectInScreen(const Matrix3f & transform,const SecRectInfo & secRectInfo)961 MMI::Rect CalRectInScreen(const Matrix3f& transform, const SecRectInfo& secRectInfo)
962 {
963     auto topLeft = transform * Vector3f(0, 0, 1.0);
964     auto bottomRight = transform * Vector3f(secRectInfo.relativeCoords.GetWidth(),
965         secRectInfo.relativeCoords.GetHeight(), 1.0);
966     auto left = std::min(topLeft[0], bottomRight[0]);
967     auto top = std::min(topLeft[1], bottomRight[1]);
968     auto topLeftX = static_cast<int32_t>(topLeft[0]);
969     auto topLeftY = static_cast<int32_t>(topLeft[1]);
970     auto bottomRightX = static_cast<int32_t>(bottomRight[0]);
971     auto bottomRightY = static_cast<int32_t>(bottomRight[1]);
972     if ((topLeftX > 0 && bottomRightX < INT32_MIN + topLeftX) ||
973         (topLeftX < 0 && bottomRightX > INT32_MAX + topLeftX)) {
974         TLOGE(WmsLogTag::WMS_EVENT, "data overflows topLeftX:%{public}d bottomRightX:%{public}d",
975             topLeftX, bottomRightX);
976     }
977     if ((topLeftY > 0 && bottomRightY < INT32_MIN + topLeftY) ||
978         (topLeftY < 0 && bottomRightY > INT32_MAX + topLeftY)) {
979         TLOGE(WmsLogTag::WMS_EVENT, "data overflows topLeftY:%{public}d bottomRightY:%{public}d",
980             topLeftY, bottomRightY);
981     }
982     auto width = std::abs(topLeftX - bottomRightX);
983     auto height = std::abs(topLeftY - bottomRightY);
984     return MMI::Rect{ left, top, width, height};
985 }
986 
987 
GetHostComponentWindowInfo(const SecSurfaceInfo & secSurfaceInfo,const MMI::WindowInfo & hostWindowinfo,const Matrix3f hostTransform) const988 MMI::WindowInfo SceneSessionDirtyManager::GetHostComponentWindowInfo(const SecSurfaceInfo& secSurfaceInfo,
989     const MMI::WindowInfo& hostWindowinfo, const Matrix3f hostTransform) const
990 {
991     MMI::WindowInfo windowinfo;
992     const auto& secRectInfoList = secSurfaceInfo.upperNodes;
993     if (secRectInfoList.size() > 0) {
994         windowinfo = MakeWindowInfoFormHostWindow(hostWindowinfo);
995     }
996     for (const auto& secRectInfo : secRectInfoList) {
997         windowinfo.pid = secSurfaceInfo.hostPid;
998         MMI::Rect hotArea = { secRectInfo.relativeCoords.GetLeft(), secRectInfo.relativeCoords.GetTop(),
999             secRectInfo.relativeCoords.GetWidth(), secRectInfo.relativeCoords.GetHeight() };
1000         windowinfo.defaultHotAreas.emplace_back(hotArea);
1001         windowinfo.pointerHotAreas.emplace_back(hotArea);
1002     }
1003     return windowinfo;
1004 }
1005 
GetSecComponentWindowInfo(const SecSurfaceInfo & secSurfaceInfo,const MMI::WindowInfo & hostWindowinfo,const sptr<SceneSession> & sceneSession,const Matrix3f hostTransform) const1006 MMI::WindowInfo SceneSessionDirtyManager::GetSecComponentWindowInfo(const SecSurfaceInfo& secSurfaceInfo,
1007     const MMI::WindowInfo& hostWindowinfo, const sptr<SceneSession>& sceneSession, const Matrix3f hostTransform) const
1008 {
1009     if (sceneSession == nullptr) {
1010         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
1011         return {};
1012     }
1013     const auto& secRectInfo = secSurfaceInfo.uiExtensionRectInfo;
1014     MMI::WindowInfo windowinfo = MakeWindowInfoFormHostWindow(hostWindowinfo);
1015     windowinfo.id = sceneSession->GetUIExtPersistentIdBySurfaceNodeId(secSurfaceInfo.uiExtensionNodeId);
1016     if (windowinfo.id == 0) {
1017         TLOGE(WmsLogTag::WMS_EVENT, "GetUIExtPersistentId ERROR");
1018         return {};
1019     }
1020     windowinfo.agentWindowId = windowinfo.id;
1021     windowinfo.pid = secSurfaceInfo.uiExtensionPid;
1022     windowinfo.privacyUIFlag = true;
1023     auto transform = CoordinateSystemHostWindowToScreen(hostTransform, secRectInfo);
1024     windowinfo.area = CalRectInScreen(transform, secRectInfo);
1025     MMI::Rect hotArea = { 0, 0, secRectInfo.relativeCoords.GetWidth(), secRectInfo.relativeCoords.GetHeight() };
1026     windowinfo.defaultHotAreas.emplace_back(hotArea);
1027     windowinfo.pointerHotAreas.emplace_back(hotArea);
1028     // 屏幕坐标系到控件坐标系转换
1029     transform = transform.Inverse();
1030     std::vector<float> transformData(transform.GetData(), transform.GetData() + TRANSFORM_DATA_LEN);
1031     windowinfo.transform = transformData;
1032     return windowinfo;
1033 }
1034 
operator ==(const SecRectInfo & a,const SecRectInfo & b)1035 bool operator==(const SecRectInfo& a, const SecRectInfo& b)
1036 {
1037     return (a.relativeCoords == b.relativeCoords && a.scale == b.scale && a.anchor == b.anchor);
1038 }
1039 
operator !=(const SecRectInfo & a,const SecRectInfo & b)1040 bool operator!=(const SecRectInfo& a, const SecRectInfo& b)
1041 {
1042     return !(a == b);
1043 }
1044 
operator ==(const SecSurfaceInfo & a,const SecSurfaceInfo & b)1045 bool operator==(const SecSurfaceInfo& a, const SecSurfaceInfo& b)
1046 {
1047     return (a.uiExtensionRectInfo == b.uiExtensionRectInfo && a.hostPid == b.hostPid &&
1048         a.uiExtensionNodeId == b.uiExtensionNodeId && a.uiExtensionPid == b.uiExtensionPid &&
1049         a.hostNodeId == b.hostNodeId && a.upperNodes == b.upperNodes);
1050 }
1051 
DumpUpperNodes(std::ostringstream & dumpSecSurfaceStream,const std::vector<SecRectInfo> & upperNodes)1052 static void DumpUpperNodes(std::ostringstream& dumpSecSurfaceStream, const std::vector<SecRectInfo>& upperNodes)
1053 {
1054     if (upperNodes.size() == 0) {
1055         return;
1056     }
1057 
1058     std::unordered_map<std::string, uint32_t> secRectInfoMap;
1059     std::vector<std::string> secRectInfoList;
1060     for (const auto& secRectInfo : upperNodes) {
1061         auto infoStr = DumpSecRectInfo(secRectInfo);
1062         if (secRectInfoMap.find(infoStr) != secRectInfoMap.end()) {
1063             secRectInfoMap[infoStr] += 1;
1064             continue;
1065         }
1066         secRectInfoMap.insert(std::pair<std::string, uint32_t>(infoStr, 1));
1067         secRectInfoList.push_back(infoStr);
1068     }
1069     for (auto& info : secRectInfoList) {
1070         auto it = secRectInfoMap.find(info);
1071         if (it == secRectInfoMap.end()) {
1072             continue;
1073         }
1074 
1075         dumpSecSurfaceStream << "," << info;
1076         if (it->second != 1) {
1077             dumpSecSurfaceStream << "|" << it->second;
1078         }
1079     }
1080 }
1081 
DumpSecSurfaceInfoMap(const std::map<uint64_t,std::vector<SecSurfaceInfo>> & secSurfaceInfoMap)1082 void DumpSecSurfaceInfoMap(const std::map<uint64_t, std::vector<SecSurfaceInfo>>& secSurfaceInfoMap)
1083 {
1084     std::ostringstream dumpSecSurfaceStream;
1085     dumpSecSurfaceStream << "DumpSecSurface map:" << secSurfaceInfoMap.size();
1086     bool isStart = false;
1087     for (auto& e : secSurfaceInfoMap) {
1088         if (isStart) {
1089             dumpSecSurfaceStream << ";{";
1090         } else {
1091             dumpSecSurfaceStream << "{";
1092         }
1093         auto hostNodeId = e.first;
1094         dumpSecSurfaceStream << "id:" << hostNodeId << ";list:" << e.second.size();
1095         for (const auto& secSurfaceInfo : e.second) {
1096             auto surfaceInfoStr = DumpSecSurfaceInfo(secSurfaceInfo);
1097             auto rectInfoStr = DumpSecRectInfo(secSurfaceInfo.uiExtensionRectInfo);
1098             dumpSecSurfaceStream << ";{" << surfaceInfoStr << ";" << rectInfoStr;
1099             DumpUpperNodes(dumpSecSurfaceStream, secSurfaceInfo.upperNodes);
1100             dumpSecSurfaceStream << "}";
1101         }
1102         isStart = true;
1103         dumpSecSurfaceStream << "}";
1104     }
1105     TLOGND(WmsLogTag::WMS_EVENT, "DumpSecSurface desc:map size{id;list;{secSurfaceInfo:"
1106         "hostPid|uiExtensionPid|hostNodeId|uiExtensionNodeId;secRectInfo:"
1107         "[x,y,width,height]|scalex|scaley|anchorx|anchory|[repet num];[upperNodes same as secRectInfo]}}");
1108     TLOGNI(WmsLogTag::WMS_EVENT, "%{public}s", dumpSecSurfaceStream.str().c_str());
1109 }
1110 
UpdateSecSurfaceInfo(const std::map<uint64_t,std::vector<SecSurfaceInfo>> & secSurfaceInfoMap)1111 void SceneSessionDirtyManager::UpdateSecSurfaceInfo(const std::map<uint64_t,
1112     std::vector<SecSurfaceInfo>>& secSurfaceInfoMap)
1113 {
1114     bool updateSecSurfaceInfoNeeded = false;
1115     {
1116         std::unique_lock<std::shared_mutex> lock(secSurfaceInfoMutex_);
1117         if (secSurfaceInfoMap_ != secSurfaceInfoMap) {
1118             secSurfaceInfoMap_ = secSurfaceInfoMap;
1119             updateSecSurfaceInfoNeeded = true;
1120         }
1121     }
1122     if (updateSecSurfaceInfoNeeded) {
1123         ResetFlushWindowInfoTask();
1124         DumpSecSurfaceInfoMap(secSurfaceInfoMap);
1125     }
1126 }
1127 
UpdateConstrainedModalUIExtInfo(const std::map<uint64_t,std::vector<SecSurfaceInfo>> & constrainedModalUIExtInfoMap)1128 void SceneSessionDirtyManager::UpdateConstrainedModalUIExtInfo(const std::map<uint64_t,
1129     std::vector<SecSurfaceInfo>>& constrainedModalUIExtInfoMap)
1130 {
1131     bool updateConstrainedModalUIExtInfoNeeded = false;
1132     {
1133         std::unique_lock<std::shared_mutex> lock(constrainedModalUIExtInfoMutex_);
1134         if (constrainedModalUIExtInfoMap_ != constrainedModalUIExtInfoMap) {
1135             constrainedModalUIExtInfoMap_ = constrainedModalUIExtInfoMap;
1136             updateConstrainedModalUIExtInfoNeeded = true;
1137         }
1138     }
1139     if (updateConstrainedModalUIExtInfoNeeded) {
1140         ResetFlushWindowInfoTask();
1141         DumpSecSurfaceInfoMap(constrainedModalUIExtInfoMap);
1142     }
1143 }
1144 
GetSecSurfaceWindowinfoList(const sptr<SceneSession> & sceneSession,const MMI::WindowInfo & hostWindowinfo,const Matrix3f & hostTransform) const1145 std::vector<MMI::WindowInfo> SceneSessionDirtyManager::GetSecSurfaceWindowinfoList(
1146     const sptr<SceneSession>& sceneSession, const MMI::WindowInfo& hostWindowinfo, const Matrix3f& hostTransform) const
1147 {
1148     if (sceneSession == nullptr) {
1149         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
1150         return {};
1151     }
1152     auto surfaceNodeId = sceneSession->GetSurfaceNodeId();
1153     if (!surfaceNodeId) {
1154         TLOGD(WmsLogTag::WMS_EVENT, "surfaceNodeId not found");
1155         return {};
1156     }
1157     std::vector<SecSurfaceInfo> secSurfaceInfoList;
1158     {
1159         std::shared_lock<std::shared_mutex> lock(secSurfaceInfoMutex_);
1160         auto iter = secSurfaceInfoMap_.find(*surfaceNodeId);
1161         if (iter == secSurfaceInfoMap_.end()) {
1162             return {};
1163         }
1164         secSurfaceInfoList = iter->second;
1165     }
1166     std::vector<MMI::WindowInfo> windowinfoList;
1167     int seczOrder = 0;
1168     MMI::WindowInfo windowinfo;
1169     for (const auto& secSurfaceInfo : secSurfaceInfoList) {
1170         windowinfo = GetSecComponentWindowInfo(secSurfaceInfo, hostWindowinfo, sceneSession, hostTransform);
1171         windowinfo.zOrder = seczOrder++;
1172         windowinfoList.emplace_back(windowinfo);
1173         windowinfo = GetHostComponentWindowInfo(secSurfaceInfo, hostWindowinfo, hostTransform);
1174         windowinfo.zOrder = seczOrder++;
1175         windowinfoList.emplace_back(windowinfo);
1176     }
1177     return windowinfoList;
1178 }
1179 } //namespace OHOS::Rosen
1180