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