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