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