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