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