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