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