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