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/geometry/ng/point_t.h"
19 #include "base/log/ace_trace.h"
20 #include "base/log/dump_log.h"
21 #include "base/memory/ace_type.h"
22 #include "base/thread/frame_trace_adapter.h"
23 #include "base/utils/utils.h"
24 #include "core/common/container.h"
25 #include "core/components_ng/base/frame_node.h"
26 #include "core/components_ng/event/touch_event.h"
27 #include "core/components_ng/gestures/recognizers/recognizer_group.h"
28 #include "core/components_ng/manager/select_overlay/select_overlay_manager.h"
29 #include "core/event/ace_events.h"
30 #include "core/event/key_event.h"
31 #include "core/event/touch_event.h"
32 #include "core/gestures/gesture_referee.h"
33 #include "core/pipeline/base/element.h"
34 #include "core/pipeline/base/render_node.h"
35
36 namespace OHOS::Ace {
37 constexpr uint8_t KEYS_MAX_VALUE = 3;
38 constexpr int32_t DUMP_START_NUMBER = 4;
39 constexpr int32_t DUMP_LIMIT_SIZE = 500;
40 constexpr int64_t EVENT_CLEAR_DURATION = 1000;
41 constexpr int64_t TRANSLATE_NS_TO_MS = 1000000;
42 const std::string SHORT_CUT_VALUE_X = "X";
43 const std::string SHORT_CUT_VALUE_Y = "Y";
44 const std::string SHORT_CUT_VALUE_Z = "Z";
45 const std::string SHORT_CUT_VALUE_A = "A";
46 const std::string SHORT_CUT_VALUE_C = "C";
47 const std::string SHORT_CUT_VALUE_V = "V";
48 enum class CtrlKeysBit {
49 CTRL = 1,
50 SHIFT = 2,
51 ALT = 4,
52 };
53
TouchTest(const TouchEvent & touchPoint,const RefPtr<RenderNode> & renderNode,TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)54 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<RenderNode>& renderNode,
55 TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
56 {
57 ContainerScope scope(instanceId_);
58
59 ACE_FUNCTION_TRACE();
60 CHECK_NULL_VOID(renderNode);
61 // first clean.
62 referee_->CleanGestureScope(touchPoint.id);
63 // collect
64 TouchTestResult hitTestResult;
65 const Point point { touchPoint.x, touchPoint.y, touchPoint.sourceType };
66 // For root node, the parent local point is the same as global point.
67 renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
68 if (needAppend) {
69 #ifdef OHOS_STANDARD_SYSTEM
70 for (auto entry = hitTestResult.begin(); entry != hitTestResult.end(); ++entry) {
71 if ((*entry)) {
72 (*entry)->SetSubPipelineGlobalOffset(offset, viewScale);
73 }
74 }
75 #endif
76 TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
77 hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
78 }
79 touchTestResults_[touchPoint.id] = std::move(hitTestResult);
80 }
81
TouchTest(const TouchEvent & touchPoint,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)82 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<NG::FrameNode>& frameNode,
83 TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
84 {
85 ContainerScope scope(instanceId_);
86
87 ACE_FUNCTION_TRACE();
88 CHECK_NULL_VOID(frameNode);
89 // collect
90 TouchTestResult hitTestResult;
91 const NG::PointF point { touchPoint.x, touchPoint.y };
92 refereeNG_->CheckSourceTypeChange(touchPoint.sourceType);
93 if (refereeNG_->QueryAllDone(touchPoint.id)) {
94 refereeNG_->CleanGestureScope(touchPoint.id);
95 if (touchTestResults_.empty() && refereeNG_->QueryAllDone()) {
96 innerEventWin_ = false;
97 responseCtrl_->Reset();
98 refereeNG_->CleanAll();
99 }
100 }
101 if (downFingerIds_.empty() && refereeNG_->QueryAllDone()) {
102 refereeNG_->ForceCleanGestureReferee();
103 CleanGestureEventHub();
104 }
105 if (frameNode->HaveSecurityComponent()) {
106 std::vector<NG::RectF> rect;
107 frameNode->CheckSecurityComponentStatus(rect);
108 }
109 if (!needAppend && touchTestResults_.empty()) {
110 NG::NGGestureRecognizer::ResetGlobalTransCfg();
111 }
112 // For root node, the parent local point is the same as global point.
113 frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, touchPoint.id);
114 if (needAppend) {
115 #ifdef OHOS_STANDARD_SYSTEM
116 for (const auto& entry : hitTestResult) {
117 if (entry) {
118 entry->SetSubPipelineGlobalOffset(offset, viewScale);
119 }
120 }
121 #endif
122 TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
123 hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
124 }
125 std::list<RefPtr<NG::NGGestureRecognizer>> hitTestRecognizers;
126 for (const auto& item : hitTestResult) {
127 auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(item);
128 if (recognizer) {
129 hitTestRecognizers.emplace_back(recognizer);
130 }
131 }
132 SetHittedFrameNode(hitTestRecognizers);
133 touchTestResults_[touchPoint.id] = std::move(hitTestResult);
134 auto container = Container::Current();
135 CHECK_NULL_VOID(container);
136 std::map<int32_t, NG::TouchTestResultInfo> touchTestResultInfo;
137 for (const auto& item : touchTestResults_[touchPoint.id]) {
138 auto node = item->GetAttachedNode().Upgrade();
139 if (!node) {
140 continue;
141 }
142 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
143 if (!frameNode) {
144 continue;
145 }
146 touchTestResultInfo[frameNode->GetId()] = { frameNode->GetId(), frameNode->GetTag(),
147 frameNode->GetInspectorIdValue(""), frameNode->GetGeometryNode()->GetFrameRect().ToString(),
148 frameNode->GetDepth() };
149 }
150 std::string resultInfo = std::string("fingerId: ").append(std::to_string(touchPoint.id));
151 for (const auto& item : touchTestResultInfo) {
152 resultInfo.append(" id: ")
153 .append(std::to_string(item.first))
154 .append(", tag: ")
155 .append(item.second.tag)
156 .append(", inspectorId: ")
157 .append(item.second.inspectorId)
158 .append(", frameRect: ")
159 .append(item.second.frameRect)
160 .append(", depth: ")
161 .append(std::to_string(item.second.depth))
162 .append(".");
163 }
164 TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "Touch test hitted node info: %{public}s", resultInfo.c_str());
165 if (touchTestResultInfo.empty()) {
166 TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "Touch test result is empty.");
167 std::list<std::pair<int32_t, std::string>> dumpList;
168 eventTree_.Dump(dumpList, 0, DUMP_START_NUMBER);
169 int32_t dumpCount = 0;
170 for (auto& item : dumpList) {
171 dumpCount++;
172 if (dumpCount > DUMP_LIMIT_SIZE) {
173 TAG_LOGW(AceLogTag::ACE_INPUTTRACKING,
174 "EventTreeDumpInfo size is over limit, the following info is dropped!");
175 break;
176 }
177 TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "EventTreeDumpInfo: %{public}s", item.second.c_str());
178 }
179 }
180 LogTouchTestResultRecognizers(touchTestResults_[touchPoint.id]);
181 }
182
LogTouchTestResultRecognizers(const TouchTestResult & result)183 void EventManager::LogTouchTestResultRecognizers(const TouchTestResult& result)
184 {
185 std::map<std::string, std::list<NG::TouchTestResultInfo>> hittedRecognizerInfo;
186 for (const auto& item : result) {
187 if (AceType::InstanceOf<NG::MultiFingersRecognizer>(item) && !AceType::InstanceOf<NG::RecognizerGroup>(item)) {
188 auto node = item->GetAttachedNode().Upgrade();
189 if (!node) {
190 hittedRecognizerInfo.emplace(AceType::TypeName(item), std::list<NG::TouchTestResultInfo>());
191 continue;
192 }
193 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
194 if (!frameNode) {
195 hittedRecognizerInfo.emplace(AceType::TypeName(item), std::list<NG::TouchTestResultInfo>());
196 continue;
197 }
198 hittedRecognizerInfo[AceType::TypeName(item)].emplace_back(NG::TouchTestResultInfo {
199 frameNode->GetId(), frameNode->GetTag(), frameNode->GetInspectorIdValue("") });
200 }
201 auto group = AceType::DynamicCast<NG::RecognizerGroup>(item);
202 if (group) {
203 group->AddHittedRecognizerType(hittedRecognizerInfo);
204 }
205 }
206 std::string hittedRecognizerTypeInfo = std::string("Touch test hitted recognizer type info: ");
207 for (const auto& item : hittedRecognizerInfo) {
208 hittedRecognizerTypeInfo.append("recognizer type ").append(item.first).append(" node info:");
209 for (const auto& nodeInfo : item.second) {
210 hittedRecognizerTypeInfo.append(" { id: ")
211 .append(std::to_string(nodeInfo.nodeId))
212 .append(", tag: ")
213 .append(nodeInfo.tag)
214 .append(", inspectorId: ")
215 .append(nodeInfo.inspectorId)
216 .append(" };");
217 }
218 }
219 TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "%{public}s", hittedRecognizerTypeInfo.c_str());
220 }
221
PostEventTouchTest(const TouchEvent & touchPoint,const RefPtr<NG::UINode> & uiNode,TouchRestrict & touchRestrict)222 bool EventManager::PostEventTouchTest(
223 const TouchEvent& touchPoint, const RefPtr<NG::UINode>& uiNode, TouchRestrict& touchRestrict)
224 {
225 ContainerScope scope(instanceId_);
226 ACE_FUNCTION_TRACE();
227 CHECK_NULL_RETURN(uiNode, false);
228 // collect
229 TouchTestResult hitTestResult;
230 const NG::PointF point { touchPoint.x, touchPoint.y };
231 postEventRefereeNG_->CheckSourceTypeChange(touchPoint.sourceType);
232 if (postEventRefereeNG_->QueryAllDone(touchPoint.id)) {
233 postEventRefereeNG_->CleanGestureScope(touchPoint.id);
234 if (postEventTouchTestResults_.empty() && postEventRefereeNG_->QueryAllDone()) {
235 postEventRefereeNG_->CleanAll();
236 }
237 }
238 // For root node, the parent local point is the same as global point.
239 uiNode->TouchTest(point, point, point, touchRestrict, hitTestResult, touchPoint.id);
240 for (const auto& item : hitTestResult) {
241 item->SetIsPostEventResult(true);
242 auto group = AceType::DynamicCast<NG::RecognizerGroup>(item);
243 if (group) {
244 group->SetIsPostEventResultRecursively(true);
245 }
246 }
247 auto result = !hitTestResult.empty();
248 postEventTouchTestResults_[touchPoint.id] = std::move(hitTestResult);
249 return result;
250 }
251
TouchTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict)252 void EventManager::TouchTest(
253 const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict)
254 {
255 ContainerScope scope(instanceId_);
256
257 if (refereeNG_->CheckSourceTypeChange(event.sourceType, true)) {
258 refereeNG_->CleanAll(true);
259 }
260 ACE_FUNCTION_TRACE();
261 CHECK_NULL_VOID(frameNode);
262 if (axisTouchTestResults_.empty() && refereeNG_->QueryAllDone()) {
263 responseCtrl_->Reset();
264 }
265 // collect
266 const NG::PointF point { event.x, event.y };
267 if (frameNode->HaveSecurityComponent()) {
268 std::vector<NG::RectF> rect;
269 frameNode->CheckSecurityComponentStatus(rect);
270 }
271 // For root node, the parent local point is the same as global point.
272 TouchTestResult hitTestResult;
273 frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, event.id);
274 axisTouchTestResults_[event.id] = std::move(hitTestResult);
275 }
276
HasDifferentDirectionGesture()277 bool EventManager::HasDifferentDirectionGesture()
278 {
279 uint8_t verticalFlag = 0;
280 uint8_t horizontalFlag = 0;
281 for (const auto& axisResult : axisTouchTestResults_) {
282 auto axisRecognizerList = axisResult.second;
283 for (const auto& axisRecognizer : axisRecognizerList) {
284 if (!axisRecognizer) {
285 continue;
286 }
287 auto axisDirection = axisRecognizer->GetAxisDirection();
288 if (axisDirection == Axis::FREE) {
289 return true;
290 }
291 if (axisDirection == Axis::VERTICAL) {
292 verticalFlag = 0x1;
293 } else if (axisDirection == Axis::HORIZONTAL) {
294 horizontalFlag = 0x2;
295 }
296 if ((verticalFlag | horizontalFlag) == 0x3) {
297 return true;
298 }
299 }
300 }
301 return (verticalFlag | horizontalFlag) == 0x3;
302 }
303
HandleGlobalEvent(const TouchEvent & touchPoint,const RefPtr<TextOverlayManager> & textOverlayManager)304 void EventManager::HandleGlobalEvent(const TouchEvent& touchPoint, const RefPtr<TextOverlayManager>& textOverlayManager)
305 {
306 if (touchPoint.type != TouchType::DOWN) {
307 return;
308 }
309 auto coordinateOffset = textOverlayManager->GetCoordinateOffset();
310 const Point point { touchPoint.x - coordinateOffset.GetX(), touchPoint.y - coordinateOffset.GetY(),
311 touchPoint.sourceType };
312 CHECK_NULL_VOID(textOverlayManager);
313 auto textOverlayBase = textOverlayManager->GetTextOverlayBase();
314 CHECK_NULL_VOID(textOverlayBase);
315 auto targetNode = textOverlayManager->GetTargetNode();
316 CHECK_NULL_VOID(targetNode);
317 for (auto& rect : textOverlayManager->GetTextOverlayRect()) {
318 if (rect.IsInRegion(point)) {
319 inSelectedRect_ = true;
320 }
321 }
322 for (auto& rect : textOverlayBase->GetSelectedRect()) {
323 if (rect.IsInRegion(point)) {
324 inSelectedRect_ = true;
325 }
326 }
327 if (!inSelectedRect_) {
328 textOverlayManager->PopTextOverlay();
329 textOverlayBase->ChangeSelection(0, 0);
330 textOverlayBase->MarkIsOverlayShowed(false);
331 targetNode->MarkNeedRender();
332 }
333 inSelectedRect_ = false;
334 }
335
HandleGlobalEventNG(const TouchEvent & touchPoint,const RefPtr<NG::SelectOverlayManager> & selectOverlayManager,const NG::OffsetF & rootOffset)336 void EventManager::HandleGlobalEventNG(const TouchEvent& touchPoint,
337 const RefPtr<NG::SelectOverlayManager>& selectOverlayManager, const NG::OffsetF& rootOffset)
338 {
339 CHECK_NULL_VOID(selectOverlayManager);
340 auto isMousePressAtSelectedNode = false;
341 if (touchPoint.type == TouchType::DOWN &&
342 (touchTestResults_.find(touchPoint.id) != touchTestResults_.end() || !currMouseTestResults_.empty())) {
343 int32_t selectedNodeId = -1;
344 if (touchPoint.sourceType == SourceType::MOUSE) {
345 selectOverlayManager->GetSelectedNodeIdByMouse(selectedNodeId);
346 }
347 if (!touchTestResults_.empty()) {
348 std::vector<std::string> touchTestIds;
349 GetTouchTestIds(touchPoint, touchTestIds, isMousePressAtSelectedNode, selectedNodeId);
350 selectOverlayManager->SetOnTouchTestResults(touchTestIds);
351 } else {
352 // When right-click on another component, close the current component selection.
353 CheckMouseTestResults(isMousePressAtSelectedNode, selectedNodeId);
354 }
355 }
356 selectOverlayManager->HandleGlobalEvent(touchPoint, rootOffset, isMousePressAtSelectedNode);
357 }
358
CheckMouseTestResults(bool & isMousePressAtSelectedNode,int32_t selectedNodeId)359 void EventManager::CheckMouseTestResults(bool& isMousePressAtSelectedNode, int32_t selectedNodeId)
360 {
361 for (const auto& result : currMouseTestResults_) {
362 TAG_LOGD(AceLogTag::ACE_INPUTTRACKING,
363 "HandleGlobalEventNG selectedNodeId: %{public}d mouseTestResult id is: %{public}d", selectedNodeId,
364 result->GetNodeId());
365 if (result->GetNodeId() == selectedNodeId) {
366 isMousePressAtSelectedNode = true;
367 }
368 }
369 }
370
GetTouchTestIds(const TouchEvent & touchPoint,std::vector<std::string> & touchTestIds,bool & isMousePressAtSelectedNode,int32_t selectedNodeId)371 void EventManager::GetTouchTestIds(const TouchEvent& touchPoint, std::vector<std::string>& touchTestIds,
372 bool& isMousePressAtSelectedNode, int32_t selectedNodeId)
373 {
374 const auto& resultList = touchTestResults_[touchPoint.id];
375 for (const auto& result : resultList) {
376 auto eventTarget = result->GetEventTarget();
377 if (eventTarget.has_value()) {
378 touchTestIds.emplace_back(eventTarget.value().id);
379 if (eventTarget.value().id == std::to_string(selectedNodeId)) {
380 TAG_LOGD(AceLogTag::ACE_INPUTTRACKING,
381 "HandleGlobalEventNG selectedNodeId: %{public}d eventTarget id is: %{public}s", selectedNodeId,
382 eventTarget.value().id.c_str());
383 isMousePressAtSelectedNode = true;
384 }
385 }
386 }
387 }
388
HandleOutOfRectCallback(const Point & point,std::vector<RectCallback> & rectCallbackList)389 void EventManager::HandleOutOfRectCallback(const Point& point, std::vector<RectCallback>& rectCallbackList)
390 {
391 for (auto iter = rectCallbackList.begin(); iter != rectCallbackList.end();) {
392 auto rectCallback = *iter;
393 auto rectGetCallback = rectCallback.rectGetCallback;
394 if (!rectGetCallback) {
395 ++iter;
396 continue;
397 }
398 std::vector<Rect> rectList;
399 rectGetCallback(rectList);
400 if (std::any_of(
401 rectList.begin(), rectList.end(), [point](const Rect& rect) { return rect.IsInRegion(point); })) {
402 ++iter;
403 continue;
404 }
405 for (const auto& rect : rectList) {
406 LOGI("Point(%{public}f, %{public}f) out of Rect-[%{public}f, %{public}f, %{public}f, %{public}f]",
407 point.GetX(), point.GetY(), rect.Left(), rect.Right(), rect.Top(), rect.Bottom());
408 }
409 if (point.GetSourceType() == SourceType::TOUCH) {
410 if (!rectCallback.touchCallback) {
411 ++iter;
412 continue;
413 }
414 rectCallback.touchCallback();
415 } else if (point.GetSourceType() == SourceType::MOUSE) {
416 if (!rectCallback.mouseCallback) {
417 ++iter;
418 continue;
419 }
420 rectCallback.mouseCallback();
421 }
422 iter = rectCallbackList.erase(iter);
423 }
424 }
425
TouchTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode,TouchRestrict & touchRestrict)426 void EventManager::TouchTest(
427 const AxisEvent& event, const RefPtr<RenderNode>& renderNode, TouchRestrict& touchRestrict)
428 {
429 ContainerScope scope(instanceId_);
430
431 ACE_FUNCTION_TRACE();
432 CHECK_NULL_VOID(renderNode);
433 // collect
434 const Point point { event.x, event.y, event.sourceType };
435 // For root node, the parent local point is the same as global point.
436 TouchTestResult hitTestResult;
437 renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
438 axisTouchTestResults_[event.id] = std::move(hitTestResult);
439 }
440
FlushTouchEventsBegin(const std::list<TouchEvent> & touchEvents)441 void EventManager::FlushTouchEventsBegin(const std::list<TouchEvent>& touchEvents)
442 {
443 for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
444 const auto result = touchTestResults_.find((*iter).id);
445 if (result != touchTestResults_.end()) {
446 for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
447 (*entry)->OnFlushTouchEventsBegin();
448 }
449 }
450 }
451 }
452
FlushTouchEventsEnd(const std::list<TouchEvent> & touchEvents)453 void EventManager::FlushTouchEventsEnd(const std::list<TouchEvent>& touchEvents)
454 {
455 for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
456 const auto result = touchTestResults_.find((*iter).id);
457 if (result != touchTestResults_.end()) {
458 for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
459 (*entry)->OnFlushTouchEventsEnd();
460 }
461 }
462 }
463 }
464
PostEventFlushTouchEventEnd(const TouchEvent & touchEvent)465 void EventManager::PostEventFlushTouchEventEnd(const TouchEvent& touchEvent)
466 {
467 const auto result = postEventTouchTestResults_.find(touchEvent.id);
468 if (result != postEventTouchTestResults_.end()) {
469 for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
470 (*entry)->OnFlushTouchEventsEnd();
471 }
472 }
473 }
474
CheckTouchEvent(TouchEvent touchEvent)475 void EventManager::CheckTouchEvent(TouchEvent touchEvent)
476 {
477 auto touchEventFindResult = downFingerIds_.find(touchEvent.id);
478 if (touchEvent.type == TouchType::DOWN) {
479 if (touchEventFindResult == downFingerIds_.end()) {
480 downFingerIds_.insert(touchEvent.id);
481 } else {
482 TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "EventManager receive DOWN event twice,"
483 " touchEvent id is %{public}d", touchEvent.id);
484 }
485 } else if (touchEvent.type == TouchType::UP) {
486 if (touchEventFindResult == downFingerIds_.end()) {
487 TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "EventManager receive UP event without receive DOWN event,"
488 " touchEvent id is %{public}d", touchEvent.id);
489 } else {
490 downFingerIds_.erase(touchEvent.id);
491 }
492 }
493 }
494
DispatchTouchEvent(const TouchEvent & event)495 bool EventManager::DispatchTouchEvent(const TouchEvent& event)
496 {
497 CheckTouchEvent(event);
498 ContainerScope scope(instanceId_);
499 TouchEvent point = event;
500 if (point.type == TouchType::PULL_MOVE || point.pullType == TouchType::PULL_MOVE) {
501 isDragging_ = false;
502 point.type = TouchType::CANCEL;
503 }
504 if (point.type == TouchType::PULL_UP || point.type == TouchType::UP) {
505 isDragging_ = false;
506 point.type = TouchType::UP;
507 }
508 ACE_SCOPED_TRACE(
509 "DispatchTouchEvent id:%d, pointX=%f pointY=%f type=%d", point.id, point.x, point.y, (int)point.type);
510 const auto iter = touchTestResults_.find(point.id);
511 if (iter == touchTestResults_.end()) {
512 return false;
513 }
514
515 if (point.type == TouchType::DOWN) {
516 refereeNG_->CleanGestureRefereeState(event.id);
517 int64_t currentEventTime = static_cast<int64_t>(point.time.time_since_epoch().count());
518 int64_t lastEventTime = static_cast<int64_t>(lastEventTime_.time_since_epoch().count());
519 int64_t duration = static_cast<int64_t>((currentEventTime - lastEventTime) / TRANSLATE_NS_TO_MS);
520 if (duration >= EVENT_CLEAR_DURATION && !refereeNG_->CheckGestureRefereeState()) {
521 TAG_LOGW(AceLogTag::ACE_INPUTTRACKING, "GestureReferee check state fail, force clean gestureReferee.");
522 std::list<std::pair<int32_t, std::string>> dumpList;
523 eventTree_.Dump(dumpList, 0);
524 for (auto& item : dumpList) {
525 TAG_LOGI(AceLogTag::ACE_INPUTTRACKING, "EventTreeDumpInfo: %{public}s", item.second.c_str());
526 }
527 refereeNG_->ForceCleanGestureReferee();
528 }
529 // first collect gesture into gesture referee.
530 if (Container::IsCurrentUseNewPipeline()) {
531 refereeNG_->AddGestureToScope(point.id, iter->second);
532 }
533 // add gesture snapshot to dump
534 for (const auto& target : iter->second) {
535 AddGestureSnapshot(point.id, 0, target);
536 }
537 }
538
539 bool dispatchSuccess = true;
540 for (auto entry = iter->second.rbegin(); entry != iter->second.rend(); ++entry) {
541 if (!(*entry)->DispatchMultiContainerEvent(point)) {
542 dispatchSuccess = false;
543 break;
544 }
545 }
546 // If one gesture recognizer has already been won, other gesture recognizers will still be affected by
547 // the event, each recognizer needs to filter the extra events by itself.
548 if (dispatchSuccess) {
549 if (Container::IsCurrentUseNewPipeline()) {
550 // Need update here: onTouch/Recognizer need update
551 bool isStopTouchEvent = false;
552 for (const auto& entry : iter->second) {
553 auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(entry);
554 if (recognizer) {
555 entry->HandleMultiContainerEvent(point);
556 eventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(AceType::RawPtr(recognizer)), point,
557 NG::TransRefereeState(recognizer->GetRefereeState()),
558 NG::TransGestureDisposal(recognizer->GetGestureDisposal()));
559 }
560 if (!recognizer && !isStopTouchEvent) {
561 isStopTouchEvent = !entry->HandleMultiContainerEvent(point);
562 eventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(AceType::RawPtr(entry)),
563 std::string("Handle").append(GestureSnapshot::TransTouchType(point.type)), "", "");
564 }
565 }
566 } else {
567 for (const auto& entry : iter->second) {
568 if (!entry->HandleMultiContainerEvent(point)) {
569 break;
570 }
571 }
572 }
573 }
574
575 if (point.type == TouchType::UP || point.type == TouchType::CANCEL) {
576 FrameTraceAdapter* ft = FrameTraceAdapter::GetInstance();
577 if (ft != nullptr) {
578 ft->SetFrameTraceLimit();
579 }
580 refereeNG_->CleanGestureScope(point.id);
581 referee_->CleanGestureScope(point.id);
582 touchTestResults_.erase(point.id);
583 if (touchTestResults_.empty()) {
584 refereeNG_->CleanRedundanceScope();
585 }
586 }
587
588 lastEventTime_ = point.time;
589 return true;
590 }
591
PostEventDispatchTouchEvent(const TouchEvent & event)592 bool EventManager::PostEventDispatchTouchEvent(const TouchEvent& event)
593 {
594 ContainerScope scope(instanceId_);
595 TouchEvent point = event;
596 const auto iter = postEventTouchTestResults_.find(point.id);
597 if (iter == postEventTouchTestResults_.end()) {
598 return false;
599 }
600 ACE_SCOPED_TRACE(
601 "PostEventDispatchTouchEvent id:%d, pointX=%f pointY=%f type=%d", point.id, point.x, point.y, (int)point.type);
602
603 if (point.type == TouchType::DOWN) {
604 // first collect gesture into gesture referee.
605 postEventRefereeNG_->AddGestureToScope(point.id, iter->second);
606 // add gesture snapshot to dump
607 for (const auto& target : iter->second) {
608 AddGestureSnapshot(point.id, 0, target);
609 }
610 }
611
612 bool dispatchSuccess = true;
613 for (auto entry = iter->second.rbegin(); entry != iter->second.rend(); ++entry) {
614 if (!(*entry)->DispatchMultiContainerEvent(point)) {
615 dispatchSuccess = false;
616 break;
617 }
618 }
619 // If one gesture recognizer has already been won, other gesture recognizers will still be affected by
620 // the event, each recognizer needs to filter the extra events by itself.
621 if (dispatchSuccess) {
622 bool isStopTouchEvent = false;
623 for (const auto& entry : iter->second) {
624 auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(entry);
625 if (recognizer) {
626 entry->HandleMultiContainerEvent(point);
627 eventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(AceType::RawPtr(recognizer)), point,
628 NG::TransRefereeState(recognizer->GetRefereeState()),
629 NG::TransGestureDisposal(recognizer->GetGestureDisposal()));
630 }
631 if (!recognizer && !isStopTouchEvent) {
632 isStopTouchEvent = !entry->HandleMultiContainerEvent(point);
633 eventTree_.AddGestureProcedure(reinterpret_cast<uintptr_t>(AceType::RawPtr(entry)),
634 std::string("Handle").append(GestureSnapshot::TransTouchType(point.type)), "", "");
635 }
636 }
637 }
638
639 if (point.type == TouchType::UP || point.type == TouchType::CANCEL) {
640 postEventRefereeNG_->CleanGestureScope(point.id);
641 postEventTouchTestResults_.erase(point.id);
642 if (postEventTouchTestResults_.empty()) {
643 postEventRefereeNG_->CleanRedundanceScope();
644 }
645 }
646 return true;
647 }
648
DispatchTouchEvent(const AxisEvent & event)649 bool EventManager::DispatchTouchEvent(const AxisEvent& event)
650 {
651 ContainerScope scope(instanceId_);
652
653 const auto curResultIter = axisTouchTestResults_.find(event.id);
654 if (curResultIter == axisTouchTestResults_.end()) {
655 LOGI("the %{public}d axis test result does not exist!", event.id);
656 return false;
657 }
658 if (event.action == AxisAction::BEGIN) {
659 // first collect gesture into gesture referee.
660 if (Container::IsCurrentUseNewPipeline()) {
661 if (refereeNG_) {
662 refereeNG_->AddGestureToScope(event.id, curResultIter->second);
663 }
664 }
665 }
666
667 ACE_FUNCTION_TRACE();
668 for (const auto& entry : curResultIter->second) {
669 if (!entry->HandleEvent(event)) {
670 break;
671 }
672 }
673 if (event.action == AxisAction::END || event.action == AxisAction::NONE || event.action == AxisAction::CANCEL) {
674 if (Container::IsCurrentUseNewPipeline()) {
675 if (refereeNG_) {
676 refereeNG_->CleanGestureScope(event.id);
677 }
678 }
679 axisTouchTestResults_.erase(event.id);
680 }
681 lastEventTime_ = event.time;
682 return true;
683 }
684
DispatchTabIndexEvent(const KeyEvent & event,const RefPtr<FocusNode> & focusNode,const RefPtr<FocusGroup> & mainNode)685 bool EventManager::DispatchTabIndexEvent(
686 const KeyEvent& event, const RefPtr<FocusNode>& focusNode, const RefPtr<FocusGroup>& mainNode)
687 {
688 CHECK_NULL_RETURN(focusNode, false);
689 CHECK_NULL_RETURN(mainNode, false);
690 if (focusNode->HandleFocusByTabIndex(event, mainNode)) {
691 LOGI("Tab index focus system handled this event");
692 return true;
693 }
694 return false;
695 }
696
DispatchKeyEvent(const KeyEvent & event,const RefPtr<FocusNode> & focusNode)697 bool EventManager::DispatchKeyEvent(const KeyEvent& event, const RefPtr<FocusNode>& focusNode)
698 {
699 CHECK_NULL_RETURN(focusNode, false);
700 if (focusNode->HandleKeyEvent(event)) {
701 LOGI("Default focus system handled this event");
702 return true;
703 }
704 return false;
705 }
706
DispatchTabIndexEventNG(const KeyEvent & event,const RefPtr<NG::FrameNode> & mainView)707 bool EventManager::DispatchTabIndexEventNG(const KeyEvent& event, const RefPtr<NG::FrameNode>& mainView)
708 {
709 CHECK_NULL_RETURN(mainView, false);
710 TAG_LOGD(AceLogTag::ACE_FOCUS,
711 "Dispatch tab index event: code:%{public}d/action:%{public}d on node: %{public}s/%{public}d.", event.code,
712 event.action, mainView->GetTag().c_str(), mainView->GetId());
713 auto mainViewFocusHub = mainView->GetFocusHub();
714 CHECK_NULL_RETURN(mainViewFocusHub, false);
715 if (mainViewFocusHub->HandleFocusByTabIndex(event)) {
716 TAG_LOGD(AceLogTag::ACE_FOCUS, "Tab index handled the key event: code:%{public}d/action:%{public}d", event.code,
717 event.action);
718 return true;
719 }
720 return false;
721 }
722
DispatchKeyEventNG(const KeyEvent & event,const RefPtr<NG::FrameNode> & focusNode)723 bool EventManager::DispatchKeyEventNG(const KeyEvent& event, const RefPtr<NG::FrameNode>& focusNode)
724 {
725 CHECK_NULL_RETURN(focusNode, false);
726 TAG_LOGD(AceLogTag::ACE_FOCUS,
727 "Dispatch key event: code:%{public}d/action:%{public}d on node: %{public}s/%{public}d.", event.code,
728 event.action, focusNode->GetTag().c_str(), focusNode->GetId());
729 auto focusNodeHub = focusNode->GetFocusHub();
730 CHECK_NULL_RETURN(focusNodeHub, false);
731 if (focusNodeHub->HandleKeyEvent(event)) {
732 TAG_LOGI(AceLogTag::ACE_FOCUS, "Focus system handled the key event: code:%{public}d/action:%{public}d",
733 event.code, event.action);
734 return true;
735 }
736 TAG_LOGD(AceLogTag::ACE_FOCUS, "Focus system do not handled the key event: code:%{public}d/action:%{public}d",
737 event.code, event.action);
738 return false;
739 }
740
MouseTest(const MouseEvent & event,const RefPtr<RenderNode> & renderNode)741 void EventManager::MouseTest(const MouseEvent& event, const RefPtr<RenderNode>& renderNode)
742 {
743 CHECK_NULL_VOID(renderNode);
744 const Point point { event.x, event.y };
745 MouseHoverTestList hitTestResult;
746 WeakPtr<RenderNode> hoverNode = nullptr;
747 renderNode->MouseDetect(point, point, hitTestResult, hoverNode);
748
749 if (event.action == MouseAction::WINDOW_LEAVE) {
750 mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
751 mouseHoverTestResults_.clear();
752 } else if (event.action == MouseAction::WINDOW_ENTER) {
753 mouseHoverTestResultsPre_.clear();
754 mouseHoverTestResults_ = std::move(hitTestResult);
755 } else {
756 mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
757 mouseHoverTestResults_ = std::move(hitTestResult);
758 }
759 mouseHoverNodePre_ = mouseHoverNode_;
760 mouseHoverNode_ = hoverNode;
761 LOGI("MouseDetect hit test last/new result size = %{public}zu/%{public}zu", mouseHoverTestResultsPre_.size(),
762 mouseHoverTestResults_.size());
763 }
764
DispatchMouseEvent(const MouseEvent & event)765 bool EventManager::DispatchMouseEvent(const MouseEvent& event)
766 {
767 if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
768 event.action == MouseAction::MOVE) {
769 for (const auto& wp : mouseHoverTestResults_) {
770 auto hoverNode = wp.Upgrade();
771 if (hoverNode) {
772 if (hoverNode->HandleMouseEvent(event)) {
773 LOGI("Do HandleMouseEvent. Dispatch node: %{public}s", AceType::TypeName(hoverNode));
774 break;
775 }
776 }
777 }
778 return true;
779 }
780 return false;
781 }
782
DispatchMouseHoverAnimation(const MouseEvent & event)783 void EventManager::DispatchMouseHoverAnimation(const MouseEvent& event)
784 {
785 auto hoverNodeCur = mouseHoverNode_.Upgrade();
786 auto hoverNodePre = mouseHoverNodePre_.Upgrade();
787 if (event.action == MouseAction::PRESS) {
788 if (hoverNodeCur) {
789 hoverNodeCur->AnimateMouseHoverExit();
790 }
791 } else if (event.action == MouseAction::RELEASE) {
792 if (hoverNodeCur) {
793 hoverNodeCur->AnimateMouseHoverEnter();
794 }
795 } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
796 if (hoverNodeCur != hoverNodePre) {
797 if (hoverNodeCur) {
798 hoverNodeCur->AnimateMouseHoverEnter();
799 }
800 if (hoverNodePre) {
801 hoverNodePre->AnimateMouseHoverExit();
802 }
803 }
804 } else if (event.action == MouseAction::WINDOW_ENTER) {
805 if (hoverNodeCur) {
806 hoverNodeCur->AnimateMouseHoverEnter();
807 }
808 } else if (event.action == MouseAction::WINDOW_LEAVE) {
809 if (hoverNodeCur) {
810 hoverNodeCur->AnimateMouseHoverExit();
811 }
812 }
813 }
814
DispatchMouseHoverEvent(const MouseEvent & event)815 bool EventManager::DispatchMouseHoverEvent(const MouseEvent& event)
816 {
817 for (const auto& wp : mouseHoverTestResultsPre_) {
818 // get all previous hover nodes while it's not in current hover nodes. Those nodes exit hover
819 auto it = std::find(mouseHoverTestResults_.begin(), mouseHoverTestResults_.end(), wp);
820 if (it == mouseHoverTestResults_.end()) {
821 auto hoverNode = wp.Upgrade();
822 if (hoverNode) {
823 hoverNode->HandleMouseHoverEvent(MouseState::NONE);
824 }
825 }
826 }
827 for (const auto& wp : mouseHoverTestResults_) {
828 // get all current hover nodes while it's not in previous hover nodes. Those nodes are new hover
829 auto it = std::find(mouseHoverTestResultsPre_.begin(), mouseHoverTestResultsPre_.end(), wp);
830 if (it == mouseHoverTestResultsPre_.end()) {
831 auto hoverNode = wp.Upgrade();
832 if (hoverNode) {
833 hoverNode->HandleMouseHoverEvent(MouseState::HOVER);
834 }
835 }
836 }
837 return true;
838 }
839
LogPrintMouseTest()840 void EventManager::LogPrintMouseTest()
841 {
842 if (!SystemProperties::GetDebugEnabled()) {
843 return;
844 }
845 if (currMouseTestResults_.empty()) {
846 TAG_LOGI(AceLogTag::ACE_MOUSE, "Mouse test onMouse result is empty.");
847 } else {
848 for (const auto& result : currMouseTestResults_) {
849 TAG_LOGI(AceLogTag::ACE_MOUSE, "Mouse test onMouse result: %{public}s/%{public}d.",
850 result->GetNodeName().c_str(), result->GetNodeId());
851 }
852 }
853 if (lastHoverTestResults_.empty()) {
854 TAG_LOGI(AceLogTag::ACE_MOUSE, "Mouse test onHover last result is empty.");
855 } else {
856 for (const auto& result : lastHoverTestResults_) {
857 TAG_LOGI(AceLogTag::ACE_MOUSE, "Mouse test onHover last result: %{public}s/%{public}d.",
858 result->GetNodeName().c_str(), result->GetNodeId());
859 }
860 }
861 if (currHoverTestResults_.empty()) {
862 TAG_LOGI(AceLogTag::ACE_MOUSE, "Mouse test onHover current result is empty.");
863 } else {
864 for (const auto& result : currHoverTestResults_) {
865 TAG_LOGI(AceLogTag::ACE_MOUSE, "Mouse test onHover current result: %{public}s/%{public}d.",
866 result->GetNodeName().c_str(), result->GetNodeId());
867 }
868 }
869 auto lastNode = lastHoverNode_.Upgrade();
870 auto currNode = currHoverNode_.Upgrade();
871 TAG_LOGI(AceLogTag::ACE_MOUSE,
872 "Mouse test last/current hoverEffect node: %{public}s/%{public}d / %{public}s/%{public}d",
873 lastNode ? lastNode->GetTag().c_str() : "NULL", lastNode ? lastNode->GetId() : -1,
874 currNode ? currNode->GetTag().c_str() : "NULL", currNode ? currNode->GetId() : -1);
875 }
876
MouseTest(const MouseEvent & event,const RefPtr<NG::FrameNode> & frameNode,TouchRestrict & touchRestrict)877 void EventManager::MouseTest(
878 const MouseEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict)
879 {
880 TAG_LOGD(AceLogTag::ACE_MOUSE,
881 "Mouse test start. Event is (%{public}f,%{public}f), button: %{public}d, action: %{public}d", event.x, event.y,
882 event.button, event.action);
883 CHECK_NULL_VOID(frameNode);
884 const NG::PointF point { event.x, event.y };
885 TouchTestResult testResult;
886 if (frameNode->HaveSecurityComponent()) {
887 std::vector<NG::RectF> rect;
888 frameNode->CheckSecurityComponentStatus(rect);
889 }
890 frameNode->TouchTest(point, point, point, touchRestrict, testResult, event.GetId());
891
892 currMouseTestResults_.clear();
893 HoverTestResult hoverTestResult;
894 WeakPtr<NG::FrameNode> hoverNode = nullptr;
895 for (const auto& result : testResult) {
896 auto mouseResult = AceType::DynamicCast<MouseEventTarget>(result);
897 if (mouseResult) {
898 currMouseTestResults_.emplace_back(mouseResult);
899 }
900 auto hoverResult = AceType::DynamicCast<HoverEventTarget>(result);
901 if (hoverResult) {
902 hoverTestResult.emplace_back(hoverResult);
903 }
904 if (!hoverNode.Upgrade()) {
905 auto hoverEffectResult = AceType::DynamicCast<HoverEffectTarget>(result);
906 if (hoverEffectResult) {
907 hoverNode = hoverEffectResult->GetHoverNode();
908 }
909 }
910 }
911 if (event.action == MouseAction::WINDOW_LEAVE) {
912 TAG_LOGI(AceLogTag::ACE_MOUSE, "Exit hover by leave-window event.");
913 lastHoverTestResults_ = std::move(currHoverTestResults_);
914 currHoverTestResults_.clear();
915 } else if (event.action == MouseAction::WINDOW_ENTER) {
916 TAG_LOGI(AceLogTag::ACE_MOUSE, "Enter hover by enter-window event.");
917 lastHoverTestResults_.clear();
918 currHoverTestResults_ = std::move(hoverTestResult);
919 } else {
920 lastHoverTestResults_ = std::move(currHoverTestResults_);
921 currHoverTestResults_ = std::move(hoverTestResult);
922 }
923 lastHoverNode_ = currHoverNode_;
924 currHoverNode_ = hoverNode;
925 LogPrintMouseTest();
926 }
927
DispatchMouseEventNG(const MouseEvent & event)928 bool EventManager::DispatchMouseEventNG(const MouseEvent& event)
929 {
930 if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
931 event.action == MouseAction::MOVE || event.action == MouseAction::WINDOW_ENTER ||
932 event.action == MouseAction::WINDOW_LEAVE) {
933 MouseTestResult handledResults;
934 handledResults.clear();
935 auto container = Container::Current();
936 CHECK_NULL_RETURN(container, false);
937 if (event.button == MouseButton::LEFT_BUTTON) {
938 for (const auto& mouseTarget : pressMouseTestResults_) {
939 if (mouseTarget) {
940 handledResults.emplace_back(mouseTarget);
941 if (mouseTarget->HandleMouseEvent(event)) {
942 break;
943 }
944 }
945 }
946 if (event.action == MouseAction::PRESS) {
947 pressMouseTestResults_ = currMouseTestResults_;
948 } else if (event.action == MouseAction::RELEASE) {
949 DoMouseActionRelease();
950 }
951 }
952 if (event.pullAction == MouseAction::PULL_UP) {
953 DoMouseActionRelease();
954 }
955 for (const auto& mouseTarget : currMouseTestResults_) {
956 if (mouseTarget &&
957 std::find(handledResults.begin(), handledResults.end(), mouseTarget) == handledResults.end()) {
958 if (mouseTarget->HandleMouseEvent(event)) {
959 return true;
960 }
961 }
962 }
963 }
964 return false;
965 }
966
DoMouseActionRelease()967 void EventManager::DoMouseActionRelease()
968 {
969 pressMouseTestResults_.clear();
970 }
971
DispatchMouseHoverAnimationNG(const MouseEvent & event)972 void EventManager::DispatchMouseHoverAnimationNG(const MouseEvent& event)
973 {
974 auto hoverNodeCur = currHoverNode_.Upgrade();
975 auto hoverNodePre = lastHoverNode_.Upgrade();
976 if (event.action == MouseAction::PRESS) {
977 if (hoverNodeCur) {
978 hoverNodeCur->AnimateHoverEffect(false);
979 }
980 } else if (event.action == MouseAction::RELEASE) {
981 if (hoverNodeCur) {
982 hoverNodeCur->AnimateHoverEffect(true);
983 }
984 } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
985 if (hoverNodeCur != hoverNodePre) {
986 if (hoverNodeCur) {
987 hoverNodeCur->AnimateHoverEffect(true);
988 }
989 if (hoverNodePre) {
990 hoverNodePre->AnimateHoverEffect(false);
991 }
992 }
993 } else if (event.action == MouseAction::WINDOW_ENTER) {
994 if (hoverNodeCur) {
995 hoverNodeCur->AnimateHoverEffect(true);
996 }
997 } else if (event.action == MouseAction::WINDOW_LEAVE) {
998 if (hoverNodeCur) {
999 hoverNodeCur->AnimateHoverEffect(false);
1000 }
1001 }
1002 }
1003
DispatchMouseHoverEventNG(const MouseEvent & event)1004 bool EventManager::DispatchMouseHoverEventNG(const MouseEvent& event)
1005 {
1006 auto lastHoverEndNode = lastHoverTestResults_.begin();
1007 auto currHoverEndNode = currHoverTestResults_.begin();
1008 RefPtr<HoverEventTarget> lastHoverEndNodeTarget;
1009 uint32_t iterCountLast = 0;
1010 uint32_t iterCountCurr = 0;
1011 for (const auto& hoverResult : lastHoverTestResults_) {
1012 // get valid part of previous hover nodes while it's not in current hover nodes. Those nodes exit hover
1013 // there may have some nodes in currHoverTestResults_ but intercepted
1014 iterCountLast++;
1015 if (lastHoverEndNode != currHoverTestResults_.end()) {
1016 lastHoverEndNode++;
1017 }
1018 if (std::find(currHoverTestResults_.begin(), currHoverTestResults_.end(), hoverResult) ==
1019 currHoverTestResults_.end()) {
1020 hoverResult->HandleHoverEvent(false, event);
1021 }
1022 if ((iterCountLast >= lastHoverDispatchLength_) && (lastHoverDispatchLength_ != 0)) {
1023 lastHoverEndNodeTarget = hoverResult;
1024 break;
1025 }
1026 }
1027 lastHoverDispatchLength_ = 0;
1028 for (const auto& hoverResult : currHoverTestResults_) {
1029 // get valid part of current hover nodes while it's not in previous hover nodes. Those nodes are new hover
1030 // the valid part stops at first interception
1031 iterCountCurr++;
1032 if (currHoverEndNode != currHoverTestResults_.end()) {
1033 currHoverEndNode++;
1034 }
1035 if (std::find(lastHoverTestResults_.begin(), lastHoverEndNode, hoverResult) == lastHoverEndNode) {
1036 if (!hoverResult->HandleHoverEvent(true, event)) {
1037 lastHoverDispatchLength_ = iterCountCurr;
1038 break;
1039 }
1040 }
1041 if (hoverResult == lastHoverEndNodeTarget) {
1042 lastHoverDispatchLength_ = iterCountCurr;
1043 break;
1044 }
1045 }
1046 for (auto hoverResultIt = lastHoverTestResults_.begin(); hoverResultIt != lastHoverEndNode; ++hoverResultIt) {
1047 // there may have previous hover nodes in the invalid part of current hover nodes. Those nodes exit hover also
1048 if (std::find(currHoverEndNode, currHoverTestResults_.end(), *hoverResultIt) != currHoverTestResults_.end()) {
1049 (*hoverResultIt)->HandleHoverEvent(false, event);
1050 }
1051 }
1052 return true;
1053 }
1054
AxisTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode)1055 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode)
1056 {
1057 CHECK_NULL_VOID(renderNode);
1058 const Point point { event.x, event.y };
1059 WeakPtr<RenderNode> axisNode = nullptr;
1060 renderNode->AxisDetect(point, point, axisNode, event.GetDirection());
1061 axisNode_ = axisNode;
1062 LOGI("Current axis node is %{public}s", AceType::TypeName(axisNode_.Upgrade()));
1063 }
1064
DispatchAxisEvent(const AxisEvent & event)1065 bool EventManager::DispatchAxisEvent(const AxisEvent& event)
1066 {
1067 auto responseNode = axisNode_.Upgrade();
1068 if (responseNode) {
1069 responseNode->HandleAxisEvent(event);
1070 }
1071 return true;
1072 }
1073
AxisTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode)1074 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode)
1075 {
1076 CHECK_NULL_VOID(frameNode);
1077 const NG::PointF point { event.x, event.y };
1078 frameNode->AxisTest(point, point, axisTestResults_);
1079 }
1080
DispatchAxisEventNG(const AxisEvent & event)1081 bool EventManager::DispatchAxisEventNG(const AxisEvent& event)
1082 {
1083 if (event.horizontalAxis == 0 && event.verticalAxis == 0 && event.pinchAxisScale == 0) {
1084 return false;
1085 }
1086 for (const auto& axisTarget : axisTestResults_) {
1087 if (axisTarget && axisTarget->HandleAxisEvent(event)) {
1088 return true;
1089 }
1090 }
1091 return true;
1092 }
1093
DispatchRotationEvent(const RotationEvent & event,const RefPtr<RenderNode> & renderNode,const RefPtr<RenderNode> & requestFocusNode)1094 bool EventManager::DispatchRotationEvent(
1095 const RotationEvent& event, const RefPtr<RenderNode>& renderNode, const RefPtr<RenderNode>& requestFocusNode)
1096 {
1097 CHECK_NULL_RETURN(renderNode, false);
1098 if (requestFocusNode && renderNode->RotationMatchTest(requestFocusNode)) {
1099 return requestFocusNode->RotationTestForward(event);
1100 } else {
1101 return renderNode->RotationTest(event);
1102 }
1103 }
1104
AddKeyboardShortcutNode(const WeakPtr<NG::FrameNode> & node)1105 void EventManager::AddKeyboardShortcutNode(const WeakPtr<NG::FrameNode>& node)
1106 {
1107 auto frameNode = node.Upgrade();
1108 CHECK_NULL_VOID(frameNode);
1109 auto iter = keyboardShortcutNode_.begin();
1110 while (iter != keyboardShortcutNode_.end()) {
1111 auto keyboardShortcutNode = (*iter).Upgrade();
1112 if (!keyboardShortcutNode) {
1113 keyboardShortcutNode_.erase(iter++);
1114 continue;
1115 }
1116 if (keyboardShortcutNode->GetId() == frameNode->GetId()) {
1117 return;
1118 }
1119 ++iter;
1120 }
1121 keyboardShortcutNode_.emplace_back(node);
1122 }
1123
GetKeyboardShortcutKeys(const std::vector<ModifierKey> & keys)1124 uint8_t EventManager::GetKeyboardShortcutKeys(const std::vector<ModifierKey>& keys)
1125 {
1126 uint8_t keyValue = 0;
1127 uint8_t ctrlTimes = 0;
1128 uint8_t shiftTimes = 0;
1129 uint8_t altTimes = 0;
1130 if (keys.size() > KEYS_MAX_VALUE) {
1131 return 0;
1132 }
1133 for (const auto& key : keys) {
1134 switch (static_cast<uint8_t>(key)) {
1135 case static_cast<uint8_t>(ModifierKey::CTRL): {
1136 keyValue |= static_cast<uint8_t>(CtrlKeysBit::CTRL);
1137 ++ctrlTimes;
1138 break;
1139 }
1140 case static_cast<uint8_t>(ModifierKey::SHIFT): {
1141 keyValue |= static_cast<uint8_t>(CtrlKeysBit::SHIFT);
1142 ++shiftTimes;
1143 break;
1144 }
1145 case static_cast<uint8_t>(ModifierKey::ALT): {
1146 keyValue |= static_cast<uint8_t>(CtrlKeysBit::ALT);
1147 ++altTimes;
1148 break;
1149 }
1150 default:
1151 keyValue |= 0;
1152 }
1153 }
1154 if (ctrlTimes > 1 || shiftTimes > 1 || altTimes > 1) {
1155 return 0;
1156 }
1157 return keyValue;
1158 }
1159
IsSystemKeyboardShortcut(const std::string & value,uint8_t keys)1160 bool EventManager::IsSystemKeyboardShortcut(const std::string& value, uint8_t keys)
1161 {
1162 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_C) {
1163 return true;
1164 }
1165 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_A) {
1166 return true;
1167 }
1168 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_V) {
1169 return true;
1170 }
1171 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_X) {
1172 return true;
1173 }
1174 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_Y) {
1175 return true;
1176 }
1177 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_Z) {
1178 return true;
1179 }
1180 if (!(keys ^ (static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT))) &&
1181 value == SHORT_CUT_VALUE_Z) {
1182 return true;
1183 }
1184 return false;
1185 }
1186
IsSameKeyboardShortcutNode(const std::string & value,uint8_t keys)1187 bool EventManager::IsSameKeyboardShortcutNode(const std::string& value, uint8_t keys)
1188 {
1189 if (IsSystemKeyboardShortcut(value, keys)) {
1190 return true;
1191 }
1192 for (auto& weakNode : keyboardShortcutNode_) {
1193 auto frameNode = weakNode.Upgrade();
1194 if (!frameNode) {
1195 continue;
1196 }
1197 auto eventHub = frameNode->GetEventHub<NG::EventHub>();
1198 if (!eventHub) {
1199 continue;
1200 }
1201 auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
1202 for (auto& keyboardShortcut : keyboardShortcuts) {
1203 if (keyboardShortcut.value.find(value) != std::string::npos && keyboardShortcut.keys == keys) {
1204 return true;
1205 }
1206 }
1207 }
1208 return false;
1209 }
1210
AddKeyboardShortcutSingleKey(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1211 void AddKeyboardShortcutSingleKey(
1212 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1213 {
1214 uint8_t index = 0;
1215 std::vector<KeyCode> keyCode1;
1216 std::vector<KeyCode> keyCode2;
1217 if (keys & static_cast<uint8_t>(CtrlKeysBit::CTRL)) {
1218 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
1219 keyCode2.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1220 permutation.emplace_back(++index);
1221 }
1222 if (keys & static_cast<uint8_t>(CtrlKeysBit::SHIFT)) {
1223 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1224 keyCode2.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1225 permutation.emplace_back(++index);
1226 }
1227 if (keys & static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1228 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
1229 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
1230 permutation.emplace_back(++index);
1231 }
1232 keyCodes.emplace_back(keyCode1);
1233 keyCodes.emplace_back(keyCode2);
1234 }
1235
AddKeyboardShortcutDoubleKeysWithCtrlShift(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1236 void AddKeyboardShortcutDoubleKeysWithCtrlShift(
1237 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1238 {
1239 uint8_t index = 0;
1240 std::vector<KeyCode> keyCode1;
1241 std::vector<KeyCode> keyCode2;
1242 std::vector<KeyCode> keyCode3;
1243 std::vector<KeyCode> keyCode4;
1244
1245 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
1246 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
1247 keyCode3.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1248 keyCode4.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1249 permutation.emplace_back(++index);
1250
1251 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1252 keyCode2.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1253 keyCode3.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1254 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1255 permutation.emplace_back(++index);
1256
1257 keyCodes.emplace_back(keyCode1);
1258 keyCodes.emplace_back(keyCode2);
1259 keyCodes.emplace_back(keyCode3);
1260 keyCodes.emplace_back(keyCode4);
1261 }
1262
AddKeyboardShortcutDoubleKeysWithCtrlAlt(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1263 void AddKeyboardShortcutDoubleKeysWithCtrlAlt(
1264 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1265 {
1266 uint8_t index = 0;
1267 std::vector<KeyCode> keyCode1;
1268 std::vector<KeyCode> keyCode2;
1269 std::vector<KeyCode> keyCode3;
1270 std::vector<KeyCode> keyCode4;
1271
1272 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
1273 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
1274 keyCode3.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1275 keyCode4.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1276 permutation.emplace_back(++index);
1277
1278 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
1279 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
1280 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
1281 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
1282 permutation.emplace_back(++index);
1283
1284 keyCodes.emplace_back(keyCode1);
1285 keyCodes.emplace_back(keyCode2);
1286 keyCodes.emplace_back(keyCode3);
1287 keyCodes.emplace_back(keyCode4);
1288 }
1289
AddKeyboardShortcutDoubleKeysWithShiftAlt(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1290 void AddKeyboardShortcutDoubleKeysWithShiftAlt(
1291 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1292 {
1293 uint8_t index = 0;
1294 std::vector<KeyCode> keyCode1;
1295 std::vector<KeyCode> keyCode2;
1296 std::vector<KeyCode> keyCode3;
1297 std::vector<KeyCode> keyCode4;
1298
1299 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1300 keyCode2.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1301 keyCode3.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1302 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1303 permutation.emplace_back(++index);
1304
1305 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
1306 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
1307 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
1308 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
1309 permutation.emplace_back(++index);
1310
1311 keyCodes.emplace_back(keyCode1);
1312 keyCodes.emplace_back(keyCode2);
1313 keyCodes.emplace_back(keyCode3);
1314 keyCodes.emplace_back(keyCode4);
1315 }
1316
AddKeyboardShortcutDoubleKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1317 void AddKeyboardShortcutDoubleKeys(
1318 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1319 {
1320 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT)) {
1321 AddKeyboardShortcutDoubleKeysWithCtrlShift(keys, keyCodes, permutation);
1322 }
1323 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1324 AddKeyboardShortcutDoubleKeysWithCtrlAlt(keys, keyCodes, permutation);
1325 }
1326 if (keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1327 AddKeyboardShortcutDoubleKeysWithShiftAlt(keys, keyCodes, permutation);
1328 }
1329 }
1330
AddKeyboardShortcutTripleKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1331 void AddKeyboardShortcutTripleKeys(
1332 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1333 {
1334 uint8_t index = 0;
1335 std::vector<KeyCode> keyCode1;
1336 std::vector<KeyCode> keyCode2;
1337 std::vector<KeyCode> keyCode3;
1338 std::vector<KeyCode> keyCode4;
1339 std::vector<KeyCode> keyCode5;
1340 std::vector<KeyCode> keyCode6;
1341 std::vector<KeyCode> keyCode7;
1342 std::vector<KeyCode> keyCode8;
1343
1344 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
1345 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
1346 keyCode3.emplace_back(KeyCode::KEY_CTRL_LEFT);
1347 keyCode4.emplace_back(KeyCode::KEY_CTRL_LEFT);
1348 keyCode5.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1349 keyCode6.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1350 keyCode7.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1351 keyCode8.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1352 permutation.emplace_back(++index);
1353
1354 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1355 keyCode2.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1356 keyCode3.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1357 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1358 keyCode5.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1359 keyCode6.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1360 keyCode7.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1361 keyCode8.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1362 permutation.emplace_back(++index);
1363
1364 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
1365 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
1366 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
1367 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
1368 keyCode5.emplace_back(KeyCode::KEY_ALT_LEFT);
1369 keyCode6.emplace_back(KeyCode::KEY_ALT_RIGHT);
1370 keyCode7.emplace_back(KeyCode::KEY_ALT_LEFT);
1371 keyCode8.emplace_back(KeyCode::KEY_ALT_RIGHT);
1372 permutation.emplace_back(++index);
1373
1374 keyCodes.emplace_back(keyCode1);
1375 keyCodes.emplace_back(keyCode2);
1376 keyCodes.emplace_back(keyCode3);
1377 keyCodes.emplace_back(keyCode4);
1378 keyCodes.emplace_back(keyCode5);
1379 keyCodes.emplace_back(keyCode6);
1380 keyCodes.emplace_back(keyCode7);
1381 keyCodes.emplace_back(keyCode8);
1382 }
1383
AddKeyboardShortcutKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1384 void AddKeyboardShortcutKeys(
1385 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1386 {
1387 // single FunctionKey
1388 if (keys == 0) {
1389 keyCodes.emplace_back(std::vector<KeyCode>());
1390 }
1391 // single key
1392 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) || keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) ||
1393 keys == static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1394 LOGI("AddKeyboardShortcutKeys single key");
1395 AddKeyboardShortcutSingleKey(keys, keyCodes, permutation);
1396 }
1397 // double keys
1398 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT) ||
1399 keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::ALT) ||
1400 keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1401 LOGI("AddKeyboardShortcutKeys double keys");
1402 AddKeyboardShortcutDoubleKeys(keys, keyCodes, permutation);
1403 }
1404 // triple keys
1405 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT) +
1406 static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1407 LOGI("AddKeyboardShortcutKeys triple keys");
1408 AddKeyboardShortcutTripleKeys(keys, keyCodes, permutation);
1409 }
1410 }
1411
TriggerKeyboardShortcut(const KeyEvent & event,const std::vector<NG::KeyboardShortcut> & keyboardShortcuts,const WeakPtr<NG::FrameNode> & node,const RefPtr<NG::EventHub> & eventHub)1412 void TriggerKeyboardShortcut(const KeyEvent& event, const std::vector<NG::KeyboardShortcut>& keyboardShortcuts,
1413 const WeakPtr<NG::FrameNode>& node, const RefPtr<NG::EventHub>& eventHub)
1414 {
1415 CHECK_NULL_VOID(eventHub);
1416 for (auto& keyboardShortcut : keyboardShortcuts) {
1417 if (keyboardShortcut.value.empty()) {
1418 continue;
1419 }
1420
1421 std::vector<std::vector<KeyCode>> keyCodes;
1422 std::vector<uint8_t> permutation;
1423 AddKeyboardShortcutKeys(keyboardShortcut.keys, keyCodes, permutation);
1424 // FunctionKey
1425 if (event.IsFunctionKey() || event.IsEscapeKey()) {
1426 if (event.ConvertInputCodeToString() != keyboardShortcut.value) {
1427 continue;
1428 }
1429 } else if (event.ConvertInputCodeToString().find(keyboardShortcut.value) == std::string::npos) {
1430 continue;
1431 }
1432 // Handle left and right the keys problem.
1433 std::vector<uint8_t> perm;
1434 for (auto& keyCode : keyCodes) {
1435 perm.assign(permutation.begin(), permutation.end());
1436 // Handle the keys order problem.
1437 do {
1438 keyCode.emplace_back(event.code);
1439 if (!event.IsKey(keyCode)) {
1440 keyCode.pop_back();
1441 std::next_permutation(keyCode.begin(), keyCode.end());
1442 continue;
1443 }
1444
1445 if (keyboardShortcut.onKeyboardShortcutAction) {
1446 keyboardShortcut.onKeyboardShortcutAction();
1447 LOGI("TriggerKeyboardShortcut action done.");
1448 } else {
1449 auto gestureEventHub = eventHub->GetGestureEventHub();
1450 if (gestureEventHub && gestureEventHub->IsClickable()) {
1451 gestureEventHub->KeyBoardShortCutClick(event, node);
1452 LOGI("TriggerKeyboardShortcut click done.");
1453 }
1454 }
1455 keyCode.pop_back();
1456 std::next_permutation(keyCode.begin(), keyCode.end());
1457 } while (std::next_permutation(perm.begin(), perm.end()));
1458 perm.clear();
1459 }
1460 keyCodes.clear();
1461 permutation.clear();
1462 }
1463 }
1464
DispatchKeyboardShortcut(const KeyEvent & event)1465 void EventManager::DispatchKeyboardShortcut(const KeyEvent& event)
1466 {
1467 if (event.action != KeyAction::DOWN) {
1468 return;
1469 }
1470 for (auto& node : keyboardShortcutNode_) {
1471 auto frameNode = node.Upgrade();
1472 if (!frameNode || !(frameNode->IsActive())) {
1473 continue;
1474 }
1475 auto eventHub = frameNode->GetEventHub<NG::EventHub>();
1476 if (!eventHub || !(eventHub->IsEnabled())) {
1477 continue;
1478 }
1479
1480 auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
1481 TriggerKeyboardShortcut(event, keyboardShortcuts, node, eventHub);
1482 }
1483 }
1484
DelKeyboardShortcutNode(int32_t nodeId)1485 void EventManager::DelKeyboardShortcutNode(int32_t nodeId)
1486 {
1487 auto iter = keyboardShortcutNode_.begin();
1488 while (iter != keyboardShortcutNode_.end()) {
1489 auto frameNode = (*iter).Upgrade();
1490 if (!frameNode) {
1491 keyboardShortcutNode_.erase(iter++);
1492 continue;
1493 }
1494 if (frameNode->GetId() == nodeId) {
1495 keyboardShortcutNode_.erase(iter);
1496 break;
1497 }
1498 ++iter;
1499 }
1500 }
1501
ClearResults()1502 void EventManager::ClearResults()
1503 {
1504 touchTestResults_.clear();
1505 postEventTouchTestResults_.clear();
1506 mouseTestResults_.clear();
1507 axisTouchTestResults_.clear();
1508 keyboardShortcutNode_.clear();
1509 }
1510
EventManager()1511 EventManager::EventManager()
1512 {
1513 refereeNG_ = AceType::MakeRefPtr<NG::GestureReferee>();
1514 postEventRefereeNG_ = AceType::MakeRefPtr<NG::GestureReferee>();
1515 referee_ = AceType::MakeRefPtr<GestureReferee>();
1516 responseCtrl_ = AceType::MakeRefPtr<NG::ResponseCtrl>();
1517
1518 auto callback = [weak = WeakClaim(this)](size_t touchId) -> bool {
1519 auto eventManager = weak.Upgrade();
1520 CHECK_NULL_RETURN(eventManager, false);
1521 auto refereeNG = eventManager->refereeNG_;
1522 CHECK_NULL_RETURN(refereeNG, false);
1523 return refereeNG->HasGestureAccepted(touchId);
1524 };
1525 referee_->SetQueryStateFunc(std::move(callback));
1526
1527 auto cleanReferee = [weak = WeakClaim(this)](size_t touchId) -> void {
1528 auto eventManager = weak.Upgrade();
1529 CHECK_NULL_VOID(eventManager);
1530 auto referee = eventManager->referee_;
1531 CHECK_NULL_VOID(referee);
1532 auto gestureScope = referee->GetGestureScope();
1533 const auto iter = gestureScope.find(touchId);
1534 if (iter == gestureScope.end()) {
1535 return;
1536 }
1537
1538 auto highRecognizers = iter->second.GetHighRecognizers();
1539 auto lowRecognizers = iter->second.GetLowRecognizers();
1540 auto parallelRecognizers = iter->second.GetParallelRecognizers();
1541
1542 for (const auto& weak : highRecognizers) {
1543 auto gesture = weak.Upgrade();
1544 if (gesture) {
1545 gesture->OnRejected(touchId);
1546 }
1547 }
1548
1549 for (const auto& weak : lowRecognizers) {
1550 auto gesture = weak.Upgrade();
1551 if (gesture) {
1552 gesture->OnRejected(touchId);
1553 }
1554 }
1555
1556 for (const auto& weak : parallelRecognizers) {
1557 auto gesture = weak.Upgrade();
1558 if (gesture) {
1559 gesture->OnRejected(touchId);
1560 }
1561 }
1562 };
1563 refereeNG_->SetQueryStateFunc(std::move(cleanReferee));
1564 }
1565
DumpEvent() const1566 void EventManager::DumpEvent() const
1567 {
1568 std::list<std::pair<int32_t, std::string>> dumpList;
1569 eventTree_.Dump(dumpList, 0);
1570 for (auto& item : dumpList) {
1571 DumpLog::GetInstance().Print(item.first, item.second);
1572 }
1573 }
1574
AddGestureSnapshot(int32_t finger,int32_t depth,const RefPtr<TouchEventTarget> & target)1575 void EventManager::AddGestureSnapshot(int32_t finger, int32_t depth, const RefPtr<TouchEventTarget>& target)
1576 {
1577 if (!target) {
1578 return;
1579 }
1580 RefPtr<GestureSnapshot> info = target->Dump();
1581 auto frameNode = target->GetAttachedNode().Upgrade();
1582 if (frameNode) {
1583 info->nodeId = frameNode->GetId();
1584 }
1585 info->depth = depth;
1586 eventTree_.AddGestureSnapshot(finger, std::move(info));
1587
1588 // add child gesture if target is group
1589 auto group = AceType::DynamicCast<NG::RecognizerGroup>(target);
1590 if (group) {
1591 for (const auto& child : group->GetGroupRecognizer()) {
1592 AddGestureSnapshot(finger, depth + 1, child);
1593 }
1594 }
1595 }
1596
SetHittedFrameNode(const std::list<RefPtr<NG::NGGestureRecognizer>> & touchTestResults)1597 void EventManager::SetHittedFrameNode(const std::list<RefPtr<NG::NGGestureRecognizer>>& touchTestResults)
1598 {
1599 if (touchTestResults.empty()) {
1600 return;
1601 }
1602 for (const auto& item : touchTestResults) {
1603 auto node = item->GetAttachedNode().Upgrade();
1604 if (node) {
1605 hittedFrameNode_.emplace(node);
1606 }
1607 auto group = AceType::DynamicCast<NG::RecognizerGroup>(item);
1608 if (group) {
1609 auto groupRecognizers = group->GetGroupRecognizer();
1610 SetHittedFrameNode(groupRecognizers);
1611 }
1612 }
1613 }
1614
CleanGestureEventHub()1615 void EventManager::CleanGestureEventHub()
1616 {
1617 for (const auto& item : hittedFrameNode_) {
1618 auto frameNode = item.Upgrade();
1619 if (frameNode) {
1620 auto gestureEventHub = frameNode->GetOrCreateGestureEventHub();
1621 if (gestureEventHub) {
1622 gestureEventHub->CleanExternalRecognizers();
1623 }
1624 }
1625 }
1626 hittedFrameNode_.clear();
1627 }
1628
1629 } // namespace OHOS::Ace
1630