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