• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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/event/gesture_event_hub.h"
17 
18 #include <cstdint>
19 #include <list>
20 #include <memory>
21 #include <string>
22 #include "drag_event.h"
23 
24 #include "base/log/log_wrapper.h"
25 #include "base/memory/ace_type.h"
26 #include "base/subwindow/subwindow_manager.h"
27 #include "base/utils/time_util.h"
28 #include "base/image/image_source.h"
29 #include "core/common/container.h"
30 #include "core/common/interaction/interaction_data.h"
31 #include "core/common/interaction/interaction_interface.h"
32 #include "core/components/common/layout/grid_system_manager.h"
33 #include "core/components/container_modal/container_modal_constants.h"
34 #include "core/components_ng/base/frame_node.h"
35 #include "core/components_ng/event/click_event.h"
36 #include "core/components_ng/event/event_hub.h"
37 #include "core/components_ng/gestures/recognizers/click_recognizer.h"
38 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
39 #include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
40 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
41 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
42 #include "core/components_ng/gestures/recognizers/pinch_recognizer.h"
43 #include "core/components_ng/gestures/recognizers/rotation_recognizer.h"
44 #include "core/components_ng/gestures/recognizers/swipe_recognizer.h"
45 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
46 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
47 #include "core/components_ng/manager/drag_drop/drag_drop_manager.h"
48 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
49 #include "core/components_ng/pattern/image/image_pattern.h"
50 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
51 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
52 #include "core/components_ng/pattern/image/image_layout_property.h"
53 #include "core/gestures/gesture_info.h"
54 #include "core/pipeline_ng/pipeline_context.h"
55 
56 #if defined(PIXEL_MAP_SUPPORTED)
57 #include "image_source.h"
58 #endif
59 
60 #include "core/common/udmf/udmf_client.h"
61 #include "core/components_ng/render/adapter/component_snapshot.h"
62 #ifdef WEB_SUPPORTED
63 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
64 #include "core/components_ng/pattern/web/web_pattern.h"
65 #else
66 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
67 #endif
68 #endif
69 namespace OHOS::Ace::NG {
70 namespace {
71 #if defined(PIXEL_MAP_SUPPORTED)
72 constexpr int32_t CREATE_PIXELMAP_TIME = 30;
73 constexpr int32_t MAX_BUILDER_DEPTH = 5;
74 #endif
75 constexpr uint32_t EXTRA_INFO_MAX_LENGTH = 200;
76 constexpr int32_t PIXELMAP_ANIMATION_DURATION = 250;
77 constexpr float PIXELMAP_OPACITY_RATE = 0.95f;
78 } // namespace
79 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
80 constexpr const char* HIT_TEST_MODE[] = {
81     "HitTestMode.Default",
82     "HitTestMode.Block",
83     "HitTestMode.Transparent",
84     "HitTestMode.None",
85 };
86 
GestureEventHub(const WeakPtr<EventHub> & eventHub)87 GestureEventHub::GestureEventHub(const WeakPtr<EventHub>& eventHub) : eventHub_(eventHub) {}
88 
GetFrameNode() const89 RefPtr<FrameNode> GestureEventHub::GetFrameNode() const
90 {
91     auto eventHub = eventHub_.Upgrade();
92     return eventHub ? eventHub->GetFrameNode() : nullptr;
93 }
94 
ProcessTouchTestHit(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & innerTargets,TouchTestResult & finalResult,int32_t touchId,const PointF & localPoint,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)95 bool GestureEventHub::ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
96     TouchTestResult& innerTargets, TouchTestResult& finalResult, int32_t touchId, const PointF& localPoint,
97     const RefPtr<TargetComponent>& targetComponent, ResponseLinkResult& responseLinkResult)
98 {
99     auto host = GetFrameNode();
100     CHECK_NULL_RETURN(host, false);
101     auto eventHub = eventHub_.Upgrade();
102     auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
103     if (scrollableActuator_) {
104         scrollableActuator_->CollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets,
105             localPoint, host, targetComponent, responseLinkResult);
106     }
107     size_t idx = innerTargets.size();
108     size_t newIdx = 0;
109     if (dragEventActuator_) {
110         dragEventActuator_->AddTouchListener(touchRestrict);
111     }
112     if (touchEventActuator_) {
113         touchEventActuator_->OnCollectTouchTarget(
114             coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
115     }
116     if (clickEventActuator_ && !redirectClick_) {
117         clickEventActuator_->OnCollectTouchTarget(
118             coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
119     }
120     if (userParallelClickEventActuator_) {
121         auto clickRecognizer = userParallelClickEventActuator_->GetClickRecognizer();
122         if (clickRecognizer) {
123             clickRecognizer->SetGestureInfo(
124                 MakeRefPtr<GestureInfo>(GestureTypeName::CLICK, GestureTypeName::CLICK, true));
125             clickRecognizer->SetOnAction(userParallelClickEventActuator_->GetClickEvent());
126             clickRecognizer->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
127             clickRecognizer->SetGetEventTargetImpl(getEventTargetImpl);
128         }
129     }
130     if (panEventActuator_) {
131         panEventActuator_->OnCollectTouchTarget(
132             coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
133     }
134 
135     TouchTestResult dragTargets;
136     if (longPressEventActuator_) {
137         longPressEventActuator_->OnCollectTouchTarget(
138             coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets, responseLinkResult);
139     }
140     if (dragEventActuator_) {
141         dragEventActuator_->OnCollectTouchTarget(
142             coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets, responseLinkResult);
143     }
144 
145     std::list<RefPtr<NGGestureRecognizer>> longPressRecognizers;
146     for (const auto& item : dragTargets) {
147         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(item);
148         if (recognizer) {
149             recognizer->BeginReferee(touchId);
150             recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
151             recognizer->SetTargetComponent(targetComponent);
152             if (AceType::InstanceOf<RecognizerGroup>(recognizer)) {
153                 auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
154                 if (group) {
155                     group->SetChildrenTargetComponent(targetComponent);
156                 }
157             }
158         }
159         longPressRecognizers.emplace_back(AceType::DynamicCast<NGGestureRecognizer>(item));
160     }
161     if (!longPressRecognizers.empty()) {
162         // this node has long press and drag event, combine into parallelRecognizer.
163         if (!nodeParallelRecognizer_) {
164             nodeParallelRecognizer_ = MakeRefPtr<ParallelRecognizer>(std::move(longPressRecognizers));
165         } else {
166             nodeParallelRecognizer_->AddChildren(longPressRecognizers);
167         }
168         innerTargets.emplace_back(nodeParallelRecognizer_);
169     } else {
170         nodeParallelRecognizer_.Reset();
171     }
172 
173     std::list<RefPtr<NGGestureRecognizer>> innerRecognizers;
174     for (auto const& eventTarget : innerTargets) {
175         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
176         if (recognizer) {
177             auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
178             if (!recognizerGroup && newIdx >= idx) {
179                 recognizer->SetNodeId(host->GetId());
180                 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
181                 recognizer->SetTargetComponent(targetComponent);
182                 recognizer->SetIsSystemGesture(true);
183             }
184             recognizer->BeginReferee(touchId);
185             innerRecognizers.push_back(std::move(recognizer));
186         } else {
187             eventTarget->SetNodeId(host->GetId());
188             eventTarget->AttachFrameNode(WeakPtr<FrameNode>(host));
189             eventTarget->SetTargetComponent(targetComponent);
190             finalResult.push_back(eventTarget);
191         }
192         newIdx++; // not process previous recognizers
193     }
194 
195     ProcessTouchTestHierarchy(
196         coordinateOffset, touchRestrict, innerRecognizers, finalResult, touchId, targetComponent, responseLinkResult);
197 
198     return false;
199 }
200 
OnModifyDone()201 void GestureEventHub::OnModifyDone()
202 {
203     if (recreateGesture_) {
204         UpdateGestureHierarchy();
205         recreateGesture_ = false;
206     }
207 }
208 
PackInnerRecognizer(const Offset & offset,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,int32_t touchId,const RefPtr<TargetComponent> & targetComponent)209 RefPtr<NGGestureRecognizer> GestureEventHub::PackInnerRecognizer(
210     const Offset& offset, std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, int32_t touchId,
211     const RefPtr<TargetComponent>& targetComponent)
212 {
213     RefPtr<NGGestureRecognizer> current;
214     // Pack inner recognizer include self inner recognizer and children.
215     if (innerRecognizers.size() == 1) {
216         current = *innerRecognizers.begin();
217     } else if (innerRecognizers.size() > 1) {
218         if (!innerExclusiveRecognizer_) {
219             innerExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(innerRecognizers));
220         } else {
221             innerExclusiveRecognizer_->AddChildren(innerRecognizers);
222         }
223         innerExclusiveRecognizer_->SetCoordinateOffset(offset);
224         innerExclusiveRecognizer_->BeginReferee(touchId);
225         auto host = GetFrameNode();
226         innerExclusiveRecognizer_->AttachFrameNode(WeakPtr<FrameNode>(host));
227         innerExclusiveRecognizer_->SetTargetComponent(targetComponent);
228         current = innerExclusiveRecognizer_;
229     }
230 
231     return current;
232 }
233 
ProcessParallelPriorityGesture(RefPtr<NGGestureRecognizer> & current,std::list<RefPtr<NGGestureRecognizer>> & recognizers,int32_t & parallelIndex,const Offset & offset,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,const RefPtr<FrameNode> & host)234 void GestureEventHub::ProcessParallelPriorityGesture(RefPtr<NGGestureRecognizer>& current,
235     std::list<RefPtr<NGGestureRecognizer>>& recognizers, int32_t& parallelIndex, const Offset& offset, int32_t touchId,
236     const RefPtr<TargetComponent>& targetComponent, const RefPtr<FrameNode>& host)
237 {
238     if (current) {
239         recognizers.push_front(current);
240     }
241     if (recognizers.size() > 1) {
242         if ((static_cast<int32_t>(externalParallelRecognizer_.size()) <= parallelIndex)) {
243             externalParallelRecognizer_.emplace_back(AceType::MakeRefPtr<ParallelRecognizer>(std::move(recognizers)));
244         } else {
245             externalParallelRecognizer_[parallelIndex]->AddChildren(recognizers);
246         }
247         externalParallelRecognizer_[parallelIndex]->SetCoordinateOffset(offset);
248         externalParallelRecognizer_[parallelIndex]->BeginReferee(touchId);
249         externalParallelRecognizer_[parallelIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
250         externalParallelRecognizer_[parallelIndex]->SetTargetComponent(targetComponent);
251         current = externalParallelRecognizer_[parallelIndex];
252         parallelIndex++;
253     } else if (recognizers.size() == 1) {
254         current = *recognizers.begin();
255     }
256 }
257 
ProcessExternalExclusiveRecognizer(RefPtr<NGGestureRecognizer> & current,std::list<RefPtr<NGGestureRecognizer>> & recognizers,int32_t & exclusiveIndex,const Offset & offset,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,const RefPtr<FrameNode> & host,GesturePriority priority)258 void GestureEventHub::ProcessExternalExclusiveRecognizer(RefPtr<NGGestureRecognizer>& current,
259     std::list<RefPtr<NGGestureRecognizer>>& recognizers, int32_t& exclusiveIndex, const Offset& offset, int32_t touchId,
260     const RefPtr<TargetComponent>& targetComponent, const RefPtr<FrameNode>& host, GesturePriority priority)
261 {
262     if (current) {
263         if (priority == GesturePriority::Low) {
264             recognizers.push_front(current);
265         } else {
266             recognizers.push_back(current);
267         }
268     }
269 
270     if (recognizers.size() > 1) {
271         if ((static_cast<int32_t>(externalExclusiveRecognizer_.size()) <= exclusiveIndex)) {
272             externalExclusiveRecognizer_.emplace_back(AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers)));
273         } else {
274             externalExclusiveRecognizer_[exclusiveIndex]->AddChildren(recognizers);
275         }
276         externalExclusiveRecognizer_[exclusiveIndex]->SetCoordinateOffset(offset);
277         externalExclusiveRecognizer_[exclusiveIndex]->BeginReferee(touchId);
278         externalExclusiveRecognizer_[exclusiveIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
279         externalExclusiveRecognizer_[exclusiveIndex]->SetTargetComponent(targetComponent);
280         current = externalExclusiveRecognizer_[exclusiveIndex];
281         exclusiveIndex++;
282     } else if (recognizers.size() == 1) {
283         current = *recognizers.begin();
284     }
285 }
286 
ProcessTouchTestHierarchy(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,TouchTestResult & finalResult,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)287 void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
288     std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult, int32_t touchId,
289     const RefPtr<TargetComponent>& targetComponent, ResponseLinkResult& responseLinkResult)
290 {
291     auto host = GetFrameNode();
292     if (!host) {
293         for (auto&& recognizer : innerRecognizers) {
294             finalResult.emplace_back(std::move(recognizer));
295         }
296         return;
297     }
298 
299     auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
300     RefPtr<NGGestureRecognizer> current;
301     current = PackInnerRecognizer(offset, innerRecognizers, touchId, targetComponent);
302     auto eventHub = eventHub_.Upgrade();
303     auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
304     int32_t parallelIndex = 0;
305     int32_t exclusiveIndex = 0;
306     for (auto const& recognizer : gestureHierarchy_) {
307         if (!recognizer) {
308             continue;
309         }
310         auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
311         if (recognizerGroup) {
312             recognizerGroup->SetRecognizerInfoRecursively(offset, host, targetComponent, getEventTargetImpl);
313             recognizerGroup->CollectResponseLinkRecognizersRecursively(responseLinkResult);
314         } else {
315             responseLinkResult.emplace_back(recognizer);
316         }
317         recognizer->SetNodeId(host->GetId());
318         recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
319         recognizer->SetTargetComponent(targetComponent);
320         recognizer->SetCoordinateOffset(offset);
321         recognizer->BeginReferee(touchId, true);
322         recognizer->SetGetEventTargetImpl(getEventTargetImpl);
323         auto gestureMask = recognizer->GetPriorityMask();
324         if (gestureMask == GestureMask::IgnoreInternal) {
325             // In ignore case, dropped the self inner recognizer and children recognizer.
326             current = recognizer;
327             continue;
328         }
329         auto priority = recognizer->GetPriority();
330         std::list<RefPtr<NGGestureRecognizer>> recognizers { 1, recognizer };
331         if (priority == GesturePriority::Parallel) {
332             ProcessParallelPriorityGesture(current, recognizers, parallelIndex, offset, touchId, targetComponent, host);
333         } else {
334             ProcessExternalExclusiveRecognizer(
335                 current, recognizers, exclusiveIndex, offset, touchId, targetComponent, host, priority);
336         }
337     }
338 
339     if (current) {
340         finalResult.emplace_back(std::move(current));
341     }
342 }
343 
UpdateGestureHierarchy()344 void GestureEventHub::UpdateGestureHierarchy()
345 {
346     auto host = GetFrameNode();
347     CHECK_NULL_VOID(host);
348     bool success = (gestures_.size() + modifierGestures_.size()) == gestureHierarchy_.size() && !needRecollect_;
349     if (success) {
350         auto iter = gestures_.begin();
351         auto recognizerIter = gestureHierarchy_.begin();
352         for (; iter != gestures_.end(); iter++, recognizerIter++) {
353             auto newRecognizer = (*iter)->CreateRecognizer();
354             success = success && (*recognizerIter)->ReconcileFrom(newRecognizer);
355             if (!success) {
356                 break;
357             }
358         }
359     }
360     if (success) {
361         gestures_.clear();
362         return;
363     }
364 
365     gestureHierarchy_.clear();
366     for (const auto& gesture : gestures_) {
367         AddGestureToGestureHierarchy(gesture);
368     }
369     for (const auto& gesture : modifierGestures_) {
370         AddGestureToGestureHierarchy(gesture);
371     }
372     needRecollect_ = false;
373     gestures_.clear();
374 }
375 
AddGestureToGestureHierarchy(const RefPtr<NG::Gesture> & gesture)376 void GestureEventHub::AddGestureToGestureHierarchy(const RefPtr<NG::Gesture>& gesture)
377 {
378     if (!gesture) {
379         return;
380     }
381     auto recognizer = gesture->CreateRecognizer();
382 
383     auto clickRecognizer = AceType::DynamicCast<ClickRecognizer>(recognizer);
384     if (clickRecognizer) {
385         clickRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
386     }
387 
388     auto longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(recognizer);
389     if (longPressRecognizer) {
390         longPressRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
391         auto host = GetFrameNode();
392         CHECK_NULL_VOID(host);
393         auto pattern = host->GetPattern();
394         if (pattern && longPressRecognizer->HasAction()) {
395             longPressRecognizer->SetOnLongPressRecorder(pattern->GetLongPressEventRecorder());
396         }
397     }
398 
399     if (!recognizer) {
400         return;
401     }
402     auto priority = gesture->GetPriority();
403     auto gestureMask = gesture->GetGestureMask();
404     recognizer->SetPriority(priority);
405     recognizer->SetPriorityMask(gestureMask);
406     gestureHierarchy_.emplace_back(recognizer);
407 }
408 
CombineIntoExclusiveRecognizer(const PointF & globalPoint,const PointF & localPoint,TouchTestResult & result,int32_t touchId)409 void GestureEventHub::CombineIntoExclusiveRecognizer(
410     const PointF& globalPoint, const PointF& localPoint, TouchTestResult& result, int32_t touchId)
411 {
412     TouchTestResult finalResult;
413     std::list<RefPtr<NGGestureRecognizer>> recognizers;
414     const auto coordinateOffset = globalPoint - localPoint;
415     auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
416     for (auto const& eventTarget : result) {
417         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
418         if (recognizer) {
419             recognizers.push_back(std::move(recognizer));
420         } else {
421             finalResult.push_back(eventTarget);
422         }
423     }
424 
425     RefPtr<NGGestureRecognizer> current;
426     if (recognizers.size() == 1) {
427         current = *recognizers.begin();
428     } else if (recognizers.size() > 1) {
429         if (!nodeExclusiveRecognizer_) {
430             nodeExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
431         } else {
432             nodeExclusiveRecognizer_->AddChildren(recognizers);
433         }
434         nodeExclusiveRecognizer_->SetCoordinateOffset(offset);
435         nodeExclusiveRecognizer_->BeginReferee(touchId);
436         current = nodeExclusiveRecognizer_;
437     }
438 
439     if (current) {
440         finalResult.emplace_back(std::move(current));
441     }
442     result.swap(finalResult);
443 }
444 
IsPixelMapNeedScale() const445 bool GestureEventHub::IsPixelMapNeedScale() const
446 {
447     CHECK_NULL_RETURN(pixelMap_, false);
448     auto frameNode = GetFrameNode();
449     CHECK_NULL_RETURN(frameNode, false);
450     auto width = pixelMap_->GetWidth();
451     auto maxWidth = DragDropManager::GetMaxWidthBaseOnGridSystem(frameNode->GetContextRefPtr());
452     if (!frameNode->GetDragPreviewOption().isScaleEnabled || width == 0 || width <= maxWidth) {
453         return false;
454     }
455     return true;
456 }
457 
InitDragDropEvent()458 void GestureEventHub::InitDragDropEvent()
459 {
460     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
461         auto gestureEventHub = weak.Upgrade();
462         CHECK_NULL_VOID(gestureEventHub);
463         gestureEventHub->HandleOnDragStart(info);
464     };
465 
466     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
467         auto gestureEventHub = weak.Upgrade();
468         CHECK_NULL_VOID(gestureEventHub);
469         gestureEventHub->HandleOnDragUpdate(info);
470     };
471 
472     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
473         auto gestureEventHub = weak.Upgrade();
474         CHECK_NULL_VOID(gestureEventHub);
475         gestureEventHub->HandleOnDragEnd(info);
476     };
477 
478     auto actionCancelTask = [weak = WeakClaim(this)]() {
479         auto gestureEventHub = weak.Upgrade();
480         CHECK_NULL_VOID(gestureEventHub);
481         gestureEventHub->HandleOnDragCancel();
482     };
483 
484     auto dragEvent = MakeRefPtr<DragEvent>(
485         std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
486     auto distance = SystemProperties::GetDragStartPanDistanceThreshold();
487     SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, Dimension(distance, DimensionUnit::VP));
488 }
489 
IsAllowedDrag(RefPtr<EventHub> eventHub)490 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
491 {
492     auto frameNode = GetFrameNode();
493     CHECK_NULL_RETURN(frameNode, false);
494     auto pattern = frameNode->GetPattern();
495     CHECK_NULL_RETURN(pattern, false);
496 
497     if (frameNode->IsDraggable()) {
498         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
499             return false;
500         }
501     } else {
502         if (frameNode->IsUserSet()) {
503             return false;
504         }
505         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
506             return false;
507         }
508     }
509     return true;
510 }
511 
StartLongPressActionForWeb(bool isFloatImage)512 void GestureEventHub::StartLongPressActionForWeb(bool isFloatImage)
513 {
514     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start long press action for web");
515     auto pipeline = PipelineContext::GetCurrentContext();
516     CHECK_NULL_VOID(pipeline);
517     auto taskScheduler = pipeline->GetTaskExecutor();
518     CHECK_NULL_VOID(taskScheduler);
519 
520     taskScheduler->PostTask(
521         [weak = WeakClaim(this), isFloatImage]() {
522             auto gestureHub = weak.Upgrade();
523             CHECK_NULL_VOID(gestureHub);
524             auto dragEventActuator = gestureHub->dragEventActuator_;
525             CHECK_NULL_VOID(dragEventActuator);
526             dragEventActuator->StartLongPressActionForWeb(isFloatImage);
527         },
528         TaskExecutor::TaskType::UI, "ArkUIGestureWebStartLongPress");
529 }
530 
CancelDragForWeb()531 void GestureEventHub::CancelDragForWeb()
532 {
533     TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop cancel drag for web");
534     auto pipeline = PipelineContext::GetCurrentContext();
535     CHECK_NULL_VOID(pipeline);
536     auto taskScheduler = pipeline->GetTaskExecutor();
537     CHECK_NULL_VOID(taskScheduler);
538 
539     taskScheduler->PostTask(
540         [weak = WeakClaim(this)]() {
541             auto gestureHub = weak.Upgrade();
542             CHECK_NULL_VOID(gestureHub);
543             auto dragEventActuator = gestureHub->dragEventActuator_;
544             CHECK_NULL_VOID(dragEventActuator);
545             dragEventActuator->CancelDragForWeb();
546         },
547         TaskExecutor::TaskType::UI, "ArkUIGestureWebCancelDrag");
548 }
549 
ResetDragActionForWeb()550 void GestureEventHub::ResetDragActionForWeb()
551 {
552     TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop reset drag action for web");
553     isReceivedDragGestureInfo_ = false;
554     CHECK_NULL_VOID(dragEventActuator_);
555     dragEventActuator_->ResetDragActionForWeb();
556 
557     // fix drag failed when long press drag after 500ms and before 800ms
558     // need to reset the state of the drag manager
559     auto pipeLine = PipelineContext::GetCurrentContext();
560     CHECK_NULL_VOID(pipeLine);
561     auto dragDropManager = pipeLine->GetDragDropManager();
562     CHECK_NULL_VOID(dragDropManager);
563     dragDropManager->ResetDragging();
564 }
565 
StartDragTaskForWeb()566 void GestureEventHub::StartDragTaskForWeb()
567 {
568     if (!isReceivedDragGestureInfo_) {
569         TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop StartDragTaskForWeb failed,"
570             "because not recv gesture info");
571         return;
572     }
573 
574     isReceivedDragGestureInfo_ = false;
575     auto pipeline = PipelineContext::GetCurrentContext();
576     CHECK_NULL_VOID(pipeline);
577     auto taskScheduler = pipeline->GetTaskExecutor();
578     CHECK_NULL_VOID(taskScheduler);
579 
580     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop post a task to start drag for web");
581     taskScheduler->PostTask(
582         [weak = WeakClaim(this)]() {
583             auto gestureHub = weak.Upgrade();
584             CHECK_NULL_VOID(gestureHub);
585             auto dragEventActuator = gestureHub->dragEventActuator_;
586             CHECK_NULL_VOID(dragEventActuator);
587             CHECK_NULL_VOID(gestureHub->gestureInfoForWeb_);
588             TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start drag task for web in async task");
589             dragEventActuator->StartDragTaskForWeb(*gestureHub->gestureInfoForWeb_);
590         },
591         TaskExecutor::TaskType::UI, "ArkUIGestureWebStartDrag");
592 }
593 
CreatePixelMapFromString(const std::string & filePath)594 RefPtr<PixelMap> CreatePixelMapFromString(const std::string& filePath)
595 {
596     auto imageSource = ImageSource::Create(filePath);
597     CHECK_NULL_RETURN(imageSource, nullptr);
598     RefPtr<PixelMap> pixelMap = imageSource->CreatePixelMap();
599     return pixelMap;
600 }
601 
CheckInSceneBoardWindow()602 bool CheckInSceneBoardWindow()
603 {
604     auto container = Container::Current();
605     CHECK_NULL_RETURN(container, false);
606     if (!container->IsSubContainer()) {
607         return container->IsScenceBoardWindow();
608     }
609     auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
610     container = Container::GetContainer(parentContainerId);
611     CHECK_NULL_RETURN(container, false);
612     return container->IsScenceBoardWindow();
613 }
614 
CheckOffsetInPixelMap(OffsetF & result,const SizeF & size)615 void CheckOffsetInPixelMap(OffsetF& result, const SizeF& size)
616 {
617     if (result.GetX() >= 0.0f) {
618         result.SetX(-1.0f);
619     }
620     if (result.GetX() + size.Width() <= 0.0f) {
621         result.SetX(1.0f - size.Width());
622     }
623     if (result.GetY() >= 0.0f) {
624         result.SetY(-1.0f);
625     }
626     if (result.GetY() + size.Height() <= 0.0f) {
627         result.SetY(1.0f - size.Height());
628     }
629 }
630 
ParseInnerRect(const std::string & extraInfo,const SizeF & size)631 RectF ParseInnerRect(const std::string& extraInfo, const SizeF& size)
632 {
633     auto innerRect = RectF();
634     if (!CheckInSceneBoardWindow() || extraInfo.empty()) {
635         return innerRect;
636     }
637     auto extraJson = JsonUtil::ParseJsonString(extraInfo);
638     CHECK_NULL_RETURN(extraJson, innerRect);
639     auto extraOffsetX = extraJson->GetInt("drag_offset_x");
640     auto extraOffsetY = extraJson->GetInt("drag_offset_y");
641     if (extraOffsetX <= 0 || extraOffsetY <= 0) {
642         return innerRect;
643     }
644     innerRect.SetOffset(OffsetF(Dimension(extraOffsetX, DimensionUnit::VP).ConvertToPx(),
645         Dimension(extraOffsetY, DimensionUnit::VP).ConvertToPx()));
646     innerRect.SetSize(size);
647     return innerRect;
648 }
649 
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const float scale,bool isCalculateInSubwindow,const RectF & innerRect) const650 OffsetF GestureEventHub::GetPixelMapOffset(
651     const GestureEvent& info, const SizeF& size, const float scale, bool isCalculateInSubwindow,
652     const RectF& innerRect) const
653 {
654     OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
655     auto frameNode = GetFrameNode();
656     CHECK_NULL_RETURN(frameNode, result);
657     auto frameTag = frameNode->GetTag();
658     auto coordinateX = frameNodeOffset_.GetX();
659     auto coordinateY = frameNodeOffset_.GetY();
660     if (!innerRect.IsEmpty() && GreatNotEqual(size.Width(), 0.0f) && GreatNotEqual(size.Height(), 0.0f)) {
661         auto rateX = innerRect.Width() / size.Width();
662         auto rateY = innerRect.Height() / size.Height();
663         result.SetX(rateX * (coordinateX + innerRect.GetOffset().GetX() - info.GetGlobalLocation().GetX()));
664         result.SetY(rateY * (coordinateY + innerRect.GetOffset().GetY() - info.GetGlobalLocation().GetY()));
665         CheckOffsetInPixelMap(result, size);
666         return result;
667     }
668     if (NearZero(frameNodeSize_.Width()) || NearZero(frameNodeSize_.Height()) ||
669         NearZero(size.Width())) {
670         result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()));
671         result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()));
672     } else {
673         auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / frameNodeSize_.Width();
674         auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / frameNodeSize_.Height();
675         result.SetX(-rateX * size.Width());
676         result.SetY(-rateY * size.Height());
677     }
678     CheckOffsetInPixelMap(result, size);
679     TAG_LOGD(AceLogTag::ACE_DRAG, "Get pixelMap offset is %{public}f and %{public}f.",
680         result.GetX(), result.GetY());
681     return result;
682 }
683 
GetPreScaledPixelMapIfExist(float targetScale,RefPtr<PixelMap> defaultPixelMap)684 RefPtr<PixelMap> GestureEventHub::GetPreScaledPixelMapIfExist(float targetScale, RefPtr<PixelMap> defaultPixelMap)
685 {
686     float preScale = 1.0f;
687     CHECK_NULL_RETURN(dragEventActuator_, defaultPixelMap);
688     auto frameNode = GetFrameNode();
689     RefPtr<PixelMap> preScaledPixelMap;
690     if (!(frameNode && frameNode->GetDragPreview().onlyForLifting)) {
691         preScaledPixelMap = dragEventActuator_->GetPreScaledPixelMapForDragThroughTouch(preScale);
692     }
693     if (preScale == targetScale && preScaledPixelMap != nullptr) {
694         return preScaledPixelMap;
695     }
696 #if defined(PIXEL_MAP_SUPPORTED)
697     preScaledPixelMap = PixelMap::CopyPixelMap(defaultPixelMap);
698     if (!preScaledPixelMap) {
699         TAG_LOGW(AceLogTag::ACE_DRAG, "duplicate PixelMap failed!");
700         preScaledPixelMap = defaultPixelMap;
701     }
702     if (!NearEqual(targetScale, 1.0f)) {
703         preScaledPixelMap->Scale(targetScale, targetScale, AceAntiAliasingOption::HIGH);
704     }
705 #endif
706     return preScaledPixelMap;
707 }
708 
GetPixelMapScale(const int32_t height,const int32_t width) const709 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
710 {
711     float scale = 1.0f;
712     if (height == 0 || width == 0) {
713         return scale;
714     }
715     auto frameNode = GetFrameNode();
716     CHECK_NULL_RETURN(frameNode, scale);
717     auto pipeline = PipelineContext::GetCurrentContext();
718     CHECK_NULL_RETURN(pipeline, scale);
719     auto dragDropManager = pipeline->GetDragDropManager();
720     CHECK_NULL_RETURN(dragDropManager, scale);
721     auto windowScale = dragDropManager->GetWindowScale();
722     if (!frameNode->GetDragPreviewOption().isScaleEnabled || !(frameNode->GetTag() == V2::WEB_ETS_TAG)) {
723         return scale * windowScale;
724     }
725     int32_t deviceHeight = SystemProperties::GetDevicePhysicalHeight();
726     int32_t deviceWidth = SystemProperties::GetDevicePhysicalWidth();
727     int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
728     int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
729     if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
730         if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
731             scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
732         }
733     } else {
734         if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
735             width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
736             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
737                 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
738         } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
739                    width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
740             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
741                 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
742         }
743     }
744     return scale * windowScale;
745 }
746 
GenerateMousePixelMap(const GestureEvent & info)747 void GestureEventHub::GenerateMousePixelMap(const GestureEvent& info)
748 {
749     auto frameNode = GetFrameNode();
750     CHECK_NULL_VOID(frameNode);
751     RefPtr<RenderContext> context;
752     if (GetTextDraggable()) {
753         auto pattern = frameNode->GetPattern<TextDragBase>();
754         CHECK_NULL_VOID(pattern);
755         auto dragNode = pattern->MoveDragNode();
756         CHECK_NULL_VOID(dragNode);
757         auto pipeline = PipelineContext::GetCurrentContext();
758         CHECK_NULL_VOID(pipeline);
759         pipeline->FlushPipelineImmediately();
760         context = dragNode->GetRenderContext();
761     } else {
762         context = frameNode->GetRenderContext();
763     }
764     CHECK_NULL_VOID(context);
765     auto thumbnailPixelMap = context->GetThumbnailPixelMap();
766     CHECK_NULL_VOID(thumbnailPixelMap);
767     SetPixelMap(thumbnailPixelMap);
768 }
769 
HandleNotallowDrag(const GestureEvent & info)770 void GestureEventHub::HandleNotallowDrag(const GestureEvent& info)
771 {
772     auto frameNode = GetFrameNode();
773     CHECK_NULL_VOID(frameNode);
774     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
775         gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
776         isReceivedDragGestureInfo_ = true;
777         TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop drag gesture info received");
778     }
779 }
780 
ParsePixelMapAsync(DragDropInfo & dragDropInfo,const DragDropInfo & dragPreviewInfo,const GestureEvent & info)781 bool GestureEventHub::ParsePixelMapAsync(DragDropInfo& dragDropInfo, const DragDropInfo& dragPreviewInfo,
782     const GestureEvent& info)
783 {
784     auto frameNode = GetFrameNode();
785     CHECK_NULL_RETURN(frameNode, false);
786 
787     if (dragPreviewInfo.inspectorId != "") {
788         ACE_SCOPED_TRACE("drag: handling with inspector");
789         auto dragPreviewPixelMap = GetDragPreviewPixelMap();
790         TAG_LOGI(AceLogTag::ACE_DRAG, "InspectorId exist, get thumbnail.");
791         if (dragPreviewPixelMap == nullptr) {
792             dragPreviewPixelMap = DragEventActuator::GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
793         }
794         dragDropInfo.pixelMap = dragPreviewPixelMap;
795         return true;
796     }
797 
798     if (info.GetSourceDevice() != SourceType::MOUSE) {
799         if (dragPreviewInfo.pixelMap != nullptr || dragPreviewInfo.customNode != nullptr) {
800             if (dragPreviewPixelMap_ != nullptr) {
801                 ACE_SCOPED_TRACE("drag: handling with drag preview");
802                 TAG_LOGI(AceLogTag::ACE_DRAG, "Non-mouse dragging, get thumbnail.");
803                 dragDropInfo.pixelMap = dragPreviewPixelMap_;
804                 return true;
805             }
806         }
807     }
808 
809     if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode == nullptr && dragPreviewInfo.pixelMap == nullptr &&
810         dragPreviewInfo.customNode == nullptr && pixelMap_ != nullptr && !frameNode->GetDragPreview().onlyForLifting) {
811         dragDropInfo.pixelMap = pixelMap_;
812         return true;
813     }
814 
815     if (dragPreviewInfo.pixelMap != nullptr) {
816         ACE_SCOPED_TRACE("drag: handling with pixelmap directly");
817         dragDropInfo.pixelMap = dragPreviewInfo.pixelMap;
818         TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap exist, get thumbnail.");
819         return true;
820     } else if (dragPreviewInfo.customNode != nullptr) {
821         dragDropInfo.customNode = dragPreviewInfo.customNode;
822     }
823     return dragDropInfo.pixelMap;
824 }
825 
HideMenu()826 void GestureEventHub::HideMenu()
827 {
828     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
829     CHECK_NULL_VOID(pipeline);
830     auto dragDrogDropManager = pipeline->GetDragDropManager();
831     CHECK_NULL_VOID(dragDrogDropManager);
832     SubwindowManager::GetInstance()->HideMenuNG(false, true);
833     auto menuWrapperNode = dragDrogDropManager->GetMenuWrapperNode();
834     CHECK_NULL_VOID(menuWrapperNode);
835     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
836     CHECK_NULL_VOID(menuWrapperPattern);
837     auto imageNode = menuWrapperPattern->GetPreview();
838     CHECK_NULL_VOID(imageNode);
839     auto imageContext = imageNode->GetRenderContext();
840     CHECK_NULL_VOID(imageContext);
841     imageContext->UpdateOpacity(0.0f);
842 }
843 
HandleOnDragStart(const GestureEvent & info)844 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
845 {
846     TAG_LOGD(AceLogTag::ACE_DRAG, "Start handle onDragStart.");
847     auto eventHub = eventHub_.Upgrade();
848     CHECK_NULL_VOID(eventHub);
849     if (!eventHub->HasOnDragStart()) {
850         TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not set onDragStart event.");
851         return;
852     }
853 
854     auto frameNode = GetFrameNode();
855     CHECK_NULL_VOID(frameNode);
856     auto pattern = frameNode->GetPattern();
857     CHECK_NULL_VOID(pattern);
858     if (!IsAllowedDrag(eventHub)) {
859         TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not allow drag, tag is %{public}s,"
860             "draggable is %{public}d, drag start event is %{public}d,"
861             "default support drag is %{public}d, user set is %{public}d.",
862             frameNode->GetTag().c_str(), frameNode->IsDraggable(), eventHub->HasOnDragStart(),
863             pattern->DefaultSupportDrag(), frameNode->IsUserSet());
864         HandleNotallowDrag(info);
865         return;
866     }
867     auto pipeline = PipelineContext::GetCurrentContext();
868     CHECK_NULL_VOID(pipeline);
869     auto eventManager = pipeline->GetEventManager();
870     CHECK_NULL_VOID(eventManager);
871     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && eventManager->IsLastMoveBeforeUp()) {
872         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag stop because user release mouse button");
873         return;
874     }
875     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
876         SetMouseDragMonitorState(true);
877     }
878 
879     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
880     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
881         event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
882         event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
883     } else {
884         event->SetX(info.GetGlobalPoint().GetX());
885         event->SetY(info.GetGlobalPoint().GetY());
886     }
887     event->SetScreenX(info.GetScreenLocation().GetX());
888     event->SetScreenY(info.GetScreenLocation().GetY());
889     event->SetDisplayX(info.GetScreenLocation().GetX());
890     event->SetDisplayY(info.GetScreenLocation().GetY());
891     event->SetSourceTool(info.GetSourceTool());
892 
893     auto frameTag = frameNode->GetTag();
894     auto hostPattern = frameNode->GetPattern<TextDragBase>();
895     if (hostPattern && GetTextDraggable() && (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
896                         frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG)) {
897         frameNodeOffset_ = hostPattern->GetDragUpperLeftCoordinates();
898         frameNodeSize_ = SizeF(0.0f, 0.0f);
899     } else {
900         auto rect = DragDropFuncWrapper::GetPaintRectToScreen(frameNode) -
901             DragDropFuncWrapper::GetCurrentWindowOffset(PipelineContext::GetCurrentContextSafelyWithCheck());
902         frameNodeOffset_ = rect.GetOffset();
903         frameNodeSize_ = rect.GetSize();
904 #ifdef WEB_SUPPORTED
905         if (frameTag == V2::WEB_ETS_TAG) {
906             auto webPattern = frameNode->GetPattern<WebPattern>();
907             if (webPattern) {
908                 frameNodeOffset_.SetX(frameNodeOffset_.GetX() + webPattern->GetDragOffset().GetX());
909                 frameNodeOffset_.SetY(frameNodeOffset_.GetY() + webPattern->GetDragOffset().GetY());
910                 frameNodeSize_ = webPattern->GetDragPixelMapSize();
911             }
912         }
913 #endif
914     }
915     /*
916      * Users may remove frameNode in the js callback function "onDragStart "triggered below,
917      * so save the offset of the framenode relative to the window in advance
918      */
919     DragDropInfo dragPreviewInfo;
920     auto dragDropInfo = GetDragDropInfo(info, frameNode, dragPreviewInfo, event);
921     auto dragDropManager = pipeline->GetDragDropManager();
922     CHECK_NULL_VOID(dragDropManager);
923     dragDropManager->SetDraggingPointer(info.GetPointerId());
924     dragDropManager->SetDraggingPressedState(true);
925     if (ParsePixelMapAsync(dragDropInfo, dragPreviewInfo, info)) {
926         OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
927         return;
928     }
929 
930 #if defined(PIXEL_MAP_SUPPORTED)
931     if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode) {
932         TAG_LOGI(AceLogTag::ACE_DRAG, "CustomNode exist, get thumbnail.");
933         StartDragForCustomBuilder(info, pipeline, frameNode, dragDropInfo, event);
934         return;
935     }
936 #endif
937     TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropInfo is empty.");
938     if (!dragDropInfo.pixelMap) {
939         if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && GetTextDraggable() && pixelMap_) {
940             dragDropInfo.pixelMap = pixelMap_;
941         } else {
942             GenerateMousePixelMap(info);
943             dragDropInfo.pixelMap = pixelMap_;
944         }
945     }
946     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && !dragDropInfo.pixelMap) {
947         TAG_LOGD(AceLogTag::ACE_DRAG, "no any pixmap got, get node snapshot final try");
948         ACE_SCOPED_TRACE("drag: no any pixmap got, get node snapshot final try");
949         dragDropInfo.pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
950     }
951     OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
952 }
953 
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)954 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
955     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
956 {
957     auto eventHub = eventHub_.Upgrade();
958     CHECK_NULL_VOID(eventHub);
959     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
960     CHECK_NULL_VOID(pipeline);
961 
962     auto dragDropManager = pipeline->GetDragDropManager();
963     CHECK_NULL_VOID(dragDropManager);
964     if (dragDropProxy_) {
965         dragDropProxy_ = nullptr;
966     }
967     CHECK_NULL_VOID(dragEvent);
968     auto eventRet = dragEvent->GetResult();
969     if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
970         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag result is %{public}d, stop dragging.", eventRet);
971         FireCustomerOnDragEnd(pipeline, eventHub);
972         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
973             SetMouseDragMonitorState(false);
974         }
975         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::APP_REFUSE_DRAG);
976         return;
977     }
978     std::string udKey;
979     int32_t recordsSize = 1;
980     auto unifiedData = GetUnifiedData(frameNode->GetTag(), dragDropInfo, dragEvent);
981     if (unifiedData) {
982         DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
983     }
984     CHECK_NULL_VOID(frameNode);
985     auto pattern = frameNode->GetPattern();
986     CHECK_NULL_VOID(pattern);
987     pattern->ResetDragOption();
988     if (pattern->GetDragRecordSize() >= 0) {
989         recordsSize = pattern->GetDragRecordSize();
990     } else if (unifiedData) {
991         auto recordSize = unifiedData->GetSize();
992         recordsSize = recordSize > 1 ? recordSize : 1;
993     }
994     auto ret = SetDragData(unifiedData, udKey);
995     if (ret != 0) {
996         TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
997         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SET_DATA_FAIL);
998     }
999 
1000     std::map<std::string, int64_t> summary;
1001     ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
1002     if (ret != 0) {
1003         TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF get summary failed, return value is %{public}d", ret);
1004     }
1005     dragDropManager->SetSummaryMap(summary);
1006     RefPtr<PixelMap> pixelMap = dragDropInfo.pixelMap;
1007     if (pixelMap) {
1008         SetPixelMap(pixelMap);
1009     } else {
1010         FireCustomerOnDragEnd(pipeline, eventHub);
1011         TAG_LOGW(AceLogTag::ACE_DRAG, "Thumbnail pixelMap is empty.");
1012         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1013             SetMouseDragMonitorState(false);
1014         }
1015         return;
1016     }
1017     SetDragGatherPixelMaps(info);
1018     dragDropManager->SetIsMouseDrag(info.GetInputEventType() == InputEventType::MOUSE_BUTTON);
1019     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
1020     auto badgeNumber = dragPreviewOptions.GetCustomerBadgeNumber();
1021     if (badgeNumber.has_value()) {
1022         recordsSize = badgeNumber.value();
1023     }
1024     auto dragNodePipeline = frameNode->GetContextRefPtr();
1025     CHECK_NULL_VOID(dragNodePipeline);
1026     auto overlayManager = dragNodePipeline->GetOverlayManager();
1027     bool isSwitchToSubWindow = false;
1028     RefPtr<FrameNode> imageNode = nullptr;
1029     RefPtr<FrameNode> textNode = nullptr;
1030     RefPtr<OverlayManager> subWindowOverlayManager = nullptr;
1031     bool isMenuShow = false;
1032     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1033     bool isStartDraggingFromSubWindow = (pipeline != mainPipeline);
1034     auto window = SubwindowManager::GetInstance()->ShowPreviewNG(isStartDraggingFromSubWindow);
1035     if (window) {
1036         subWindowOverlayManager = window->GetOverlayManager();
1037         CHECK_NULL_VOID(subWindowOverlayManager);
1038         isMenuShow = subWindowOverlayManager->IsMenuShow();
1039     }
1040     if (isMenuShow) {
1041         dragDropManager->SetIsDragWithContextMenu(true);
1042         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag with contextMenu.");
1043     } else {
1044         dragDropManager->SetIsDragWithContextMenu(false);
1045     }
1046     float defaultPixelMapScale =
1047         info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
1048     // use menuPreviewScale for drag framework. this is not final solution.
1049     if (!frameNode->GetDragPreview().onlyForLifting && isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f)) {
1050         auto menuPreviewRect = DragDropManager::GetMenuPreviewRect();
1051         if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(menuPreviewRect.Height(), 0.0f)) {
1052             frameNodeOffset_ = menuPreviewRect.GetOffset();
1053             frameNodeSize_ = menuPreviewRect.GetSize();
1054         }
1055         auto originPixelMapWidth = pixelMap->GetWidth();
1056         if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(originPixelMapWidth, 0.0f) &&
1057             menuPreviewRect.Width() < originPixelMapWidth * menuPreviewScale_) {
1058             defaultPixelMapScale = menuPreviewRect.Width() / originPixelMapWidth;
1059         } else {
1060             defaultPixelMapScale = menuPreviewScale_;
1061         }
1062     }
1063     auto windowScale = dragDropManager->GetWindowScale();
1064     float scale = windowScale * defaultPixelMapScale;
1065     auto focusHub = frameNode->GetFocusHub();
1066     bool hasContextMenu = focusHub == nullptr
1067                               ? false : focusHub->FindContextMenuOnKeyEvent(OnKeyEventType::CONTEXT_MENU);
1068     bool isBindMenuPreview = GetPreviewMode() != MenuPreviewMode::NONE;
1069     dragDropManager->ResetContextMenuDragPosition();
1070     if (IsNeedSwitchToSubWindow() || isMenuShow) {
1071         imageNode = overlayManager->GetPixelMapContentNode();
1072         DragEventActuator::CreatePreviewNode(frameNode, imageNode, defaultPixelMapScale);
1073         OffsetF previewOffset;
1074         auto originPoint = imageNode->GetPositionToWindowWithTransform();
1075         if (hasContextMenu || isMenuShow) {
1076             auto previewDragMovePosition = dragDropManager->GetUpdateDragMovePosition();
1077             auto ret = SubwindowManager::GetInstance()->GetMenuPreviewCenter(previewOffset);
1078             if (isBindMenuPreview && ret) {
1079                 previewOffset = previewOffset - OffsetF(pixelMap->GetWidth() / 2.0f, pixelMap->GetHeight() / 2.0f)
1080                                 + previewDragMovePosition;
1081                 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, previewOffset);
1082             } else {
1083                 previewOffset = previewDragMovePosition + originPoint;
1084                 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, previewOffset);
1085             }
1086         }
1087 
1088         auto frameTag = frameNode->GetTag();
1089         if (IsPixelMapNeedScale() && GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1090             auto textDragPattern = frameNode->GetPattern<TextDragBase>();
1091             CHECK_NULL_VOID(textDragPattern);
1092             auto dragNode = textDragPattern->MoveDragNode();
1093             if (dragNode) {
1094                 auto dragNodeOffset = dragNode->GetPaintRectOffset();
1095                 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, dragNodeOffset);
1096             }
1097         }
1098 
1099         if (IsPixelMapNeedScale() && frameTag == V2::WEB_ETS_TAG) {
1100             OffsetF webOffset;
1101             CHECK_NULL_VOID(pipeline);
1102             auto window = pipeline->GetWindow();
1103             CHECK_NULL_VOID(window);
1104             auto offset = window->GetCurrentWindowRect().GetOffset();
1105             webOffset.SetX(frameNodeOffset_.GetX() + offset.GetX());
1106             webOffset.SetY(frameNodeOffset_.GetY() + offset.GetY());
1107             DragEventActuator::UpdatePreviewPositionAndScale(imageNode, webOffset);
1108         }
1109 
1110         CHECK_NULL_VOID(imageNode);
1111         float previewScale =
1112             info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
1113         if (IsPixelMapNeedScale()) {
1114             previewScale = static_cast<float>(imageNode->GetPreviewScaleVal());
1115             scale = previewScale * windowScale;
1116         }
1117         // use menu preview scale replace default pixelMap scale.
1118         if (isMenuShow) {
1119             auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
1120             CHECK_NULL_VOID(imageGestureEventHub);
1121             if (!IsPixelMapNeedScale()) {
1122                 imageGestureEventHub->SetMenuPreviewScale(defaultPixelMapScale);
1123             } else {
1124                 imageGestureEventHub->SetMenuPreviewScale(scale);
1125             }
1126         }
1127         auto childSize = badgeNumber.has_value() ? badgeNumber.value() : GetSelectItemSize();
1128         if (childSize > 1) {
1129             recordsSize = childSize;
1130         }
1131         textNode = DragEventActuator::CreateBadgeTextNode(frameNode, childSize, previewScale, true, previewOffset);
1132         if (window) {
1133             isSwitchToSubWindow = true;
1134             overlayManager->RemovePixelMap();
1135         }
1136     }
1137     CHECK_NULL_VOID(overlayManager);
1138     if (!overlayManager->GetIsOnAnimation()) {
1139         if (dragEventActuator_ != nullptr) {
1140             dragEventActuator_->SetIsNotInPreviewState(true);
1141         }
1142     }
1143     RefPtr<PixelMap> pixelMapDuplicated = GetPreScaledPixelMapIfExist(scale, pixelMap);
1144     dragEventActuator_->ResetPreScaledPixelMapForDragThroughTouch();
1145     dragPreviewPixelMap_ = nullptr;
1146     auto width = pixelMapDuplicated->GetWidth();
1147     auto height = pixelMapDuplicated->GetHeight();
1148     auto extraInfoLimited = dragDropInfo.extraInfo.size() > EXTRA_INFO_MAX_LENGTH
1149                                 ? dragDropInfo.extraInfo.substr(EXTRA_INFO_MAX_LENGTH + 1)
1150                                 : dragDropInfo.extraInfo;
1151     auto innerRect = ParseInnerRect(extraInfoLimited, SizeF(width, height));
1152     auto pixelMapOffset = OffsetF();
1153     if (isMenuShow && GreatNotEqual(defaultPixelMapScale, 0.0f)) {
1154         pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale / defaultPixelMapScale, true, innerRect);
1155     } else {
1156         pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale);
1157     }
1158     windowScale = NearZero(windowScale) ? 1.0f : windowScale;
1159     dragDropManager->SetPixelMapOffset(pixelMapOffset / windowScale);
1160     DragEventActuator::ResetNode(frameNode);
1161     auto arkExtraInfoJson = JsonUtil::Create(true);
1162     auto dragNodeGrayscale = pipeline->GetDragNodeGrayscale();
1163     auto dipScale = pipeline->GetDipScale();
1164     arkExtraInfoJson->Put("scale", scale);
1165     arkExtraInfoJson->Put("dip_scale", dipScale);
1166     arkExtraInfoJson->Put("drag_node_gray_scale", dragNodeGrayscale);
1167     arkExtraInfoJson->Put("event_id", info.GetPointerEventId());
1168     UpdateExtraInfo(frameNode, arkExtraInfoJson, scale);
1169     auto container = Container::Current();
1170     CHECK_NULL_VOID(container);
1171     DragDropBehaviorReporterTrigger trigger(DragReporterPharse::DRAG_START, container->GetInstanceId());
1172     auto windowId = container->GetWindowId();
1173     ShadowInfoCore shadowInfo { pixelMapDuplicated, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
1174     DragDataCore dragData { { shadowInfo }, {}, udKey, extraInfoLimited, arkExtraInfoJson->ToString(),
1175         static_cast<int32_t>(info.GetSourceDevice()), recordsSize, info.GetPointerId(), info.GetScreenLocation().GetX(),
1176         info.GetScreenLocation().GetY(), info.GetTargetDisplayId(), windowId, true, false, summary };
1177     std::string summarys;
1178     for (const auto& [udkey, recordSize] : summary) {
1179         std::string str = udkey + "-" + std::to_string(recordSize) + ";";
1180         summarys += str;
1181     }
1182     DragDropBehaviorReporter::GetInstance().UpdateSummaryType(summarys);
1183     TAG_LOGI(AceLogTag::ACE_DRAG,
1184         "Start drag, frameNode is %{public}s, pixelMap width %{public}d height %{public}d, "
1185         "scale is %{public}f, udkey %{public}s, recordsSize %{public}d, pointerId %{public}d, "
1186         "displayId %{public}d, windowId %{public}d, summary %{public}s.",
1187         frameNode->GetTag().c_str(), width, height, scale, udKey.c_str(),
1188         recordsSize, info.GetPointerId(), info.GetTargetDisplayId(), windowId, summarys.c_str());
1189     dragDropManager->GetGatherPixelMap(dragData, scale, width, height);
1190     ret = InteractionInterface::GetInstance()->StartDrag(dragData, GetDragCallback(pipeline, eventHub));
1191     if (ret != 0) {
1192         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAGFWK_START_FAIL);
1193         if (dragDropManager->IsNeedDisplayInSubwindow() && subWindowOverlayManager) {
1194             SubwindowManager::GetInstance()->HidePreviewNG();
1195             overlayManager->RemovePixelMap();
1196         }
1197         FireCustomerOnDragEnd(pipeline, eventHub);
1198         TAG_LOGW(AceLogTag::ACE_DRAG, "Start drag failed, return value is %{public}d", ret);
1199         return;
1200     }
1201     DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAG_START_SUCCESS);
1202     if (isSwitchToSubWindow && subWindowOverlayManager) {
1203         std::vector<GatherNodeChildInfo> gatherNodeChildrenInfo;
1204         auto gatherNode = DragEventActuator::GetOrCreateGatherNode(overlayManager,
1205             dragEventActuator_, gatherNodeChildrenInfo);
1206         DragEventActuator::MountGatherNode(subWindowOverlayManager, frameNode, gatherNode, gatherNodeChildrenInfo);
1207         DragEventActuator::UpdatePreviewPositionAndScale(
1208             imageNode, imageNode->GetOffsetInSubwindow(window->GetRect().GetOffset()));
1209         if (textNode) {
1210             DragEventActuator::UpdatePreviewPositionAndScale(
1211                 textNode, textNode->GetOffsetInSubwindow(window->GetRect().GetOffset()));
1212         }
1213         DragEventActuator::MountPixelMap(
1214             subWindowOverlayManager, eventHub->GetGestureEventHub(), imageNode, textNode, true);
1215         HideMenu();
1216         pipeline->FlushSyncGeometryNodeTasks();
1217         DragAnimationHelper::ShowBadgeAnimation(textNode);
1218         dragDropManager->DoDragStartAnimation(
1219             subWindowOverlayManager, info, eventHub->GetGestureEventHub(), isMenuShow);
1220         if (hasContextMenu) {
1221             //response: 0.347, dampingRatio: 0.99, blendDuration: 0.0
1222             const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
1223             AnimationOption option;
1224             option.SetCurve(curve);
1225             option.SetDuration(PIXELMAP_ANIMATION_DURATION);
1226             auto renderContext = imageNode->GetRenderContext();
1227             AnimationUtils::Animate(
1228                 option,
1229                 [renderContext]() {
1230                     if (renderContext) {
1231                         renderContext->UpdateOpacity(PIXELMAP_OPACITY_RATE);
1232                     }
1233                 },
1234                 option.GetOnFinishEvent());
1235         }
1236     }
1237     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && IsNeedSwitchToSubWindow()) {
1238         ret = RegisterCoordinationListener(pipeline);
1239         if (ret != 0) {
1240             TAG_LOGW(AceLogTag::ACE_DRAG, "Register coordination listener failed, error is %{public}d", ret);
1241         }
1242     }
1243     dragDropManager->SetPreviewRect(Rect(pixelMapOffset.GetX(), pixelMapOffset.GetY(), width, height));
1244     dragDropManager->ResetRecordSize(static_cast<uint32_t>(recordsSize));
1245     auto eventManager = pipeline->GetEventManager();
1246     CHECK_NULL_VOID(eventManager);
1247     eventManager->DoMouseActionRelease();
1248     eventManager->SetIsDragging(true);
1249     if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_ != nullptr &&
1250         dragEventActuator_->GetIsNotInPreviewState()) {
1251         if (!dragDropManager->IsNeedDisplayInSubwindow() && !isMenuShow) {
1252             overlayManager->RemovePixelMap();
1253             overlayManager->RemovePreviewBadgeNode();
1254             overlayManager->RemoveGatherNode();
1255             pipeline->AddAfterRenderTask([]() { InteractionInterface::GetInstance()->SetDragWindowVisible(true); });
1256         }
1257     } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1258         if (!dragDropManager->IsNeedDisplayInSubwindow() && !isMenuShow) {
1259             pipeline->AddDragWindowVisibleTask([]() {
1260                 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1261             });
1262         }
1263         dragDropManager->SetIsDragWindowShow(true);
1264     }
1265     dragDropManager->FireOnEditableTextComponent(frameNode, DragEventType::ENTER);
1266     dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
1267     CHECK_NULL_VOID(dragDropProxy_);
1268     dragDropProxy_->OnDragStart(info, extraInfoLimited, GetFrameNode());
1269     if (!dragDropManager->IsDraggingPressed(info.GetPointerId())) {
1270         dragDropManager->OnDragEnd(
1271             DragPointerEvent(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()), extraInfoLimited);
1272     }
1273 }
1274 
UpdateExtraInfo(const RefPtr<FrameNode> & frameNode,std::unique_ptr<JsonValue> & arkExtraInfoJson,float scale)1275 void GestureEventHub::UpdateExtraInfo(const RefPtr<FrameNode>& frameNode,
1276     std::unique_ptr<JsonValue>& arkExtraInfoJson, float scale)
1277 {
1278     double opacity = frameNode->GetDragPreviewOption().options.opacity;
1279     auto optionInfo = frameNode->GetDragPreviewOption().options;
1280     arkExtraInfoJson->Put("dip_opacity", opacity);
1281     TAG_LOGD(AceLogTag::ACE_DRAG, "The info of opacity update to the framework is %{public}s",
1282         arkExtraInfoJson->ToString().c_str());
1283 
1284     if (optionInfo.blurbgEffect.backGroundEffect.radius.IsValid()) {
1285         optionInfo.blurbgEffect.ToJsonValue(arkExtraInfoJson);
1286     }
1287     DragEventActuator::PrepareShadowParametersForDragData(frameNode, arkExtraInfoJson, scale);
1288     DragEventActuator::PrepareRadiusParametersForDragData(frameNode, arkExtraInfoJson);
1289 }
1290 
RegisterCoordinationListener(const RefPtr<PipelineBase> & context)1291 int32_t GestureEventHub::RegisterCoordinationListener(const RefPtr<PipelineBase>& context)
1292 {
1293     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1294     CHECK_NULL_RETURN(pipeline, -1);
1295     auto callback = [id = Container::CurrentId(), weak = WeakClaim(RawPtr(pipeline))]() {
1296         ContainerScope scope(id);
1297         auto context = weak.Upgrade();
1298         CHECK_NULL_VOID(context);
1299         auto dragDropManager = context->GetDragDropManager();
1300         CHECK_NULL_VOID(dragDropManager);
1301         auto taskScheduler = context->GetTaskExecutor();
1302         CHECK_NULL_VOID(taskScheduler);
1303         taskScheduler->PostTask([dragDropManager]() { dragDropManager->HideDragPreviewOverlay(); },
1304             TaskExecutor::TaskType::UI, "ArkUIGestureHideDragPreviewOverlay");
1305     };
1306     return InteractionInterface::GetInstance()->RegisterCoordinationListener(callback);
1307 }
1308 
HandleOnDragUpdate(const GestureEvent & info)1309 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
1310 {
1311     gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
1312     CHECK_NULL_VOID(dragDropProxy_);
1313     auto pipeline = PipelineContext::GetCurrentContext();
1314     CHECK_NULL_VOID(pipeline);
1315     auto dragDropManager = pipeline->GetDragDropManager();
1316     if (dragDropManager->IsDragged()) {
1317         dragDropProxy_->OnDragMove(info);
1318     }
1319     if (IsNeedSwitchToSubWindow()) {
1320         DragPointerEvent pointerEvent =
1321             DragPointerEvent(info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
1322         dragDropManager->DoDragMoveAnimate(pointerEvent);
1323     }
1324 }
1325 
HandleOnDragEnd(const GestureEvent & info)1326 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
1327 {
1328     auto pipeline = NG::PipelineContext::GetCurrentContext();
1329     const static int32_t PLATFORM_VERSION_TEN = 10;
1330     if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
1331         auto eventHub = eventHub_.Upgrade();
1332         CHECK_NULL_VOID(eventHub);
1333 
1334         auto frameNode = GetFrameNode();
1335         CHECK_NULL_VOID(frameNode);
1336 
1337         // Only the onDrop callback of dragged frame node is triggered.
1338         // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
1339         if (eventHub->HasOnDrop() || eventHub->HasCustomerOnDrop()) {
1340             RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1341             if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1342                 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1343                 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1344             } else {
1345                 event->SetX(info.GetGlobalPoint().GetX());
1346                 event->SetY(info.GetGlobalPoint().GetY());
1347             }
1348             event->SetScreenX(info.GetScreenLocation().GetX());
1349             event->SetScreenY(info.GetScreenLocation().GetY());
1350             event->SetPressedKeyCodes(info.GetPressedKeyCodes());
1351             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event);
1352             eventHub->HandleInternalOnDrop(event, "");
1353         }
1354     }
1355     CHECK_NULL_VOID(dragDropProxy_);
1356     dragDropProxy_->DestroyDragWindow();
1357     dragDropProxy_ = nullptr;
1358 }
1359 
HandleOnDragCancel()1360 void GestureEventHub::HandleOnDragCancel()
1361 {
1362     CHECK_NULL_VOID(dragDropProxy_);
1363     dragDropProxy_->DestroyDragWindow();
1364     dragDropProxy_ = nullptr;
1365 }
1366 
SetFocusClickEvent(GestureEventFunc && clickEvent)1367 void GestureEventHub::SetFocusClickEvent(GestureEventFunc&& clickEvent)
1368 {
1369     auto eventHub = eventHub_.Upgrade();
1370     CHECK_NULL_VOID(eventHub);
1371     auto focusHub = eventHub->GetFocusHub();
1372     CHECK_NULL_VOID(focusHub);
1373     focusHub->SetOnClickCallback(std::move(clickEvent));
1374 }
1375 
1376 // helper function to ensure clickActuator is initialized
CheckClickActuator()1377 void GestureEventHub::CheckClickActuator()
1378 {
1379     if (!clickEventActuator_) {
1380         clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1381         clickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
1382     }
1383 
1384     if (parallelCombineClick && !userParallelClickEventActuator_) {
1385         userParallelClickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1386         userParallelClickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
1387     }
1388 }
1389 
SetUserOnClick(GestureEventFunc && clickEvent,double distanceThreshold)1390 void GestureEventHub::SetUserOnClick(GestureEventFunc&& clickEvent, double distanceThreshold)
1391 {
1392     CheckClickActuator();
1393     if (parallelCombineClick) {
1394         userParallelClickEventActuator_->SetUserCallback(std::move(clickEvent));
1395         SetFocusClickEvent(userParallelClickEventActuator_->GetClickEvent());
1396         auto clickRecognizer = userParallelClickEventActuator_->GetClickRecognizer();
1397         clickRecognizer->SetDistanceThreshold(distanceThreshold);
1398     } else {
1399         clickEventActuator_->SetUserCallback(std::move(clickEvent));
1400         SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1401         auto clickRecognizer = clickEventActuator_->GetClickRecognizer();
1402         clickRecognizer->SetDistanceThreshold(distanceThreshold);
1403     }
1404 }
1405 
SetJSFrameNodeOnClick(GestureEventFunc && clickEvent)1406 void GestureEventHub::SetJSFrameNodeOnClick(GestureEventFunc&& clickEvent)
1407 {
1408     CheckClickActuator();
1409     if (parallelCombineClick) {
1410         userParallelClickEventActuator_->SetJSFrameNodeCallback(std::move(clickEvent));
1411         SetFocusClickEvent(userParallelClickEventActuator_->GetClickEvent());
1412     } else {
1413         clickEventActuator_->SetJSFrameNodeCallback(std::move(clickEvent));
1414         SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1415     }
1416 }
1417 
SetOnGestureJudgeBegin(GestureJudgeFunc && gestureJudgeFunc)1418 void GestureEventHub::SetOnGestureJudgeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1419 {
1420     gestureJudgeFunc_ = std::move(gestureJudgeFunc);
1421 }
1422 
SetOnTouchIntercept(TouchInterceptFunc && touchInterceptFunc)1423 void GestureEventHub::SetOnTouchIntercept(TouchInterceptFunc&& touchInterceptFunc)
1424 {
1425     touchInterceptFunc_ = std::move(touchInterceptFunc);
1426 }
1427 
GetOnTouchIntercept() const1428 TouchInterceptFunc GestureEventHub::GetOnTouchIntercept() const
1429 {
1430     return touchInterceptFunc_;
1431 }
1432 
SetShouldBuildinRecognizerParallelWithFunc(ShouldBuiltInRecognizerParallelWithFunc && parallelGestureToFunc)1433 void GestureEventHub::SetShouldBuildinRecognizerParallelWithFunc(
1434     ShouldBuiltInRecognizerParallelWithFunc&& parallelGestureToFunc)
1435 {
1436     shouldBuildinRecognizerParallelWithFunc_ = std::move(parallelGestureToFunc);
1437 }
1438 
GetParallelInnerGestureToFunc() const1439 ShouldBuiltInRecognizerParallelWithFunc GestureEventHub::GetParallelInnerGestureToFunc() const
1440 {
1441     return shouldBuildinRecognizerParallelWithFunc_;
1442 }
1443 
SetOnGestureRecognizerJudgeBegin(GestureRecognizerJudgeFunc && gestureRecognizerJudgeFunc)1444 void GestureEventHub::SetOnGestureRecognizerJudgeBegin(GestureRecognizerJudgeFunc&& gestureRecognizerJudgeFunc)
1445 {
1446     gestureRecognizerJudgeFunc_ = std::move(gestureRecognizerJudgeFunc);
1447 }
1448 
GetOnGestureRecognizerJudgeBegin() const1449 GestureRecognizerJudgeFunc GestureEventHub::GetOnGestureRecognizerJudgeBegin() const
1450 {
1451     return gestureRecognizerJudgeFunc_;
1452 }
1453 
SetOnGestureJudgeNativeBegin(GestureJudgeFunc && gestureJudgeFunc)1454 void GestureEventHub::SetOnGestureJudgeNativeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1455 {
1456     gestureJudgeNativeFunc_ = std::move(gestureJudgeFunc);
1457 }
1458 
AddClickEvent(const RefPtr<ClickEvent> & clickEvent,double distanceThreshold)1459 void GestureEventHub::AddClickEvent(const RefPtr<ClickEvent>& clickEvent, double distanceThreshold)
1460 {
1461     CheckClickActuator();
1462     clickEventActuator_->AddClickEvent(clickEvent);
1463     clickEventActuator_->AddDistanceThreshold(distanceThreshold);
1464 
1465     SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1466 }
1467 
AddClickAfterEvent(const RefPtr<ClickEvent> & clickEvent)1468 void GestureEventHub::AddClickAfterEvent(const RefPtr<ClickEvent>& clickEvent)
1469 {
1470     CheckClickActuator();
1471     clickEventActuator_->AddClickAfterEvent(clickEvent);
1472 
1473     SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1474 }
1475 
1476 // replace last showMenu callback
BindMenu(GestureEventFunc && showMenu)1477 void GestureEventHub::BindMenu(GestureEventFunc&& showMenu)
1478 {
1479     if (showMenu_) {
1480         RemoveClickEvent(showMenu_);
1481     }
1482     showMenu_ = MakeRefPtr<ClickEvent>(std::move(showMenu));
1483     AddClickEvent(showMenu_);
1484 }
1485 
GetOnAccessibilityEventFunc()1486 OnAccessibilityEventFunc GestureEventHub::GetOnAccessibilityEventFunc()
1487 {
1488     auto callback = [weak = WeakClaim(this)](AccessibilityEventType eventType) {
1489         auto gestureHub = weak.Upgrade();
1490         CHECK_NULL_VOID(gestureHub);
1491         auto node = gestureHub->GetFrameNode();
1492         CHECK_NULL_VOID(node);
1493         node->OnAccessibilityEvent(eventType);
1494     };
1495     return callback;
1496 }
1497 
1498 template<typename T>
AccessibilityRecursionSearchRecognizer(const RefPtr<NGGestureRecognizer> & recognizer)1499 const RefPtr<T> GestureEventHub::AccessibilityRecursionSearchRecognizer(const RefPtr<NGGestureRecognizer>& recognizer)
1500 {
1501     auto CheckRecognizer = [](const RefPtr<NGGestureRecognizer>& recognizer) {
1502         const auto re = AceType::DynamicCast<ClickRecognizer>(recognizer);
1503         if (re != nullptr && re->GetFingers() == 1 && re->GetCount() == 1) {
1504             return true;
1505         } else if (AceType::DynamicCast<LongPressRecognizer>(recognizer) != nullptr &&
1506                    AceType::DynamicCast<LongPressRecognizer>(recognizer)->GetFingers() == 1) {
1507             return true;
1508         }
1509         return false;
1510     };
1511 
1512     const auto re = AceType::DynamicCast<T>(recognizer);
1513     if (re != nullptr && CheckRecognizer(recognizer)) {
1514         return re;
1515     } else if (AceType::DynamicCast<RecognizerGroup>(recognizer) != nullptr) {
1516         for (const auto& recognizerElement : AceType::DynamicCast<RecognizerGroup>(recognizer)->GetGroupRecognizer()) {
1517             const auto& tmpRecognizer = AccessibilityRecursionSearchRecognizer<T>(recognizerElement);
1518             if (tmpRecognizer != nullptr) {
1519                 return tmpRecognizer;
1520             }
1521         }
1522     }
1523     return nullptr;
1524 }
1525 
1526 template<typename T>
GetAccessibilityRecognizer()1527 const RefPtr<T> GestureEventHub::GetAccessibilityRecognizer()
1528 {
1529     for (const auto& recognizer : gestureHierarchy_) {
1530         const auto& re = AccessibilityRecursionSearchRecognizer<T>(recognizer);
1531         if (re != nullptr) {
1532             return re;
1533         }
1534     }
1535     return nullptr;
1536 }
1537 
ActClick(std::shared_ptr<JsonValue> secComphandle)1538 bool GestureEventHub::ActClick(std::shared_ptr<JsonValue> secComphandle)
1539 {
1540     auto host = GetFrameNode();
1541     CHECK_NULL_RETURN(host, false);
1542     GestureEventFunc click;
1543     GestureEvent info;
1544     std::chrono::microseconds microseconds(GetMicroTickCount());
1545     TimeStamp time(microseconds);
1546     info.SetTimeStamp(time);
1547     EventTarget clickEventTarget;
1548     clickEventTarget.id = host->GetInspectorId().value_or("").c_str();
1549     clickEventTarget.type = host->GetTag();
1550 #ifdef SECURITY_COMPONENT_ENABLE
1551     info.SetSecCompHandleEvent(secComphandle);
1552 #endif
1553     auto geometryNode = host->GetGeometryNode();
1554     CHECK_NULL_RETURN(geometryNode, false);
1555     auto offset = geometryNode->GetFrameOffset();
1556     auto size = geometryNode->GetFrameSize();
1557     clickEventTarget.area.SetOffset(DimensionOffset(offset));
1558     clickEventTarget.area.SetHeight(Dimension(size.Height()));
1559     clickEventTarget.area.SetWidth(Dimension(size.Width()));
1560     clickEventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1561     info.SetTarget(clickEventTarget);
1562     Offset globalOffset(offset.GetX(), offset.GetY());
1563     info.SetGlobalLocation(globalOffset);
1564     if (clickEventActuator_) {
1565         click = clickEventActuator_->GetClickEvent();
1566         CHECK_NULL_RETURN(click, true);
1567         click(info);
1568         return true;
1569     }
1570     const RefPtr<ClickRecognizer> clickRecognizer = GetAccessibilityRecognizer<ClickRecognizer>();
1571     if (clickRecognizer) {
1572         click = clickRecognizer->GetTapActionFunc();
1573         click(info);
1574         host->OnAccessibilityEvent(AccessibilityEventType::CLICK);
1575         return true;
1576     }
1577     return false;
1578 }
1579 
ActLongClick()1580 bool GestureEventHub::ActLongClick()
1581 {
1582     auto host = GetFrameNode();
1583     CHECK_NULL_RETURN(host, false);
1584     GestureEventFunc click;
1585     GestureEvent info;
1586     std::chrono::microseconds microseconds(GetMicroTickCount());
1587     TimeStamp time(microseconds);
1588     info.SetTimeStamp(time);
1589     EventTarget longPressTarget;
1590     longPressTarget.id = host->GetInspectorId().value_or("").c_str();
1591     longPressTarget.type = host->GetTag();
1592     auto geometryNode = host->GetGeometryNode();
1593     CHECK_NULL_RETURN(geometryNode, false);
1594     auto offset = geometryNode->GetFrameOffset();
1595     auto size = geometryNode->GetFrameSize();
1596     longPressTarget.area.SetOffset(DimensionOffset(offset));
1597     longPressTarget.area.SetHeight(Dimension(size.Height()));
1598     longPressTarget.area.SetWidth(Dimension(size.Width()));
1599     longPressTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1600     info.SetTarget(longPressTarget);
1601     Offset globalOffset(offset.GetX(), offset.GetY());
1602     info.SetGlobalLocation(globalOffset);
1603     if (longPressEventActuator_) {
1604         click = longPressEventActuator_->GetGestureEventFunc();
1605         CHECK_NULL_RETURN(click, true);
1606         click(info);
1607         return true;
1608     }
1609     RefPtr<LongPressRecognizer> longPressRecognizer;
1610     for (auto gestureRecognizer : gestureHierarchy_) {
1611         longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
1612         if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
1613             click = longPressRecognizer->GetLongPressActionFunc();
1614             click(info);
1615             host->OnAccessibilityEvent(AccessibilityEventType::LONG_PRESS);
1616             return true;
1617         }
1618     }
1619     return false;
1620 }
1621 
GetHitTestModeStr() const1622 std::string GestureEventHub::GetHitTestModeStr() const
1623 {
1624     auto mode = static_cast<int32_t>(hitTestMode_);
1625     if (mode < 0 || mode >= static_cast<int32_t>(std::size(HIT_TEST_MODE))) {
1626         return HIT_TEST_MODE[0];
1627     }
1628     return HIT_TEST_MODE[mode];
1629 }
1630 
KeyBoardShortCutClick(const KeyEvent & event,const WeakPtr<NG::FrameNode> & node)1631 bool GestureEventHub::KeyBoardShortCutClick(const KeyEvent& event, const WeakPtr<NG::FrameNode>& node)
1632 {
1633     auto host = node.Upgrade();
1634     CHECK_NULL_RETURN(host, false);
1635     CHECK_NULL_RETURN(clickEventActuator_, false);
1636     auto click = clickEventActuator_->GetClickEvent();
1637     CHECK_NULL_RETURN(click, false);
1638     GestureEvent info;
1639     info.SetSourceDevice(event.sourceType);
1640     info.SetTimeStamp(event.timeStamp);
1641     EventTarget target;
1642     target.id = host->GetInspectorId().value_or("").c_str();
1643     target.type = host->GetTag();
1644     auto geometryNode = host->GetGeometryNode();
1645     CHECK_NULL_RETURN(geometryNode, false);
1646     auto offset = geometryNode->GetFrameOffset();
1647     auto size = geometryNode->GetFrameSize();
1648     target.area.SetOffset(DimensionOffset(offset));
1649     target.area.SetHeight(Dimension(size.Height()));
1650     target.area.SetWidth(Dimension(size.Width()));
1651     target.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1652     info.SetTarget(target);
1653     click(info);
1654     return true;
1655 }
1656 
SetDragData(const RefPtr<UnifiedData> & unifiedData,std::string & udKey)1657 int32_t GestureEventHub::SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey)
1658 {
1659     CHECK_NULL_RETURN(unifiedData, -1);
1660     return UdmfClient::GetInstance()->SetData(unifiedData, udKey);
1661 }
1662 
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1663 OnDragCallbackCore GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1664 {
1665     auto ret = [](const DragNotifyMsgCore& notifyMessage) {};
1666     auto eventHub = hub.Upgrade();
1667     CHECK_NULL_RETURN(eventHub, ret);
1668     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1669     CHECK_NULL_RETURN(pipeline, ret);
1670     auto taskScheduler = pipeline->GetTaskExecutor();
1671     CHECK_NULL_RETURN(taskScheduler, ret);
1672     auto dragDropManager = pipeline->GetDragDropManager();
1673     CHECK_NULL_RETURN(dragDropManager, ret);
1674     auto eventManager = pipeline->GetEventManager();
1675     RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1676     auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager](
1677                         const DragNotifyMsgCore& notifyMessage) {
1678         ContainerScope scope(id);
1679         taskScheduler->PostTask(
1680             [eventHub, dragEvent, dragDropManager, eventManager, notifyMessage, id]() {
1681                 dragDropManager->SetDragResult(notifyMessage, dragEvent);
1682                 dragDropManager->SetDragBehavior(notifyMessage, dragEvent);
1683                 dragDropManager->DoDragReset();
1684                 dragDropManager->SetIsDragged(false);
1685                 dragDropManager->SetDraggingPointer(-1);
1686                 dragDropManager->SetDraggingPressedState(false);
1687                 dragDropManager->ResetDragPreviewInfo();
1688                 dragDropManager->HideDragPreviewWindow(id);
1689                 dragEvent->SetPressedKeyCodes(dragDropManager->GetDragDropPointerEvent().pressedKeyCodes_);
1690                 auto ret = InteractionInterface::GetInstance()->UnRegisterCoordinationListener();
1691                 if (ret != 0) {
1692                     TAG_LOGW(AceLogTag::ACE_DRAG, "Unregister coordination listener failed, error is %{public}d", ret);
1693                 }
1694                 if (eventManager) {
1695                     eventManager->DoMouseActionRelease();
1696                 }
1697                 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1698                 if (eventHub->HasOnDragEnd()) {
1699                     (eventHub->GetOnDragEnd())(dragEvent);
1700                 }
1701             },
1702             TaskExecutor::TaskType::UI, "ArkUIGestureDragEnd");
1703     };
1704     return callback;
1705 }
1706 
IsAccessibilityClickable()1707 bool GestureEventHub::IsAccessibilityClickable()
1708 {
1709     return IsClickable() || GetAccessibilityRecognizer<ClickRecognizer>() != nullptr;
1710 }
1711 
IsAccessibilityLongClickable()1712 bool GestureEventHub::IsAccessibilityLongClickable()
1713 {
1714     return IsLongClickable() || GetAccessibilityRecognizer<LongPressRecognizer>() != nullptr;
1715 }
1716 
GetMonopolizeEvents() const1717 bool GestureEventHub::GetMonopolizeEvents() const
1718 {
1719     return monopolizeEvents_;
1720 }
1721 
SetMonopolizeEvents(bool monopolizeEvents)1722 void GestureEventHub::SetMonopolizeEvents(bool monopolizeEvents)
1723 {
1724     monopolizeEvents_ = monopolizeEvents;
1725 }
1726 
ClearUserOnClick()1727 void GestureEventHub::ClearUserOnClick()
1728 {
1729     if (clickEventActuator_) {
1730         clickEventActuator_->ClearUserCallback();
1731     }
1732 }
1733 
ClearUserOnTouch()1734 void GestureEventHub::ClearUserOnTouch()
1735 {
1736     if (touchEventActuator_) {
1737         touchEventActuator_->ClearUserCallback();
1738     }
1739 }
1740 
ClearJSFrameNodeOnClick()1741 void GestureEventHub::ClearJSFrameNodeOnClick()
1742 {
1743     if (clickEventActuator_) {
1744         clickEventActuator_->ClearJSFrameNodeCallback();
1745     }
1746 }
1747 
ClearJSFrameNodeOnTouch()1748 void GestureEventHub::ClearJSFrameNodeOnTouch()
1749 {
1750     if (touchEventActuator_) {
1751         touchEventActuator_->ClearJSFrameNodeCallback();
1752     }
1753 }
1754 
CopyGestures(const RefPtr<GestureEventHub> & gestureEventHub)1755 void GestureEventHub::CopyGestures(const RefPtr<GestureEventHub>& gestureEventHub)
1756 {
1757     CHECK_NULL_VOID(gestureEventHub);
1758     gestures_ = gestureEventHub->backupGestures_;
1759     modifierGestures_ = gestureEventHub->backupModifierGestures_;
1760     recreateGesture_ = true;
1761 }
1762 
CopyEvent(const RefPtr<GestureEventHub> & gestureEventHub)1763 void GestureEventHub::CopyEvent(const RefPtr<GestureEventHub>& gestureEventHub)
1764 {
1765     CHECK_NULL_VOID(gestureEventHub);
1766     auto originalTouchEventActuator = gestureEventHub->touchEventActuator_;
1767     if (originalTouchEventActuator) {
1768         touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1769         touchEventActuator_->CopyTouchEvent(originalTouchEventActuator);
1770     }
1771 
1772     auto originalClickEventActuator = gestureEventHub->clickEventActuator_;
1773     if (originalClickEventActuator) {
1774         clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1775         clickEventActuator_->CopyClickEvent(originalClickEventActuator);
1776     }
1777 
1778     auto originalLongPressEventActuator = gestureEventHub->longPressEventActuator_;
1779     if (originalLongPressEventActuator) {
1780         longPressEventActuator_ = MakeRefPtr<LongPressEventActuator>(WeakClaim(this));
1781         longPressEventActuator_->CopyLongPressEvent(originalLongPressEventActuator);
1782     }
1783 
1784     auto originalDragEventActuator = gestureEventHub->dragEventActuator_;
1785     if (originalDragEventActuator) {
1786         dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), originalDragEventActuator->GetDirection(),
1787             originalDragEventActuator->GetFingers(), originalDragEventActuator->GetDistance());
1788         dragEventActuator_->CopyDragEvent(originalDragEventActuator);
1789     }
1790     auto originalShowMenu = gestureEventHub->showMenu_;
1791     if (originalShowMenu) {
1792         if (showMenu_) {
1793             RemoveClickEvent(showMenu_);
1794         }
1795         auto originalGetGestureEventFunc = originalShowMenu->GetGestureEventFunc();
1796         showMenu_= MakeRefPtr<ClickEvent>(std::move(originalGetGestureEventFunc));
1797         AddClickEvent(showMenu_);
1798     }
1799 }
1800 
IsTextCategoryComponent(const std::string & frameTag)1801 bool GestureEventHub::IsTextCategoryComponent(const std::string& frameTag)
1802 {
1803     return frameTag == V2::TEXTAREA_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
1804            frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG ||
1805            frameTag == V2::RICH_EDITOR_ETS_TAG;
1806 }
1807 
SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)1808 void GestureEventHub::SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)
1809 {
1810     isDragForbiddenForWholeSubTree_ = isDragForbiddenForWholeSubTree;
1811 }
1812 
IsDragForbidden() const1813 bool GestureEventHub::IsDragForbidden() const
1814 {
1815     return isDragForbiddenForWholeSubTree_;
1816 }
1817 
GetDragDropInfo(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo & dragPreviewInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1818 DragDropInfo GestureEventHub::GetDragDropInfo(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
1819     DragDropInfo& dragPreviewInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1820 {
1821     DragDropInfo dragDropInfo;
1822     CHECK_NULL_RETURN(dragEventActuator_, dragDropInfo);
1823     dragEventActuator_->SetIsDefaultOnDragStartExecuted(false);
1824     auto eventHub = eventHub_.Upgrade();
1825     CHECK_NULL_RETURN(eventHub, dragDropInfo);
1826     auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
1827     auto onDragStart = eventHub->GetOnDragStart();
1828     if (!onDragStart && eventHub->HasDefaultOnDragStart()) {
1829         onDragStart = eventHub->GetDefaultOnDragStart();
1830         dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1831     }
1832     if (GetTextDraggable() && info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1833         GenerateMousePixelMap(info);
1834     }
1835     dragEvent->SetPressedKeyCodes(info.GetPressedKeyCodes());
1836     dragDropInfo = onDragStart(dragEvent, extraParams);
1837 
1838     auto frameTag = frameNode->GetTag();
1839     if (GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1840         TAG_LOGD(AceLogTag::ACE_DRAG, "Get drag drop info, pixelmap and customNode are set to null "
1841             "when frameTag is %{public}s", frameTag.c_str());
1842         dragDropInfo.pixelMap = nullptr;
1843         dragDropInfo.customNode = nullptr;
1844     } else {
1845         auto dragPreview = frameNode->GetDragPreview();
1846         if (dragPreview.onlyForLifting) {
1847             return dragDropInfo;
1848         }
1849         if (!dragPreview.customNode && dragPreview.delayCreating && dragPreview.buildFunc) {
1850             dragPreview.customNode = dragPreview.buildFunc();
1851         }
1852         frameNode->SetDragPreview(dragPreview);
1853         dragPreviewInfo = dragPreview;
1854     }
1855     return dragDropInfo;
1856 }
1857 
GetUnifiedData(const std::string & frameTag,DragDropInfo & dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1858 RefPtr<UnifiedData> GestureEventHub::GetUnifiedData(const std::string& frameTag, DragDropInfo& dragDropInfo,
1859     const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1860 {
1861     auto eventHub = eventHub_.Upgrade();
1862     CHECK_NULL_RETURN(eventHub, nullptr);
1863     auto unifiedData = dragEvent->GetData();
1864     bool hasData = static_cast<bool>(unifiedData);
1865     if (!unifiedData && eventHub->HasDefaultOnDragStart()) {
1866         auto defaultDropInfo = eventHub->GetDefaultOnDragStart()(dragEvent, "");
1867         if (dragDropInfo.extraInfo.empty()) {
1868             dragDropInfo.extraInfo = defaultDropInfo.extraInfo;
1869         }
1870         CHECK_NULL_RETURN(dragEventActuator_, nullptr);
1871         dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1872         unifiedData = dragEvent->GetData();
1873     }
1874     auto defaultOnDragStart = eventHub->GetDefaultOnDragStart();
1875     CHECK_NULL_RETURN(defaultOnDragStart, unifiedData);
1876     if (hasData && IsTextCategoryComponent(frameTag) && !dragEventActuator_->IsDefaultOnDragStartExecuted()) {
1877         defaultOnDragStart(dragEvent, "");
1878     }
1879     return unifiedData;
1880 }
1881 
SetOnTouchEvent(TouchEventFunc && touchEventFunc)1882 void GestureEventHub::SetOnTouchEvent(TouchEventFunc&& touchEventFunc)
1883 {
1884     if (!touchEventActuator_) {
1885         touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1886     }
1887     touchEventActuator_->SetOnTouchEvent(std::move(touchEventFunc));
1888 }
1889 
SetJSFrameNodeOnTouchEvent(TouchEventFunc && touchEventFunc)1890 void GestureEventHub::SetJSFrameNodeOnTouchEvent(TouchEventFunc&& touchEventFunc)
1891 {
1892     if (!touchEventActuator_) {
1893         touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1894     }
1895     touchEventActuator_->SetJSFrameNodeOnTouchEvent(std::move(touchEventFunc));
1896 }
1897 
SetResponseRegion(const std::vector<DimensionRect> & responseRegion)1898 void GestureEventHub::SetResponseRegion(const std::vector<DimensionRect>& responseRegion)
1899 {
1900     responseRegion_ = responseRegion;
1901     if (!responseRegion_.empty()) {
1902         isResponseRegion_ = true;
1903     }
1904     if (responseRegionFunc_) {
1905         responseRegionFunc_(responseRegion_);
1906     }
1907 }
1908 
RemoveLastResponseRect()1909 void GestureEventHub::RemoveLastResponseRect()
1910 {
1911     if (responseRegion_.empty()) {
1912         isResponseRegion_ = false;
1913         return;
1914     }
1915     responseRegion_.pop_back();
1916     if (responseRegion_.empty()) {
1917         isResponseRegion_ = false;
1918     }
1919 
1920     if (responseRegionFunc_) {
1921         responseRegionFunc_(responseRegion_);
1922     }
1923 }
1924 
RemoveGesturesByTag(const std::string & gestureTag)1925 void GestureEventHub::RemoveGesturesByTag(const std::string& gestureTag)
1926 {
1927     bool needRecollect = false;
1928     for (auto iter = modifierGestures_.begin(); iter != modifierGestures_.end();) {
1929         auto tag = (*iter)->GetTag();
1930         if (tag.has_value() && tag.value() == gestureTag) {
1931             iter = modifierGestures_.erase(iter);
1932             backupModifierGestures_.remove(*iter);
1933             needRecollect = true;
1934         } else {
1935             auto group = AceType::DynamicCast<GestureGroup>(*iter);
1936             if (group) {
1937                 group->RemoveChildrenByTag(gestureTag, needRecollect);
1938             }
1939             iter++;
1940         }
1941     }
1942     if (needRecollect) {
1943         recreateGesture_ = true;
1944         needRecollect_ = true;
1945         OnModifyDone();
1946     }
1947 }
1948 
ClearModifierGesture()1949 void GestureEventHub::ClearModifierGesture()
1950 {
1951     modifierGestures_.clear();
1952     backupModifierGestures_.clear();
1953     recreateGesture_ = true;
1954     OnModifyDone();
1955 }
1956 
IsNeedSwitchToSubWindow() const1957 bool GestureEventHub::IsNeedSwitchToSubWindow() const
1958 {
1959     auto frameNode = GetFrameNode();
1960     CHECK_NULL_RETURN(frameNode, false);
1961     auto focusHub = frameNode->GetFocusHub();
1962     CHECK_NULL_RETURN(focusHub, false);
1963     if (IsPixelMapNeedScale()) {
1964         return true;
1965     }
1966     CHECK_NULL_RETURN(dragEventActuator_, false);
1967     return dragEventActuator_->IsNeedGather();
1968 }
1969 
SetDragGatherPixelMaps(const GestureEvent & info)1970 void GestureEventHub::SetDragGatherPixelMaps(const GestureEvent& info)
1971 {
1972     CHECK_NULL_VOID(dragEventActuator_);
1973     if (!dragEventActuator_->IsNeedGather()) {
1974         return;
1975     }
1976     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1977         SetMouseDragGatherPixelMaps();
1978     } else {
1979         SetNotMouseDragGatherPixelMaps();
1980     }
1981 }
1982 
ClearGesture()1983 void GestureEventHub::ClearGesture()
1984 {
1985     gestures_.clear();
1986     backupGestures_.clear();
1987     recreateGesture_ = true;
1988 }
1989 
SetMouseDragGatherPixelMaps()1990 void GestureEventHub::SetMouseDragGatherPixelMaps()
1991 {
1992     auto frameNode = GetFrameNode();
1993     CHECK_NULL_VOID(frameNode);
1994     auto pipeline = PipelineContext::GetCurrentContext();
1995     CHECK_NULL_VOID(pipeline);
1996     auto dragDropManager = pipeline->GetDragDropManager();
1997     CHECK_NULL_VOID(dragDropManager);
1998     dragDropManager->ClearGatherPixelMap();
1999     CHECK_NULL_VOID(dragEventActuator_);
2000     auto fatherNode = dragEventActuator_->GetItemParentNode();
2001     CHECK_NULL_VOID(fatherNode);
2002     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
2003     CHECK_NULL_VOID(scrollPattern);
2004     auto children = scrollPattern->GetVisibleSelectedItems();
2005     int cnt = 0;
2006     for (const auto& itemFrameNode : children) {
2007         if (itemFrameNode == frameNode) {
2008             continue;
2009         }
2010         CHECK_NULL_VOID(itemFrameNode);
2011         DragEventActuator::GetFrameNodePreviewPixelMap(itemFrameNode);
2012         auto gestureHub = itemFrameNode->GetOrCreateGestureEventHub();
2013         CHECK_NULL_VOID(gestureHub);
2014         dragDropManager->PushGatherPixelMap(gestureHub->GetDragPreviewPixelMap());
2015         cnt++;
2016         if (cnt > 1) {
2017             break;
2018         }
2019     }
2020 }
2021 
SetNotMouseDragGatherPixelMaps()2022 void GestureEventHub::SetNotMouseDragGatherPixelMaps()
2023 {
2024     auto pipeline = PipelineContext::GetCurrentContext();
2025     CHECK_NULL_VOID(pipeline);
2026     auto dragDropManager = pipeline->GetDragDropManager();
2027     CHECK_NULL_VOID(dragDropManager);
2028     dragDropManager->ClearGatherPixelMap();
2029     auto mainPipeline = PipelineContext::GetMainPipelineContext();
2030     CHECK_NULL_VOID(mainPipeline);
2031     auto overlayManager = mainPipeline->GetOverlayManager();
2032     CHECK_NULL_VOID(overlayManager);
2033     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
2034     int cnt = 0;
2035     for (auto iter = gatherNodeChildrenInfo.rbegin(); iter != gatherNodeChildrenInfo.rend(); ++iter) {
2036         auto imageNode = (*iter).imageNode.Upgrade();
2037         CHECK_NULL_VOID(imageNode);
2038         auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
2039         CHECK_NULL_VOID(imageLayoutProperty);
2040         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value_or(ImageSourceInfo());
2041         dragDropManager->PushGatherPixelMap(imageSourceInfo.GetPixmap());
2042         cnt++;
2043         if (cnt > 1) {
2044             break;
2045         }
2046     }
2047 }
2048 
GetSelectItemSize()2049 int32_t GestureEventHub::GetSelectItemSize()
2050 {
2051     CHECK_NULL_RETURN(dragEventActuator_, 0);
2052     if (!dragEventActuator_->IsNeedGather()) {
2053         return 0;
2054     }
2055     auto fatherNode = dragEventActuator_->GetItemParentNode();
2056     CHECK_NULL_RETURN(fatherNode, 0);
2057     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
2058     CHECK_NULL_RETURN(scrollPattern, 0);
2059     auto children = scrollPattern->GetVisibleSelectedItems();
2060     return children.size();
2061 }
2062 
FireCustomerOnDragEnd(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)2063 void GestureEventHub::FireCustomerOnDragEnd(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
2064 {
2065     auto eventHub = hub.Upgrade();
2066     CHECK_NULL_VOID(eventHub);
2067     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
2068     CHECK_NULL_VOID(pipeline);
2069     auto dragDropManager = pipeline->GetDragDropManager();
2070     CHECK_NULL_VOID(dragDropManager);
2071     auto dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
2072     CHECK_NULL_VOID(dragEvent);
2073     dragEvent->SetResult(DragRet::DRAG_FAIL);
2074     dragEvent->SetDragBehavior(DragBehavior::UNKNOWN);
2075     dragDropManager->DoDragReset();
2076     dragDropManager->SetIsDragged(false);
2077     dragDropManager->ResetDragging();
2078     dragDropManager->SetDraggingPointer(-1);
2079     dragDropManager->SetDraggingPressedState(false);
2080     dragDropManager->ResetDragPreviewInfo();
2081     eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
2082     if (eventHub->HasOnDragEnd()) {
2083         (eventHub->GetOnDragEnd())(dragEvent);
2084     }
2085 }
2086 
2087 #if defined(PIXEL_MAP_SUPPORTED)
PrintBuilderNode(const RefPtr<UINode> & customNode)2088 void GestureEventHub::PrintBuilderNode(const RefPtr<UINode>& customNode)
2089 {
2090     CHECK_NULL_VOID(customNode);
2091     bool hasImageNode = false;
2092     std::list<RefPtr<FrameNode>> imageNodes;
2093     int32_t depth = 1;
2094     PrintIfImageNode(customNode, depth, hasImageNode, imageNodes);
2095     CheckImageDecode(imageNodes);
2096     imageNodes.clear();
2097 }
2098 
PrintIfImageNode(const RefPtr<UINode> & builderNode,int32_t depth,bool & hasImageNode,std::list<RefPtr<FrameNode>> & imageNodes)2099 void GestureEventHub::PrintIfImageNode(
2100     const RefPtr<UINode>& builderNode, int32_t depth, bool& hasImageNode, std::list<RefPtr<FrameNode>>& imageNodes)
2101 {
2102     if (depth > MAX_BUILDER_DEPTH) {
2103         return;
2104     }
2105     if (builderNode->GetTag() == V2::IMAGE_ETS_TAG) {
2106         auto frameNode = AceType::DynamicCast<FrameNode>(builderNode);
2107         CHECK_NULL_VOID(frameNode);
2108         auto pattern = frameNode->GetPattern<ImagePattern>();
2109         CHECK_NULL_VOID(pattern);
2110         hasImageNode = true;
2111         imageNodes.push_back(frameNode);
2112         TAG_LOGI(AceLogTag::ACE_DRAG,
2113             "customNode has ImageNode, syncLoad: %{public}d, decode complete: %{public}d",
2114             pattern->GetSyncLoad(), pattern->GetCanvasImage() != nullptr);
2115     }
2116 
2117     auto children = builderNode->GetChildren();
2118     for (const auto& child : children) {
2119         PrintIfImageNode(child, depth + 1, hasImageNode, imageNodes);
2120     }
2121 }
2122 
CheckImageDecode(std::list<RefPtr<FrameNode>> & imageNodes)2123 void GestureEventHub::CheckImageDecode(std::list<RefPtr<FrameNode>>& imageNodes)
2124 {
2125     if (imageNodes.empty()) {
2126         return;
2127     }
2128 
2129     for (const auto& imageNode : imageNodes) {
2130         auto pattern = imageNode->GetPattern<ImagePattern>();
2131         CHECK_NULL_VOID(pattern);
2132         if (!pattern->GetCanvasImage()) {
2133             TAG_LOGW(
2134                 AceLogTag::ACE_DRAG, "ImageNode did not complete decoding.");
2135         }
2136     }
2137 }
2138 
StartDragForCustomBuilder(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)2139 void GestureEventHub::StartDragForCustomBuilder(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
2140     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
2141 {
2142     SnapshotParam param;
2143     param.delay = CREATE_PIXELMAP_TIME;
2144     param.checkImageStatus = true;
2145     param.options.waitUntilRenderFinished = true;
2146     std::shared_ptr<Media::PixelMap> pixelMap = ComponentSnapshot::CreateSync(dragDropInfo.customNode, param);
2147     if (pixelMap != nullptr) {
2148         dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
2149         OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
2150         return;
2151     }
2152     TAG_LOGI(AceLogTag::ACE_DRAG, "Snapshot createSync failed, get thumbnail by async.");
2153     auto callback = [id = Container::CurrentId(), pipeline, info, gestureEventHubPtr = AceType::Claim(this), frameNode,
2154         dragDropInfo, event](std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()>
2155         finishCallback) mutable {
2156         ContainerScope scope(id);
2157         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail callback executed.");
2158         if (pixelMap != nullptr) {
2159             dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
2160         } else {
2161             DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
2162         }
2163         auto taskScheduler = pipeline->GetTaskExecutor();
2164         CHECK_NULL_VOID(taskScheduler);
2165         taskScheduler->PostTask(
2166             [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event, finishCallback]() {
2167                 if (finishCallback) {
2168                     finishCallback();
2169                 }
2170                 CHECK_NULL_VOID(gestureEventHubPtr);
2171                 CHECK_NULL_VOID(frameNode);
2172                 gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
2173             },
2174             TaskExecutor::TaskType::UI, "ArkUIGestureDragStart");
2175     };
2176     NG::ComponentSnapshot::Create(dragDropInfo.customNode, std::move(callback), true, param);
2177     PrintBuilderNode(dragDropInfo.customNode);
2178 }
2179 #endif
2180 
SetMouseDragMonitorState(bool state)2181 void GestureEventHub::SetMouseDragMonitorState(bool state)
2182 {
2183     auto ret = InteractionInterface::GetInstance()->SetMouseDragMonitorState(state);
2184     if (ret != 0) {
2185         TAG_LOGW(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d failed, return value is %{public}d",
2186             state, ret);
2187         return;
2188     }
2189     TAG_LOGI(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d success", state);
2190 }
2191 
SetBindMenuStatus(bool setIsShow,bool isShow,MenuPreviewMode previewMode)2192 void GestureEventHub::SetBindMenuStatus(bool setIsShow, bool isShow, MenuPreviewMode previewMode)
2193 {
2194     if (setIsShow) {
2195         bindMenuStatus_.isBindCustomMenu = true;
2196         bindMenuStatus_.isShow = isShow;
2197         bindMenuStatus_.isShowPreviewMode = previewMode;
2198     } else {
2199         bindMenuStatus_.isBindLongPressMenu = true;
2200         bindMenuStatus_.longPressPreviewMode = previewMode;
2201     }
2202 }
2203 
IsGestureEmpty() const2204 bool GestureEventHub::IsGestureEmpty() const
2205 {
2206     return gestures_.empty();
2207 }
2208 
IsPanEventEmpty() const2209 bool GestureEventHub::IsPanEventEmpty() const
2210 {
2211     if (panEventActuator_) {
2212         return panEventActuator_->IsPanEventEmpty();
2213     }
2214     return true;
2215 }
2216 
DumpVelocityInfoFroPanEvent(int32_t fingerId)2217 void GestureEventHub::DumpVelocityInfoFroPanEvent(int32_t fingerId)
2218 {
2219     CHECK_NULL_VOID(panEventActuator_);
2220     panEventActuator_->DumpVelocityInfo(fingerId);
2221 }
2222 } // namespace OHOS::Ace::NG
2223