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