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