• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "core/common/event_manager.h"
17 
18 #include "base/log/dump_log.h"
19 #include "base/thread/frame_trace_adapter.h"
20 #include "core/common/container.h"
21 #include "core/common/xcollie/xcollieInterface.h"
22 #include "core/components_ng/manager/select_overlay/select_overlay_manager.h"
23 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
24 #include "core/event/focus_axis_event.h"
25 
26 namespace OHOS::Ace {
27 constexpr int32_t DUMP_START_NUMBER = 4;
28 constexpr int32_t DUMP_LIMIT_SIZE = 500;
29 constexpr int64_t EVENT_CLEAR_DURATION = 1000;
30 constexpr int64_t TRANSLATE_NS_TO_MS = 1000000;
31 
TouchTest(const TouchEvent & touchPoint,const RefPtr<RenderNode> & renderNode,TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)32 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<RenderNode>& renderNode,
33     TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
34 {
35     ContainerScope scope(instanceId_);
36 
37     ACE_FUNCTION_TRACE();
38     CHECK_NULL_VOID(renderNode);
39     // first clean.
40     referee_->CleanGestureScope(touchPoint.id);
41     // collect
42     TouchTestResult hitTestResult;
43     const Point point { touchPoint.x, touchPoint.y, touchPoint.sourceType };
44     // For root node, the parent local point is the same as global point.
45     renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
46     if (needAppend) {
47 #ifdef OHOS_STANDARD_SYSTEM
48         for (auto entry = hitTestResult.begin(); entry != hitTestResult.end(); ++entry) {
49             if ((*entry)) {
50                 (*entry)->SetSubPipelineGlobalOffset(offset, viewScale);
51             }
52         }
53 #endif
54         TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
55         hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
56     }
57     touchTestResults_[touchPoint.id] = std::move(hitTestResult);
58 }
59 
TouchTest(const TouchEvent & touchPoint,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)60 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<NG::FrameNode>& frameNode,
61     TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
62 {
63     ContainerScope scope(instanceId_);
64 
65     ACE_FUNCTION_TRACE();
66     CHECK_NULL_VOID(frameNode);
67     if (!curAccessibilityHoverResults_.empty()) {
68         FalsifyHoverCancelEventAndDispatch(touchPoint);
69     }
70     // collect
71     TouchTestResult hitTestResult;
72     const NG::PointF point { touchPoint.x, touchPoint.y };
73     if (refereeNG_->CheckEventTypeChange(touchPoint.sourceType)) {
74         AxisEvent axisEvent;
75         FalsifyCancelEventAndDispatch(axisEvent);
76         responseCtrl_->Reset();
77         refereeNG_->CleanAll(true);
78         touchTestResults_.clear();
79         axisTouchTestResults_.clear();
80     }
81     refereeNG_->CheckSourceTypeChange(touchPoint.sourceType);
82     if (refereeNG_->QueryAllDone(touchPoint.id)) {
83         refereeNG_->CleanGestureScope(touchPoint.id);
84         if (touchTestResults_.empty() && refereeNG_->QueryAllDone()) {
85             innerEventWin_ = false;
86             responseCtrl_->Reset();
87             refereeNG_->CleanAll();
88         }
89     }
90     if (lastDownFingerNumber_ == 0 && refereeNG_->QueryAllDone()) {
91         FalsifyCancelEventAndDispatch(touchPoint);
92         refereeNG_->ForceCleanGestureReferee();
93         responseCtrl_->Reset();
94         refereeNG_->CleanAll();
95         CleanGestureEventHub();
96     }
97     ResponseLinkResult responseLinkResult;
98     // For root node, the parent local point is the same as global point.
99     frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, touchPoint.id, responseLinkResult);
100     TouchTestResult savePrevHitTestResult = touchTestResults_[touchPoint.id];
101     SetResponseLinkRecognizers(hitTestResult, responseLinkResult);
102     if (needAppend) {
103 #ifdef OHOS_STANDARD_SYSTEM
104         for (const auto& entry : hitTestResult) {
105             if (entry) {
106                 entry->SetSubPipelineGlobalOffset(offset, viewScale);
107             }
108         }
109 #endif
110         TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
111         hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
112     }
113     std::list<RefPtr<NG::NGGestureRecognizer>> hitTestRecognizers;
114     for (const auto& item : hitTestResult) {
115         auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(item);
116         if (recognizer) {
117             hitTestRecognizers.emplace_back(recognizer);
118         }
119     }
120     SetHittedFrameNode(hitTestRecognizers);
121     refereeNG_->AddGestureToScope(touchPoint.id, hitTestResult);
122     touchTestResults_[touchPoint.id] = std::move(hitTestResult);
123 
124     int64_t currentEventTime = static_cast<int64_t>(touchPoint.time.time_since_epoch().count());
125     int64_t lastEventTime = static_cast<int64_t>(lastEventTime_.time_since_epoch().count());
126     int64_t duration = static_cast<int64_t>((currentEventTime - lastEventTime) / TRANSLATE_NS_TO_MS);
127     if (duration >= EVENT_CLEAR_DURATION && !refereeNG_->IsReady()) {
128         TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "GestureReferee is not ready, force clean gestureReferee.");
129 #ifndef IS_RELEASE_VERSION
130         std::list<std::pair<int32_t, std::string>> dumpList;
131         eventTree_.Dump(dumpList, 0);
132         for (auto& item : dumpList) {
133             TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "EventTreeDumpInfo: " SEC_PLD(%{public}s) ".",
134                 SEC_PARAM(item.second.c_str()));
135         }
136 #endif
137         eventTree_.eventTreeList.clear();
138         FalsifyCancelEventAndDispatch(touchPoint);
139         refereeNG_->ForceCleanGestureReferee();
140         responseCtrl_->Reset();
141         refereeNG_->CleanAll();
142 
143         TouchTestResult reHitTestResult;
144         ResponseLinkResult reResponseLinkResult;
145         frameNode->TouchTest(point, point, point, touchRestrict,
146             reHitTestResult, touchPoint.id, reResponseLinkResult);
147         SetResponseLinkRecognizers(reHitTestResult, reResponseLinkResult);
148         if (!refereeNG_->IsReady()) {
149             TAG_LOGW(AceLogTag::ACE_INPUTTRACKING,
150                 "GestureReferee is contaminate by new comming recognizer, force clean gestureReferee.");
151             refereeNG_->ForceCleanGestureReferee();
152         }
153         if (needAppend) {
154 #ifdef OHOS_STANDARD_SYSTEM
155             for (const auto& entry : reHitTestResult) {
156                 if (entry) {
157                     entry->SetSubPipelineGlobalOffset(offset, viewScale);
158                 }
159             }
160 #endif
161             reHitTestResult.splice(reHitTestResult.end(), savePrevHitTestResult);
162         }
163         touchTestResults_[touchPoint.id] = std::move(reHitTestResult);
164         const auto& reTouchTestResult = touchTestResults_.find(touchPoint.id);
165         if (reTouchTestResult != touchTestResults_.end()) {
166             refereeNG_->AddGestureToScope(touchPoint.id, reTouchTestResult->second);
167         }
168     }
169 
170     auto container = Container::Current();
171     CHECK_NULL_VOID(container);
172     std::map<int32_t, NG::TouchTestResultInfo> touchTestResultInfo;
173     for (const auto& item : touchTestResults_[touchPoint.id]) {
174         auto node = item->GetAttachedNode().Upgrade();
175         if (!node) {
176             continue;
177         }
178         auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
179         if (!frameNode) {
180             continue;
181         }
182         touchTestResultInfo[frameNode->GetId()] = { frameNode->GetId(), frameNode->GetTag(),
183             frameNode->GetInspectorIdValue(""), frameNode->GetGeometryNode()->GetFrameRect().ToString(),
184             frameNode->GetDepth() };
185     }
186     std::string resultInfo = std::string("fingerId: ").append(std::to_string(touchPoint.id));
187     for (const auto& item : touchTestResultInfo) {
188         resultInfo.append("{ ").append("tag: ").append(item.second.tag);
189 #ifndef IS_RELEASE_VERSION
190         resultInfo.append(", inspectorId: ")
191             .append(item.second.inspectorId)
192             .append(", frameRect: ")
193             .append(item.second.frameRect);
194 #endif
195         resultInfo.append(", depth: ").append(std::to_string(item.second.depth)).append(" };");
196     }
197     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "InputTracking id:%{public}d, touch test hitted node info: %{public}s",
198         touchPoint.touchEventId, resultInfo.c_str());
199     if (touchTestResultInfo.empty()) {
200         TAG_LOGW(AceLogTag::ACE_INPUTKEYFLOW, "Touch test result is empty.");
201         std::list<std::pair<int32_t, std::string>> dumpList;
202         eventTree_.Dump(dumpList, 0, DUMP_START_NUMBER);
203         int32_t dumpCount = 0;
204         for ([[maybe_unused]] auto& item : dumpList) {
205             dumpCount++;
206             if (dumpCount > DUMP_LIMIT_SIZE) {
207                 TAG_LOGW(AceLogTag::ACE_INPUTTRACKING,
208                     "EventTreeDumpInfo size is over limit, the following info is dropped!");
209                 break;
210             }
211             TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "EventTreeDumpInfo: " SEC_PLD(%{public}s) ".",
212                 SEC_PARAM(item.second.c_str()));
213         }
214         RecordHitEmptyMessage(touchPoint, resultInfo, frameNode);
215     }
216     LogTouchTestResultRecognizers(touchTestResults_[touchPoint.id], touchPoint.touchEventId);
217 }
218 
RecordHitEmptyMessage(const TouchEvent & touchPoint,const std::string & resultInfo,const RefPtr<NG::FrameNode> & frameNode)219 void EventManager::RecordHitEmptyMessage(
220     const TouchEvent& touchPoint, const std::string& resultInfo, const RefPtr<NG::FrameNode>& frameNode)
221 {
222     auto hitEmptyMessage = JsonUtil::Create(true);
223     auto container = Container::Current();
224     CHECK_NULL_VOID(container);
225     uint32_t windowId = 0;
226 #ifdef WINDOW_SCENE_SUPPORTED
227     windowId = static_cast<uint32_t>(NG::WindowSceneHelper::GetWindowIdForWindowScene(frameNode));
228 #endif
229     if (windowId == 0) {
230         windowId = container->GetWindowId();
231     }
232     hitEmptyMessage->Put("windowId", static_cast<int32_t>(windowId));
233     auto pipelineContext = container->GetPipelineContext();
234     if (pipelineContext) {
235         auto window = pipelineContext->GetWindow();
236         if (window) {
237             hitEmptyMessage->Put("windowName", window->GetWindowName().c_str());
238         }
239     }
240     hitEmptyMessage->Put("resultInfo", resultInfo.c_str());
241     hitEmptyMessage->Put("x", touchPoint.x);
242     hitEmptyMessage->Put("y", touchPoint.y);
243     hitEmptyMessage->Put("currentTime", static_cast<int64_t>(touchPoint.time.time_since_epoch().count()));
244     hitEmptyMessage->Put("bundleName", container->GetBundleName().c_str());
245     auto frontEnd = container->GetFrontend();
246     if (frontEnd) {
247         hitEmptyMessage->Put("pageInfo", frontEnd->GetCurrentPageUrl().c_str());
248     }
249     XcollieInterface::GetInstance().TriggerTimerCount("HIT_EMPTY_WARNING", true, hitEmptyMessage->ToString());
250 }
251 
LogTouchTestResultRecognizers(const TouchTestResult & result,int32_t touchEventId)252 void EventManager::LogTouchTestResultRecognizers(const TouchTestResult& result, int32_t touchEventId)
253 {
254     std::map<std::string, std::list<NG::TouchTestResultInfo>> hittedRecognizerInfo;
255     for (const auto& item : result) {
256         if (AceType::InstanceOf<NG::MultiFingersRecognizer>(item) && !AceType::InstanceOf<NG::RecognizerGroup>(item)) {
257             auto node = item->GetAttachedNode().Upgrade();
258             if (!node) {
259                 hittedRecognizerInfo.emplace(AceType::TypeName(item), std::list<NG::TouchTestResultInfo>());
260                 continue;
261             }
262             auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
263             if (!frameNode) {
264                 hittedRecognizerInfo.emplace(AceType::TypeName(item), std::list<NG::TouchTestResultInfo>());
265                 continue;
266             }
267             hittedRecognizerInfo[AceType::TypeName(item)].emplace_back(NG::TouchTestResultInfo {
268                 frameNode->GetId(), frameNode->GetTag(), frameNode->GetInspectorIdValue("") });
269         }
270         auto group = AceType::DynamicCast<NG::RecognizerGroup>(item);
271         if (group) {
272             group->AddHittedRecognizerType(hittedRecognizerInfo);
273         }
274     }
275     std::string hittedRecognizerTypeInfo = std::string("InputTracking id:");
276     hittedRecognizerTypeInfo.append(std::to_string(touchEventId)).append(", touch test hitted recognizer type info: ");
277     for (const auto& item : hittedRecognizerInfo) {
278         hittedRecognizerTypeInfo.append("recognizer type ").append(item.first).append(" node info:");
279         for (const auto& nodeInfo : item.second) {
280             hittedRecognizerTypeInfo.append(" { ")
281                 .append("tag: ")
282                 .append(nodeInfo.tag)
283                 .append(" };");
284         }
285     }
286     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "%{public}s", hittedRecognizerTypeInfo.c_str());
287     if (hittedRecognizerInfo.empty()) {
288         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "Hitted recognizer info is empty.");
289         std::list<std::pair<int32_t, std::string>> dumpList;
290         eventTree_.Dump(dumpList, 0, DUMP_START_NUMBER);
291         for (auto& item : dumpList) {
292             if (!SystemProperties::GetAceCommercialLogEnabled()) {
293                 TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "EventTreeDumpInfo: %{public}s", item.second.c_str());
294             }
295         }
296     }
297 }
298 
PostEventTouchTest(const TouchEvent & touchPoint,const RefPtr<NG::UINode> & uiNode,TouchRestrict & touchRestrict)299 bool EventManager::PostEventTouchTest(
300     const TouchEvent& touchPoint, const RefPtr<NG::UINode>& uiNode, TouchRestrict& touchRestrict)
301 {
302     ContainerScope scope(instanceId_);
303     ACE_FUNCTION_TRACE();
304     CHECK_NULL_RETURN(uiNode, false);
305     // collect
306     TouchTestResult hitTestResult;
307     const NG::PointF point { touchPoint.x, touchPoint.y };
308     postEventRefereeNG_->CheckSourceTypeChange(touchPoint.sourceType);
309     if (postEventRefereeNG_->QueryAllDone(touchPoint.id)) {
310         postEventRefereeNG_->CleanGestureScope(touchPoint.id);
311         if (postEventTouchTestResults_.empty() && postEventRefereeNG_->QueryAllDone()) {
312             postEventRefereeNG_->CleanAll();
313         }
314     }
315     ResponseLinkResult responseLinkResult;
316     // For root node, the parent local point is the same as global point.
317     uiNode->TouchTest(point, point, point, touchRestrict, hitTestResult, touchPoint.id, responseLinkResult);
318     for (const auto& item : hitTestResult) {
319         item->SetIsPostEventResult(true);
320         auto group = AceType::DynamicCast<NG::RecognizerGroup>(item);
321         if (group) {
322             group->SetIsPostEventResultRecursively(true);
323             group->SetResponseLinkRecognizersRecursively(responseLinkResult);
324             continue;
325         }
326         auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(item);
327         if (recognizer) {
328             recognizer->SetResponseLinkRecognizers(responseLinkResult);
329         }
330     }
331     auto result = !hitTestResult.empty();
332     postEventTouchTestResults_[touchPoint.id] = std::move(hitTestResult);
333     return result;
334 }
335 
TouchTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict)336 void EventManager::TouchTest(
337     const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict)
338 {
339     ContainerScope scope(instanceId_);
340 
341     if (refereeNG_->CheckSourceTypeChange(event.sourceType, true)) {
342         TouchEvent touchEvent = ConvertAxisEventToTouchEvent(event);
343         FalsifyCancelEventAndDispatch(touchEvent);
344         responseCtrl_->Reset();
345         refereeNG_->CleanAll(true);
346         if (event.sourceTool != lastSourceTool_) {
347             touchTestResults_.clear();
348             axisTouchTestResults_.clear();
349         }
350     }
351     ACE_FUNCTION_TRACE();
352     CHECK_NULL_VOID(frameNode);
353     if (axisTouchTestResults_.empty() && refereeNG_->QueryAllDone()) {
354         responseCtrl_->Reset();
355     }
356     // collect
357     const NG::PointF point { event.x, event.y };
358     // For root node, the parent local point is the same as global point.
359     TouchTestResult hitTestResult;
360     ResponseLinkResult responseLinkResult;
361     frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, event.id, responseLinkResult);
362     SetResponseLinkRecognizers(hitTestResult, responseLinkResult);
363     axisTouchTestResults_[event.id] = std::move(hitTestResult);
364     LogTouchTestResultRecognizers(axisTouchTestResults_[event.id], event.touchEventId);
365 }
366 
ConvertAxisEventToTouchEvent(const AxisEvent & axisEvent)367 TouchEvent EventManager::ConvertAxisEventToTouchEvent(const AxisEvent& axisEvent)
368 {
369     TouchType type = TouchType::UNKNOWN;
370     if (axisEvent.action == AxisAction::BEGIN) {
371         type = TouchType::DOWN;
372     } else if (axisEvent.action == AxisAction::END) {
373         type = TouchType::UP;
374     } else if (axisEvent.action == AxisAction::UPDATE) {
375         type = TouchType::MOVE;
376     } else if (axisEvent.action == AxisAction::CANCEL) {
377         type = TouchType::CANCEL;
378     } else {
379         type = TouchType::UNKNOWN;
380     }
381     TouchPoint point { .id = axisEvent.id,
382         .x = axisEvent.x,
383         .y = axisEvent.y,
384         .screenX = axisEvent.screenX,
385         .screenY = axisEvent.screenY,
386         .downTime = axisEvent.time,
387         .size = 0.0,
388         .isPressed = (type == TouchType::DOWN),
389         .originalId = axisEvent.id };
390     TouchEvent event;
391     event.SetId(axisEvent.id)
392         .SetX(axisEvent.x)
393         .SetY(axisEvent.y)
394         .SetScreenX(axisEvent.screenX)
395         .SetScreenY(axisEvent.screenY)
396         .SetType(type)
397         .SetTime(axisEvent.time)
398         .SetSize(0.0)
399         .SetDeviceId(axisEvent.deviceId)
400         .SetTargetDisplayId(axisEvent.targetDisplayId)
401         .SetSourceType(axisEvent.sourceType)
402         .SetSourceTool(axisEvent.sourceTool)
403         .SetPointerEvent(axisEvent.pointerEvent)
404         .SetTouchEventId(axisEvent.touchEventId)
405         .SetOriginalId(axisEvent.originalId)
406         .SetIsInjected(axisEvent.isInjected);
407     event.pointers.emplace_back(std::move(point));
408     event.pressedKeyCodes_ = axisEvent.pressedCodes;
409     return event;
410 }
411 
HasDifferentDirectionGesture()412 bool EventManager::HasDifferentDirectionGesture()
413 {
414     uint8_t verticalFlag = 0;
415     uint8_t horizontalFlag = 0;
416     for (const auto& axisResult : axisTouchTestResults_) {
417         auto axisRecognizerList = axisResult.second;
418         for (const auto& axisRecognizer : axisRecognizerList) {
419             if (!axisRecognizer) {
420                 continue;
421             }
422             auto axisDirection = axisRecognizer->GetAxisDirection();
423             if (axisDirection == Axis::FREE) {
424                 return true;
425             }
426             if (axisDirection == Axis::VERTICAL) {
427                 verticalFlag = 0x1;
428             } else if (axisDirection == Axis::HORIZONTAL) {
429                 horizontalFlag = 0x2;
430             }
431             if ((verticalFlag | horizontalFlag) == 0x3) {
432                 return true;
433             }
434         }
435     }
436     return (verticalFlag | horizontalFlag) == 0x3;
437 }
438 
HandleGlobalEvent(const TouchEvent & touchPoint,const RefPtr<TextOverlayManager> & textOverlayManager)439 void EventManager::HandleGlobalEvent(const TouchEvent& touchPoint, const RefPtr<TextOverlayManager>& textOverlayManager)
440 {
441     if (touchPoint.type != TouchType::DOWN) {
442         return;
443     }
444     auto coordinateOffset = textOverlayManager->GetCoordinateOffset();
445     const Point point { touchPoint.x - coordinateOffset.GetX(), touchPoint.y - coordinateOffset.GetY(),
446         touchPoint.sourceType };
447     CHECK_NULL_VOID(textOverlayManager);
448     auto textOverlayBase = textOverlayManager->GetTextOverlayBase();
449     CHECK_NULL_VOID(textOverlayBase);
450     auto targetNode = textOverlayManager->GetTargetNode();
451     CHECK_NULL_VOID(targetNode);
452     for (auto& rect : textOverlayManager->GetTextOverlayRect()) {
453         if (rect.IsInRegion(point)) {
454             inSelectedRect_ = true;
455         }
456     }
457     for (auto& rect : textOverlayBase->GetSelectedRect()) {
458         if (rect.IsInRegion(point)) {
459             inSelectedRect_ = true;
460         }
461     }
462     if (!inSelectedRect_) {
463         textOverlayManager->PopTextOverlay();
464         textOverlayBase->ChangeSelection(0, 0);
465         textOverlayBase->MarkIsOverlayShowed(false);
466         targetNode->MarkNeedRender();
467     }
468     inSelectedRect_ = false;
469 }
470 
HandleGlobalEventNG(const TouchEvent & touchPoint,const RefPtr<NG::SelectOverlayManager> & selectOverlayManager,const NG::OffsetF & rootOffset)471 void EventManager::HandleGlobalEventNG(const TouchEvent& touchPoint,
472     const RefPtr<NG::SelectOverlayManager>& selectOverlayManager, const NG::OffsetF& rootOffset)
473 {
474     CHECK_NULL_VOID(selectOverlayManager);
475     auto isMousePressAtSelectedNode = false;
476     if (touchPoint.type == TouchType::DOWN &&
477         (touchTestResults_.find(touchPoint.id) != touchTestResults_.end() || !currMouseTestResults_.empty())) {
478         int32_t selectedNodeId = -1;
479         if (touchPoint.sourceType == SourceType::MOUSE) {
480             selectOverlayManager->GetSelectedNodeIdByMouse(selectedNodeId);
481         }
482         if (!touchTestResults_.empty()) {
483             std::vector<std::string> touchTestIds;
484             GetTouchTestIds(touchPoint, touchTestIds, isMousePressAtSelectedNode, selectedNodeId);
485             selectOverlayManager->SetOnTouchTestResults(touchTestIds);
486         } else {
487             // When right-click on another component, close the current component selection.
488             CheckMouseTestResults(isMousePressAtSelectedNode, selectedNodeId);
489         }
490     }
491     selectOverlayManager->HandleGlobalEvent(touchPoint, rootOffset, isMousePressAtSelectedNode);
492 }
493 
CheckMouseTestResults(bool & isMousePressAtSelectedNode,int32_t selectedNodeId)494 void EventManager::CheckMouseTestResults(bool& isMousePressAtSelectedNode, int32_t selectedNodeId)
495 {
496     for (const auto& result : currMouseTestResults_) {
497         TAG_LOGD(AceLogTag::ACE_INPUTTRACKING,
498             "HandleGlobalEventNG selectedNodeId: %{public}d mouseTestResult id is: "
499             SEC_PLD(%{public}d) ".", selectedNodeId, SEC_PARAM(result->GetNodeId()));
500         if (result->GetNodeId() == selectedNodeId) {
501             isMousePressAtSelectedNode = true;
502         }
503     }
504 }
505 
GetTouchTestIds(const TouchEvent & touchPoint,std::vector<std::string> & touchTestIds,bool & isMousePressAtSelectedNode,int32_t selectedNodeId)506 void EventManager::GetTouchTestIds(const TouchEvent& touchPoint, std::vector<std::string>& touchTestIds,
507     bool& isMousePressAtSelectedNode, int32_t selectedNodeId)
508 {
509     const auto& resultList = touchTestResults_[touchPoint.id];
510     for (const auto& result : resultList) {
511         auto eventTarget = result->GetEventTarget();
512         if (eventTarget.has_value()) {
513             touchTestIds.emplace_back(eventTarget.value().id);
514             if (eventTarget.value().id == std::to_string(selectedNodeId)) {
515                 TAG_LOGD(AceLogTag::ACE_INPUTTRACKING,
516                     "HandleGlobalEventNG selectedNodeId: %{public}d", selectedNodeId);
517                 isMousePressAtSelectedNode = true;
518             }
519         }
520     }
521 }
522 
HandleOutOfRectCallback(const Point & point,std::vector<RectCallback> & rectCallbackList)523 void EventManager::HandleOutOfRectCallback(const Point& point, std::vector<RectCallback>& rectCallbackList)
524 {
525     for (auto iter = rectCallbackList.begin(); iter != rectCallbackList.end();) {
526         auto rectCallback = *iter;
527         auto rectGetCallback = rectCallback.rectGetCallback;
528         if (!rectGetCallback) {
529             ++iter;
530             continue;
531         }
532         std::vector<Rect> rectList;
533         rectGetCallback(rectList);
534         if (std::any_of(
535                 rectList.begin(), rectList.end(), [point](const Rect& rect) { return rect.IsInRegion(point); })) {
536             ++iter;
537             continue;
538         }
539         for ([[maybe_unused]] const auto& rect : rectList) {
540             TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, SEC_PLD(,
541                 "Point(%{public}f, %{public}f) out of Rect-[%{public}f, %{public}f, %{public}f, %{public}f]"),
542                 SEC_PARAM(point.GetX(), point.GetY(), rect.Left(), rect.Right(), rect.Top(), rect.Bottom()));
543         }
544         if (point.GetSourceType() == SourceType::TOUCH) {
545             if (!rectCallback.touchCallback) {
546                 ++iter;
547                 continue;
548             }
549             rectCallback.touchCallback();
550         } else if (point.GetSourceType() == SourceType::MOUSE) {
551             if (!rectCallback.mouseCallback) {
552                 ++iter;
553                 continue;
554             }
555             rectCallback.mouseCallback();
556         }
557         iter = rectCallbackList.erase(iter);
558     }
559 }
560 
TouchTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode,TouchRestrict & touchRestrict)561 void EventManager::TouchTest(
562     const AxisEvent& event, const RefPtr<RenderNode>& renderNode, TouchRestrict& touchRestrict)
563 {
564     ContainerScope scope(instanceId_);
565 
566     ACE_FUNCTION_TRACE();
567     CHECK_NULL_VOID(renderNode);
568     // collect
569     const Point point { event.x, event.y, event.sourceType };
570     // For root node, the parent local point is the same as global point.
571     TouchTestResult hitTestResult;
572     renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
573     axisTouchTestResults_[event.id] = std::move(hitTestResult);
574 }
575 
FlushTouchEventsBegin(const std::list<TouchEvent> & touchEvents)576 void EventManager::FlushTouchEventsBegin(const std::list<TouchEvent>& touchEvents)
577 {
578     for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
579         const auto result = touchTestResults_.find((*iter).id);
580         if (result != touchTestResults_.end()) {
581             for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
582                 (*entry)->OnFlushTouchEventsBegin();
583             }
584         }
585     }
586 }
587 
FlushTouchEventsEnd(const std::list<TouchEvent> & touchEvents)588 void EventManager::FlushTouchEventsEnd(const std::list<TouchEvent>& touchEvents)
589 {
590     bool isResampled = false;
591     for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
592         const auto result = touchTestResults_.find((*iter).id);
593         if (result != touchTestResults_.end()) {
594             for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
595                 (*entry)->OnFlushTouchEventsEnd();
596             }
597             // only when no up received situation, the test result can be found
598             if ((*iter).history.size() != 0) {
599                 // for resample case, the history list must not be empty
600                 isResampled = true;
601             }
602         }
603     }
604 
605     if (!isResampled) {
606         // for no-resample case, we do not request a new frame, let the FlushVsync itself to do it as needed.
607         return;
608     }
609 
610     // request new frame for the cases we do the resampling for more than one touch events
611     auto container = Container::GetContainer(instanceId_);
612     CHECK_NULL_VOID(container);
613     auto pipeline = container->GetPipelineContext();
614     CHECK_NULL_VOID(pipeline);
615     // Since we cache the received touch move events and process them in FlushVsync, requesting a new frame
616     // when we cache them can not ensure that the frames are continuous afterwhile dure the whole touch access,
617     // as there are some situation where no any dirty generated after FlushVsync,  which will not request new frame
618     // by FlushVsync itself, this is not friendly for some components, like UIExtension, which relies on the events
619     // dispatching on host to resend the touchs to the supplier, so we also need to request a new frame after all
620     // resampled touch move events are actually dispatched.
621     pipeline->RequestFrame();
622 }
623 
PostEventFlushTouchEventEnd(const TouchEvent & touchEvent)624 void EventManager::PostEventFlushTouchEventEnd(const TouchEvent& touchEvent)
625 {
626     const auto result = postEventTouchTestResults_.find(touchEvent.id);
627     if (result != postEventTouchTestResults_.end()) {
628         for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
629             (*entry)->OnFlushTouchEventsEnd();
630         }
631     }
632 }
633 
CheckDownEvent(const TouchEvent & touchEvent)634 void EventManager::CheckDownEvent(const TouchEvent& touchEvent)
635 {
636     auto touchEventFindResult = downFingerIds_.find(touchEvent.id);
637     if (touchEvent.type == TouchType::DOWN) {
638         if (touchEventFindResult != downFingerIds_.end()) {
639             TAG_LOGW(AceLogTag::ACE_INPUTTRACKING,
640                 "InputTracking id:%{public}d, eventManager receive DOWN event twice,"
641                 " touchEvent id is %{public}d",
642                 touchEvent.touchEventId, touchEvent.id);
643             FalsifyCancelEventAndDispatch(touchEvent);
644             refereeNG_->ForceCleanGestureReferee();
645             touchTestResults_.clear();
646             downFingerIds_.clear();
647         }
648         downFingerIds_[touchEvent.id] = touchEvent.originalId;
649     }
650 }
651 
CheckUpEvent(const TouchEvent & touchEvent)652 void EventManager::CheckUpEvent(const TouchEvent& touchEvent)
653 {
654     if (touchEvent.isFalsified) {
655         return;
656     }
657     auto touchEventFindResult = downFingerIds_.find(touchEvent.id);
658     if (touchEvent.type == TouchType::UP || touchEvent.type == TouchType::CANCEL) {
659         if (touchEventFindResult == downFingerIds_.end()) {
660             TAG_LOGW(AceLogTag::ACE_INPUTTRACKING,
661                 "InputTracking id:%{public}d, eventManager receive UP/CANCEL event "
662                 "without receive DOWN event, touchEvent id is %{public}d",
663                 touchEvent.touchEventId, touchEvent.id);
664             FalsifyCancelEventAndDispatch(touchEvent);
665             refereeNG_->ForceCleanGestureReferee();
666             downFingerIds_.clear();
667         } else {
668             downFingerIds_.erase(touchEvent.id);
669         }
670     }
671 }
672 
DispatchTouchEvent(const TouchEvent & event)673 bool EventManager::DispatchTouchEvent(const TouchEvent& event)
674 {
675     ContainerScope scope(instanceId_);
676     TouchEvent point = event;
677     if (point.type == TouchType::PULL_MOVE || point.pullType == TouchType::PULL_MOVE) {
678         isDragging_ = false;
679         point.type = TouchType::CANCEL;
680         point.pullType = TouchType::PULL_MOVE;
681     }
682     if (point.type == TouchType::PULL_UP || point.type == TouchType::UP) {
683         isDragging_ = false;
684         point.type = TouchType::UP;
685     }
686     const auto iter = touchTestResults_.find(point.id);
687     if (iter == touchTestResults_.end()) {
688         CheckUpEvent(event);
689         lastDownFingerNumber_ = static_cast<int32_t>(downFingerIds_.size());
690         return false;
691     }
692     ACE_SCOPED_TRACE("DispatchTouchEvent id:%d, pointX=%f pointY=%f type=%d",
693         point.id, point.x, point.y, (int)point.type);
694     lastTouchEvent_ = event;
695 
696     if (point.type == TouchType::DOWN) {
697         refereeNG_->CleanGestureRefereeState(event.id);
698         // add gesture snapshot to dump
699         for (const auto& target : iter->second) {
700             AddGestureSnapshot(point.id, 0, target, NG::EventTreeType::TOUCH);
701         }
702     }
703 
704     bool dispatchSuccess = true;
705     for (auto entry = iter->second.rbegin(); entry != iter->second.rend(); ++entry) {
706         if (!(*entry)->DispatchMultiContainerEvent(point)) {
707             dispatchSuccess = false;
708             if ((*entry)->GetAttachedNode().Upgrade()) {
709                 TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "FrameNode %{public}s dispatch multi container event fail.",
710                     (*entry)->GetAttachedNode().Upgrade()->GetTag().c_str());
711             }
712             break;
713         }
714     }
715     // If one gesture recognizer has already been won, other gesture recognizers will still be affected by
716     // the event, each recognizer needs to filter the extra events by itself.
717     if (dispatchSuccess) {
718         if (Container::IsCurrentUseNewPipeline()) {
719             if (point.type == TouchType::CANCEL && point.pullType == TouchType::PULL_MOVE) {
720                 CleanRecognizersForDragBegin(point);
721                 lastEventTime_ = point.time;
722                 lastTouchEventEndTimestamp_ = GetSysTimestamp();
723                 return true;
724             }
725             // Need update here: onTouch/Recognizer need update
726             bool hasFailRecognizer = false;
727             bool allDone = false;
728             if (point.type == TouchType::DOWN) {
729                 hasFailRecognizer = refereeNG_->HasFailRecognizer(point.id);
730                 allDone = refereeNG_->QueryAllDone();
731             }
732             DispatchTouchEventToTouchTestResult(point, iter->second, true);
733             if (!allDone && point.type == TouchType::DOWN && !hasFailRecognizer &&
734                 refereeNG_->HasFailRecognizer(point.id) && downFingerIds_.size() <= 1) {
735                     refereeNG_->ForceCleanGestureReferee();
736                     DispatchTouchEventToTouchTestResult(point, iter->second, false);
737                 }
738         } else {
739             for (const auto& entry : iter->second) {
740                 if (!entry->HandleMultiContainerEvent(point)) {
741                     break;
742                 }
743             }
744         }
745     }
746 
747     CheckUpEvent(event);
748     if (point.type == TouchType::UP || point.type == TouchType::CANCEL) {
749         LogTouchTestRecognizerStates(point.id);
750         refereeNG_->CleanGestureScope(point.id);
751         referee_->CleanGestureScope(point.id);
752         touchTestResults_.erase(point.id);
753         if (touchTestResults_.empty()) {
754             refereeNG_->CleanRedundanceScope();
755         }
756     }
757 
758     lastEventTime_ = point.time;
759     lastTouchEventEndTimestamp_ = GetSysTimestamp();
760     lastDownFingerNumber_ = static_cast<int32_t>(downFingerIds_.size());
761     lastSourceTool_ = event.sourceTool;
762     return true;
763 }
764 
LogTouchTestRecognizerStates(int32_t touchEventId)765 void EventManager::LogTouchTestRecognizerStates(int32_t touchEventId)
766 {
767     if (eventTree_.eventTreeList.size() == 0) {
768         return;
769     }
770     std::string log = "";
771     auto lastEventTree = eventTree_.eventTreeList.back();
772 
773     std::map<int32_t, std::string> hitFrameNode;
774     std::list<NG::FrameNodeSnapshot> frameNodeSnapShots = lastEventTree.hitTestTree;
775     for (auto iter : frameNodeSnapShots) {
776         hitFrameNode[iter.nodeId] = iter.tag;
777     }
778 
779     std::list<RefPtr<GestureSnapshot>> gestureSnapshots = lastEventTree.gestureTree[touchEventId];
780     for (auto gestureSnapshot : gestureSnapshots) {
781         if (gestureSnapshot->type.find("TouchEventActuator") != std::string::npos ||
782             gestureSnapshot->type.find("ExclusiveRecognizer") != std::string::npos ||
783             gestureSnapshot->type.find("ParallelRecognizer") != std::string::npos ||
784             gestureSnapshot->type.find("SequenceRecognizer") != std::string::npos) {
785             continue;
786         }
787         std::string gestureLog = "{";
788         gestureLog += "types: " + gestureSnapshot->type.substr(0, gestureSnapshot->type.find("Recognizer"));
789         gestureLog += ", node: " + hitFrameNode[gestureSnapshot->nodeId];
790 
791         auto stateHistorys = gestureSnapshot->stateHistory;
792         for (auto stateHistory : stateHistorys) {
793             if (stateHistory.procedure.find("Down") != std::string::npos) {
794                 gestureLog += ", prcd: Down";
795             } else {
796                 gestureLog += ", prcd: Up";
797             }
798             gestureLog += ", state: " + stateHistory.state;
799             if (stateHistory.extraInfo != "") {
800                 gestureLog += ", extraInfo: " + stateHistory.extraInfo;
801             }
802         }
803         gestureLog += "}";
804         log += gestureLog;
805     }
806     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "id: %{public}d, log: %{public}s", touchEventId, log.c_str());
807 }
808 
ClearTouchTestTargetForPenStylus(TouchEvent & touchEvent)809 void EventManager::ClearTouchTestTargetForPenStylus(TouchEvent& touchEvent)
810 {
811     refereeNG_->CleanGestureScope(touchEvent.id);
812     referee_->CleanGestureScope(touchEvent.id);
813     touchTestResults_.erase(touchEvent.id);
814     touchEvent.isFalsified = true;
815     touchEvent.type = TouchType::CANCEL;
816     for (const auto& iter : downFingerIds_) {
817         touchEvent.id = iter.first;
818         DispatchTouchEvent(touchEvent);
819     }
820 }
821 
CleanRecognizersForDragBegin(TouchEvent & touchEvent)822 void EventManager::CleanRecognizersForDragBegin(TouchEvent& touchEvent)
823 {
824     // send cancel to all recognizer
825     for (const auto& iter : touchTestResults_) {
826         touchEvent.id = iter.first;
827         touchEvent.isInterpolated = true;
828         if (!downFingerIds_.empty() && downFingerIds_.find(iter.first) != downFingerIds_.end()) {
829             touchEvent.originalId = downFingerIds_[touchEvent.id];
830         }
831         DispatchTouchEventToTouchTestResult(touchEvent, iter.second, true);
832         refereeNG_->CleanGestureScope(touchEvent.id);
833         referee_->CleanGestureScope(touchEvent.id);
834     }
835     downFingerIds_.erase(touchEvent.id);
836     touchTestResults_.clear();
837     refereeNG_->CleanRedundanceScope();
838 }
839 
DispatchTouchEventToTouchTestResult(TouchEvent touchEvent,TouchTestResult touchTestResult,bool sendOnTouch)840 void EventManager::DispatchTouchEventToTouchTestResult(TouchEvent touchEvent,
841     TouchTestResult touchTestResult, bool sendOnTouch)
842 {
843     bool isStopTouchEvent = false;
844     for (const auto& entry : touchTestResult) {
845         auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(entry);
846         if (recognizer) {
847             entry->HandleMultiContainerEvent(touchEvent);
848             eventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(AceType::RawPtr(recognizer)), touchEvent, "",
849                 NG::TransRefereeState(recognizer->GetRefereeState()),
850                 NG::TransGestureDisposal(recognizer->GetGestureDisposal()));
851         }
852         if (!recognizer && !isStopTouchEvent && sendOnTouch) {
853             isStopTouchEvent = !entry->HandleMultiContainerEvent(touchEvent);
854             eventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(AceType::RawPtr(entry)), "",
855                 std::string("Handle").append(GestureSnapshot::TransTouchType(touchEvent.type)), "", "");
856         }
857     }
858 }
859 
DispatchTouchCancelToRecognizer(TouchEventTarget * touchEventTarget,const std::vector<std::pair<int32_t,TouchTestResult::iterator>> & items)860 void EventManager::DispatchTouchCancelToRecognizer(
861     TouchEventTarget* touchEventTarget, const std::vector<std::pair<int32_t, TouchTestResult::iterator>>& items)
862 {
863     TouchEvent touchEvent;
864     touchEvent.type = TouchType::CANCEL;
865     touchEvent.isFalsified = true;
866     for (auto& item : items) {
867         touchEvent.originalId = item.first;
868         touchEvent.id = item.first;
869         touchEventTarget->HandleMultiContainerEvent(touchEvent);
870         eventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(touchEventTarget), "",
871             std::string("Handle").append(GestureSnapshot::TransTouchType(touchEvent.type)), "", "");
872 
873         touchTestResults_[item.first].erase(item.second);
874         if (touchTestResults_[item.first].empty()) {
875             touchTestResults_.erase(item.first);
876         }
877     }
878 }
879 
PostEventDispatchTouchEvent(const TouchEvent & event)880 bool EventManager::PostEventDispatchTouchEvent(const TouchEvent& event)
881 {
882     ContainerScope scope(instanceId_);
883     TouchEvent point = event;
884     const auto iter = postEventTouchTestResults_.find(point.id);
885     if (iter == postEventTouchTestResults_.end()) {
886         return false;
887     }
888     ACE_SCOPED_TRACE(
889         "PostEventDispatchTouchEvent id:%d, pointX=%f pointY=%f type=%d", point.id, point.x, point.y, (int)point.type);
890 
891     if (point.type == TouchType::DOWN) {
892         // first collect gesture into gesture referee.
893         postEventRefereeNG_->AddGestureToScope(point.id, iter->second);
894         // add gesture snapshot to dump
895         for (const auto& target : iter->second) {
896             AddGestureSnapshot(point.id, 0, target, NG::EventTreeType::POST_EVENT);
897         }
898     }
899 
900     bool dispatchSuccess = true;
901     for (auto entry = iter->second.rbegin(); entry != iter->second.rend(); ++entry) {
902         if (!(*entry)->DispatchMultiContainerEvent(point)) {
903             dispatchSuccess = false;
904             break;
905         }
906     }
907     // If one gesture recognizer has already been won, other gesture recognizers will still be affected by
908     // the event, each recognizer needs to filter the extra events by itself.
909     if (dispatchSuccess) {
910         bool isStopTouchEvent = false;
911         for (const auto& entry : iter->second) {
912             auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(entry);
913             if (recognizer) {
914                 entry->HandleMultiContainerEvent(point);
915                 postEventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(AceType::RawPtr(recognizer)), point, "",
916                     NG::TransRefereeState(recognizer->GetRefereeState()),
917                     NG::TransGestureDisposal(recognizer->GetGestureDisposal()));
918             }
919             if (!recognizer && !isStopTouchEvent) {
920                 isStopTouchEvent = !entry->HandleMultiContainerEvent(point);
921                 postEventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(AceType::RawPtr(entry)), "",
922                     std::string("Handle").append(GestureSnapshot::TransTouchType(point.type)), "", "");
923             }
924         }
925     }
926 
927     if (point.type == TouchType::UP || point.type == TouchType::CANCEL) {
928         postEventRefereeNG_->CleanGestureScope(point.id);
929         postEventTouchTestResults_.erase(point.id);
930         if (postEventTouchTestResults_.empty()) {
931             postEventRefereeNG_->CleanRedundanceScope();
932         }
933     }
934     return true;
935 }
936 
DispatchTouchEvent(const AxisEvent & event)937 bool EventManager::DispatchTouchEvent(const AxisEvent& event)
938 {
939     ContainerScope scope(instanceId_);
940 
941     const auto curResultIter = axisTouchTestResults_.find(event.id);
942     if (curResultIter == axisTouchTestResults_.end()) {
943         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "the %{public}d axis test result does not exist!", event.id);
944         return false;
945     }
946     // rotate event is no need to add scope.
947     if (event.action == AxisAction::BEGIN && !event.isRotationEvent) {
948         // first collect gesture into gesture referee.
949         if (Container::IsCurrentUseNewPipeline()) {
950             if (refereeNG_) {
951                 refereeNG_->AddGestureToScope(event.id, curResultIter->second);
952             }
953         }
954     }
955 
956     ACE_FUNCTION_TRACE();
957     for (const auto& entry : curResultIter->second) {
958         if (!entry->HandleEvent(event)) {
959             break;
960         }
961     }
962     if ((event.action == AxisAction::END || event.action == AxisAction::NONE || event.action == AxisAction::CANCEL) &&
963         !event.isRotationEvent) {
964         if (Container::IsCurrentUseNewPipeline()) {
965             if (refereeNG_) {
966                 refereeNG_->CleanGestureScope(event.id);
967             }
968         }
969         axisTouchTestResults_.erase(event.id);
970     }
971     lastEventTime_ = event.time;
972     lastTouchEventEndTimestamp_ = GetSysTimestamp();
973     lastSourceTool_ = event.sourceTool;
974     return true;
975 }
976 
MouseTest(const MouseEvent & event,const RefPtr<RenderNode> & renderNode)977 void EventManager::MouseTest(const MouseEvent& event, const RefPtr<RenderNode>& renderNode)
978 {
979     CHECK_NULL_VOID(renderNode);
980     const Point point { event.x, event.y };
981     MouseHoverTestList hitTestResult;
982     WeakPtr<RenderNode> hoverNode = nullptr;
983     renderNode->MouseDetect(point, point, hitTestResult, hoverNode);
984 
985     if (event.action == MouseAction::WINDOW_LEAVE) {
986         mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
987         mouseHoverTestResults_.clear();
988     } else if (event.action == MouseAction::WINDOW_ENTER) {
989         mouseHoverTestResultsPre_.clear();
990         mouseHoverTestResults_ = std::move(hitTestResult);
991     } else {
992         mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
993         mouseHoverTestResults_ = std::move(hitTestResult);
994     }
995     mouseHoverNodePre_ = mouseHoverNode_;
996     mouseHoverNode_ = hoverNode;
997     TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "MouseDetect hit test last/new result size = %{public}zu/%{public}zu",
998         mouseHoverTestResultsPre_.size(), mouseHoverTestResults_.size());
999 }
1000 
DispatchMouseEvent(const MouseEvent & event)1001 bool EventManager::DispatchMouseEvent(const MouseEvent& event)
1002 {
1003     if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
1004         event.action == MouseAction::MOVE) {
1005         for (const auto& wp : mouseHoverTestResults_) {
1006             auto hoverNode = wp.Upgrade();
1007             if (hoverNode) {
1008                 if (hoverNode->HandleMouseEvent(event)) {
1009                     TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "Do HandleMouseEvent. Dispatch node: %{public}s",
1010                         AceType::TypeName(hoverNode));
1011                     break;
1012                 }
1013             }
1014         }
1015         return true;
1016     }
1017     return false;
1018 }
1019 
DispatchMouseHoverAnimation(const MouseEvent & event)1020 void EventManager::DispatchMouseHoverAnimation(const MouseEvent& event)
1021 {
1022     auto hoverNodeCur = mouseHoverNode_.Upgrade();
1023     auto hoverNodePre = mouseHoverNodePre_.Upgrade();
1024     if (event.action == MouseAction::PRESS) {
1025         if (hoverNodeCur) {
1026             hoverNodeCur->AnimateMouseHoverExit();
1027         }
1028     } else if (event.action == MouseAction::RELEASE) {
1029         if (hoverNodeCur) {
1030             hoverNodeCur->AnimateMouseHoverEnter();
1031         }
1032     } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
1033         if (hoverNodeCur != hoverNodePre) {
1034             if (hoverNodeCur) {
1035                 hoverNodeCur->AnimateMouseHoverEnter();
1036             }
1037             if (hoverNodePre) {
1038                 hoverNodePre->AnimateMouseHoverExit();
1039             }
1040         }
1041     } else if (event.action == MouseAction::WINDOW_ENTER) {
1042         if (hoverNodeCur) {
1043             hoverNodeCur->AnimateMouseHoverEnter();
1044         }
1045     } else if (event.action == MouseAction::WINDOW_LEAVE) {
1046         if (hoverNodeCur) {
1047             hoverNodeCur->AnimateMouseHoverExit();
1048         }
1049     }
1050 }
1051 
DispatchMouseHoverEvent(const MouseEvent & event)1052 bool EventManager::DispatchMouseHoverEvent(const MouseEvent& event)
1053 {
1054     for (const auto& wp : mouseHoverTestResultsPre_) {
1055         // get all previous hover nodes while it's not in current hover nodes. Those nodes exit hover
1056         auto it = std::find(mouseHoverTestResults_.begin(), mouseHoverTestResults_.end(), wp);
1057         if (it == mouseHoverTestResults_.end()) {
1058             auto hoverNode = wp.Upgrade();
1059             if (hoverNode) {
1060                 hoverNode->HandleMouseHoverEvent(MouseState::NONE);
1061             }
1062         }
1063     }
1064     for (const auto& wp : mouseHoverTestResults_) {
1065         // get all current hover nodes while it's not in previous hover nodes. Those nodes are new hover
1066         auto it = std::find(mouseHoverTestResultsPre_.begin(), mouseHoverTestResultsPre_.end(), wp);
1067         if (it == mouseHoverTestResultsPre_.end()) {
1068             auto hoverNode = wp.Upgrade();
1069             if (hoverNode) {
1070                 hoverNode->HandleMouseHoverEvent(MouseState::HOVER);
1071             }
1072         }
1073     }
1074     return true;
1075 }
1076 
LogPrintMouseTest()1077 void EventManager::LogPrintMouseTest()
1078 {
1079     if (!SystemProperties::GetDebugEnabled()) {
1080         return;
1081     }
1082     if (currMouseTestResults_.empty()) {
1083         TAG_LOGD(AceLogTag::ACE_MOUSE, "Mouse test onMouse result is empty.");
1084     } else {
1085         for (const auto& result : currMouseTestResults_) {
1086             TAG_LOGD(AceLogTag::ACE_MOUSE, "Mouse test onMouse result: %{public}s/"
1087                 SEC_PLD(%{public}d) ".",
1088                 result->GetNodeName().c_str(), SEC_PARAM(result->GetNodeId()));
1089         }
1090     }
1091     if (lastHoverTestResults_.empty()) {
1092         TAG_LOGD(AceLogTag::ACE_MOUSE, "Mouse test onHover last result is empty.");
1093     } else {
1094         for (const auto& result : lastHoverTestResults_) {
1095             TAG_LOGD(AceLogTag::ACE_MOUSE, "Mouse test onHover last result: %{public}s/"
1096                 SEC_PLD(%{public}d) ".",
1097                 result->GetNodeName().c_str(), SEC_PARAM(result->GetNodeId()));
1098         }
1099     }
1100     if (currHoverTestResults_.empty()) {
1101         TAG_LOGD(AceLogTag::ACE_MOUSE, "Mouse test onHover current result is empty.");
1102     } else {
1103         for (const auto& result : currHoverTestResults_) {
1104             TAG_LOGD(AceLogTag::ACE_MOUSE, "Mouse test onHover current result: %{public}s/"
1105                 SEC_PLD(%{public}d) ".",
1106                 result->GetNodeName().c_str(), SEC_PARAM(result->GetNodeId()));
1107         }
1108     }
1109     auto lastNode = lastHoverNode_.Upgrade();
1110     auto currNode = currHoverNode_.Upgrade();
1111     TAG_LOGD(AceLogTag::ACE_MOUSE,
1112         "Mouse test last/current hoverEffect node: %{public}s/%{public}d / %{public}s/%{public}d",
1113         lastNode ? lastNode->GetTag().c_str() : "NULL", lastNode ? lastNode->GetId() : -1,
1114         currNode ? currNode->GetTag().c_str() : "NULL", currNode ? currNode->GetId() : -1);
1115 }
1116 
AccessibilityHoverTest(const TouchEvent & event,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict)1117 void EventManager::AccessibilityHoverTest(
1118     const TouchEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict)
1119 {
1120     CHECK_NULL_VOID(frameNode);
1121     if (downFingerIds_.empty()) {
1122         FalsifyCancelEventAndDispatch(event);
1123         responseCtrl_->Reset();
1124         refereeNG_->CleanAll();
1125         touchTestResults_.clear();
1126         downFingerIds_.clear();
1127     }
1128     const NG::PointF point { event.x, event.y };
1129     TouchTestResult testResult;
1130     ResponseLinkResult responseLinkResult;
1131     frameNode->TouchTest(
1132         point, point, point, touchRestrict, testResult, event.id, responseLinkResult);
1133     SetResponseLinkRecognizers(testResult, responseLinkResult);
1134     UpdateAccessibilityHoverNode(event, testResult);
1135 }
1136 
MouseTest(const MouseEvent & event,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict)1137 void EventManager::MouseTest(
1138     const MouseEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict)
1139 {
1140     TAG_LOGD(AceLogTag::ACE_MOUSE,
1141         "Mouse test start. Event is (" SEC_PLD(%{public}f) "," SEC_PLD(%{public}f) "), "
1142         "button: %{public}d, action: %{public}d", SEC_PARAM(event.x), SEC_PARAM(event.y),
1143         event.button, event.action);
1144     CHECK_NULL_VOID(frameNode);
1145     const NG::PointF point { event.x, event.y };
1146     TouchTestResult testResult;
1147 
1148     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1149         if (event.pullAction == MouseAction::PULL_MOVE) {
1150             UpdateHoverNode(event, testResult);
1151             LogPrintMouseTest();
1152             return;
1153         } else if ((event.action == MouseAction::MOVE && event.button != MouseButton::NONE_BUTTON)) {
1154             testResult = mouseTestResults_[event.GetPointerId(event.id)];
1155         } else {
1156             ResponseLinkResult responseLinkResult;
1157             if (event.action != MouseAction::MOVE) {
1158                 touchRestrict.touchEvent.isMouseTouchTest = true;
1159             }
1160             frameNode->TouchTest(
1161                 point, point, point, touchRestrict, testResult, event.GetPointerId(event.id), responseLinkResult);
1162             SetResponseLinkRecognizers(testResult, responseLinkResult);
1163             mouseTestResults_[event.GetPointerId(event.id)] = testResult;
1164         }
1165     } else {
1166         ResponseLinkResult responseLinkResult;
1167         if (event.action != MouseAction::MOVE) {
1168             touchRestrict.touchEvent.isMouseTouchTest = true;
1169         }
1170         frameNode->TouchTest(
1171             point, point, point, touchRestrict, testResult, event.GetPointerId(event.id), responseLinkResult);
1172         SetResponseLinkRecognizers(testResult, responseLinkResult);
1173     }
1174     UpdateHoverNode(event, testResult);
1175     LogPrintMouseTest();
1176 }
1177 
UpdateAccessibilityHoverNode(const TouchEvent & event,const TouchTestResult & testResult)1178 void EventManager::UpdateAccessibilityHoverNode(const TouchEvent& event, const TouchTestResult& testResult)
1179 {
1180     HoverTestResult hoverTestResult;
1181     for (const auto& result : testResult) {
1182         auto hoverResult = AceType::DynamicCast<HoverEventTarget>(result);
1183         if (hoverResult && hoverResult->IsAccessibilityHoverTarget()) {
1184             hoverTestResult.emplace_back(hoverResult);
1185         }
1186     }
1187     if (event.type == TouchType::HOVER_EXIT) {
1188         TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "Exit hover by HOVER_EXIT event.");
1189         lastAccessibilityHoverResults_ = std::move(curAccessibilityHoverResults_);
1190         curAccessibilityHoverResults_.clear();
1191     } else if (event.type == TouchType::HOVER_CANCEL) {
1192         TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "Cancel hover by HOVER_CANCEL event.");
1193         lastAccessibilityHoverResults_ = std::move(curAccessibilityHoverResults_);
1194         curAccessibilityHoverResults_.clear();
1195     } else if (event.type == TouchType::HOVER_ENTER) {
1196         TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "Enter hover by HOVER_ENTER event.");
1197         lastAccessibilityHoverResults_.clear();
1198         curAccessibilityHoverResults_ = std::move(hoverTestResult);
1199     } else {
1200         lastAccessibilityHoverResults_ = std::move(curAccessibilityHoverResults_);
1201         curAccessibilityHoverResults_ = std::move(hoverTestResult);
1202     }
1203 }
1204 
UpdateHoverNode(const MouseEvent & event,const TouchTestResult & testResult)1205 void EventManager::UpdateHoverNode(const MouseEvent& event, const TouchTestResult& testResult)
1206 {
1207     currMouseTestResults_.clear();
1208     HoverTestResult hoverTestResult;
1209     WeakPtr<NG::FrameNode> hoverNode = nullptr;
1210     for (const auto& result : testResult) {
1211         auto mouseResult = AceType::DynamicCast<MouseEventTarget>(result);
1212         if (mouseResult) {
1213             currMouseTestResults_.emplace_back(mouseResult);
1214         }
1215         auto hoverResult = AceType::DynamicCast<HoverEventTarget>(result);
1216         if (hoverResult && hoverResult->IsHoverTarget()) {
1217             hoverTestResult.emplace_back(hoverResult);
1218         }
1219         if (!hoverNode.Upgrade()) {
1220             auto hoverEffectResult = AceType::DynamicCast<HoverEffectTarget>(result);
1221             if (hoverEffectResult) {
1222                 hoverNode = hoverEffectResult->GetHoverNode();
1223             }
1224         }
1225     }
1226     if (event.action == MouseAction::WINDOW_LEAVE) {
1227         TAG_LOGI(AceLogTag::ACE_MOUSE, "Exit hover by leave-window event.");
1228         lastHoverTestResults_ = std::move(currHoverTestResults_);
1229         currHoverTestResults_.clear();
1230     } else if (event.action == MouseAction::WINDOW_ENTER) {
1231         TAG_LOGI(AceLogTag::ACE_MOUSE, "Enter hover by enter-window event.");
1232         lastHoverTestResults_.clear();
1233         currHoverTestResults_ = std::move(hoverTestResult);
1234     } else {
1235         lastHoverTestResults_ = std::move(currHoverTestResults_);
1236         currHoverTestResults_ = std::move(hoverTestResult);
1237     }
1238     lastHoverNode_ = currHoverNode_;
1239     currHoverNode_ = hoverNode;
1240 }
1241 
DispatchMouseEventNG(const MouseEvent & event)1242 bool EventManager::DispatchMouseEventNG(const MouseEvent& event)
1243 {
1244     const static std::set<MouseAction> validAction = {
1245         MouseAction::PRESS,
1246         MouseAction::RELEASE,
1247         MouseAction::MOVE,
1248         MouseAction::WINDOW_ENTER,
1249         MouseAction::WINDOW_LEAVE
1250     };
1251     if (validAction.find(event.action) == validAction.end()) {
1252         return false;
1253     }
1254     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_THIRTEEN)) {
1255         return DispatchMouseEventInGreatOrEqualAPI13(event);
1256     }
1257     return DispatchMouseEventInLessAPI13(event);
1258 }
1259 
DispatchMouseEventInGreatOrEqualAPI13(const MouseEvent & event)1260 bool EventManager::DispatchMouseEventInGreatOrEqualAPI13(const MouseEvent& event)
1261 {
1262     MouseTestResult handledResults;
1263     bool isStopPropagation = false;
1264     if (event.button != MouseButton::NONE_BUTTON) {
1265         if (auto mouseTargetIter = pressMouseTestResultsMap_.find(event.button);
1266             mouseTargetIter != pressMouseTestResultsMap_.end()) {
1267             DispatchMouseEventToPressResults(event, mouseTargetIter->second, handledResults, isStopPropagation);
1268         }
1269         if (event.action == MouseAction::PRESS) {
1270             pressMouseTestResultsMap_[event.button] = currMouseTestResults_;
1271         }
1272     }
1273     auto result = DispatchMouseEventToCurResults(event, handledResults, isStopPropagation);
1274     if (event.action == MouseAction::RELEASE) {
1275         DoSingleMouseActionRelease(event.button);
1276     }
1277     return result;
1278 }
1279 
DispatchMouseEventInLessAPI13(const MouseEvent & event)1280 bool EventManager::DispatchMouseEventInLessAPI13(const MouseEvent& event)
1281 {
1282     MouseTestResult handledResults;
1283     bool isStopPropagation = false;
1284     if (event.button == MouseButton::LEFT_BUTTON) {
1285         DispatchMouseEventToPressResults(event, pressMouseTestResults_, handledResults, isStopPropagation);
1286         if (event.action == MouseAction::PRESS) {
1287             pressMouseTestResults_ = currMouseTestResults_;
1288         }
1289     }
1290     auto result = DispatchMouseEventToCurResultsInLessAPI13(event, handledResults, isStopPropagation);
1291     if (event.action == MouseAction::RELEASE) {
1292         DoMouseActionRelease();
1293     }
1294     return result;
1295 }
1296 
DispatchMouseEventToPressResults(const MouseEvent & event,const MouseTestResult & targetResults,MouseTestResult & handledResults,bool & isStopPropagation)1297 void EventManager::DispatchMouseEventToPressResults(const MouseEvent& event, const MouseTestResult& targetResults,
1298     MouseTestResult& handledResults, bool& isStopPropagation)
1299 {
1300     for (const auto& mouseTarget : targetResults) {
1301         if (!mouseTarget) {
1302             continue;
1303         }
1304         handledResults.emplace_back(mouseTarget);
1305         if (mouseTarget->HandleMouseEvent(event)) {
1306             isStopPropagation = true;
1307             break;
1308         }
1309     }
1310 }
1311 
DispatchMouseEventToCurResults(const MouseEvent & event,const MouseTestResult & handledResults,bool isStopPropagation)1312 bool EventManager::DispatchMouseEventToCurResults(
1313     const MouseEvent& event, const MouseTestResult& handledResults, bool isStopPropagation)
1314 {
1315     auto currMouseTestResults = currMouseTestResults_;
1316     for (const auto& mouseTarget : currMouseTestResults) {
1317         if (!mouseTarget) {
1318             continue;
1319         }
1320         if (!isStopPropagation) {
1321             auto ret = std::find(handledResults.begin(), handledResults.end(), mouseTarget) == handledResults.end();
1322             // if pressMouseTestResults doesn't have any isStopPropagation, use default handledResults.
1323             if (ret && mouseTarget->HandleMouseEvent(event)) {
1324                 return true;
1325             }
1326             continue;
1327         }
1328         auto mouseTargetIter = pressMouseTestResultsMap_.find(event.button);
1329         if ((mouseTargetIter != pressMouseTestResultsMap_.end() &&
1330             std::find(mouseTargetIter->second.begin(), mouseTargetIter->second.end(), mouseTarget) ==
1331             mouseTargetIter->second.end()) || mouseTargetIter == pressMouseTestResultsMap_.end()) {
1332             // if pressMouseTestResults has isStopPropagation, use pressMouseTestResults as handledResults.
1333             if (mouseTarget->HandleMouseEvent(event)) {
1334                 return true;
1335             }
1336         }
1337     }
1338     return false;
1339 }
1340 
DispatchMouseEventToCurResultsInLessAPI13(const MouseEvent & event,const MouseTestResult & handledResults,bool isStopPropagation)1341 bool EventManager::DispatchMouseEventToCurResultsInLessAPI13(
1342     const MouseEvent& event, const MouseTestResult& handledResults, bool isStopPropagation)
1343 {
1344     auto currMouseTestResults = currMouseTestResults_;
1345     for (const auto& mouseTarget : currMouseTestResults) {
1346         if (!mouseTarget) {
1347             continue;
1348         }
1349         if (!isStopPropagation) {
1350             auto ret = std::find(handledResults.begin(), handledResults.end(), mouseTarget) == handledResults.end();
1351             // if pressMouseTestResults doesn't have any isStopPropagation, use default handledResults.
1352             if (ret && mouseTarget->HandleMouseEvent(event)) {
1353                 return true;
1354             }
1355             continue;
1356         }
1357         if (std::find(pressMouseTestResults_.begin(), pressMouseTestResults_.end(), mouseTarget) ==
1358             pressMouseTestResults_.end()) {
1359             // if pressMouseTestResults has isStopPropagation, use pressMouseTestResults as handledResults.
1360             if (mouseTarget->HandleMouseEvent(event)) {
1361                 return true;
1362             }
1363         }
1364     }
1365     return false;
1366 }
1367 
DoMouseActionRelease()1368 void EventManager::DoMouseActionRelease()
1369 {
1370     pressMouseTestResults_.clear();
1371 }
1372 
DoSingleMouseActionRelease(MouseButton button)1373 void EventManager::DoSingleMouseActionRelease(MouseButton button)
1374 {
1375     pressMouseTestResultsMap_.erase(button);
1376 }
1377 
DispatchMouseHoverAnimationNG(const MouseEvent & event)1378 void EventManager::DispatchMouseHoverAnimationNG(const MouseEvent& event)
1379 {
1380     auto hoverNodeCur = currHoverNode_.Upgrade();
1381     auto hoverNodePre = lastHoverNode_.Upgrade();
1382     if (event.action == MouseAction::PRESS) {
1383         if (hoverNodeCur) {
1384             hoverNodeCur->AnimateHoverEffect(false);
1385         }
1386     } else if (event.action == MouseAction::RELEASE) {
1387         if (hoverNodeCur) {
1388             hoverNodeCur->AnimateHoverEffect(true);
1389         }
1390     } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
1391         if (hoverNodeCur != hoverNodePre) {
1392             if (hoverNodeCur) {
1393                 hoverNodeCur->AnimateHoverEffect(true);
1394             }
1395             if (hoverNodePre) {
1396                 hoverNodePre->AnimateHoverEffect(false);
1397             }
1398         }
1399     } else if (event.action == MouseAction::WINDOW_ENTER) {
1400         if (hoverNodeCur) {
1401             hoverNodeCur->AnimateHoverEffect(true);
1402         }
1403     } else if (event.action == MouseAction::WINDOW_LEAVE) {
1404         if (hoverNodeCur) {
1405             hoverNodeCur->AnimateHoverEffect(false);
1406         }
1407     }
1408 }
1409 
DispatchMouseHoverEventNG(const MouseEvent & event)1410 bool EventManager::DispatchMouseHoverEventNG(const MouseEvent& event)
1411 {
1412     auto lastHoverEndNode = lastHoverTestResults_.begin();
1413     auto currHoverEndNode = currHoverTestResults_.begin();
1414     RefPtr<HoverEventTarget> lastHoverEndNodeTarget;
1415     uint32_t iterCountLast = 0;
1416     uint32_t iterCountCurr = 0;
1417     for (const auto& hoverResult : lastHoverTestResults_) {
1418         // get valid part of previous hover nodes while it's not in current hover nodes. Those nodes exit hover
1419         // there may have some nodes in currHoverTestResults_ but intercepted
1420         iterCountLast++;
1421         if (lastHoverEndNode != currHoverTestResults_.end()) {
1422             lastHoverEndNode++;
1423         }
1424         if (std::find(currHoverTestResults_.begin(), currHoverTestResults_.end(), hoverResult) ==
1425             currHoverTestResults_.end()) {
1426             hoverResult->HandleHoverEvent(false, event);
1427         }
1428         if ((iterCountLast >= lastHoverDispatchLength_) && (lastHoverDispatchLength_ != 0)) {
1429             lastHoverEndNodeTarget = hoverResult;
1430             break;
1431         }
1432     }
1433     lastHoverDispatchLength_ = 0;
1434     for (const auto& hoverResult : currHoverTestResults_) {
1435         // get valid part of current hover nodes while it's not in previous hover nodes. Those nodes are new hover
1436         // the valid part stops at first interception
1437         iterCountCurr++;
1438         if (currHoverEndNode != currHoverTestResults_.end()) {
1439             currHoverEndNode++;
1440         }
1441         if (std::find(lastHoverTestResults_.begin(), lastHoverEndNode, hoverResult) == lastHoverEndNode) {
1442             if (!hoverResult->HandleHoverEvent(true, event)) {
1443                 lastHoverDispatchLength_ = iterCountCurr;
1444                 break;
1445             }
1446         }
1447         if (hoverResult == lastHoverEndNodeTarget) {
1448             lastHoverDispatchLength_ = iterCountCurr;
1449             break;
1450         }
1451     }
1452     for (auto hoverResultIt = lastHoverTestResults_.begin(); hoverResultIt != lastHoverEndNode; ++hoverResultIt) {
1453         // there may have previous hover nodes in the invalid part of current hover nodes. Those nodes exit hover also
1454         if (std::find(currHoverEndNode, currHoverTestResults_.end(), *hoverResultIt) != currHoverTestResults_.end()) {
1455             (*hoverResultIt)->HandleHoverEvent(false, event);
1456         }
1457     }
1458     return true;
1459 }
1460 
DispatchAccessibilityHoverEventNG(const TouchEvent & event)1461 void EventManager::DispatchAccessibilityHoverEventNG(const TouchEvent& event)
1462 {
1463     auto lastHoverEndNode = lastAccessibilityHoverResults_.begin();
1464     auto currHoverEndNode = curAccessibilityHoverResults_.begin();
1465     RefPtr<HoverEventTarget> lastHoverEndNodeTarget;
1466     uint32_t iterCountLast = 0;
1467     uint32_t iterCountCurr = 0;
1468     for (const auto& hoverResult : lastAccessibilityHoverResults_) {
1469         // get valid part of previous hover nodes while it's not in current hover nodes. Those nodes exit hover
1470         // there may have some nodes in curAccessibilityHoverResults_ but intercepted
1471         iterCountLast++;
1472         if (lastHoverEndNode != curAccessibilityHoverResults_.end()) {
1473             lastHoverEndNode++;
1474         }
1475         if (std::find(curAccessibilityHoverResults_.begin(), curAccessibilityHoverResults_.end(), hoverResult) ==
1476             curAccessibilityHoverResults_.end()) {
1477             hoverResult->HandleAccessibilityHoverEvent(false, event);
1478         }
1479         if ((iterCountLast >= lastAccessibilityHoverDispatchLength_) && (lastAccessibilityHoverDispatchLength_ != 0)) {
1480             lastHoverEndNodeTarget = hoverResult;
1481             break;
1482         }
1483     }
1484     lastAccessibilityHoverDispatchLength_ = 0;
1485     for (const auto& hoverResult : curAccessibilityHoverResults_) {
1486         // get valid part of current hover nodes while it's not in previous hover nodes. Those nodes are new hover
1487         // the valid part stops at first interception
1488         iterCountCurr++;
1489         if (currHoverEndNode != curAccessibilityHoverResults_.end()) {
1490             currHoverEndNode++;
1491         }
1492         if (std::find(lastAccessibilityHoverResults_.begin(), lastHoverEndNode, hoverResult) == lastHoverEndNode) {
1493             hoverResult->HandleAccessibilityHoverEvent(true, event);
1494         }
1495         if (hoverResult == lastHoverEndNodeTarget) {
1496             lastAccessibilityHoverDispatchLength_ = iterCountCurr;
1497             break;
1498         }
1499     }
1500     for (auto hoverResultIt = lastAccessibilityHoverResults_.begin(); hoverResultIt != lastHoverEndNode;
1501          ++hoverResultIt) {
1502         // there may have previous hover nodes in the invalid part of current hover nodes. Those nodes exit hover also
1503         if (std::find(currHoverEndNode, curAccessibilityHoverResults_.end(), *hoverResultIt) !=
1504             curAccessibilityHoverResults_.end()) {
1505             (*hoverResultIt)->HandleAccessibilityHoverEvent(false, event);
1506         }
1507     }
1508 }
1509 
AxisTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode)1510 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode)
1511 {
1512     CHECK_NULL_VOID(renderNode);
1513     const Point point { event.x, event.y };
1514     WeakPtr<RenderNode> axisNode = nullptr;
1515     renderNode->AxisDetect(point, point, axisNode, event.GetDirection());
1516     axisNode_ = axisNode;
1517     TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "Current axis node is %{public}s", AceType::TypeName(axisNode_.Upgrade()));
1518 }
1519 
DispatchAxisEvent(const AxisEvent & event)1520 bool EventManager::DispatchAxisEvent(const AxisEvent& event)
1521 {
1522     auto responseNode = axisNode_.Upgrade();
1523     if (responseNode) {
1524         responseNode->HandleAxisEvent(event);
1525     }
1526     return true;
1527 }
1528 
AxisTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode)1529 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode)
1530 {
1531     CHECK_NULL_VOID(frameNode);
1532     const NG::PointF point { event.x, event.y };
1533     TouchRestrict touchRestrict { TouchRestrict::NONE };
1534     touchRestrict.sourceType = event.sourceType;
1535     touchRestrict.hitTestType = SourceType::MOUSE;
1536     touchRestrict.inputEventType = InputEventType::AXIS;
1537     touchRestrict.touchEvent = ConvertAxisEventToTouchEvent(event);
1538     frameNode->AxisTest(point, point, point, touchRestrict, axisTestResults_);
1539 }
1540 
DispatchAxisEventNG(const AxisEvent & event)1541 bool EventManager::DispatchAxisEventNG(const AxisEvent& event)
1542 {
1543     // when api >= 15, do not block this event.
1544     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_FIFTEEN)) {
1545         if (event.horizontalAxis == 0 && event.verticalAxis == 0 && event.pinchAxisScale == 0 &&
1546             !event.isRotationEvent) {
1547             axisTestResults_.clear();
1548             return false;
1549         }
1550     }
1551     for (const auto& axisTarget : axisTestResults_) {
1552         if (axisTarget && axisTarget->HandleAxisEvent(event)) {
1553             axisTestResults_.clear();
1554             return true;
1555         }
1556     }
1557     axisTestResults_.clear();
1558     return true;
1559 }
1560 
DispatchRotationEvent(const RotationEvent & event,const RefPtr<RenderNode> & renderNode,const RefPtr<RenderNode> & requestFocusNode)1561 bool EventManager::DispatchRotationEvent(
1562     const RotationEvent& event, const RefPtr<RenderNode>& renderNode, const RefPtr<RenderNode>& requestFocusNode)
1563 {
1564     CHECK_NULL_RETURN(renderNode, false);
1565     if (requestFocusNode && renderNode->RotationMatchTest(requestFocusNode)) {
1566         return requestFocusNode->RotationTestForward(event);
1567     } else {
1568         return renderNode->RotationTest(event);
1569     }
1570 }
1571 
ClearResults()1572 void EventManager::ClearResults()
1573 {
1574     touchTestResults_.clear();
1575     postEventTouchTestResults_.clear();
1576     mouseTestResults_.clear();
1577     axisTouchTestResults_.clear();
1578 }
1579 
EventManager()1580 EventManager::EventManager()
1581 {
1582     refereeNG_ = AceType::MakeRefPtr<NG::GestureReferee>();
1583     postEventRefereeNG_ = AceType::MakeRefPtr<NG::GestureReferee>();
1584     referee_ = AceType::MakeRefPtr<GestureReferee>();
1585     responseCtrl_ = AceType::MakeRefPtr<NG::ResponseCtrl>();
1586     mouseStyleManager_ = AceType::MakeRefPtr<MouseStyleManager>();
1587 
1588     auto callback = [weak = WeakClaim(this)](size_t touchId) -> bool {
1589         auto eventManager = weak.Upgrade();
1590         CHECK_NULL_RETURN(eventManager, false);
1591         auto refereeNG = eventManager->refereeNG_;
1592         CHECK_NULL_RETURN(refereeNG, false);
1593         return refereeNG->HasGestureAccepted(touchId);
1594     };
1595     referee_->SetQueryStateFunc(std::move(callback));
1596 
1597     auto cleanReferee = [weak = WeakClaim(this)](size_t touchId) -> void {
1598         auto eventManager = weak.Upgrade();
1599         CHECK_NULL_VOID(eventManager);
1600         auto referee = eventManager->referee_;
1601         CHECK_NULL_VOID(referee);
1602         auto gestureScope = referee->GetGestureScope();
1603         const auto iter = gestureScope.find(touchId);
1604         if (iter == gestureScope.end()) {
1605             return;
1606         }
1607 
1608         auto highRecognizers = iter->second.GetHighRecognizers();
1609         auto lowRecognizers = iter->second.GetLowRecognizers();
1610         auto parallelRecognizers = iter->second.GetParallelRecognizers();
1611 
1612         for (const auto& weak : highRecognizers) {
1613             auto gesture = weak.Upgrade();
1614             if (gesture) {
1615                 gesture->OnRejected(touchId);
1616             }
1617         }
1618 
1619         for (const auto& weak : lowRecognizers) {
1620             auto gesture = weak.Upgrade();
1621             if (gesture) {
1622                 gesture->OnRejected(touchId);
1623             }
1624         }
1625 
1626         for (const auto& weak : parallelRecognizers) {
1627             auto gesture = weak.Upgrade();
1628             if (gesture) {
1629                 gesture->OnRejected(touchId);
1630             }
1631         }
1632     };
1633     refereeNG_->SetQueryStateFunc(std::move(cleanReferee));
1634 }
1635 
DumpEvent(NG::EventTreeType type)1636 void EventManager::DumpEvent(NG::EventTreeType type)
1637 {
1638     auto& eventTree = GetEventTreeRecord(type);
1639     std::list<std::pair<int32_t, std::string>> dumpList;
1640     eventTree.Dump(dumpList, 0);
1641     for (auto& item : dumpList) {
1642         DumpLog::GetInstance().Print(item.first, item.second);
1643     }
1644 }
1645 
AddGestureSnapshot(int32_t finger,int32_t depth,const RefPtr<TouchEventTarget> & target,NG::EventTreeType type)1646 void EventManager::AddGestureSnapshot(
1647     int32_t finger, int32_t depth, const RefPtr<TouchEventTarget>& target, NG::EventTreeType type)
1648 {
1649     if (!target) {
1650         return;
1651     }
1652     RefPtr<GestureSnapshot> info = target->Dump();
1653     auto frameNode = target->GetAttachedNode().Upgrade();
1654     if (frameNode) {
1655         info->nodeId = frameNode->GetId();
1656     }
1657     info->depth = depth;
1658     auto& eventTree = GetEventTreeRecord(type);
1659     eventTree.AddGestureSnapshot(finger, std::move(info));
1660 
1661     // add child gesture if target is group
1662     auto group = AceType::DynamicCast<NG::RecognizerGroup>(target);
1663     if (group) {
1664         for (const auto& child : group->GetGroupRecognizer()) {
1665             AddGestureSnapshot(finger, depth + 1, child, type);
1666         }
1667     }
1668 }
1669 
SetHittedFrameNode(const std::list<RefPtr<NG::NGGestureRecognizer>> & touchTestResults)1670 void EventManager::SetHittedFrameNode(const std::list<RefPtr<NG::NGGestureRecognizer>>& touchTestResults)
1671 {
1672     if (touchTestResults.empty()) {
1673         return;
1674     }
1675     for (const auto& item : touchTestResults) {
1676         auto node = item->GetAttachedNode().Upgrade();
1677         if (node) {
1678             hittedFrameNode_.emplace(node);
1679         }
1680         auto group = AceType::DynamicCast<NG::RecognizerGroup>(item);
1681         if (group) {
1682             auto groupRecognizers = group->GetGroupRecognizer();
1683             SetHittedFrameNode(groupRecognizers);
1684         }
1685     }
1686 }
1687 
CleanGestureEventHub()1688 void EventManager::CleanGestureEventHub()
1689 {
1690     for (const auto& item : hittedFrameNode_) {
1691         auto frameNode = item.Upgrade();
1692         if (frameNode) {
1693             auto gestureEventHub = frameNode->GetOrCreateGestureEventHub();
1694             if (gestureEventHub) {
1695                 gestureEventHub->CleanExternalRecognizers();
1696                 gestureEventHub->CleanInnerRecognizer();
1697                 gestureEventHub->CleanNodeRecognizer();
1698             }
1699         }
1700     }
1701     hittedFrameNode_.clear();
1702 }
1703 
CheckAndLogLastReceivedTouchEventInfo(int32_t eventId,TouchType type)1704 void EventManager::CheckAndLogLastReceivedTouchEventInfo(int32_t eventId, TouchType type)
1705 {
1706     CheckAndLogLastReceivedEventInfo(
1707         eventId, type == TouchType::DOWN || type == TouchType::UP || type == TouchType::CANCEL);
1708 }
1709 
CheckAndLogLastConsumedTouchEventInfo(int32_t eventId,TouchType type)1710 void EventManager::CheckAndLogLastConsumedTouchEventInfo(int32_t eventId, TouchType type)
1711 {
1712     CheckAndLogLastConsumedEventInfo(
1713         eventId, type == TouchType::DOWN || type == TouchType::UP || type == TouchType::CANCEL);
1714 }
1715 
CheckAndLogLastReceivedMouseEventInfo(int32_t eventId,MouseAction action)1716 void EventManager::CheckAndLogLastReceivedMouseEventInfo(int32_t eventId, MouseAction action)
1717 {
1718     CheckAndLogLastReceivedEventInfo(eventId, action == MouseAction::PRESS || action == MouseAction::RELEASE);
1719 }
1720 
CheckAndLogLastConsumedMouseEventInfo(int32_t eventId,MouseAction action)1721 void EventManager::CheckAndLogLastConsumedMouseEventInfo(int32_t eventId, MouseAction action)
1722 {
1723     CheckAndLogLastConsumedEventInfo(eventId, action == MouseAction::PRESS || action == MouseAction::RELEASE);
1724 }
1725 
CheckAndLogLastReceivedAxisEventInfo(int32_t eventId,AxisAction action)1726 void EventManager::CheckAndLogLastReceivedAxisEventInfo(int32_t eventId, AxisAction action)
1727 {
1728     CheckAndLogLastReceivedEventInfo(
1729         eventId, action == AxisAction::BEGIN || action == AxisAction::END || action == AxisAction::CANCEL);
1730 }
1731 
CheckAndLogLastConsumedAxisEventInfo(int32_t eventId,AxisAction action)1732 void EventManager::CheckAndLogLastConsumedAxisEventInfo(int32_t eventId, AxisAction action)
1733 {
1734     CheckAndLogLastConsumedEventInfo(
1735         eventId, action == AxisAction::BEGIN || action == AxisAction::END || action == AxisAction::CANCEL);
1736 }
1737 
CheckAndLogLastReceivedEventInfo(int32_t eventId,bool logImmediately)1738 void EventManager::CheckAndLogLastReceivedEventInfo(int32_t eventId, bool logImmediately)
1739 {
1740     if (logImmediately) {
1741         if (SystemProperties::GetDebugEnabled()) {
1742             TAG_LOGD(AceLogTag::ACE_INPUTKEYFLOW,
1743                 "Received new event id=%{public}d in ace_container, lastEventInfo: id:%{public}d", eventId,
1744                 lastReceivedEvent_.eventId);
1745         }
1746         return;
1747     }
1748     auto currentTime = GetSysTimestamp();
1749     auto lastLogTimeStamp = lastReceivedEvent_.lastLogTimeStamp;
1750     if (lastReceivedEvent_.lastLogTimeStamp != 0 &&
1751         (currentTime - lastReceivedEvent_.lastLogTimeStamp) > EVENT_CLEAR_DURATION * TRANSLATE_NS_TO_MS) {
1752         if (SystemProperties::GetDebugEnabled()) {
1753             TAG_LOGD(AceLogTag::ACE_INPUTKEYFLOW,
1754                 "Received new event id=%{public}d has been more than a second since the last one event "
1755                 "received "
1756                 "in ace_container, lastEventInfo: id:%{public}d",
1757                 eventId, lastReceivedEvent_.eventId);
1758         }
1759         lastLogTimeStamp = currentTime;
1760     }
1761     lastReceivedEvent_ = { eventId, lastLogTimeStamp };
1762 }
1763 
CheckAndLogLastConsumedEventInfo(int32_t eventId,bool logImmediately)1764 void EventManager::CheckAndLogLastConsumedEventInfo(int32_t eventId, bool logImmediately)
1765 {
1766     if (logImmediately) {
1767         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
1768             "Consumed new event id=%{public}d in ace_container, lastEventInfo: id:%{public}d", eventId,
1769             lastConsumedEvent_.eventId);
1770         return;
1771     }
1772     auto currentTime = GetSysTimestamp();
1773     auto lastLogTimeStamp = lastConsumedEvent_.lastLogTimeStamp;
1774     if (lastConsumedEvent_.lastLogTimeStamp != 0 &&
1775         (currentTime - lastConsumedEvent_.lastLogTimeStamp) > EVENT_CLEAR_DURATION * TRANSLATE_NS_TO_MS) {
1776         TAG_LOGW(AceLogTag::ACE_INPUTTRACKING,
1777             "Consumed new event id=%{public}d has been more than a second since the last one event "
1778             "markProcessed "
1779             "in ace_container, lastEventInfo: id:%{public}d",
1780             eventId, lastConsumedEvent_.eventId);
1781         lastLogTimeStamp = currentTime;
1782     }
1783     lastConsumedEvent_ = { eventId, lastLogTimeStamp };
1784 }
1785 
SetResponseLinkRecognizers(const TouchTestResult & result,const ResponseLinkResult & responseLinkRecognizers)1786 void EventManager::SetResponseLinkRecognizers(
1787     const TouchTestResult& result, const ResponseLinkResult& responseLinkRecognizers)
1788 {
1789     for (const auto& item : result) {
1790         auto group = AceType::DynamicCast<NG::RecognizerGroup>(item);
1791         if (group) {
1792             group->SetResponseLinkRecognizersRecursively(responseLinkRecognizers);
1793             continue;
1794         }
1795         auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(item);
1796         if (recognizer) {
1797             recognizer->SetResponseLinkRecognizers(responseLinkRecognizers);
1798         }
1799     }
1800 }
1801 
FalsifyCancelEventAndDispatch(const TouchEvent & touchPoint)1802 void EventManager::FalsifyCancelEventAndDispatch(const TouchEvent& touchPoint)
1803 {
1804     TouchEvent falsifyEvent = touchPoint;
1805     falsifyEvent.isFalsified = true;
1806     falsifyEvent.type = TouchType::CANCEL;
1807     falsifyEvent.sourceType = SourceType::TOUCH;
1808     falsifyEvent.isInterpolated = true;
1809     auto downFingerIds = downFingerIds_;
1810     for (const auto& iter : downFingerIds) {
1811         falsifyEvent.id = iter.first;
1812         falsifyEvent.pointers = lastTouchEvent_.pointers;
1813         if (touchPoint.id != iter.first) {
1814             falsifyEvent.history.clear();
1815         }
1816         falsifyEvent.originalId = iter.second;
1817         DispatchTouchEvent(falsifyEvent);
1818     }
1819 }
1820 
FalsifyCancelEventAndDispatch(const AxisEvent & axisEvent)1821 void EventManager::FalsifyCancelEventAndDispatch(const AxisEvent& axisEvent)
1822 {
1823     if (axisTouchTestResults_.empty()) {
1824         return;
1825     }
1826     AxisEvent falsifyEvent = axisEvent;
1827     falsifyEvent.action = AxisAction::CANCEL;
1828     falsifyEvent.id = static_cast<int32_t>(axisTouchTestResults_.begin()->first);
1829     DispatchTouchEvent(falsifyEvent);
1830 }
1831 #if defined(SUPPORT_TOUCH_TARGET_TEST)
1832 
TouchTargetHitTest(const TouchEvent & touchPoint,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend,const std::string & target)1833 bool EventManager::TouchTargetHitTest(const TouchEvent& touchPoint, const RefPtr<NG::FrameNode>& frameNode,
1834     TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend, const std::string& target)
1835 {
1836     CHECK_NULL_RETURN(frameNode, false);
1837     TouchTestResult hitTestResult;
1838     ResponseLinkResult responseLinkResult;
1839     const NG::PointF point { touchPoint.x, touchPoint.y };
1840     frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, touchPoint.id, responseLinkResult);
1841     for (const auto& entry : hitTestResult) {
1842         if (entry) {
1843             auto frameNodeInfo = entry->GetAttachedNode().Upgrade();
1844             if (frameNodeInfo && frameNodeInfo->GetTag().compare(target) == 0) {
1845                 return true;
1846             }
1847         }
1848     }
1849     return false;
1850 }
1851 #endif
1852 
FalsifyHoverCancelEventAndDispatch(const TouchEvent & touchPoint)1853 void EventManager::FalsifyHoverCancelEventAndDispatch(const TouchEvent& touchPoint)
1854 {
1855     lastAccessibilityHoverResults_ = std::move(curAccessibilityHoverResults_);
1856     curAccessibilityHoverResults_.clear();
1857     TouchEvent falsifyEvent = touchPoint;
1858     falsifyEvent.isFalsified = true;
1859     falsifyEvent.type = TouchType::HOVER_CANCEL;
1860     DispatchAccessibilityHoverEventNG(falsifyEvent);
1861 }
1862 
GetResampleTouchEvent(const std::vector<TouchEvent> & history,const std::vector<TouchEvent> & current,uint64_t nanoTimeStamp,TouchEvent & newTouchEvent)1863 bool EventManager::GetResampleTouchEvent(const std::vector<TouchEvent>& history,
1864     const std::vector<TouchEvent>& current, uint64_t nanoTimeStamp, TouchEvent& newTouchEvent)
1865 {
1866     auto newXy = ResampleAlgo::GetResampleCoord(std::vector<PointerEvent>(history.begin(), history.end()),
1867         std::vector<PointerEvent>(current.begin(), current.end()), nanoTimeStamp, false);
1868     auto newScreenXy = ResampleAlgo::GetResampleCoord(std::vector<PointerEvent>(history.begin(), history.end()),
1869         std::vector<PointerEvent>(current.begin(), current.end()), nanoTimeStamp, true);
1870     newTouchEvent = GetLatestPoint(current, nanoTimeStamp);
1871     bool ret = false;
1872     if (newXy.x != 0 && newXy.y != 0) {
1873         newTouchEvent.x = newXy.x;
1874         newTouchEvent.y = newXy.y;
1875         newTouchEvent.screenX = newScreenXy.x;
1876         newTouchEvent.screenY = newScreenXy.y;
1877         std::chrono::nanoseconds nanoseconds(nanoTimeStamp);
1878         newTouchEvent.time = TimeStamp(nanoseconds);
1879         newTouchEvent.history = current;
1880         newTouchEvent.isInterpolated = true;
1881         newTouchEvent.inputXDeltaSlope = newXy.inputXDeltaSlope;
1882         newTouchEvent.inputYDeltaSlope = newXy.inputYDeltaSlope;
1883         ret = true;
1884     }
1885     if (SystemProperties::GetDebugEnabled()) {
1886         TAG_LOGD(AceLogTag::ACE_UIEVENT,
1887             "Touch Interpolate point is %{public}d, %{public}f, %{public}f, %{public}f, %{public}f, %{public}"
1888             PRIu64 "", newTouchEvent.id, newTouchEvent.x, newTouchEvent.y,
1889             newTouchEvent.screenX, newTouchEvent.screenY,
1890             static_cast<uint64_t>(newTouchEvent.time.time_since_epoch().count()));
1891     }
1892     return ret;
1893 }
1894 
GetLatestPoint(const std::vector<TouchEvent> & current,uint64_t nanoTimeStamp)1895 TouchEvent EventManager::GetLatestPoint(const std::vector<TouchEvent>& current, uint64_t nanoTimeStamp)
1896 {
1897     TouchEvent result;
1898     uint64_t gap = UINT64_MAX;
1899     for (auto iter = current.begin(); iter != current.end(); iter++) {
1900         uint64_t timeStamp = static_cast<uint64_t>(iter->time.time_since_epoch().count());
1901         if (timeStamp == nanoTimeStamp) {
1902             result = *iter;
1903             return result;
1904         } else if (timeStamp > nanoTimeStamp) {
1905             if (timeStamp - nanoTimeStamp < gap) {
1906                 gap = timeStamp - nanoTimeStamp;
1907                 result = *iter;
1908             }
1909         } else {
1910             if (nanoTimeStamp - timeStamp < gap) {
1911                 gap = nanoTimeStamp - timeStamp;
1912                 result = *iter;
1913             }
1914         }
1915     }
1916     return result;
1917 }
1918 
OnNonPointerEvent(const NonPointerEvent & event)1919 bool EventManager::OnNonPointerEvent(const NonPointerEvent& event)
1920 {
1921     if (event.eventType == UIInputEventType::KEY) {
1922         return OnKeyEvent(static_cast<const KeyEvent&>(event));
1923     }
1924     if (event.eventType == UIInputEventType::FOCUS_AXIS) {
1925         return OnFocusAxisEvent(static_cast<const NG::FocusAxisEvent&>(event));
1926     }
1927     return false;
1928 }
1929 } // namespace OHOS::Ace
1930