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