• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/components_ng/gestures/recognizers/long_press_recognizer.h"
17 
18 #include "base/perf/socperf_client.h"
19 #include "base/thread/frame_trace_adapter.h"
20 #include "base/utils/time_util.h"
21 #include "base/utils/utils.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/event/gesture_event_hub.h"
25 #include "core/components_ng/gestures/base_gesture_event.h"
26 #include "core/components_ng/gestures/gesture_referee.h"
27 #include "core/components_ng/gestures/recognizers/gesture_recognizer.h"
28 #include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
29 #include "core/event/ace_events.h"
30 #include "core/pipeline_ng/pipeline_context.h"
31 
32 namespace OHOS::Ace::NG {
33 namespace {
34 constexpr double MAX_THRESHOLD = 15.0;
35 constexpr int32_t MAX_LONGPRESS_FINGERS = 10;
36 constexpr int32_t DEFAULT_LONGPRESS_FINGERS = 1;
37 constexpr int32_t DEFAULT_LONGPRESS_DURATION = 500;
38 } // namespace
39 
LongPressRecognizer(int32_t duration,int32_t fingers,bool repeat,bool isForDrag,bool isDisableMouseLeft,bool isLimitFingerCount)40 LongPressRecognizer::LongPressRecognizer(
41     int32_t duration, int32_t fingers, bool repeat, bool isForDrag, bool isDisableMouseLeft, bool isLimitFingerCount)
42     : MultiFingersRecognizer(fingers, isLimitFingerCount), duration_(duration), repeat_(repeat), isForDrag_(isForDrag),
43       isDisableMouseLeft_(isDisableMouseLeft)
44 {
45     if (fingers_ > MAX_LONGPRESS_FINGERS || fingers_ < DEFAULT_LONGPRESS_FINGERS) {
46         fingers_ = DEFAULT_LONGPRESS_FINGERS;
47     }
48     if (duration_ <= 0) {
49         duration_ = DEFAULT_LONGPRESS_DURATION;
50     }
51 }
52 
OnAccepted()53 void LongPressRecognizer::OnAccepted()
54 {
55     int64_t acceptTime = GetSysTimestamp();
56     int64_t inputTime = acceptTime;
57     if (firstInputTime_.has_value()) {
58         inputTime = static_cast<int64_t>(firstInputTime_.value().time_since_epoch().count());
59     }
60     if (SystemProperties::GetTraceInputEventEnabled()) {
61         ACE_SCOPED_TRACE("UserEvent InputTime:%lld AcceptTime:%lld InputType:LongPressGesture",
62             static_cast<long long>(inputTime), static_cast<long long>(acceptTime));
63     }
64 
65     auto node = GetAttachedNode().Upgrade();
66     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "LongPress accepted, tag = %{public}s",
67         node ? node->GetTag().c_str() : "null");
68     if (onAccessibilityEventFunc_) {
69         onAccessibilityEventFunc_(AccessibilityEventType::LONG_PRESS);
70     }
71     refereeState_ = RefereeState::SUCCEED;
72     if (onLongPress_ && !touchPoints_.empty()) {
73         TouchEvent trackPoint = touchPoints_.begin()->second;
74         PointF localPoint(trackPoint.GetOffset().GetX(), trackPoint.GetOffset().GetY());
75         NGGestureRecognizer::Transform(localPoint, GetAttachedNode(), false,
76             isPostEventResult_, trackPoint.postEventNodeId);
77         LongPressInfo info(trackPoint.id);
78         info.SetTimeStamp(time_);
79         info.SetScreenLocation(trackPoint.GetScreenOffset());
80         info.SetGlobalLocation(trackPoint.GetOffset()).SetLocalLocation(Offset(localPoint.GetX(), localPoint.GetY()));
81         info.SetTarget(GetEventTarget().value_or(EventTarget()));
82         onLongPress_(info);
83     }
84 
85     UpdateFingerListInfo();
86     SendCallbackMsg(onActionUpdate_, false);
87     SendCallbackMsg(onAction_, false, true);
88     if (repeat_) {
89         StartRepeatTimer();
90     }
91 }
92 
OnRejected()93 void LongPressRecognizer::OnRejected()
94 {
95     if (refereeState_ == RefereeState::SUCCEED) {
96         return;
97     }
98     SendRejectMsg();
99     refereeState_ = RefereeState::FAIL;
100     firstInputTime_.reset();
101 }
102 
ThumbnailTimer(int32_t time)103 void LongPressRecognizer::ThumbnailTimer(int32_t time)
104 {
105     auto context = PipelineContext::GetCurrentContext();
106     CHECK_NULL_VOID(context);
107     if (!callback_) {
108         return;
109     }
110     auto&& callback = [weakPtr = AceType::WeakClaim(this), customCallback = callback_]() {
111         auto refPtr = weakPtr.Upgrade();
112         if (!refPtr) {
113             return;
114         }
115         if (refPtr->refereeState_ == RefereeState::DETECTING) {
116             customCallback(Offset(refPtr->globalPoint_.GetX(), refPtr->globalPoint_.GetY()));
117         }
118     };
119     thumbnailTimer_.Reset(callback);
120     auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
121     taskExecutor.PostDelayedTask(thumbnailTimer_, time, "ArkUIGestureLongPressThumbnailTimer");
122 }
123 
HandleTouchDownEvent(const TouchEvent & event)124 void LongPressRecognizer::HandleTouchDownEvent(const TouchEvent& event)
125 {
126     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "Id:%{public}d, LongPress %{public}d down, state: %{public}d",
127         event.touchEventId, event.id, refereeState_);
128     extraInfo_ = "";
129     if (!firstInputTime_.has_value()) {
130         firstInputTime_ = event.time;
131     }
132 
133     if (isDisableMouseLeft_ && event.sourceType == SourceType::MOUSE) {
134         TAG_LOGI(AceLogTag::ACE_GESTURE, "Mouse left button is disabled for long press recognizer");
135         extraInfo_ += "Reject: mouse left button disabled.";
136         Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
137         return;
138     }
139 
140     if (!IsInAttachedNode(event)) {
141         extraInfo_ += "Reject: not in attached node.";
142         Adjudicate(Claim(this), GestureDisposal::REJECT);
143         return;
144     }
145     int32_t curDuration = duration_;
146 #if defined(OHOS_STANDARD_SYSTEM) && !defined(PREVIEW)
147     if (!IsPostEventResult()) {
148         int64_t currentTimeStamp = GetSysTimestamp();
149         int64_t eventTimeStamp = static_cast<int64_t>(event.time.time_since_epoch().count());
150         if (currentTimeStamp > eventTimeStamp) {
151             // nanoseconds to millisceond.
152             curDuration = curDuration - static_cast<int32_t>((currentTimeStamp - eventTimeStamp) / (1000 * 1000));
153             curDuration = curDuration < 0 ? 0 : curDuration;
154         }
155     }
156 #endif
157 
158     if (isForDrag_ && event.sourceType == SourceType::MOUSE) {
159         curDuration = 0;
160     }
161     if ((touchRestrict_.forbiddenType & TouchRestrict::LONG_PRESS) == TouchRestrict::LONG_PRESS) {
162         extraInfo_ += "Reject: long press forbidden.";
163         Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
164         return;
165     }
166     if (fingersId_.find(event.id) == fingersId_.end()) {
167         fingersId_.insert(event.id);
168     }
169     globalPoint_ = Point(event.x, event.y);
170     touchPoints_[event.id] = event;
171     lastTouchEvent_ = event;
172     UpdateFingerListInfo();
173     if (GetValidFingersCount() == fingers_) {
174         refereeState_ = RefereeState::DETECTING;
175         if (useCatchMode_) {
176             DeadlineTimer(curDuration, true);
177         } else {
178             DeadlineTimer(curDuration, false);
179         }
180     } else {
181         PrintCurrentFingersInfo();
182     }
183 
184     ThumbnailTimer(thumbnailDeadline);
185 }
186 
HandleTouchUpEvent(const TouchEvent & event)187 void LongPressRecognizer::HandleTouchUpEvent(const TouchEvent& event)
188 {
189     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "Id:%{public}d, LongPress %{public}d up, state: %{public}d",
190         event.touchEventId, event.id, refereeState_);
191     auto context = PipelineContext::GetCurrentContext();
192     CHECK_NULL_VOID(context);
193     context->RemoveGestureTask(task_);
194     if (fingersId_.find(event.id) != fingersId_.end()) {
195         fingersId_.erase(event.id);
196     }
197     if (touchPoints_.find(event.id) != touchPoints_.end()) {
198         touchPoints_.erase(event.id);
199     }
200     lastTouchEvent_ = event;
201     if (refereeState_ == RefereeState::SUCCEED) {
202         if (isLimitFingerCount_ && static_cast<int32_t>(touchPoints_.size()) == fingers_) {
203             SendCallbackMsg(onAction_, false, true);
204         }
205         SendCallbackMsg(onActionUpdate_, false);
206         if (static_cast<int32_t>(touchPoints_.size()) == 0) {
207             SendCallbackMsg(onActionEnd_, false);
208             int64_t overTime = GetSysTimestamp();
209             int64_t inputTime = overTime;
210             if (firstInputTime_.has_value()) {
211                 inputTime = static_cast<int64_t>(firstInputTime_.value().time_since_epoch().count());
212             }
213             if (SystemProperties::GetTraceInputEventEnabled()) {
214                 ACE_SCOPED_TRACE("UserEvent InputTime:%lld OverTime:%lld InputType:LongPressGesture",
215                     static_cast<long long>(inputTime), static_cast<long long>(overTime));
216             }
217             firstInputTime_.reset();
218         }
219     } else {
220         extraInfo_ += "Reject: received up but not succeed.";
221         Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
222     }
223 }
224 
HandleTouchMoveEvent(const TouchEvent & event)225 void LongPressRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
226 {
227     lastTouchEvent_.pressedKeyCodes_ = event.pressedKeyCodes_;
228     if (static_cast<int32_t>(touchPoints_.size()) < fingers_) {
229         return;
230     }
231     if (IsRefereeFinished()) {
232         return;
233     }
234     Offset offset = event.GetOffset() - touchPoints_[event.id].GetOffset();
235     if (offset.GetDistance() > MAX_THRESHOLD) {
236         extraInfo_ += "Reject: move over max threshold.";
237         Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
238         return;
239     }
240     touchPoints_[event.id].operatingHand = event.operatingHand;
241     lastTouchEvent_ = event;
242     UpdateFingerListInfo();
243     time_ = event.time;
244 }
245 
HandleTouchCancelEvent(const TouchEvent & event)246 void LongPressRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
247 {
248     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "Id:%{public}d, LongPress %{public}d cancel, TPS:%{public}d",
249         event.touchEventId, event.id, static_cast<int32_t>(touchPoints_.size()));
250     if (refereeState_ == RefereeState::FAIL) {
251         return;
252     }
253     lastTouchEvent_ = event;
254     if (touchPoints_.find(event.id) != touchPoints_.end()) {
255         touchPoints_.erase(event.id);
256     }
257     if (refereeState_ == RefereeState::SUCCEED && static_cast<int32_t>(touchPoints_.size()) == 0) {
258         SendCancelMsg();
259         refereeState_ = RefereeState::READY;
260         extraInfo_ += "Reject: received cancel and succeed.";
261     } else {
262         extraInfo_ += "Reject: received cancel but not succeed.";
263         Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
264     }
265 }
266 
HandleOverdueDeadline(bool isCatchMode)267 void LongPressRecognizer::HandleOverdueDeadline(bool isCatchMode)
268 {
269     if (refereeState_ != RefereeState::DETECTING) {
270         return;
271     }
272     if (!isCatchMode) {
273         OnAccepted();
274         return;
275     }
276     if (gestureInfo_ && gestureInfo_->GetType() == GestureTypeName::DRAG) {
277         auto dragEventActuator = GetDragEventActuator();
278         CHECK_NULL_VOID(dragEventActuator);
279         if (dragEventActuator->IsDragUserReject()) {
280             TAG_LOGI(AceLogTag::ACE_GESTURE, "Drag long press reject because of user's reject");
281             extraInfo_ += "Reject: user reject.";
282             Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
283             return;
284         }
285     }
286     auto onGestureJudgeBeginResult = TriggerGestureJudgeCallback();
287     if (onGestureJudgeBeginResult == GestureJudgeResult::REJECT) {
288         TAG_LOGI(AceLogTag::ACE_GESTURE, "Long press reject as judge result is reject");
289         extraInfo_ += "Reject: judge reject.";
290         Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
291         if (gestureInfo_ && gestureInfo_->GetType() == GestureTypeName::DRAG) {
292             auto dragEventActuator = GetDragEventActuator();
293             CHECK_NULL_VOID(dragEventActuator);
294             dragEventActuator->SetIsDragUserReject(true);
295         }
296         return;
297     }
298     if (CheckLimitFinger()) {
299         Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
300         return;
301     }
302     Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
303 }
304 
DeadlineTimer(int32_t time,bool isCatchMode)305 void LongPressRecognizer::DeadlineTimer(int32_t time, bool isCatchMode)
306 {
307     auto context = PipelineContext::GetCurrentContext();
308     CHECK_NULL_VOID(context);
309 
310     auto&& callback = [weakPtr = AceType::WeakClaim(this), isCatchMode]() {
311         auto refPtr = weakPtr.Upgrade();
312         if (refPtr) {
313             refPtr->HandleOverdueDeadline(isCatchMode);
314         }
315     };
316     task_ = { WeakClaim(this), GetSysTimestamp(), time, callback };
317     context->AddGestureTask(task_);
318 
319     auto&& flushCallback = []() {
320         auto context = PipelineContext::GetCurrentContext();
321         CHECK_NULL_VOID(context);
322         context->RequestFrame();
323     };
324     deadlineTimer_.Reset(flushCallback);
325     auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
326     taskExecutor.PostDelayedTask(deadlineTimer_, time, "ArkUIGestureLongPressDeadlineTimer");
327 }
328 
DoRepeat()329 void LongPressRecognizer::DoRepeat()
330 {
331     if (static_cast<int32_t>(touchPoints_.size()) < fingers_) {
332         return;
333     }
334     if (static_cast<int32_t>(touchPoints_.size()) > fingers_ && isLimitFingerCount_) {
335         return;
336     }
337     if (refereeState_ == RefereeState::SUCCEED) {
338         SendCallbackMsg(onAction_, true, true);
339         StartRepeatTimer();
340     }
341 }
342 
StartRepeatTimer()343 void LongPressRecognizer::StartRepeatTimer()
344 {
345     auto context = PipelineContext::GetCurrentContext();
346     CHECK_NULL_VOID(context);
347 
348     auto&& callback = [weakPtr = AceType::WeakClaim(this)]() {
349         auto refPtr = weakPtr.Upgrade();
350         if (refPtr) {
351             refPtr->DoRepeat();
352         }
353     };
354     timer_.Reset(callback);
355     auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
356     taskExecutor.PostDelayedTask(timer_, duration_, "ArkUIGestureLongPressRepeatTimer");
357 }
358 
ConvertPxToVp(double offset) const359 double LongPressRecognizer::ConvertPxToVp(double offset) const
360 {
361     auto context = PipelineContext::GetCurrentContext();
362     CHECK_NULL_RETURN(context, offset);
363 
364     double vpOffset = context->ConvertPxToVp(Dimension(offset, DimensionUnit::PX));
365     return vpOffset;
366 }
367 
SendCallbackMsg(const std::unique_ptr<GestureEventFunc> & callback,bool isRepeat,bool isOnAction)368 void LongPressRecognizer::SendCallbackMsg(
369     const std::unique_ptr<GestureEventFunc>& callback, bool isRepeat, bool isOnAction)
370 {
371     if (gestureInfo_ && gestureInfo_->GetDisposeTag()) {
372         return;
373     }
374     if (callback && *callback) {
375         GestureEvent info;
376         info.SetTimeStamp(time_);
377         info.SetRepeat(isRepeat);
378         info.SetFingerList(fingerList_);
379         info.SetSourceDevice(deviceType_);
380         info.SetDeviceId(deviceId_);
381         info.SetTargetDisplayId(lastTouchEvent_.targetDisplayId);
382         info.SetGlobalPoint(globalPoint_);
383         info.SetScreenLocation(lastTouchEvent_.GetScreenOffset());
384         info.SetGlobalLocation(lastTouchEvent_.GetOffset())
385             .SetLocalLocation(lastTouchEvent_.GetOffset() - coordinateOffset_);
386         info.SetTarget(GetEventTarget().value_or(EventTarget()));
387         info.SetForce(lastTouchEvent_.force);
388         if (lastTouchEvent_.tiltX.has_value()) {
389             info.SetTiltX(lastTouchEvent_.tiltX.value());
390         }
391         if (lastTouchEvent_.tiltY.has_value()) {
392             info.SetTiltY(lastTouchEvent_.tiltY.value());
393         }
394         info.SetSourceTool(lastTouchEvent_.sourceTool);
395         info.SetPointerEvent(lastPointEvent_);
396         Platform::UpdatePressedKeyCodes(lastTouchEvent_.pressedKeyCodes_);
397         info.SetPressedKeyCodes(lastTouchEvent_.pressedKeyCodes_);
398         info.SetInputEventType(inputEventType_);
399         // callback may be overwritten in its invoke so we copy it first
400         auto callbackFunction = *callback;
401         callbackFunction(info);
402         if (isOnAction && longPressRecorder_ && *longPressRecorder_) {
403             (*longPressRecorder_)(info);
404         }
405     }
406 }
407 
OnResetStatus()408 void LongPressRecognizer::OnResetStatus()
409 {
410     MultiFingersRecognizer::OnResetStatus();
411     timer_.Cancel();
412     deadlineTimer_.Cancel();
413     auto context = PipelineContext::GetCurrentContext();
414     CHECK_NULL_VOID(context);
415     context->RemoveGestureTask(task_);
416 }
417 
ReconcileFrom(const RefPtr<NGGestureRecognizer> & recognizer)418 bool LongPressRecognizer::ReconcileFrom(const RefPtr<NGGestureRecognizer>& recognizer)
419 {
420     RefPtr<LongPressRecognizer> curr = AceType::DynamicCast<LongPressRecognizer>(recognizer);
421     if (!curr) {
422         ResetStatus();
423         return false;
424     }
425 
426     if (curr->duration_ != duration_ || curr->fingers_ != fingers_ || curr->repeat_ != repeat_ ||
427         curr->priorityMask_ != priorityMask_) {
428         if (refereeState_ == RefereeState::SUCCEED && static_cast<int32_t>(touchPoints_.size()) > 0) {
429             SendCancelMsg();
430         }
431         ResetStatus();
432         return false;
433     }
434 
435     onAction_ = std::move(curr->onAction_);
436     onActionEnd_ = std::move(curr->onActionEnd_);
437     onActionCancel_ = std::move(curr->onActionCancel_);
438     ReconcileGestureInfoFrom(recognizer);
439     return true;
440 }
441 
GetLongPressActionFunc()442 GestureEventFunc LongPressRecognizer::GetLongPressActionFunc()
443 {
444     auto callback = [weak = WeakClaim(this)](GestureEvent& info) {
445         auto longPressRecognizer = weak.Upgrade();
446         CHECK_NULL_VOID(longPressRecognizer);
447         if (longPressRecognizer->onActionUpdate_) {
448             (*(longPressRecognizer->onActionUpdate_))(info);
449         }
450         if (longPressRecognizer->onAction_) {
451             (*(longPressRecognizer->onAction_))(info);
452         }
453         if (longPressRecognizer->onActionUpdate_) {
454             (*(longPressRecognizer->onActionUpdate_))(info);
455         }
456         if (longPressRecognizer->onActionEnd_) {
457             (*(longPressRecognizer->onActionEnd_))(info);
458         }
459     };
460     return callback;
461 }
462 
Dump() const463 RefPtr<GestureSnapshot> LongPressRecognizer::Dump() const
464 {
465     RefPtr<GestureSnapshot> info = NGGestureRecognizer::Dump();
466     std::stringstream oss;
467     oss << "duration: " << duration_ << ", "
468         << "isForDrag: " << isForDrag_ << ", "
469         << "repeat: " << repeat_ << ", "
470         << "fingers: " << fingers_ << ", "
471         << DumpGestureInfo();
472     info->customInfo = oss.str();
473     return info;
474 }
475 
PrintCurrentFingersInfo() const476 void LongPressRecognizer::PrintCurrentFingersInfo() const
477 {
478     std::string log = "Fingers number = ";
479     log += std::to_string(GetValidFingersCount());
480     log += " fingers_ = ";
481     log += std::to_string(fingers_);
482     log += ". ";
483     for (const auto& iter : touchPoints_) {
484         log += "Event id = ";
485         log += std::to_string(iter.first);
486         log += ", event type = ";
487         log += std::to_string(static_cast<int32_t>(iter.second.type));
488         log += "; ";
489     }
490     TAG_LOGI(AceLogTag::ACE_GESTURE, "Finger info : %{public}s", log.c_str());
491 }
492 
TriggerGestureJudgeCallback()493 GestureJudgeResult LongPressRecognizer::TriggerGestureJudgeCallback()
494 {
495     auto targetComponent = GetTargetComponent();
496     CHECK_NULL_RETURN(targetComponent, GestureJudgeResult::CONTINUE);
497     auto gestureRecognizerJudgeFunc = targetComponent->GetOnGestureRecognizerJudgeBegin();
498     auto callback = targetComponent->GetOnGestureJudgeBeginCallback();
499     if (!callback && !gestureRecognizerJudgeFunc) {
500         return GestureJudgeResult::CONTINUE;
501     }
502     auto info = std::make_shared<LongPressGestureEvent>();
503     info->SetTimeStamp(time_);
504     info->SetDeviceId(deviceId_);
505     info->SetRepeat(repeat_);
506     info->SetFingerList(fingerList_);
507     TouchEvent trackPoint = {};
508     if (!touchPoints_.empty()) {
509         trackPoint = touchPoints_.begin()->second;
510     }
511     info->SetSourceDevice(deviceType_);
512     info->SetTarget(GetEventTarget().value_or(EventTarget()));
513     info->SetForce(trackPoint.force);
514     if (gestureInfo_) {
515         gestureInfo_->SetInputEventType(inputEventType_);
516     }
517     if (trackPoint.tiltX.has_value()) {
518         info->SetTiltX(trackPoint.tiltX.value());
519     }
520     if (trackPoint.tiltY.has_value()) {
521         info->SetTiltY(trackPoint.tiltY.value());
522     }
523     info->SetSourceTool(trackPoint.sourceTool);
524     if (gestureRecognizerJudgeFunc) {
525         return gestureRecognizerJudgeFunc(info, Claim(this), responseLinkRecognizer_);
526     }
527     return callback(gestureInfo_, info);
528 }
529 
GetDragEventActuator()530 RefPtr<DragEventActuator> LongPressRecognizer::GetDragEventActuator()
531 {
532     auto targetComponent = GetTargetComponent();
533     CHECK_NULL_RETURN(targetComponent, nullptr);
534     auto uiNode = targetComponent->GetUINode().Upgrade();
535     CHECK_NULL_RETURN(uiNode, nullptr);
536     auto frameNode = AceType::DynamicCast<FrameNode>(uiNode);
537     CHECK_NULL_RETURN(frameNode, nullptr);
538     auto gestureEventHub = frameNode->GetOrCreateGestureEventHub();
539     CHECK_NULL_RETURN(gestureEventHub, nullptr);
540     return gestureEventHub->GetDragEventActuator();
541 }
542 
543 } // namespace OHOS::Ace::NG
544