• 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/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 
ConvertDegreeToMMIRotation(float degree,MMI::DisplayMode displayMode)47 MMI::Direction ConvertDegreeToMMIRotation(float degree, MMI::DisplayMode displayMode)
48 {
49     MMI::Direction rotation = MMI::DIRECTION0;
50     if (NearEqual(degree, DIRECTION0)) {
51         rotation = MMI::DIRECTION0;
52     }
53     if (NearEqual(degree, DIRECTION90)) {
54         rotation = MMI::DIRECTION90;
55     }
56     if (NearEqual(degree, DIRECTION180)) {
57         rotation = MMI::DIRECTION180;
58     }
59     if (NearEqual(degree, DIRECTION270)) {
60         rotation = MMI::DIRECTION270;
61     }
62     if ((displayMode == MMI::DisplayMode::FULL && g_screenRotationOffset != 0) ||
63         (displayMode == MMI::DisplayMode::MAIN && FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice())) {
64         switch (rotation) {
65             case MMI::DIRECTION0:
66                 rotation = MMI::DIRECTION90;
67                 break;
68             case MMI::DIRECTION90:
69                 rotation = MMI::DIRECTION180;
70                 break;
71             case MMI::DIRECTION180:
72                 rotation = MMI::DIRECTION270;
73                 break;
74             case MMI::DIRECTION270:
75                 rotation = MMI::DIRECTION0;
76                 break;
77             default:
78                 rotation = MMI::DIRECTION0;
79                 break;
80         }
81     }
82     return rotation;
83 }
84 
CmpMMIWindowInfo(const MMI::WindowInfo & a,const MMI::WindowInfo & b)85 bool CmpMMIWindowInfo(const MMI::WindowInfo& a, const MMI::WindowInfo& b)
86 {
87     return a.defaultHotAreas.size() > b.defaultHotAreas.size();
88 }
89 
CalRotationToTranslate(const MMI::Direction & displayRotation,float width,float height,const Vector2f & offset,float & rotate)90 Vector2f CalRotationToTranslate(const MMI::Direction& displayRotation, float width, float height,
91     const Vector2f& offset, float& rotate)
92 {
93     Vector2f translate = offset;
94     switch (displayRotation) {
95         case MMI::DIRECTION0: {
96             break;
97         }
98         case MMI::DIRECTION270: {
99             translate.x_ = offset.y_;
100             translate.y_ = height - offset.x_;
101             rotate = -M_PI_2;
102             break;
103         }
104         case MMI::DIRECTION180:
105             translate.x_ = width - offset.x_;
106             translate.y_ = height - offset.y_;
107             rotate = M_PI;
108             break;
109         case MMI::DIRECTION90: {
110             translate.x_ = width - offset.y_;
111             translate.y_ = offset.x_;
112             rotate = M_PI_2;
113             break;
114         }
115         default:
116             break;
117     }
118     return translate;
119 }
120 
CalNotRotateTransform(const sptr<SceneSession> & sceneSession,Matrix3f & transform,bool useUIExtension) const121 void SceneSessionDirtyManager::CalNotRotateTransform(const sptr<SceneSession>& sceneSession, Matrix3f& transform,
122     bool useUIExtension) const
123 {
124     if (sceneSession == nullptr) {
125         WLOGFE("sceneSession is nullptr");
126         return;
127     }
128     auto sessionProperty = sceneSession->GetSessionProperty();
129     if (sessionProperty == nullptr) {
130         WLOGFE("sessionProperty is nullptr");
131         return;
132     }
133     auto displayId = sessionProperty->GetDisplayId();
134     auto displayMode = Rosen::ScreenSessionManagerClient::GetInstance().GetFoldDisplayMode();
135     std::map<ScreenId, ScreenProperty> screensProperties =
136         Rosen::ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
137     if (screensProperties.find(displayId) == screensProperties.end()) {
138         return;
139     }
140     auto screenProperty = screensProperties[displayId];
141     MMI::Direction displayRotation = ConvertDegreeToMMIRotation(screenProperty.GetRotation(),
142         static_cast<MMI::DisplayMode>(displayMode));
143     float width = screenProperty.GetBounds().rect_.GetWidth();
144     float height = screenProperty.GetBounds().rect_.GetHeight();
145     Vector2f scale(sceneSession->GetScaleX(), sceneSession->GetScaleY());
146     Vector2f offset = sceneSession->GetSessionGlobalPosition(useUIExtension);
147     float rotate = 0.0f;
148     Vector2f translate = CalRotationToTranslate(displayRotation, width, height, offset, rotate);
149     transform = transform.Translate(translate).Rotate(rotate).Scale(scale, sceneSession->GetPivotX(),
150         sceneSession->GetPivotY());
151     transform = transform.Inverse();
152 }
153 
CalTransform(const sptr<SceneSession> & sceneSession,Matrix3f & transform,bool useUIExtension) const154 void SceneSessionDirtyManager::CalTransform(const sptr<SceneSession>& sceneSession, Matrix3f& transform,
155     bool useUIExtension) const
156 {
157     if (sceneSession == nullptr) {
158         WLOGFE("sceneSession is nullptr");
159         return;
160     }
161     transform = Matrix3f::IDENTITY;
162     bool isRotate = sceneSession->GetSessionInfo().isRotable_;
163     auto displayMode = Rosen::ScreenSessionManagerClient::GetInstance().GetFoldDisplayMode();
164     if (isRotate || !sceneSession->GetSessionInfo().isSystem_ ||
165         static_cast<MMI::DisplayMode>(displayMode) == MMI::DisplayMode::FULL ||
166         (static_cast<MMI::DisplayMode>(displayMode) == MMI::DisplayMode::MAIN &&
167          FoldScreenStateInternel::IsSingleDisplayPocketFoldDevice())) {
168         Vector2f scale(sceneSession->GetScaleX(), sceneSession->GetScaleY());
169         Vector2f translate = sceneSession->GetSessionGlobalPosition(useUIExtension);
170         transform = transform.Translate(translate);
171         transform = transform.Scale(scale, sceneSession->GetPivotX(), sceneSession->GetPivotY());
172         transform = transform.Inverse();
173         return;
174     }
175     CalNotRotateTransform(sceneSession, transform, useUIExtension);
176 }
177 
178 
UpdateDefaultHotAreas(sptr<SceneSession> sceneSession,std::vector<MMI::Rect> & touchHotAreas,std::vector<MMI::Rect> & pointerHotAreas) const179 void SceneSessionDirtyManager::UpdateDefaultHotAreas(sptr<SceneSession> sceneSession,
180     std::vector<MMI::Rect>& touchHotAreas,
181     std::vector<MMI::Rect>& pointerHotAreas) const
182 {
183     if (sceneSession == nullptr) {
184         WLOGFE("sceneSession is nullptr");
185         return;
186     }
187     WSRect windowRect = sceneSession->GetSessionGlobalRect();
188     uint32_t touchOffset = 0;
189     uint32_t pointerOffset = 0;
190     bool isMidScene = sceneSession->GetIsMidScene();
191     bool isAppMainWindowOrPip = sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
192                                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_PIP;
193     if (isAppMainWindowOrPip && !isMidScene) {
194         float vpr = 1.5f; // 1.5: default vp
195         auto sessionProperty = sceneSession->GetSessionProperty();
196         if (sessionProperty != nullptr) {
197             auto displayId = sessionProperty->GetDisplayId();
198             auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
199             if (screenSession != nullptr) {
200                 vpr = screenSession->GetScreenProperty().GetDensity();
201             }
202         }
203         touchOffset = static_cast<uint32_t>(HOTZONE_TOUCH * vpr);
204         pointerOffset = static_cast<uint32_t>(HOTZONE_POINTER * vpr);
205     }
206 
207     MMI::Rect touchRect = {
208         .x = -touchOffset,
209         .y = -touchOffset,
210         .width = windowRect.width_ + static_cast<int32_t>(touchOffset * 2),  // 2 : double touchOffset
211         .height = windowRect.height_ + static_cast<int32_t>(touchOffset * 2) // 2 : double touchOffset
212     };
213 
214     MMI::Rect pointerRect = {
215         .x = -pointerOffset,
216         .y = -pointerOffset,
217         .width = windowRect.width_ + static_cast<int32_t>(pointerOffset * 2),  // 2 : double pointerOffset
218         .height = windowRect.height_ + static_cast<int32_t>(pointerOffset * 2) // 2 : double pointerOffset
219     };
220 
221     touchHotAreas.emplace_back(touchRect);
222     pointerHotAreas.emplace_back(pointerRect);
223 }
224 
UpdateHotAreas(sptr<SceneSession> sceneSession,std::vector<MMI::Rect> & touchHotAreas,std::vector<MMI::Rect> & pointerHotAreas) const225 void SceneSessionDirtyManager::UpdateHotAreas(sptr<SceneSession> sceneSession, std::vector<MMI::Rect>& touchHotAreas,
226     std::vector<MMI::Rect>& pointerHotAreas) const
227 {
228     if (sceneSession == nullptr) {
229         WLOGFE("sceneSession is nullptr");
230         return;
231     }
232     WSRect windowRect = sceneSession->GetSessionGlobalRect();
233     const std::vector<Rect>& hotAreas = sceneSession->GetTouchHotAreas();
234     for (auto area : hotAreas) {
235         MMI::Rect rect;
236         rect.x = area.posX_;
237         rect.y = area.posY_;
238         rect.width = static_cast<int32_t>(area.width_);
239         rect.height = static_cast<int32_t>(area.height_);
240         auto iter = std::find_if(touchHotAreas.begin(), touchHotAreas.end(),
241             [&rect](const MMI::Rect& var) { return rect == var; });
242         if (iter != touchHotAreas.end()) {
243             continue;
244         }
245         touchHotAreas.emplace_back(rect);
246         pointerHotAreas.emplace_back(rect);
247         if (touchHotAreas.size() == static_cast<uint32_t>(MMI::WindowInfo::MAX_HOTAREA_COUNT)) {
248             auto sessionid = sceneSession->GetWindowId();
249             WLOGFE("id = %{public}d hotAreas size > %{public}d", sessionid, static_cast<int>(hotAreas.size()));
250             break;
251         }
252     }
253     if (touchHotAreas.empty()) {
254         return UpdateDefaultHotAreas(sceneSession, touchHotAreas, pointerHotAreas);
255     }
256 }
257 
AddDialogSessionMapItem(const sptr<SceneSession> & session,std::map<int32_t,sptr<SceneSession>> & dialogMap)258 static void AddDialogSessionMapItem(const sptr<SceneSession>& session,
259     std::map<int32_t, sptr<SceneSession>>& dialogMap)
260 {
261     const auto& mainSession = session->GetMainSession();
262     if (mainSession == nullptr) {
263         return;
264     }
265     bool isTopmostModalSubWindow = false;
266     const auto& property = session->GetSessionProperty();
267     if (property != nullptr && property->IsTopmost()) {
268         isTopmostModalSubWindow = true;
269     }
270     if (auto iter = dialogMap.find(mainSession->GetPersistentId());
271         iter != dialogMap.end() && iter->second != nullptr) {
272         auto& targetSession = iter->second;
273         if (targetSession->GetSessionProperty() &&
274             targetSession->GetSessionProperty()->IsTopmost() &&
275             !isTopmostModalSubWindow) {
276             return;
277         }
278         if (targetSession->GetZOrder() > session->GetZOrder()) {
279             return;
280         }
281     }
282     dialogMap[mainSession->GetPersistentId()] = session;
283     TLOGD(WmsLogTag::WMS_DIALOG, "Add dialog session, id: %{public}d, mainSessionId: %{public}d",
284         session->GetPersistentId(), mainSession->GetPersistentId());
285 }
286 
GetDialogSessionMap(const std::map<int32_t,sptr<SceneSession>> & sessionMap) const287 std::map<int32_t, sptr<SceneSession>> SceneSessionDirtyManager::GetDialogSessionMap(
288     const std::map<int32_t, sptr<SceneSession>>& sessionMap) const
289 {
290     std::map<int32_t, sptr<SceneSession>> dialogMap;
291     for (const auto& elem: sessionMap) {
292         const auto& session = elem.second;
293         if (session == nullptr || session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
294             continue;
295         }
296         bool isModalSubWindow = false;
297         const auto& property = session->GetSessionProperty();
298         if (property != nullptr) {
299             isModalSubWindow = WindowHelper::IsModalSubWindow(property->GetWindowType(), property->GetWindowFlags());
300         }
301         if (isModalSubWindow || session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
302             AddDialogSessionMapItem(session, dialogMap);
303         }
304     }
305     return dialogMap;
306 }
307 
IsFilterSession(const sptr<SceneSession> & sceneSession) const308 bool SceneSessionDirtyManager::IsFilterSession(const sptr<SceneSession>& sceneSession) const
309 {
310     if (sceneSession == nullptr) {
311         return true;
312     }
313 
314     if (sceneSession->IsSystemInput()) {
315         return false;
316     } else if (sceneSession->IsSystemSession() && sceneSession->IsVisible() && sceneSession->IsSystemActive()) {
317         return false;
318     }
319     if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(sceneSession)) {
320         return true;
321     }
322     return false;
323 }
324 
NotifyWindowInfoChange(const sptr<SceneSession> & sceneSession,const WindowUpdateType & type,const bool startMoving)325 void SceneSessionDirtyManager::NotifyWindowInfoChange(const sptr<SceneSession>& sceneSession,
326     const WindowUpdateType& type, const bool startMoving)
327 {
328     if (sceneSession == nullptr) {
329         WLOGFW("sceneSession is null");
330         return;
331     }
332 
333     if (type == WindowUpdateType::WINDOW_UPDATE_ADDED || type == WindowUpdateType::WINDOW_UPDATE_REMOVED||
334         type == WindowUpdateType::WINDOW_UPDATE_ACTIVE) {
335             WLOGFD("[EventDispatch] wid = %{public}d, winType = %{public}d",
336                 sceneSession->GetWindowId(), static_cast<int>(type));
337     }
338     ResetFlushWindowInfoTask();
339 }
340 
ResetFlushWindowInfoTask()341 void SceneSessionDirtyManager::ResetFlushWindowInfoTask()
342 {
343     sessionDirty_.store(true);
344     bool hasPostTask = false;
345     if (hasPostTask_.compare_exchange_strong(hasPostTask, true)) {
346         auto task = [this]() {
347             hasPostTask_.store(false);
348             if (!sessionDirty_.load() || flushWindowInfoCallback_ == nullptr) {
349                 return;
350             }
351             flushWindowInfoCallback_();
352         };
353         SceneSessionManager::GetInstance().PostFlushWindowInfoTask(task,
354             UPDATE_WINDOW_INFO_TASK, UPDATE_TASK_DURATION);
355     }
356 }
357 
AddModalExtensionWindowInfo(std::vector<MMI::WindowInfo> & windowInfoList,MMI::WindowInfo windowInfo,const sptr<SceneSession> & sceneSession)358 void SceneSessionDirtyManager::AddModalExtensionWindowInfo(std::vector<MMI::WindowInfo>& windowInfoList,
359     MMI::WindowInfo windowInfo, const sptr<SceneSession>& sceneSession)
360 {
361     if (sceneSession == nullptr) {
362         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
363         return;
364     }
365 
366     auto extensionInfo = sceneSession->GetLastModalUIExtensionEventInfo();
367     windowInfo.id = extensionInfo.persistentId;
368     if (extensionInfo.windowRect.width_ != 0 || extensionInfo.windowRect.height_ != 0) {
369         MMI::Rect windowRect = {
370             .x = extensionInfo.windowRect.posX_,
371             .y = extensionInfo.windowRect.posY_,
372             .width = extensionInfo.windowRect.width_,
373             .height = extensionInfo.windowRect.height_
374         };
375         windowInfo.area =  windowRect;
376         std::vector<MMI::Rect> touchHotAreas;
377         MMI::Rect touchRect = {
378             .x = 0,
379             .y = 0,
380             .width = extensionInfo.windowRect.width_,
381             .height = extensionInfo.windowRect.height_
382         };
383         touchHotAreas.emplace_back(touchRect);
384         windowInfo.defaultHotAreas = touchHotAreas;
385         windowInfo.pointerHotAreas = touchHotAreas;
386         Matrix3f transform;
387         CalTransform(sceneSession, transform, true);
388         std::vector<float> transformData(transform.GetData(), transform.GetData() + TRANSFORM_DATA_LEN);
389         windowInfo.transform = transformData;
390     }
391 
392     windowInfo.agentWindowId = extensionInfo.persistentId;
393     windowInfo.pid = extensionInfo.pid;
394     std::vector<int32_t> pointerChangeAreas(POINTER_CHANGE_AREA_COUNT, 0);
395     windowInfo.pointerChangeAreas = pointerChangeAreas;
396     windowInfo.zOrder = windowInfo.zOrder + ZORDER_UIEXTENSION_INDEX;
397 
398     windowInfoList.emplace_back(windowInfo);
399 }
400 
GetFullWindowInfoList()401 auto SceneSessionDirtyManager::GetFullWindowInfoList() ->
402 std::pair<std::vector<MMI::WindowInfo>, std::vector<std::shared_ptr<Media::PixelMap>>>
403 {
404     std::vector<MMI::WindowInfo> windowInfoList;
405     std::vector<std::shared_ptr<Media::PixelMap>> pixelMapList;
406     const auto sceneSessionMap = Rosen::SceneSessionManager::GetInstance().GetSceneSessionMap();
407     // all input event should trans to dialog window if dialog exists
408     const auto dialogMap = GetDialogSessionMap(sceneSessionMap);
409     uint32_t maxHotAreasNum = 0;
410     for (const auto& sceneSessionValuePair : sceneSessionMap) {
411         const auto& sceneSessionValue = sceneSessionValuePair.second;
412         if (sceneSessionValue == nullptr) {
413             continue;
414         }
415         WLOGFD("[EventDispatch] FullSceneSessionInfoUpdate windowName = %{public}s bundleName = %{public}s"
416             " windowId = %{public}d activeStatus = %{public}d", sceneSessionValue->GetWindowName().c_str(),
417             sceneSessionValue->GetSessionInfo().bundleName_.c_str(), sceneSessionValue->GetWindowId(),
418             sceneSessionValue->GetForegroundInteractiveStatus());
419         auto [windowInfo, pixelMap] = GetWindowInfo(sceneSessionValue, WindowAction::WINDOW_ADD);
420         auto iter = (sceneSessionValue->GetMainSessionId() == INVALID_SESSION_ID) ?
421             dialogMap.find(sceneSessionValue->GetPersistentId()) :
422             dialogMap.find(sceneSessionValue->GetMainSessionId());
423         if (iter != dialogMap.end() && iter->second != nullptr &&
424             sceneSessionValue->GetPersistentId() != iter->second->GetPersistentId() &&
425             iter->second->GetZOrder() > sceneSessionValue->GetZOrder()) {
426             windowInfo.agentWindowId = static_cast<int32_t>(iter->second->GetPersistentId());
427             windowInfo.pid = static_cast<int32_t>(iter->second->GetCallingPid());
428         } else if (sceneSessionValue->HasModalUIExtension()) {
429             AddModalExtensionWindowInfo(windowInfoList, windowInfo, sceneSessionValue);
430         }
431         TLOGD(WmsLogTag::WMS_EVENT, "windowId = %{public}d, agentWindowId = %{public}d, zOrder = %{public}f",
432             windowInfo.id, windowInfo.agentWindowId, windowInfo.zOrder);
433         windowInfoList.emplace_back(windowInfo);
434         pixelMapList.emplace_back(pixelMap);
435         // set the number of hot areas to the maximum number of hot areas when it exceeds the maximum number
436         // to avoid exceeding socket buff limits
437         if (windowInfo.defaultHotAreas.size() > maxHotAreasNum) {
438             maxHotAreasNum = windowInfo.defaultHotAreas.size();
439         }
440     }
441     if (maxHotAreasNum > MMI::WindowInfo::DEFAULT_HOTAREA_COUNT) {
442         std::sort(windowInfoList.begin(), windowInfoList.end(), CmpMMIWindowInfo);
443     }
444     return {windowInfoList, pixelMapList};
445 }
446 
UpdatePointerAreas(sptr<SceneSession> sceneSession,std::vector<int32_t> & pointerChangeAreas) const447 void SceneSessionDirtyManager::UpdatePointerAreas(sptr<SceneSession> sceneSession,
448     std::vector<int32_t>& pointerChangeAreas) const
449 {
450     if (!sceneSession) {
451         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is null");
452         return;
453     }
454     auto sessionProperty = sceneSession->GetSessionProperty();
455     if (!sessionProperty) {
456         TLOGE(WmsLogTag::WMS_EVENT, "sessionProperty is null");
457         return;
458     }
459     bool dragEnabled = sessionProperty->GetDragEnabled();
460     if (dragEnabled) {
461         float vpr = 1.5f; // 1.5: default vp
462         auto displayId = sessionProperty->GetDisplayId();
463         auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
464         if (screenSession != nullptr) {
465             vpr = screenSession->GetScreenProperty().GetDensity();
466         }
467         int32_t pointerAreaFivePx = static_cast<int32_t>(POINTER_CHANGE_AREA_FIVE * vpr);
468         int32_t pointerAreaSixteenPx = static_cast<int32_t>(POINTER_CHANGE_AREA_SIXTEEN * vpr);
469         if (sceneSession->GetSessionInfo().isSetPointerAreas_) {
470             pointerChangeAreas = {POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT,
471                 POINTER_CHANGE_AREA_DEFAULT, pointerAreaFivePx, pointerAreaSixteenPx,
472                 pointerAreaFivePx, pointerAreaSixteenPx, pointerAreaFivePx};
473             return;
474         }
475         auto limits = sessionProperty->GetWindowLimits();
476         if (limits.minWidth_ == limits.maxWidth_ && limits.minHeight_ != limits.maxHeight_) {
477             pointerChangeAreas = {POINTER_CHANGE_AREA_DEFAULT, pointerAreaFivePx,
478                 POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT,
479                 pointerAreaFivePx, POINTER_CHANGE_AREA_DEFAULT,  POINTER_CHANGE_AREA_DEFAULT};
480         } else if (limits.minWidth_ != limits.maxWidth_ && limits.minHeight_ == limits.maxHeight_) {
481             pointerChangeAreas = {POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT,
482                 POINTER_CHANGE_AREA_DEFAULT, pointerAreaFivePx, POINTER_CHANGE_AREA_DEFAULT,
483                 POINTER_CHANGE_AREA_DEFAULT, POINTER_CHANGE_AREA_DEFAULT, pointerAreaFivePx};
484         } else if (limits.minWidth_ != limits.maxWidth_ && limits.minHeight_ != limits.maxHeight_) {
485             pointerChangeAreas = {pointerAreaSixteenPx, pointerAreaFivePx,
486                 pointerAreaSixteenPx, pointerAreaFivePx, pointerAreaSixteenPx,
487                 pointerAreaFivePx, pointerAreaSixteenPx, pointerAreaFivePx};
488         }
489     } else {
490         WLOGFD("UpdatePointerAreas sceneSession is: %{public}d dragEnabled is false", sceneSession->GetPersistentId());
491     }
492 }
493 
UpdatePrivacyMode(const sptr<SceneSession> & sceneSession,MMI::WindowInfo & windowInfo) const494 void SceneSessionDirtyManager::UpdatePrivacyMode(const sptr<SceneSession>& sceneSession,
495     MMI::WindowInfo& windowInfo) const
496 {
497     if (sceneSession == nullptr) {
498         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
499         return;
500     }
501     windowInfo.privacyMode = MMI::SecureFlag::DEFAULT_MODE;
502     sptr<WindowSessionProperty> windowSessionProperty = sceneSession->GetSessionProperty();
503     if (windowSessionProperty == nullptr) {
504         TLOGE(WmsLogTag::WMS_EVENT, "windowSessionProperty is nullptr");
505         return;
506     }
507     if (windowSessionProperty->GetPrivacyMode() || windowSessionProperty->GetSystemPrivacyMode() ||
508         sceneSession->GetCombinedExtWindowFlags().privacyModeFlag) {
509         windowInfo.privacyMode = MMI::SecureFlag::PRIVACY_MODE;
510     }
511 }
512 
UpdateWindowFlags(DisplayId displayId,const sptr<SceneSession> & sceneSession,MMI::WindowInfo & windowInfo) const513 void SceneSessionDirtyManager::UpdateWindowFlags(DisplayId displayId, const sptr<SceneSession>& sceneSession,
514     MMI::WindowInfo& windowInfo) const
515 {
516     windowInfo.flags = 0;
517     auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(displayId);
518     if (screenSession != nullptr) {
519         if (!screenSession->IsTouchEnabled() || !sceneSession->GetSystemTouchable() ||
520             !sceneSession->GetForegroundInteractiveStatus()) {
521             windowInfo.flags |= MMI::WindowInfo::FLAG_BIT_UNTOUCHABLE;
522         }
523     }
524 }
525 
GetWindowInfo(const sptr<SceneSession> & sceneSession,const SceneSessionDirtyManager::WindowAction & action) const526 std::pair<MMI::WindowInfo, std::shared_ptr<Media::PixelMap>> SceneSessionDirtyManager::GetWindowInfo(
527     const sptr<SceneSession>& sceneSession, const SceneSessionDirtyManager::WindowAction& action) const
528 {
529     if (sceneSession == nullptr) {
530         WLOGFE("sceneSession is nullptr");
531         return {};
532     }
533     sptr<WindowSessionProperty> windowSessionProperty = sceneSession->GetSessionProperty();
534     if (windowSessionProperty == nullptr) {
535         TLOGE(WmsLogTag::WMS_EVENT, "GetSessionProperty is nullptr");
536         return {};
537     }
538     Matrix3f transform;
539     WSRect windowRect = sceneSession->GetSessionGlobalRect();
540     auto pid = sceneSession->GetCallingPid();
541     auto uid = sceneSession->GetCallingUid();
542     auto windowId = sceneSession->GetWindowId();
543     auto displayId = windowSessionProperty->GetDisplayId();
544     CalTransform(sceneSession, transform);
545     std::vector<float> transformData(transform.GetData(), transform.GetData() + TRANSFORM_DATA_LEN);
546 
547     auto agentWindowId = sceneSession->GetWindowId();
548     auto zOrder = sceneSession->GetZOrder();
549     std::vector<int32_t> pointerChangeAreas(POINTER_CHANGE_AREA_COUNT, 0);
550     auto windowMode = windowSessionProperty->GetWindowMode();
551     auto maxMode = windowSessionProperty->GetMaximizeMode();
552     WindowType windowType = windowSessionProperty->GetWindowType();
553     bool isMainWindow = Rosen::WindowHelper::IsMainWindow(windowType);
554     bool isDecorDialog = Rosen::WindowHelper::IsDialogWindow(windowType) && windowSessionProperty->IsDecorEnable();
555     bool isDecorSubWindow = WindowHelper::IsSubWindow(windowType) && windowSessionProperty->IsDecorEnable();
556     if ((windowMode == Rosen::WindowMode::WINDOW_MODE_FLOATING &&
557         (isMainWindow || isDecorDialog || isDecorSubWindow) &&
558         maxMode != Rosen::MaximizeMode::MODE_AVOID_SYSTEM_BAR) || (sceneSession->GetSessionInfo().isSetPointerAreas_)) {
559             UpdatePointerAreas(sceneSession, pointerChangeAreas);
560     }
561     std::vector<MMI::Rect> touchHotAreas;
562     std::vector<MMI::Rect> pointerHotAreas;
563     UpdateHotAreas(sceneSession, touchHotAreas, pointerHotAreas);
564     auto pixelMap = windowSessionProperty->GetWindowMask();
565     MMI::WindowInfo windowInfo = {
566         .id = windowId,
567         .pid = sceneSession->IsStartMoving() ? static_cast<int32_t>(getpid()) : pid,
568         .uid = uid,
569         .area = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ },
570         .defaultHotAreas = touchHotAreas,
571         .pointerHotAreas = pointerHotAreas,
572         .agentWindowId = agentWindowId,
573         .action = static_cast<MMI::WINDOW_UPDATE_ACTION>(action),
574         .displayId = displayId,
575         .zOrder = zOrder,
576         .pointerChangeAreas = pointerChangeAreas,
577         .transform = transformData,
578         .pixelMap = pixelMap.get(),
579         .windowInputType = static_cast<MMI::WindowInputType>(sceneSession->GetSessionInfo().windowInputType_),
580         .windowType = static_cast<int32_t>(windowType),
581     };
582     UpdateWindowFlags(displayId, sceneSession, windowInfo);
583     if (windowSessionProperty->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_HANDWRITING)) {
584         windowInfo.flags |= MMI::WindowInfo::FLAG_BIT_HANDWRITING;
585     }
586     UpdatePrivacyMode(sceneSession, windowInfo);
587     windowInfo.uiExtentionWindowInfo = GetSecSurfaceWindowinfoList(sceneSession, windowInfo, transform);
588     return {windowInfo, pixelMap};
589 }
590 
RegisterFlushWindowInfoCallback(const FlushWindowInfoCallback && callback)591 void SceneSessionDirtyManager::RegisterFlushWindowInfoCallback(const FlushWindowInfoCallback &&callback)
592 {
593     flushWindowInfoCallback_ = std::move(callback);
594 }
595 
ResetSessionDirty()596 void SceneSessionDirtyManager::ResetSessionDirty()
597 {
598     sessionDirty_.store(false);
599 }
600 
DumpRect(const std::vector<MMI::Rect> & rects)601 std::string DumpRect(const std::vector<MMI::Rect>& rects)
602 {
603     std::string rectStr = "";
604     for (const auto& rect : rects) {
605         rectStr = rectStr + " hot : [ " + std::to_string(rect.x) +" , " + std::to_string(rect.y) +
606         " , " + std::to_string(rect.width) + " , " + std::to_string(rect.height) + "]";
607     }
608     return rectStr;
609 }
610 
DumpWindowInfo(const MMI::WindowInfo & info)611 std::string DumpWindowInfo(const MMI::WindowInfo& info)
612 {
613     std::string infoStr = "windowInfo:";
614     infoStr = infoStr + "windowId: " + std::to_string(info.id) + " pid : " + std::to_string(info.pid) +
615         " uid: " + std::to_string(info.uid) + " area: [ " + std::to_string(info.area.x) + " , " +
616         std::to_string(info.area.y) +  " , " + std::to_string(info.area.width) + " , " +
617         std::to_string(info.area.height) + "] agentWindowId:" + std::to_string(info.agentWindowId) + " flags:" +
618         std::to_string(info.flags)  +" displayId: " + std::to_string(info.displayId) +
619         " action: " + std::to_string(static_cast<int>(info.action)) + " zOrder: " + std::to_string(info.zOrder);
620     return infoStr + DumpRect(info.defaultHotAreas);
621 }
622 
DumpSecRectInfo(const SecRectInfo & secRectInfo)623 std::string DumpSecRectInfo(const SecRectInfo & secRectInfo)
624 {
625     std::string infoStr = " area: [ " + std::to_string(secRectInfo.relativeCoords.GetLeft()) + " , " +
626         std::to_string(secRectInfo.relativeCoords.GetTop()) +  " , " +
627         std::to_string(secRectInfo.relativeCoords.GetWidth()) + " , " +
628         std::to_string(secRectInfo.relativeCoords.GetHeight()) + "]" +
629         " scaleX:" + std::to_string(secRectInfo.scale[0]) + " scaleY:" + std::to_string(secRectInfo.scale[1]) +
630         " anchorX:" + std::to_string(secRectInfo.anchor[0]) + " anchorY:" + std::to_string(secRectInfo.anchor[1]);
631     return infoStr;
632 }
633 
DumpSecSurfaceInfo(const SecSurfaceInfo & secSurfaceInfo)634 std::string DumpSecSurfaceInfo(const SecSurfaceInfo& secSurfaceInfo)
635 {
636     std::string infoStr = "hostPid:" + std::to_string(secSurfaceInfo.hostPid) +
637         " uiExtensionPid:" + std::to_string(secSurfaceInfo.uiExtensionPid) +
638         " hostNodeId:" + std::to_string(secSurfaceInfo.hostNodeId) +
639         " uiExtensionNodeId:" + std::to_string(secSurfaceInfo.uiExtensionNodeId);
640     return infoStr;
641 }
642 
MakeWindowInfoFormHostWindow(const SecRectInfo & secRectInfo,const MMI::WindowInfo & hostWindowinfo) const643 MMI::WindowInfo SceneSessionDirtyManager::MakeWindowInfoFormHostWindow(const SecRectInfo& secRectInfo,
644     const MMI::WindowInfo& hostWindowinfo) const
645 {
646     MMI::WindowInfo windowinfo;
647     windowinfo.id = hostWindowinfo.id;
648     windowinfo.pid = hostWindowinfo.pid;
649     windowinfo.uid = hostWindowinfo.uid;
650     windowinfo.area = hostWindowinfo.area;
651     windowinfo.agentWindowId = hostWindowinfo.agentWindowId;
652     windowinfo.action = hostWindowinfo.action;
653     windowinfo.displayId = hostWindowinfo.displayId;
654     windowinfo.flags = hostWindowinfo.flags;
655     windowinfo.privacyMode = hostWindowinfo.privacyMode;
656     windowinfo.transform = hostWindowinfo.transform;
657     return windowinfo;
658 }
659 
CoordinateSystemHostWindowToScreen(const Matrix3f hostTransform,const SecRectInfo & secRectInfo)660 Matrix3f CoordinateSystemHostWindowToScreen(const Matrix3f hostTransform, const SecRectInfo& secRectInfo)
661 {
662     Matrix3f transform = Matrix3f::IDENTITY;
663     Vector2f translate(secRectInfo.relativeCoords.GetLeft(), secRectInfo.relativeCoords.GetTop());
664     transform = transform.Translate(translate);
665     Vector2f scale(secRectInfo.scale[0], secRectInfo.scale[1]);
666     transform = transform.Scale(scale, secRectInfo.anchor[0], secRectInfo.anchor[1]);
667     transform = hostTransform.Inverse() * transform;
668     return transform;
669 }
670 
CalRectInScreen(const Matrix3f & transform,const SecRectInfo & secRectInfo)671 MMI::Rect CalRectInScreen(const Matrix3f& transform, const SecRectInfo& secRectInfo)
672 {
673     auto topLeft = transform * Vector3f(0, 0, 1.0);
674     auto bottomRight = transform * Vector3f(secRectInfo.relativeCoords.GetWidth(),
675         secRectInfo.relativeCoords.GetHeight(), 1.0);
676     auto left = std::min(topLeft[0], bottomRight[0]);
677     auto top = std::min(topLeft[1], bottomRight[1]);
678     auto topLeftX = static_cast<int32_t>(topLeft[0]);
679     auto topLeftY = static_cast<int32_t>(topLeft[1]);
680     auto bottomRightX = static_cast<int32_t>(bottomRight[0]);
681     auto bottomRightY = static_cast<int32_t>(bottomRight[1]);
682     if ((topLeftX > 0 && bottomRightX < INT32_MIN + topLeftX) ||
683         (topLeftX < 0 && bottomRightX > INT32_MAX + topLeftX)) {
684         TLOGE(WmsLogTag::WMS_EVENT, "data overflows topLeftX:%{public}d bottomRightX:%{public}d",
685             topLeftX, bottomRightX);
686     }
687     if ((topLeftY > 0 && bottomRightY < INT32_MIN + topLeftY) ||
688         (topLeftY < 0 && bottomRightY > INT32_MAX + topLeftY)) {
689         TLOGE(WmsLogTag::WMS_EVENT, "data overflows topLeftY:%{public}d bottomRightY:%{public}d",
690             topLeftY, bottomRightY);
691     }
692     auto width = std::abs(topLeftX - bottomRightX);
693     auto height = std::abs(topLeftY - bottomRightY);
694     return MMI::Rect{ left, top, width, height};
695 }
696 
697 
GetHostComponentWindowInfo(const SecSurfaceInfo & secSurfaceInfo,const MMI::WindowInfo & hostWindowinfo,const Matrix3f hostTransform) const698 MMI::WindowInfo SceneSessionDirtyManager::GetHostComponentWindowInfo(const SecSurfaceInfo& secSurfaceInfo,
699     const MMI::WindowInfo& hostWindowinfo, const Matrix3f hostTransform) const
700 {
701     MMI::WindowInfo windowinfo;
702     const auto& secRectInfoList = secSurfaceInfo.upperNodes;
703     if (secRectInfoList.size() > 0) {
704         windowinfo = MakeWindowInfoFormHostWindow(secRectInfoList[0], hostWindowinfo);
705     }
706     for (const auto& secRectInfo : secRectInfoList) {
707         windowinfo.pid = secSurfaceInfo.hostPid;
708         MMI::Rect hotArea = { secRectInfo.relativeCoords.GetLeft(), secRectInfo.relativeCoords.GetTop(),
709             secRectInfo.relativeCoords.GetWidth(), secRectInfo.relativeCoords.GetHeight() };
710         windowinfo.defaultHotAreas.emplace_back(hotArea);
711         windowinfo.pointerHotAreas.emplace_back(hotArea);
712     }
713     return windowinfo;
714 }
715 
GetSecComponentWindowInfo(const SecSurfaceInfo & secSurfaceInfo,const MMI::WindowInfo & hostWindowinfo,const sptr<SceneSession> & sceneSession,const Matrix3f hostTransform) const716 MMI::WindowInfo SceneSessionDirtyManager::GetSecComponentWindowInfo(const SecSurfaceInfo& secSurfaceInfo,
717     const MMI::WindowInfo& hostWindowinfo, const sptr<SceneSession>& sceneSession, const Matrix3f hostTransform) const
718 {
719     if (sceneSession == nullptr) {
720         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
721         return {};
722     }
723     MMI::WindowInfo windowinfo;
724     const auto& secRectInfo = secSurfaceInfo.uiExtensionRectInfo;
725     windowinfo = MakeWindowInfoFormHostWindow(secRectInfo, hostWindowinfo);
726     windowinfo.id = sceneSession->GetUIExtPersistentIdBySurfaceNodeId(secSurfaceInfo.uiExtensionNodeId);
727     if (windowinfo.id == 0) {
728         TLOGE(WmsLogTag::WMS_EVENT, "GetUIExtPersistentId ERROR");
729         return {};
730     }
731     windowinfo.agentWindowId = windowinfo.id;
732     windowinfo.pid = secSurfaceInfo.uiExtensionPid;
733     windowinfo.privacyUIFlag = true;
734     auto transform = CoordinateSystemHostWindowToScreen(hostTransform, secRectInfo);
735     windowinfo.area = CalRectInScreen(transform, secRectInfo);
736     MMI::Rect hotArea = { 0, 0, secRectInfo.relativeCoords.GetWidth(), secRectInfo.relativeCoords.GetHeight() };
737     windowinfo.defaultHotAreas.emplace_back(hotArea);
738     windowinfo.pointerHotAreas.emplace_back(hotArea);
739     // 屏幕坐标系到控件坐标系转换
740     transform = transform.Inverse();
741     std::vector<float> transformData(transform.GetData(), transform.GetData() + TRANSFORM_DATA_LEN);
742     windowinfo.transform = transformData;
743     return windowinfo;
744 }
745 
operator ==(const SecRectInfo & a,const SecRectInfo & b)746 bool operator==(const SecRectInfo& a, const SecRectInfo& b)
747 {
748     return (a.relativeCoords == b.relativeCoords && a.scale == b.scale && a.anchor == b.anchor);
749 }
750 
operator !=(const SecRectInfo & a,const SecRectInfo & b)751 bool operator!=(const SecRectInfo& a, const SecRectInfo& b)
752 {
753     return !(a == b);
754 }
755 
operator ==(const SecSurfaceInfo & a,const SecSurfaceInfo & b)756 bool operator==(const SecSurfaceInfo& a, const SecSurfaceInfo& b)
757 {
758     return (a.uiExtensionRectInfo == b.uiExtensionRectInfo && a.hostPid == b.hostPid &&
759         a.uiExtensionNodeId == b.uiExtensionNodeId && a.uiExtensionPid == b.uiExtensionPid &&
760         a.hostNodeId == b.hostNodeId && a.upperNodes == b.upperNodes);
761 }
762 
DumpSecSurfaceInfoMap(const std::map<uint64_t,std::vector<SecSurfaceInfo>> & secSurfaceInfoMap)763 void DumpSecSurfaceInfoMap(const std::map<uint64_t, std::vector<SecSurfaceInfo>>& secSurfaceInfoMap)
764 {
765     TLOGI(WmsLogTag::WMS_EVENT, "secSurfaceInfoMap size:%{public}d", static_cast<int>(secSurfaceInfoMap.size()));
766     for (auto& e : secSurfaceInfoMap) {
767         auto hostNodeId = e.first;
768         TLOGI(WmsLogTag::WMS_EVENT, "hostNodeId:%{public}" PRIu64 " secSurfaceInfoList size:%{public}d",
769             hostNodeId, static_cast<int>(e.second.size()));
770         for (const auto& secSurfaceInfo : e.second) {
771             auto surfaceInfoStr = DumpSecSurfaceInfo(secSurfaceInfo);
772             auto rectInfoStr = DumpSecRectInfo(secSurfaceInfo.uiExtensionRectInfo);
773             TLOGI(WmsLogTag::WMS_EVENT, "secSurfaceInfo:%{public}s secRectInfo:%{public}s", surfaceInfoStr.c_str(),
774                 rectInfoStr.c_str());
775             for (const auto& secRectInfo : secSurfaceInfo.upperNodes) {
776                 auto infoStr = DumpSecRectInfo(secRectInfo);
777                 TLOGI(WmsLogTag::WMS_EVENT, "hostRectInfo:%{public}s", infoStr.c_str());
778             }
779         }
780     }
781 }
782 
UpdateSecSurfaceInfo(const std::map<uint64_t,std::vector<SecSurfaceInfo>> & secSurfaceInfoMap)783 void SceneSessionDirtyManager::UpdateSecSurfaceInfo(const std::map<uint64_t,
784     std::vector<SecSurfaceInfo>>& secSurfaceInfoMap)
785 {
786     std::unique_lock<std::shared_mutex> lock(secSurfaceInfoMutex_);
787     if (secSurfaceInfoMap.size() != secSurfaceInfoMap_.size() || secSurfaceInfoMap_ != secSurfaceInfoMap) {
788         secSurfaceInfoMap_ = secSurfaceInfoMap;
789         ResetFlushWindowInfoTask();
790         DumpSecSurfaceInfoMap(secSurfaceInfoMap_);
791     }
792 }
793 
GetSecSurfaceWindowinfoList(const sptr<SceneSession> & sceneSession,const MMI::WindowInfo & hostWindowinfo,const Matrix3f & hostTransform) const794 std::vector<MMI::WindowInfo> SceneSessionDirtyManager::GetSecSurfaceWindowinfoList(
795     const sptr<SceneSession>& sceneSession, const MMI::WindowInfo& hostWindowinfo, const Matrix3f& hostTransform) const
796 {
797     if (secSurfaceInfoMap_.size() == 0) {
798         return {};
799     }
800     if (sceneSession == nullptr) {
801         TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr");
802         return {};
803     }
804     auto surfaceNode = sceneSession->GetSurfaceNode();
805     if (surfaceNode == nullptr) {
806         TLOGE(WmsLogTag::WMS_EVENT, "surfaceNode is nullptr");
807         return {};
808     }
809     std::vector<SecSurfaceInfo> secSurfaceInfoList;
810     auto surfaceNodeId = surfaceNode->GetId();
811     {
812         std::shared_lock<std::shared_mutex> lock(secSurfaceInfoMutex_);
813         auto iter = secSurfaceInfoMap_.find(surfaceNodeId);
814         if (iter == secSurfaceInfoMap_.end()) {
815             return {};
816         }
817         secSurfaceInfoList = iter->second;
818     }
819     std::vector<MMI::WindowInfo> windowinfoList;
820     int seczOrder = 0;
821     MMI::WindowInfo windowinfo;
822     for (const auto& secSurfaceInfo : secSurfaceInfoList) {
823         windowinfo = GetSecComponentWindowInfo(secSurfaceInfo, hostWindowinfo, sceneSession, hostTransform);
824         windowinfo.zOrder = seczOrder++;
825         windowinfoList.emplace_back(windowinfo);
826         windowinfo = GetHostComponentWindowInfo(secSurfaceInfo, hostWindowinfo, hostTransform);
827         windowinfo.zOrder = seczOrder++;
828         windowinfoList.emplace_back(windowinfo);
829     }
830     return windowinfoList;
831 }
832 } //namespace OHOS::Rosen
833