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