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