• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "base/image/image_source.h"
17 #include "base/log/ace_trace.h"
18 #include "base/log/log_wrapper.h"
19 #include "base/memory/ace_type.h"
20 #include "base/subwindow/subwindow_manager.h"
21 #include "core/common/container.h"
22 #include "core/common/interaction/interaction_data.h"
23 #include "core/common/interaction/interaction_interface.h"
24 #include "core/components/container_modal/container_modal_constants.h"
25 #include "core/components_ng/event/gesture_event_hub.h"
26 #include "core/components_ng/gestures/gesture_referee.h"
27 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
28 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
29 #include "core/components_ng/manager/drag_drop/drag_drop_global_controller.h"
30 #include "core/components_ng/manager/drag_drop/drag_drop_manager.h"
31 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
32 #include "core/components_ng/pattern/image/image_pattern.h"
33 #include "core/components_ng/pattern/relative_container/relative_container_pattern.h"
34 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
35 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
36 #include "core/components_ng/pattern/menu/preview/menu_preview_pattern.h"
37 #include "core/common/vibrator/vibrator_utils.h"
38 
39 #if defined(PIXEL_MAP_SUPPORTED)
40 #include "image_source.h"
41 #endif
42 
43 #include "core/common/udmf/udmf_client.h"
44 #include "core/components_ng/render/adapter/component_snapshot.h"
45 #ifdef WEB_SUPPORTED
46 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
47 #include "core/components_ng/pattern/web/web_pattern.h"
48 #else
49 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
50 #endif
51 #endif
52 namespace OHOS::Ace::NG {
53 namespace {
54 #if defined(PIXEL_MAP_SUPPORTED)
55 constexpr int32_t CREATE_PIXELMAP_TIME = 30;
56 constexpr int32_t MAX_BUILDER_DEPTH = 5;
57 #endif
58 constexpr uint32_t EXTRA_INFO_MAX_LENGTH = 1024;
59 constexpr int32_t DEFAULT_DRAG_DROP_STATUS = 0;
60 constexpr int32_t NEW_DRAG_DROP_STATUS = 1;
61 constexpr int32_t OLD_DRAG_DROP_STATUS = 3;
62 constexpr float HALF_DIVIDE = 2.0f;
63 const std::unordered_set<std::string> OLD_FRAMEWORK_TAG = {
64     V2::WEB_ETS_TAG,
65     V2::TEXTAREA_ETS_TAG,
66     V2::TEXT_ETS_TAG,
67     V2::TEXTINPUT_ETS_TAG,
68     V2::SEARCH_Field_ETS_TAG,
69     V2::RICH_EDITOR_ETS_TAG,
70 };
71 const std::unordered_set<std::string> VALID_TAG = {
72     V2::WEB_ETS_TAG,
73 };
74 constexpr int32_t HALF_PIXELMAP = 2;
75 constexpr int32_t PASS_THROUGH_EVENT_ID = 100000;
76 } // namespace
77 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
78 
IsPixelMapNeedScale() const79 bool GestureEventHub::IsPixelMapNeedScale() const
80 {
81     auto frameNode = GetFrameNode();
82     CHECK_NULL_RETURN(frameNode, false);
83     auto scale = DragDropFuncWrapper::GetPixelMapScale(frameNode);
84     return scale != 1.0f;
85 }
86 
IsDragNewFwk() const87 bool GestureEventHub::IsDragNewFwk() const
88 {
89     return isDragNewFwk_;
90 }
91 
CheckNeedDragDropFrameworkStatus(const std::string & tag)92 bool CheckNeedDragDropFrameworkStatus(const std::string& tag)
93 {
94     auto dragDropFrameworkStatus = SystemProperties::GetDragDropFrameworkStatus();
95     if (dragDropFrameworkStatus == DEFAULT_DRAG_DROP_STATUS &&
96         (OLD_FRAMEWORK_TAG.find(tag) != OLD_FRAMEWORK_TAG.end())) {
97         return false;
98     } else if ((dragDropFrameworkStatus == NEW_DRAG_DROP_STATUS) && (VALID_TAG.find(tag) != VALID_TAG.end())) {
99         return false;
100     } else if (dragDropFrameworkStatus == OLD_DRAG_DROP_STATUS) {
101         return false;
102     }
103     return true;
104 }
105 
InitDragDropEvent()106 void GestureEventHub::InitDragDropEvent()
107 {
108     auto frameNode = GetFrameNode();
109     if (frameNode && CheckNeedDragDropFrameworkStatus(frameNode->GetTag())) {
110         SetDragDropEvent();
111         return;
112     }
113     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
114         auto gestureEventHub = weak.Upgrade();
115         CHECK_NULL_VOID(gestureEventHub);
116         gestureEventHub->HandleOnDragStart(info);
117     };
118 
119     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
120         auto gestureEventHub = weak.Upgrade();
121         CHECK_NULL_VOID(gestureEventHub);
122         gestureEventHub->HandleOnDragUpdate(info);
123     };
124 
125     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
126         auto gestureEventHub = weak.Upgrade();
127         CHECK_NULL_VOID(gestureEventHub);
128         gestureEventHub->HandleOnDragEnd(info);
129     };
130 
131     auto actionCancelTask = [weak = WeakClaim(this)]() {
132         auto gestureEventHub = weak.Upgrade();
133         CHECK_NULL_VOID(gestureEventHub);
134         gestureEventHub->HandleOnDragCancel();
135     };
136     auto dragEvent = MakeRefPtr<DragEvent>(
137         std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
138     auto distance = SystemProperties::GetDragStartPanDistanceThreshold();
139     SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, Dimension(distance, DimensionUnit::VP));
140     CHECK_NULL_VOID(dragEventActuator_);
141     dragEventActuator_->SetIsForDragDrop(false);
142 }
143 
IsAllowedDrag(RefPtr<EventHub> eventHub)144 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
145 {
146     auto frameNode = GetFrameNode();
147     CHECK_NULL_RETURN(frameNode, false);
148     auto pattern = frameNode->GetPattern();
149     CHECK_NULL_RETURN(pattern, false);
150 
151     if (frameNode->IsDraggable()) {
152         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
153             return false;
154         }
155     } else {
156         if (frameNode->IsUserSet()) {
157             return false;
158         }
159         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
160             return false;
161         }
162     }
163     return true;
164 }
165 
StartLongPressActionForWeb()166 void GestureEventHub::StartLongPressActionForWeb()
167 {
168     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start long press action for web");
169     auto pipeline = PipelineContext::GetCurrentContext();
170     CHECK_NULL_VOID(pipeline);
171     auto taskScheduler = pipeline->GetTaskExecutor();
172     CHECK_NULL_VOID(taskScheduler);
173 
174     taskScheduler->PostTask(
175         [weak = WeakClaim(this)]() {
176             auto gestureHub = weak.Upgrade();
177             CHECK_NULL_VOID(gestureHub);
178             auto dragEventActuator = gestureHub->dragEventActuator_;
179             CHECK_NULL_VOID(dragEventActuator);
180             dragEventActuator->StartLongPressActionForWeb();
181         },
182         TaskExecutor::TaskType::UI, "ArkUIGestureWebStartLongPress");
183 }
184 
CancelDragForWeb()185 void GestureEventHub::CancelDragForWeb()
186 {
187     TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop cancel drag for web");
188     auto pipeline = PipelineContext::GetCurrentContext();
189     CHECK_NULL_VOID(pipeline);
190     auto taskScheduler = pipeline->GetTaskExecutor();
191     CHECK_NULL_VOID(taskScheduler);
192 
193     taskScheduler->PostTask(
194         [weak = WeakClaim(this)]() {
195             auto gestureHub = weak.Upgrade();
196             CHECK_NULL_VOID(gestureHub);
197             auto dragEventActuator = gestureHub->dragEventActuator_;
198             CHECK_NULL_VOID(dragEventActuator);
199             dragEventActuator->CancelDragForWeb();
200         },
201         TaskExecutor::TaskType::UI, "ArkUIGestureWebCancelDrag");
202 }
203 
ResetDragActionForWeb()204 void GestureEventHub::ResetDragActionForWeb()
205 {
206     TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop reset drag action for web");
207     isReceivedDragGestureInfo_ = false;
208     CHECK_NULL_VOID(dragEventActuator_);
209     dragEventActuator_->ResetDragActionForWeb();
210 
211     // fix drag failed when long press drag after 500ms and before 800ms
212     // need to reset the state of the drag manager
213     auto pipeLine = PipelineContext::GetCurrentContext();
214     CHECK_NULL_VOID(pipeLine);
215     auto dragDropManager = pipeLine->GetDragDropManager();
216     CHECK_NULL_VOID(dragDropManager);
217     dragDropManager->ResetDragging();
218 }
219 
StartDragTaskForWeb()220 bool GestureEventHub::StartDragTaskForWeb()
221 {
222     if (!isReceivedDragGestureInfo_) {
223         TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop StartDragTaskForWeb failed,"
224                                      "because not recv gesture info");
225         return false;
226     }
227 
228     isReceivedDragGestureInfo_ = false;
229     auto pipeline = PipelineContext::GetCurrentContext();
230     CHECK_NULL_RETURN(pipeline, false);
231     auto taskScheduler = pipeline->GetTaskExecutor();
232     CHECK_NULL_RETURN(taskScheduler, false);
233 
234     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop post a task to start drag for web");
235     taskScheduler->PostTask(
236         [weak = WeakClaim(this)]() {
237             auto gestureHub = weak.Upgrade();
238             CHECK_NULL_VOID(gestureHub);
239             auto dragEventActuator = gestureHub->dragEventActuator_;
240             CHECK_NULL_VOID(dragEventActuator);
241             CHECK_NULL_VOID(gestureHub->gestureInfoForWeb_);
242             TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start drag task for web in async task");
243             dragEventActuator->StartDragTaskForWeb(*gestureHub->gestureInfoForWeb_);
244         },
245         TaskExecutor::TaskType::UI, "ArkUIGestureWebStartDrag");
246     return true;
247 }
248 
CreatePixelMapFromString(const std::string & filePath)249 RefPtr<PixelMap> CreatePixelMapFromString(const std::string& filePath)
250 {
251     auto imageSource = ImageSource::Create(filePath);
252     CHECK_NULL_RETURN(imageSource, nullptr);
253     RefPtr<PixelMap> pixelMap = imageSource->CreatePixelMap();
254     return pixelMap;
255 }
256 
CalcFrameNodeOffsetAndSize(const RefPtr<FrameNode> frameNode,bool isMenuShow)257 void GestureEventHub::CalcFrameNodeOffsetAndSize(const RefPtr<FrameNode> frameNode, bool isMenuShow)
258 {
259     CHECK_NULL_VOID(frameNode);
260     auto frameTag = frameNode->GetTag();
261     auto hostPattern = frameNode->GetPattern<TextDragBase>();
262     if (hostPattern && GetTextDraggable() &&
263         (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG || frameTag == V2::TEXTINPUT_ETS_TAG ||
264             frameTag == V2::SEARCH_Field_ETS_TAG)) {
265         frameNodeOffset_ = hostPattern->GetDragUpperLeftCoordinates();
266         frameNodeSize_ = SizeF(0.0f, 0.0f);
267     } else {
268         auto center = DragDropFuncWrapper::GetPaintRectCenterToScreen(frameNode) -
269             DragDropFuncWrapper::GetCurrentWindowOffset(PipelineContext::GetCurrentContextSafelyWithCheck());
270         auto geometryNode = frameNode->GetGeometryNode();
271         if (geometryNode) {
272             auto scale = frameNode->GetTransformScaleRelativeToWindow();
273             auto size = geometryNode->GetFrameSize();
274             frameNodeSize_ = SizeF(size.Width() * scale.x, size.Height() * scale.y);
275         } else {
276             frameNodeSize_ = SizeF(0.0f, 0.0f);
277         }
278         frameNodeOffset_ = center - OffsetF(frameNodeSize_.Width(), frameNodeSize_.Height()) / HALF_DIVIDE;
279 #ifdef WEB_SUPPORTED
280         if (frameTag == V2::WEB_ETS_TAG) {
281             auto webPattern = frameNode->GetPattern<WebPattern>();
282             if (webPattern) {
283                 frameNodeOffset_.SetX(frameNodeOffset_.GetX() + webPattern->GetDragOffset().GetX());
284                 frameNodeOffset_.SetY(frameNodeOffset_.GetY() + webPattern->GetDragOffset().GetY());
285                 frameNodeSize_ = webPattern->GetDragPixelMapSize();
286             }
287         }
288 #endif
289     }
290 
291     // use menuPreview's size and offset for drag framework.
292     if (!frameNode->GetDragPreview().onlyForLifting && isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f) &&
293         (GreatNotEqual(DragAnimationHelper::GetPreviewMenuAnimationRate(), 0.0f) ||
294             frameNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT)) {
295         auto menuPreviewRect = DragDropManager::GetMenuPreviewRect();
296         if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(menuPreviewRect.Height(), 0.0f)) {
297             frameNodeOffset_ = menuPreviewRect.GetOffset();
298             frameNodeSize_ = menuPreviewRect.GetSize();
299         }
300     }
301 }
302 
GetDefaultPixelMapScale(const RefPtr<FrameNode> & frameNode,const GestureEvent & info,bool isMenuShow,RefPtr<PixelMap> pixelMap)303 float GestureEventHub::GetDefaultPixelMapScale(
304     const RefPtr<FrameNode>& frameNode, const GestureEvent& info, bool isMenuShow, RefPtr<PixelMap> pixelMap)
305 {
306     float defaultPixelMapScale =
307         info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
308     CHECK_NULL_RETURN(pixelMap, defaultPixelMapScale);
309     // use menuPreviewScale for drag framework. this is not final solution.
310     if (!frameNode->GetDragPreview().onlyForLifting && isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f)) {
311         auto menuPreviewRectWidth = frameNodeSize_.Width();
312         int32_t originPixelMapWidth = pixelMap->GetWidth();
313         if (GreatNotEqual(menuPreviewRectWidth, 0.0f) && GreatNotEqual(originPixelMapWidth, 0.0f) &&
314             menuPreviewRectWidth < originPixelMapWidth * menuPreviewScale_) {
315             defaultPixelMapScale = menuPreviewRectWidth / originPixelMapWidth;
316         } else {
317             defaultPixelMapScale = menuPreviewScale_;
318         }
319     }
320     return defaultPixelMapScale;
321 }
322 
CheckInSceneBoardWindow()323 bool CheckInSceneBoardWindow()
324 {
325     auto container = Container::Current();
326     CHECK_NULL_RETURN(container, false);
327     if (!container->IsSubContainer()) {
328         return container->IsSceneBoardWindow();
329     }
330     auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
331     container = Container::GetContainer(parentContainerId);
332     CHECK_NULL_RETURN(container, false);
333     return container->IsSceneBoardWindow();
334 }
335 
CheckOffsetInPixelMap(OffsetF & result,const SizeF & size)336 void CheckOffsetInPixelMap(OffsetF& result, const SizeF& size)
337 {
338     if (result.GetX() >= 0.0f) {
339         result.SetX(-1.0f);
340     }
341     if (result.GetX() + size.Width() <= 0.0f) {
342         result.SetX(1.0f - size.Width());
343     }
344     if (result.GetY() >= 0.0f) {
345         result.SetY(-1.0f);
346     }
347     if (result.GetY() + size.Height() <= 0.0f) {
348         result.SetY(1.0f - size.Height());
349     }
350 }
351 
ParseInnerRect(const std::string & extraInfo,const SizeF & size)352 RectF ParseInnerRect(const std::string& extraInfo, const SizeF& size)
353 {
354     auto innerRect = RectF();
355     if (!CheckInSceneBoardWindow() || extraInfo.empty()) {
356         return innerRect;
357     }
358     auto extraJson = JsonUtil::ParseJsonString(extraInfo);
359     CHECK_NULL_RETURN(extraJson, innerRect);
360     auto extraOffsetX = extraJson->GetInt("drag_offset_x");
361     auto extraOffsetY = extraJson->GetInt("drag_offset_y");
362     if (extraOffsetX <= 0 || extraOffsetY <= 0) {
363         return innerRect;
364     }
365     innerRect.SetOffset(OffsetF(Dimension(extraOffsetX, DimensionUnit::VP).ConvertToPx(),
366         Dimension(extraOffsetY, DimensionUnit::VP).ConvertToPx()));
367     innerRect.SetSize(size);
368     return innerRect;
369 }
370 
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const PreparedInfoForDrag & dragInfoData,const float scale,const RectF & innerRect) const371 OffsetF GestureEventHub::GetPixelMapOffset(const GestureEvent& info, const SizeF& size,
372     const PreparedInfoForDrag& dragInfoData, const float scale, const RectF& innerRect) const
373 {
374     OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
375     auto frameNode = GetFrameNode();
376     CHECK_NULL_RETURN(frameNode, result);
377     auto frameTag = frameNode->GetTag();
378     auto coordinateX = frameNodeOffset_.GetX();
379     auto coordinateY = frameNodeOffset_.GetY();
380     if (!innerRect.IsEmpty() && !NearZero(size.Width()) && !NearZero(size.Height())) {
381         auto rateX = innerRect.Width() / size.Width();
382         auto rateY = innerRect.Height() / size.Height();
383         result.SetX(rateX * (coordinateX + innerRect.GetOffset().GetX() - info.GetGlobalLocation().GetX()));
384         result.SetY(rateY * (coordinateY + innerRect.GetOffset().GetY() - info.GetGlobalLocation().GetY()));
385         CheckOffsetInPixelMap(result, size);
386         return result;
387     }
388     if (NearZero(frameNodeSize_.Width()) || NearZero(frameNodeSize_.Height()) ||
389         NearZero(size.Width()) || NearZero(size.Height())) {
390         result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()));
391         result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()));
392     } else {
393         if (dragInfoData.isNeedCreateTiled) {
394             result.SetX(-size.Width() / HALF_PIXELMAP);
395             result.SetY(-size.Height() / HALF_PIXELMAP);
396         } else if (frameNode->GetDragPreviewOption().isTouchPointCalculationBasedOnFinalPreviewEnable) {
397             auto centerX = coordinateX + frameNodeSize_.Width() / HALF_PIXELMAP;
398             auto centerY = coordinateY + frameNodeSize_.Height() / HALF_PIXELMAP;
399             coordinateX = centerX - dragInfoData.dragPreviewRect.Width() / HALF_PIXELMAP;
400             coordinateY = centerY - dragInfoData.dragPreviewRect.Height() / HALF_PIXELMAP;
401             auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / dragInfoData.dragPreviewRect.Width();
402             auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / dragInfoData.dragPreviewRect.Height();
403             result.SetX(-rateX * size.Width());
404             result.SetY(-rateY * size.Height());
405         } else {
406             auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / frameNodeSize_.Width();
407             auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / frameNodeSize_.Height();
408             result.SetX(-rateX * size.Width());
409             result.SetY(-rateY * size.Height());
410         }
411     }
412     CheckOffsetInPixelMap(result, size);
413     TAG_LOGD(AceLogTag::ACE_DRAG, "Get pixelMap offset is %{public}f and %{public}f.", result.GetX(), result.GetY());
414     return result;
415 }
416 
ProcessMenuPreviewScale(const RefPtr<FrameNode> imageNode,float & scale,float previewScale,float windowScale,float defaultMenuPreviewScale)417 void GestureEventHub::ProcessMenuPreviewScale(const RefPtr<FrameNode> imageNode, float& scale, float previewScale,
418     float windowScale, float defaultMenuPreviewScale)
419 {
420     auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
421     CHECK_NULL_VOID(imageGestureEventHub);
422     if (!IsPixelMapNeedScale()) {
423         if (CheckInSceneBoardWindow()) {
424             imageGestureEventHub->SetMenuPreviewScale(defaultMenuPreviewScale);
425         } else {
426             //if not in sceneboard,use default drag scale
427             scale = previewScale * windowScale;
428             imageGestureEventHub->SetMenuPreviewScale(previewScale);
429         }
430     } else {
431         imageGestureEventHub->SetMenuPreviewScale(scale);
432     }
433 }
434 
GetPreScaledPixelMapIfExist(float targetScale,RefPtr<PixelMap> defaultPixelMap)435 RefPtr<PixelMap> GestureEventHub::GetPreScaledPixelMapIfExist(float targetScale, RefPtr<PixelMap> defaultPixelMap)
436 {
437     ACE_SCOPED_TRACE("drag: get scaled pixmal, %f", targetScale);
438     float preScale = 1.0f;
439     CHECK_NULL_RETURN(dragEventActuator_, defaultPixelMap);
440     auto frameNode = GetFrameNode();
441     RefPtr<PixelMap> preScaledPixelMap;
442     if (!(frameNode && frameNode->GetDragPreview().onlyForLifting)) {
443         preScaledPixelMap = dragEventActuator_->GetPreScaledPixelMapForDragThroughTouch(preScale);
444     }
445     if (preScale == targetScale && preScaledPixelMap != nullptr) {
446         return preScaledPixelMap;
447     }
448 #if defined(PIXEL_MAP_SUPPORTED)
449     preScaledPixelMap = PixelMap::CopyPixelMap(defaultPixelMap);
450     if (!preScaledPixelMap) {
451         TAG_LOGW(AceLogTag::ACE_DRAG, "duplicate PixelMap failed!");
452         preScaledPixelMap = defaultPixelMap;
453     }
454     if (!NearEqual(targetScale, 1.0f)) {
455         preScaledPixelMap->Scale(targetScale, targetScale, AceAntiAliasingOption::HIGH);
456     }
457 #else
458     preScaledPixelMap = defaultPixelMap;
459 #endif
460     return preScaledPixelMap;
461 }
462 
GetPixelMapScale(const int32_t height,const int32_t width) const463 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
464 {
465     float scale = 1.0f;
466     if (height == 0 || width == 0) {
467         return scale;
468     }
469     auto frameNode = GetFrameNode();
470     CHECK_NULL_RETURN(frameNode, scale);
471     auto pipeline = frameNode->GetContextRefPtr();
472     CHECK_NULL_RETURN(pipeline, scale);
473     auto dragDropManager = pipeline->GetDragDropManager();
474     CHECK_NULL_RETURN(dragDropManager, scale);
475     auto windowScale = dragDropManager->GetWindowScale();
476     if (!frameNode->GetDragPreviewOption().isScaleEnabled || !(frameNode->GetTag() == V2::WEB_ETS_TAG)) {
477         return scale * windowScale;
478     }
479     int32_t deviceHeight = SystemProperties::GetDevicePhysicalHeight();
480     int32_t deviceWidth = SystemProperties::GetDevicePhysicalWidth();
481     int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
482     int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
483     if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
484         if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
485             scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
486         }
487     } else {
488         if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
489             width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
490             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
491                 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
492         } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
493                    width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
494             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
495                 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
496         }
497     }
498     return scale * windowScale;
499 }
500 
GenerateMousePixelMap(const GestureEvent & info)501 void GestureEventHub::GenerateMousePixelMap(const GestureEvent& info)
502 {
503     auto frameNode = GetFrameNode();
504     CHECK_NULL_VOID(frameNode);
505     RefPtr<RenderContext> context;
506     if (GetTextDraggable()) {
507         auto pattern = frameNode->GetPattern<TextDragBase>();
508         CHECK_NULL_VOID(pattern);
509         auto dragNode = pattern->MoveDragNode();
510         CHECK_NULL_VOID(dragNode);
511         auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
512         CHECK_NULL_VOID(pipeline);
513         pipeline->FlushPipelineImmediately();
514         context = dragNode->GetRenderContext();
515     } else {
516         context = frameNode->GetRenderContext();
517     }
518     CHECK_NULL_VOID(context);
519     auto thumbnailPixelMap = context->GetThumbnailPixelMap(false, GetTextDraggable());
520     CHECK_NULL_VOID(thumbnailPixelMap);
521     SetPixelMap(thumbnailPixelMap);
522 }
523 
HandleNotAllowDrag(const GestureEvent & info)524 void GestureEventHub::HandleNotAllowDrag(const GestureEvent& info)
525 {
526     auto frameNode = GetFrameNode();
527     CHECK_NULL_VOID(frameNode);
528     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
529         gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
530         isReceivedDragGestureInfo_ = true;
531         TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop drag gesture info received");
532     }
533 }
534 
HandleDragThroughTouch(const RefPtr<FrameNode> frameNode)535 void GestureEventHub::HandleDragThroughTouch(const RefPtr<FrameNode> frameNode)
536 {
537     CHECK_NULL_VOID(frameNode);
538     dragframeNodeInfo_.frameNode = frameNode;
539     auto pipeline = frameNode->GetContextRefPtr();
540     CHECK_NULL_VOID(pipeline);
541     auto dragDropManager = pipeline->GetDragDropManager();
542     CHECK_NULL_VOID(dragDropManager);
543     auto grayedState = dragDropManager->GetGrayedState();
544     if (grayedState) {
545         return;
546     }
547     auto overlayManager = pipeline->GetOverlayManager();
548     CHECK_NULL_VOID(overlayManager);
549     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
550     if (!gatherNodeChildrenInfo.empty()) {
551         for (const auto& itemFrameNode : gatherNodeChildrenInfo) {
552             auto node = itemFrameNode.preImageNode.Upgrade();
553             CHECK_NULL_VOID(node);
554             dragframeNodeInfo_.gatherFrameNode.push_back(node);
555             DragAnimationHelper::DoDragStartGrayedAnimation(node);
556         }
557         dragframeNodeInfo_.gatherFrameNode.push_back(frameNode);
558     }
559     DragAnimationHelper::DoDragStartGrayedAnimation(frameNode);
560     dragDropManager->SetGrayedState(true);
561 }
562 
HandleDragThroughMouse(const RefPtr<FrameNode> frameNode)563 void GestureEventHub::HandleDragThroughMouse(const RefPtr<FrameNode> frameNode)
564 {
565     CHECK_NULL_VOID(frameNode);
566     dragframeNodeInfo_.frameNode = frameNode;
567     auto pipeline = frameNode->GetContextRefPtr();
568     CHECK_NULL_VOID(pipeline);
569     auto dragDropManager = pipeline->GetDragDropManager();
570     CHECK_NULL_VOID(dragDropManager);
571     auto grayedState = dragDropManager->GetGrayedState();
572     if (grayedState) {
573         return;
574     }
575     auto size = GetSelectItemSize();
576     if (size) {
577         auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
578         CHECK_NULL_VOID(fatherNode);
579         auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
580         CHECK_NULL_VOID(scrollPattern);
581         auto children = scrollPattern->GetVisibleSelectedItems();
582         dragframeNodeInfo_.gatherFrameNode = children;
583         for (const auto& itemFrameNode : children) {
584             DragAnimationHelper::DoDragStartGrayedAnimation(itemFrameNode);
585         }
586     } else {
587         DragAnimationHelper::DoDragStartGrayedAnimation(frameNode);
588     }
589     dragDropManager->SetGrayedState(true);
590 }
591 
IsNeedSwitchToSubWindow(const PreparedInfoForDrag & dragInfoData) const592 bool GestureEventHub::IsNeedSwitchToSubWindow(const PreparedInfoForDrag& dragInfoData) const
593 {
594     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
595     CHECK_NULL_RETURN(pipeline, false);
596     auto dragDropManager = pipeline->GetDragDropManager();
597     CHECK_NULL_RETURN(dragDropManager, false);
598     if (dragInfoData.isMenuShow) {
599         return true;
600     }
601     if (dragInfoData.isNeedCreateTiled) {
602         return false;
603     }
604     if (IsPixelMapNeedScale() || DragDropGlobalController::GetInstance().GetAsyncDragCallback() != nullptr) {
605         return true;
606     }
607     CHECK_NULL_RETURN(dragEventActuator_, false);
608     return dragEventActuator_->IsNeedGather();
609 }
610 
HandleOnDragStart(const GestureEvent & info)611 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
612 {
613     TAG_LOGD(AceLogTag::ACE_DRAG, "Start handle onDragStart.");
614     auto frameNode = GetFrameNode();
615     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
616     if (!frameNode || !pipeline || !CheckAllowDrag(info, pipeline, frameNode)) {
617         TAG_LOGE(AceLogTag::ACE_DRAG, "Check not allow drag");
618         HandleNotAllowDrag(info);
619         return;
620     }
621 
622     // set menu window touchable
623     auto mainPipeline = PipelineContext::GetMainPipelineContext();
624     DragDropFuncWrapper::SetMenuSubWindowTouchable((mainPipeline != pipeline));
625     // set drag drop status is moving
626     DragDropGlobalController::GetInstance().UpdateDragDropInitiatingStatus(frameNode, DragDropInitiatingStatus::MOVING);
627 
628     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
629         SetMouseDragMonitorState(true);
630     }
631 
632     CalcFrameNodeOffsetAndSize(frameNode, DragDropGlobalController::GetInstance().IsMenuShowing());
633 
634     // create drag event
635     auto event = CreateDragEvent(info, pipeline, frameNode);
636 
637     /*
638      * Users may remove frameNode in the js callback function "onDragStart "triggered below,
639      * so save the offset of the framenode relative to the window in advance
640      */
641     DragDropInfo dragPreviewInfo;
642     auto dragDropInfo = GetDragDropInfo(info, frameNode, dragPreviewInfo, event);
643     auto callAnsyncEnd = [weak = WeakClaim(this), frameNode](DragStartRequestStatus dragStatus) {
644         if (dragStatus == DragStartRequestStatus::WAITING) {
645             auto gestureEventHub = weak.Upgrade();
646             CHECK_NULL_VOID(gestureEventHub);
647             auto pipeline = frameNode->GetContextRefPtr();
648             CHECK_NULL_VOID(pipeline);
649             auto eventHub = gestureEventHub->eventHub_.Upgrade();
650             CHECK_NULL_VOID(eventHub);
651             gestureEventHub->FireCustomerOnDragEnd(pipeline, eventHub);
652         }
653     };
654     auto continueFunc = [id = Container::CurrentId(), weak = WeakClaim(this), dragPreviewInfo, info, event,
655         dragDropInfo, frameNode, pipeline]() {
656         ContainerScope scope(id);
657         auto gestureEventHub = weak.Upgrade();
658         CHECK_NULL_VOID(gestureEventHub);
659         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
660             gestureEventHub->SetMouseDragMonitorState(true);
661         }
662         gestureEventHub->DoOnDragStartHandling(info, frameNode, dragDropInfo, event, dragPreviewInfo, pipeline);
663     };
664     auto dragDropManager = pipeline->GetDragDropManager();
665     CHECK_NULL_VOID(dragDropManager);
666     dragDropManager->ResetBundleInfo();
667     if (DragDropGlobalController::GetInstance().GetDragStartRequestStatus() == DragStartRequestStatus::READY) {
668         DoOnDragStartHandling(info, frameNode, dragDropInfo, event, dragPreviewInfo, pipeline);
669     } else {
670         dragDropManager->SetDelayDragCallBack(continueFunc);
671         dragDropManager->SetCallAnsyncDragEnd(callAnsyncEnd);
672         TAG_LOGI(AceLogTag::ACE_DRAG, "drag start pended");
673     }
674 }
675 
ParsePixelMapAsync(DragDropInfo & dragDropInfo,const DragDropInfo & dragPreviewInfo,const GestureEvent & info)676 bool GestureEventHub::ParsePixelMapAsync(DragDropInfo& dragDropInfo, const DragDropInfo& dragPreviewInfo,
677     const GestureEvent& info)
678 {
679     auto frameNode = GetFrameNode();
680     CHECK_NULL_RETURN(frameNode, false);
681     if (DragDropFuncWrapper::IsNeedCreateTiledPixelMap(frameNode, dragEventActuator_, info.GetSourceDevice())) {
682         ACE_SCOPED_TRACE("drag: create titled pixelMap");
683         dragDropInfo.pixelMap = DragDropFuncWrapper::CreateTiledPixelMap(frameNode);
684         return true;
685     }
686 
687     if (dragPreviewInfo.inspectorId != "") {
688         ACE_SCOPED_TRACE("drag: handling with inspector");
689         auto dragPreviewPixelMap = GetDragPreviewPixelMap();
690         TAG_LOGI(AceLogTag::ACE_DRAG, "InspectorId exist, get thumbnail.");
691         if (dragPreviewPixelMap == nullptr) {
692             dragPreviewPixelMap = DragDropFuncWrapper::GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
693         }
694         dragDropInfo.pixelMap = dragPreviewPixelMap;
695         return true;
696     }
697 
698     if (info.GetSourceDevice() != SourceType::MOUSE) {
699         if (dragPreviewInfo.pixelMap != nullptr || dragPreviewInfo.customNode != nullptr) {
700             if (dragPreviewPixelMap_ != nullptr) {
701                 ACE_SCOPED_TRACE("drag: handling with drag preview");
702                 TAG_LOGI(AceLogTag::ACE_DRAG, "Non-mouse dragging, get thumbnail.");
703                 dragDropInfo.pixelMap = dragPreviewPixelMap_;
704                 return true;
705             }
706         }
707         if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode == nullptr &&
708             dragPreviewInfo.pixelMap == nullptr && dragPreviewInfo.customNode == nullptr && pixelMap_ != nullptr &&
709             !frameNode->GetDragPreview().onlyForLifting) {
710             dragDropInfo.pixelMap = pixelMap_;
711             return true;
712         }
713     }
714     if (dragPreviewInfo.pixelMap != nullptr) {
715         ACE_SCOPED_TRACE("drag: handling with pixelmap directly");
716         dragDropInfo.pixelMap = dragPreviewInfo.pixelMap;
717         TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap exist, get thumbnail.");
718         return true;
719     } else if (dragPreviewInfo.customNode != nullptr) {
720         dragDropInfo.customNode = dragPreviewInfo.customNode;
721     }
722     return dragDropInfo.pixelMap;
723 }
724 
DoOnDragStartHandling(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event,DragDropInfo dragPreviewInfo,const RefPtr<PipelineContext> & pipeline)725 void GestureEventHub::DoOnDragStartHandling(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
726     DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event, DragDropInfo dragPreviewInfo,
727     const RefPtr<PipelineContext>& pipeline)
728 {
729     CHECK_NULL_VOID(frameNode);
730     GetUnifiedData(frameNode->GetTag(), dragDropInfo, event);
731     // set drag pointer status
732     auto dragDropManager = pipeline->GetDragDropManager();
733     CHECK_NULL_VOID(dragDropManager);
734     dragDropManager->SetDraggingPointer(info.GetPointerId());
735     dragDropManager->SetDraggingPressedState(true);
736 
737     if (ParsePixelMapAsync(dragDropInfo, dragPreviewInfo, info)) {
738         OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
739         return;
740     }
741 
742 #if defined(PIXEL_MAP_SUPPORTED)
743     if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode) {
744         ACE_SCOPED_TRACE("drag: handling for custom builder");
745         StartDragForCustomBuilder(info, pipeline, frameNode, dragDropInfo, event);
746         return;
747     }
748 #endif
749     TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropInfo is empty.");
750     ACE_SCOPED_TRACE("drag: handling without preview");
751     if (!dragDropInfo.pixelMap) {
752         if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && GetTextDraggable() && pixelMap_) {
753             dragDropInfo.pixelMap = pixelMap_;
754         } else {
755             GenerateMousePixelMap(info);
756             dragDropInfo.pixelMap = pixelMap_;
757         }
758     }
759     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && !dragDropInfo.pixelMap) {
760         TAG_LOGD(AceLogTag::ACE_DRAG, "no any pixmap got, get node snapshot final try");
761         ACE_SCOPED_TRACE("drag: no any pixmap got, get node snapshot final try");
762         dragDropInfo.pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
763     }
764     OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
765 }
766 
HideMenu()767 void GestureEventHub::HideMenu()
768 {
769     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
770     CHECK_NULL_VOID(pipeline);
771     auto dragDrogDropManager = pipeline->GetDragDropManager();
772     CHECK_NULL_VOID(dragDrogDropManager);
773     TAG_LOGI(AceLogTag::ACE_DRAG, "Hide menu. showPreviewAnimation false, startDrag true.");
774     SubwindowManager::GetInstance()->HideMenuNG(false, true);
775     auto menuWrapperNode = dragDrogDropManager->GetMenuWrapperNode();
776     CHECK_NULL_VOID(menuWrapperNode);
777     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
778     CHECK_NULL_VOID(menuWrapperPattern);
779     auto imageNode = menuWrapperPattern->GetPreview();
780     CHECK_NULL_VOID(imageNode);
781     auto imageContext = imageNode->GetRenderContext();
782     CHECK_NULL_VOID(imageContext);
783     imageContext->UpdateOpacity(0.0f);
784 }
785 
CalcPreviewPaintRect(const RefPtr<FrameNode> menuWrapperNode,PreparedInfoForDrag & data)786 void CalcPreviewPaintRect(const RefPtr<FrameNode> menuWrapperNode, PreparedInfoForDrag& data)
787 {
788     data.originPreviewRect = data.dragPreviewRect;
789     CHECK_NULL_VOID(menuWrapperNode);
790     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
791     CHECK_NULL_VOID(menuWrapperPattern);
792     auto menuPreview = menuWrapperPattern->GetPreview();
793     CHECK_NULL_VOID(menuPreview);
794     auto pipeline = PipelineContext::GetCurrentContextPtrSafelyWithCheck();
795     CHECK_NULL_VOID(pipeline);
796     auto menuTheme = pipeline->GetTheme<NG::MenuTheme>();
797     CHECK_NULL_VOID(menuTheme);
798     auto previewBorderRadiusValue = menuTheme->GetPreviewBorderRadius();
799     data.borderRadius = BorderRadiusProperty(previewBorderRadiusValue);
800     auto menuNode = menuWrapperPattern->GetMenu();
801     CHECK_NULL_VOID(menuNode);
802     auto menuPattern = menuNode->GetPattern<MenuPattern>();
803     CHECK_NULL_VOID(menuPattern);
804     auto isShowHoverImage = menuPattern->GetIsShowHoverImage();
805     data.menuPreviewNode = menuPreview;
806     data.originPreviewRect = DragDropFuncWrapper::GetPaintRectToScreen(menuPreview);
807     CHECK_EQUAL_VOID(isShowHoverImage, false);
808     auto animationInfo = menuWrapperPattern->GetPreviewMenuAnimationInfo();
809     auto previewPattern = menuPreview->GetPattern<MenuPreviewPattern>();
810     CHECK_NULL_VOID(previewPattern);
811     auto rate = animationInfo.clipRate;
812     auto scaleBefore = menuPattern->GetPreviewBeforeAnimationScale();
813     auto scaleAfter = menuPattern->GetPreviewAfterAnimationScale();
814     auto previewBeforeAnimationScale =
815         LessNotEqual(scaleBefore, 0.0) ? menuTheme->GetPreviewBeforeAnimationScale() : scaleBefore;
816     auto previewAfterAnimationScale =
817         LessNotEqual(scaleAfter, 0.0) ? menuTheme->GetPreviewAfterAnimationScale() : scaleAfter;
818     auto previewScale = rate * (previewAfterAnimationScale - previewBeforeAnimationScale) + previewBeforeAnimationScale;
819     if (!GreatNotEqual(rate, 0.0f)) {
820         data.sizeChangeEffect = DraggingSizeChangeEffect::SIZE_TRANSITION;
821         data.originPreviewRect = data.dragPreviewRect;
822         return;
823     }
824     auto clipStartWidth = previewPattern->GetHoverImageAfterScaleWidth() * previewScale;
825     auto clipStartHeight = previewPattern->GetHoverImageAfterScaleHeight() * previewScale;
826     auto clipEndWidth = previewPattern->GetStackAfterScaleActualWidth() * previewScale;
827     auto clipEndHeight = previewPattern->GetStackAfterScaleActualHeight() * previewScale;
828     auto curentWidth = rate * (clipEndWidth - clipStartWidth) + clipStartWidth;
829     auto curentHeight = rate * (clipEndHeight - clipStartHeight) + clipStartHeight;
830     auto centerX = data.originPreviewRect.GetX() + data.originPreviewRect.Width() / 2;
831     auto centerY = data.originPreviewRect.GetY() + data.originPreviewRect.Height() / 2;
832     auto x = centerX - curentWidth / 2;
833     auto y = centerY - curentHeight / 2;
834     data.originPreviewRect = RectF(x, y, curentWidth, curentHeight);
835     data.borderRadius = animationInfo.borderRadius;
836 }
837 
PrepareDragStartInfo(RefPtr<PipelineContext> & pipeline,PreparedInfoForDrag & data,const RefPtr<FrameNode> frameNode)838 void GestureEventHub::PrepareDragStartInfo(
839     RefPtr<PipelineContext>& pipeline, PreparedInfoForDrag& data, const RefPtr<FrameNode> frameNode)
840 {
841     CHECK_NULL_VOID(pipeline);
842     auto dragDropManager = pipeline->GetDragDropManager();
843     CHECK_NULL_VOID(dragDropManager);
844     auto menuWrapperNode = dragDropManager->GetMenuWrapperNode();
845     CalcPreviewPaintRect(menuWrapperNode, data);
846     auto relativeContainerNode =
847         FrameNode::GetOrCreateFrameNode(V2::RELATIVE_CONTAINER_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
848             []() { return AceType::MakeRefPtr<OHOS::Ace::NG::RelativeContainerPattern>(); });
849     CHECK_NULL_VOID(relativeContainerNode);
850     data.relativeContainerNode = relativeContainerNode;
851     auto relativeContainerLayoutProperty = relativeContainerNode->GetLayoutProperty();
852     CHECK_NULL_VOID(relativeContainerLayoutProperty);
853     relativeContainerLayoutProperty->UpdateUserDefinedIdealSize(
854         { CalcLength(data.originPreviewRect.Width(), DimensionUnit::PX),
855             CalcLength(data.originPreviewRect.Height(), DimensionUnit::PX) });
856     auto relativeContainerRenderContext = relativeContainerNode->GetRenderContext();
857     CHECK_NULL_VOID(relativeContainerRenderContext);
858     relativeContainerRenderContext->UpdateTransformTranslate({ 0, 0, 0.0f });
859     CHECK_NULL_VOID(frameNode);
860     GestureEventHub::UpdateMenuNode(menuWrapperNode, data, frameNode);
861 }
862 
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)863 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
864     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
865 {
866     ACE_SCOPED_TRACE("drag: to start");
867     auto dragNodePipeline = frameNode->GetContextRefPtr();
868     CHECK_NULL_VOID(dragNodePipeline);
869     auto overlayManager = dragNodePipeline->GetOverlayManager();
870     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
871     CHECK_NULL_VOID(pipeline);
872 
873     auto dragDropManager = pipeline->GetDragDropManager();
874     CHECK_NULL_VOID(dragDropManager);
875 
876     bool needChangeFwkForLeaveWindow = false;
877     if (DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
878         auto rootNode = dragDropManager->GetRootNode();
879         CHECK_NULL_VOID(rootNode);
880         auto geometryNode = rootNode->GetGeometryNode();
881         CHECK_NULL_VOID(geometryNode);
882         RectF rectF = geometryNode->GetFrameRect();
883         auto point = dragDropManager->GetDragMoveLastPointByCurrentPointer(info.GetPointerId());
884         if (!rectF.IsInRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
885             needChangeFwkForLeaveWindow = true;
886         }
887     }
888     auto eventHub = eventHub_.Upgrade();
889     CHECK_NULL_VOID(eventHub);
890     if (dragDropProxy_) {
891         dragDropProxy_ = nullptr;
892     }
893     CHECK_NULL_VOID(dragEvent);
894     auto eventRet = dragEvent->GetResult();
895     if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
896         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag result is %{public}d, stop dragging.", eventRet);
897         FireCustomerOnDragEnd(pipeline, eventHub);
898         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
899             SetMouseDragMonitorState(false);
900         }
901         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::APP_REFUSE_DRAG);
902         return;
903     }
904     std::string udKey;
905     int32_t ret = -1;
906     DragSummaryInfo dragSummaryInfo;
907     DragDropFuncWrapper::ProcessDragDropData(dragEvent, udKey, dragSummaryInfo, ret);
908     int32_t recordsSize = GetBadgeNumber(dragEvent);
909     RefPtr<PixelMap> pixelMap = dragDropInfo.pixelMap;
910     if (pixelMap) {
911         SetPixelMap(pixelMap);
912     } else if (pixelMap == nullptr) {
913         FireCustomerOnDragEnd(pipeline, eventHub);
914         TAG_LOGW(AceLogTag::ACE_DRAG, "Thumbnail pixelMap is empty.");
915         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
916             SetMouseDragMonitorState(false);
917         }
918         return;
919     }
920     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
921     if (dragPreviewOptions.isDefaultDragItemGrayEffectEnabled) {
922         (info.GetSourceDevice() == SourceType::MOUSE) ? HandleDragThroughMouse(frameNode)
923                                                       : HandleDragThroughTouch(frameNode);
924     }
925     SetDragGatherPixelMaps(info);
926     bool isMenuShow = DragDropGlobalController::GetInstance().IsMenuShowing();
927     if (isMenuShow) {
928         dragDropManager->SetIsDragWithContextMenu(true);
929         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag with contextMenu.");
930     } else {
931         dragDropManager->SetIsDragWithContextMenu(false);
932     }
933     float defaultPixelMapScale = GetDefaultPixelMapScale(frameNode, info, isMenuShow, pixelMap);
934     auto windowScale = dragDropManager->GetWindowScale();
935     float scale = windowScale * defaultPixelMapScale;
936     auto isNeedCreateTiled =
937         DragDropFuncWrapper::IsNeedCreateTiledPixelMap(frameNode, dragEventActuator_, info.GetSourceDevice());
938     PreparedInfoForDrag data = { isMenuShow, recordsSize, defaultPixelMapScale, isNeedCreateTiled, OffsetF(), OffsetF(),
939         pixelMap, nullptr, dragPreviewOptions.sizeChangeEffect };
940     dragDropManager->ResetContextMenuDragPosition();
941     RefPtr<Subwindow> subWindow = nullptr;
942     data.dragPreviewRect = RectF(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight());
943     data.deviceType = info.GetSourceDevice();
944     if (!needChangeFwkForLeaveWindow && IsNeedSwitchToSubWindow(data)) {
945         GestureEventHub::PrepareDragStartInfo(pipeline, data, frameNode);
946         auto imageNode = overlayManager->GetPixelMapContentNode();
947         DragAnimationHelper::CreatePreviewNode(frameNode, imageNode, defaultPixelMapScale, data);
948         CHECK_NULL_VOID(imageNode);
949         data.imageNode = imageNode;
950         data.dragPreviewOffsetToScreen = GetDragPreviewInitPositionToScreen(context, data);
951         float previewScale =
952             info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
953         if (IsPixelMapNeedScale()) {
954             previewScale = DragDropFuncWrapper::GetPixelMapScale(frameNode);
955             scale = previewScale * windowScale;
956         }
957         data.previewScale = previewScale;
958         // use menu preview scale replace default pixelMap scale.
959         if (isMenuShow) {
960             ProcessMenuPreviewScale(imageNode, scale, previewScale, windowScale, defaultPixelMapScale);
961         }
962         {
963             ACE_SCOPED_TRACE("drag: sub window show");
964             auto mainPipeline = PipelineContext::GetMainPipelineContext();
965             subWindow = SubwindowManager::GetInstance()->ShowPreviewNG((pipeline != mainPipeline));
966         }
967     }
968     if (!overlayManager->GetIsOnAnimation()) {
969         if (dragEventActuator_ != nullptr) {
970             dragEventActuator_->SetIsNotInPreviewState(true);
971         }
972     }
973     RefPtr<PixelMap> pixelMapDuplicated = GetPreScaledPixelMapIfExist(scale, pixelMap);
974     CHECK_NULL_VOID(dragEventActuator_);
975     dragEventActuator_->ResetPreScaledPixelMapForDragThroughTouch();
976     dragPreviewPixelMap_ = nullptr;
977     CHECK_NULL_VOID(pixelMapDuplicated);
978     auto width = pixelMapDuplicated->GetWidth();
979     auto height = pixelMapDuplicated->GetHeight();
980     auto extraInfoLimited = dragDropInfo.extraInfo.size() > EXTRA_INFO_MAX_LENGTH
981                                 ? dragDropInfo.extraInfo.substr(0, EXTRA_INFO_MAX_LENGTH)
982                                 : dragDropInfo.extraInfo;
983     auto innerRect = ParseInnerRect(extraInfoLimited, SizeF(width, height));
984     auto pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), data, scale, innerRect);
985     windowScale = NearZero(windowScale) ? 1.0f : windowScale;
986     dragDropManager->SetPixelMapOffset(pixelMapOffset / windowScale);
987     DragDropFuncWrapper::ResetNode(frameNode);
988     auto arkExtraInfoJson = JsonUtil::Create(true);
989     auto dragNodeGrayscale = pipeline->GetDragNodeGrayscale();
990     auto dipScale = pipeline->GetDipScale();
991     arkExtraInfoJson->Put("scale", scale);
992     arkExtraInfoJson->Put("dip_scale", dipScale);
993     arkExtraInfoJson->Put("drag_node_gray_scale", dragNodeGrayscale);
994     arkExtraInfoJson->Put("event_id", info.GetPointerEventId());
995     UpdateExtraInfo(frameNode, arkExtraInfoJson, scale, data);
996     auto container = Container::Current();
997     CHECK_NULL_VOID(container);
998     DragDropBehaviorReporterTrigger trigger(DragReporterPharse::DRAG_START, container->GetInstanceId());
999     auto windowId = container->GetWindowId();
1000     ShadowInfoCore shadowInfo { pixelMapDuplicated, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
1001     auto dragMoveLastPoint = dragDropManager->GetDragMoveLastPointByCurrentPointer(info.GetPointerId());
1002     auto screenX = DragDropGlobalController::GetInstance().GetAsyncDragCallback() ?
1003         dragMoveLastPoint.GetScreenX() : info.GetScreenLocation().GetX();
1004     auto screenY = DragDropGlobalController::GetInstance().GetAsyncDragCallback() ?
1005         dragMoveLastPoint.GetScreenY() : info.GetScreenLocation().GetY();
1006 
1007     const int32_t pointerId = info.GetPassThrough() ? info.GetPointerId() % PASS_THROUGH_EVENT_ID : info.GetPointerId();
1008     DragDataCore dragData { { shadowInfo }, {}, udKey, extraInfoLimited, arkExtraInfoJson->ToString(),
1009         static_cast<int32_t>(info.GetSourceDevice()), recordsSize, pointerId, screenX, screenY,
1010         info.GetTargetDisplayId(), windowId, true, false, dragSummaryInfo.summary, false,
1011         dragSummaryInfo.detailedSummary, dragSummaryInfo.summaryFormat, dragSummaryInfo.version,
1012         dragSummaryInfo.totalSize };
1013     if (AceApplicationInfo::GetInstance().IsMouseTransformEnable() && (info.GetSourceTool() == SourceTool::MOUSE) &&
1014         (info.GetSourceDevice() == SourceType::TOUCH)) {
1015         dragData.sourceType = static_cast<int32_t>(SourceType::MOUSE);
1016     }
1017     std::string summarys = DragDropFuncWrapper::GetSummaryString(dragSummaryInfo.summary);
1018     std::string detailedSummarys = DragDropFuncWrapper::GetSummaryString(dragSummaryInfo.detailedSummary);
1019     DragDropBehaviorReporter::GetInstance().UpdateSummaryType(summarys);
1020     TAG_LOGI(AceLogTag::ACE_DRAG,
1021         "Start drag, frameNode is %{public}s, pixelMap width %{public}d height %{public}d, "
1022         "scale is %{public}f, udkey %{public}s, recordsSize %{public}d, extraInfo length %{public}d, "
1023         "pointerId %{public}d, displayId %{public}d, windowId %{public}d, summary %{public}s, "
1024         "eventId %{public}d, detailedSummary %{public}s.",
1025         frameNode->GetTag().c_str(), width, height, scale, DragDropFuncWrapper::GetAnonyString(udKey).c_str(),
1026         recordsSize, static_cast<int32_t>(extraInfoLimited.length()), pointerId,
1027         info.GetTargetDisplayId(), windowId, summarys.c_str(), info.GetPointerEventId(), detailedSummarys.c_str());
1028     dragDropManager->GetGatherPixelMap(dragData, scale, width, height);
1029     {
1030         ACE_SCOPED_TRACE("drag: call msdp start drag");
1031         ret = InteractionInterface::GetInstance()->StartDrag(dragData, GetDragCallback(pipeline, eventHub));
1032     }
1033     if (ret != 0) {
1034         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAGFWK_START_FAIL);
1035         if (subWindow) {
1036             SubwindowManager::GetInstance()->HidePreviewNG();
1037             overlayManager->RemovePixelMap();
1038         }
1039         FireCustomerOnDragEnd(pipeline, eventHub);
1040         TAG_LOGW(AceLogTag::ACE_DRAG, "Start drag failed, return value is %{public}d", ret);
1041         return;
1042     }
1043     StartVibratorByDrag(frameNode);
1044     dragEventActuator_->NotifyDragStart();
1045     DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::DRAG_START_SUCCESS);
1046     bool isSwitchedToSubWindow = false;
1047     dragDropManager->SetIsMouseDrag(info.GetInputEventType() == InputEventType::MOUSE_BUTTON);
1048     if (!needChangeFwkForLeaveWindow && subWindow && TryDoDragStartAnimation(context, subWindow, info, data)) {
1049         dragDropManager->SetIsReDragStart(pipeline != dragNodePipeline);
1050         isSwitchedToSubWindow = true;
1051     } else {
1052         dragDropManager->SetIsReDragStart(false);
1053         HideMenu();
1054         DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1055     }
1056     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && isSwitchedToSubWindow) {
1057         ret = RegisterCoordinationListener(pipeline);
1058         if (ret != 0) {
1059             TAG_LOGW(AceLogTag::ACE_DRAG, "Register coordination listener failed, error is %{public}d", ret);
1060         }
1061     }
1062     dragDropManager->SetPreviewRect(Rect(pixelMapOffset.GetX(), pixelMapOffset.GetY(), width, height));
1063     dragDropManager->ResetRecordSize(static_cast<uint32_t>(recordsSize));
1064     auto eventManager = pipeline->GetEventManager();
1065     CHECK_NULL_VOID(eventManager);
1066     eventManager->DoMouseActionRelease();
1067     eventManager->SetIsDragging(true);
1068     if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && needChangeFwkForLeaveWindow) {
1069         overlayManager->RemovePixelMap();
1070         overlayManager->RemovePreviewBadgeNode();
1071         overlayManager->RemoveGatherNode();
1072         dragEventActuator_->NotifyTransDragWindowToFwk();
1073         pipeline->AddAfterRenderTask([]() {
1074             ACE_SCOPED_TRACE("drag: set drag window visible, touch");
1075             InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1076         });
1077     } else if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_ != nullptr &&
1078         dragEventActuator_->GetIsNotInPreviewState()) {
1079         if (!isSwitchedToSubWindow) {
1080             overlayManager->RemovePixelMap();
1081             overlayManager->RemovePreviewBadgeNode();
1082             overlayManager->RemoveGatherNode();
1083             dragEventActuator_->NotifyTransDragWindowToFwk();
1084             pipeline->AddAfterRenderTask([]() {
1085                 ACE_SCOPED_TRACE("drag: set drag window visible, touch");
1086                 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1087             });
1088         }
1089     } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1090         if (!isSwitchedToSubWindow) {
1091             dragEventActuator_->NotifyTransDragWindowToFwk();
1092             pipeline->AddDragWindowVisibleTask([]() {
1093                 ACE_SCOPED_TRACE("drag: set drag window visible, mouse");
1094                 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1095             });
1096             pipeline->RequestFrame();
1097         }
1098         dragDropManager->SetIsDragWindowShow(true);
1099     }
1100     dragDropManager->FireOnEditableTextComponent(frameNode, DragEventType::ENTER);
1101     dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
1102     CHECK_NULL_VOID(dragDropProxy_);
1103     dragDropProxy_->OnDragStart(info, extraInfoLimited, GetFrameNode());
1104     if (!dragDropManager->IsDraggingPressed(info.GetPointerId())) {
1105         dragDropManager->SetIsDisableDefaultDropAnimation(true);
1106         dragDropManager->OnDragEnd(
1107             DragPointerEvent(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()), extraInfoLimited);
1108     }
1109 }
1110 
StartVibratorByDrag(const RefPtr<FrameNode> & frameNode)1111 void GestureEventHub::StartVibratorByDrag(const RefPtr<FrameNode>& frameNode)
1112 {
1113     bool enableHapticFeedback = frameNode->GetDragPreviewOption().enableHapticFeedback;
1114     auto parent = frameNode->GetAncestorNodeOfFrame(false);
1115     if (parent && parent->GetTag() == V2::RICH_EDITOR_ETS_TAG) {
1116         enableHapticFeedback = parent->GetDragPreviewOption().enableHapticFeedback;
1117     }
1118     if (!enableHapticFeedback || !DragDropGlobalController::GetInstance().IsDragFilterShowing()) {
1119         return;
1120     }
1121     TAG_LOGI(AceLogTag::ACE_DRAG, "Enable haptic feedback, start vibrator by drag.");
1122     VibratorUtils::StartViratorDirectly("haptic.drag");
1123     DragDropGlobalController::GetInstance().UpdateDragFilterShowingStatus(false);
1124 }
1125 
UpdateExtraInfo(const RefPtr<FrameNode> & frameNode,std::unique_ptr<JsonValue> & arkExtraInfoJson,float scale,const PreparedInfoForDrag & dragInfoData)1126 void GestureEventHub::UpdateExtraInfo(const RefPtr<FrameNode>& frameNode, std::unique_ptr<JsonValue>& arkExtraInfoJson,
1127     float scale, const PreparedInfoForDrag& dragInfoData)
1128 {
1129     double opacity = frameNode->GetDragPreviewOption().options.opacity;
1130     auto optionInfo = frameNode->GetDragPreviewOption().options;
1131     arkExtraInfoJson->Put("dip_opacity", opacity);
1132     TAG_LOGD(AceLogTag::ACE_DRAG, "The info of opacity update to the framework is %{public}s",
1133         arkExtraInfoJson->ToString().c_str());
1134 
1135     if (optionInfo.blurbgEffect.backGroundEffect.radius.IsValid()) {
1136         optionInfo.blurbgEffect.ToJsonValue(arkExtraInfoJson);
1137     }
1138     DragEventActuator::PrepareShadowParametersForDragData(frameNode, arkExtraInfoJson, scale);
1139     if (dragInfoData.isNeedCreateTiled) {
1140         return;
1141     }
1142     DragEventActuator::PrepareRadiusParametersForDragData(frameNode, arkExtraInfoJson);
1143 }
1144 
RegisterCoordinationListener(const RefPtr<PipelineBase> & context)1145 int32_t GestureEventHub::RegisterCoordinationListener(const RefPtr<PipelineBase>& context)
1146 {
1147     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1148     CHECK_NULL_RETURN(pipeline, -1);
1149     auto callback = [id = Container::CurrentId(), weak = WeakClaim(RawPtr(pipeline))]() {
1150         ContainerScope scope(id);
1151         auto context = weak.Upgrade();
1152         CHECK_NULL_VOID(context);
1153         auto dragDropManager = context->GetDragDropManager();
1154         CHECK_NULL_VOID(dragDropManager);
1155         auto taskScheduler = context->GetTaskExecutor();
1156         CHECK_NULL_VOID(taskScheduler);
1157         taskScheduler->PostTask([dragDropManager]() { dragDropManager->HideDragPreviewOverlay(); },
1158             TaskExecutor::TaskType::UI, "ArkUIGestureHideDragPreviewOverlay");
1159     };
1160     return InteractionInterface::GetInstance()->RegisterCoordinationListener(callback);
1161 }
1162 
HandleOnDragUpdate(const GestureEvent & info)1163 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
1164 {
1165     gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
1166 }
1167 
HandleDragEndAction(const DragframeNodeInfo & info)1168 void GestureEventHub::HandleDragEndAction(const DragframeNodeInfo& info)
1169 {
1170     auto weakFrameNode = info.frameNode;
1171     auto frameNode = weakFrameNode.Upgrade();
1172     CHECK_NULL_VOID(frameNode);
1173     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
1174     if (!dragPreviewOptions.isDefaultDragItemGrayEffectEnabled) {
1175         return;
1176     }
1177     auto pipeline = frameNode->GetContextRefPtr();
1178     CHECK_NULL_VOID(pipeline);
1179     auto dragDropManager = pipeline->GetDragDropManager();
1180     CHECK_NULL_VOID(dragDropManager);
1181     auto state = dragDropManager->GetGrayedState();
1182     if (!state) {
1183         return;
1184     }
1185     if (!info.gatherFrameNode.empty()) {
1186         auto gatherFrameNode = info.gatherFrameNode;
1187         for (const auto& itemFrameNode : gatherFrameNode) {
1188             DragAnimationHelper::SetPreOpacity(itemFrameNode);
1189         }
1190     } else {
1191         DragAnimationHelper::SetPreOpacity(frameNode);
1192     }
1193     dragDropManager->SetGrayedState(false);
1194 }
1195 
HandleOnDragEnd(const GestureEvent & info)1196 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
1197 {
1198     auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
1199     const static int32_t PLATFORM_VERSION_TEN = 10;
1200     if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
1201         auto eventHub = eventHub_.Upgrade();
1202         CHECK_NULL_VOID(eventHub);
1203 
1204         auto frameNode = GetFrameNode();
1205         CHECK_NULL_VOID(frameNode);
1206 
1207         // Only the onDrop callback of dragged frame node is triggered.
1208         // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
1209         if (eventHub->HasOnDrop() || eventHub->HasCustomerOnDrop()) {
1210             RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1211             if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1212                 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1213                 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1214             } else {
1215                 event->SetX(info.GetGlobalPoint().GetX());
1216                 event->SetY(info.GetGlobalPoint().GetY());
1217             }
1218             event->SetScreenX(info.GetScreenLocation().GetX());
1219             event->SetScreenY(info.GetScreenLocation().GetY());
1220             event->SetGlobalDisplayX(info.GetGlobalDisplayLocation().GetX());
1221             event->SetGlobalDisplayY(info.GetGlobalDisplayLocation().GetY());
1222             event->SetPressedKeyCodes(info.GetPressedKeyCodes());
1223             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event);
1224             eventHub->HandleInternalOnDrop(event, "");
1225         }
1226     }
1227     HandleDragEndAction(dragframeNodeInfo_);
1228     CHECK_NULL_VOID(dragDropProxy_);
1229     dragDropProxy_->DestroyDragWindow();
1230     dragDropProxy_ = nullptr;
1231 }
1232 
HandleOnDragCancel()1233 void GestureEventHub::HandleOnDragCancel()
1234 {
1235     CHECK_NULL_VOID(dragDropProxy_);
1236     dragDropProxy_->DestroyDragWindow();
1237     dragDropProxy_ = nullptr;
1238 }
1239 
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1240 OnDragCallbackCore GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1241 {
1242     auto ret = [](const DragNotifyMsgCore& notifyMessage) {};
1243     auto eventHub = hub.Upgrade();
1244     CHECK_NULL_RETURN(eventHub, ret);
1245     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1246     CHECK_NULL_RETURN(pipeline, ret);
1247     auto taskScheduler = pipeline->GetTaskExecutor();
1248     CHECK_NULL_RETURN(taskScheduler, ret);
1249     auto dragDropManager = pipeline->GetDragDropManager();
1250     CHECK_NULL_RETURN(dragDropManager, ret);
1251     auto eventManager = pipeline->GetEventManager();
1252     RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1253     auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager,
1254                         dragframeNodeInfo = dragframeNodeInfo_,
1255                         gestureEventHubPtr = AceType::Claim(this)](const DragNotifyMsgCore& notifyMessage) {
1256         ContainerScope scope(id);
1257         taskScheduler->PostTask(
1258             [eventHub, dragEvent, dragDropManager, eventManager, notifyMessage, id, dragframeNodeInfo,
1259                 gestureEventHubPtr]() {
1260                 auto container = Container::GetContainer(id);
1261                 if (!container) {
1262                     TAG_LOGE(AceLogTag::ACE_DRAG, "handle drag end callback, can not get container.");
1263                     return;
1264                 }
1265                 DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1266                 TAG_LOGI(
1267                     AceLogTag::ACE_DRAG, "handle drag end callback, windowId is %{public}d.", container->GetWindowId());
1268                 dragDropManager->ResetDragEndOption(notifyMessage, dragEvent, id);
1269                 auto ret = InteractionInterface::GetInstance()->UnRegisterCoordinationListener();
1270                 if (ret != 0) {
1271                     TAG_LOGW(AceLogTag::ACE_DRAG, "Unregister coordination listener failed, error is %{public}d", ret);
1272                 }
1273                 if (eventManager) {
1274                     eventManager->DoMouseActionRelease();
1275                 }
1276                 if (notifyMessage.isInnerAndOuterTriggerBothNeeded) {
1277                     eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1278                 }
1279                 if (eventHub->HasOnDragEnd()) {
1280                     (eventHub->GetOnDragEnd())(dragEvent);
1281                 }
1282                 gestureEventHubPtr->HandleDragEndAction(dragframeNodeInfo);
1283                 auto dragEventActuator = gestureEventHubPtr->GetDragEventActuator();
1284                 CHECK_NULL_VOID(dragEventActuator);
1285                 dragEventActuator->NotifyDragEnd();
1286             },
1287             TaskExecutor::TaskType::UI, "ArkUIGestureDragEnd");
1288     };
1289     return callback;
1290 }
1291 
GetDragDropInfo(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo & dragPreviewInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1292 DragDropInfo GestureEventHub::GetDragDropInfo(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
1293     DragDropInfo& dragPreviewInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1294 {
1295     ACE_SCOPED_TRACE("drag: execute user onDragStart");
1296     DragDropInfo dragDropInfo;
1297     CHECK_NULL_RETURN(dragEventActuator_, dragDropInfo);
1298     dragEventActuator_->SetIsDefaultOnDragStartExecuted(false);
1299     auto eventHub = eventHub_.Upgrade();
1300     CHECK_NULL_RETURN(eventHub, dragDropInfo);
1301     auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
1302     auto onDragStart = eventHub->GetOnDragStart();
1303     if (!onDragStart && eventHub->HasDefaultOnDragStart()) {
1304         onDragStart = eventHub->GetDefaultOnDragStart();
1305         dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1306     }
1307     dragEvent->SetPressedKeyCodes(info.GetPressedKeyCodes());
1308     if (GetTextDraggable() && info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1309         GenerateMousePixelMap(info);
1310     }
1311     dragDropInfo = onDragStart(dragEvent, extraParams);
1312 
1313     auto frameTag = frameNode->GetTag();
1314     if (GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1315         TAG_LOGD(AceLogTag::ACE_DRAG,
1316             "Get drag drop info, pixelmap and customNode are set to null "
1317             "when frameTag is %{public}s",
1318             frameTag.c_str());
1319         dragDropInfo.pixelMap = nullptr;
1320         dragDropInfo.customNode = nullptr;
1321     } else {
1322         auto dragPreview = frameNode->GetDragPreview();
1323         if (dragPreview.onlyForLifting) {
1324             return dragDropInfo;
1325         }
1326         if (!dragPreview.customNode && dragPreview.delayCreating && dragPreview.buildFunc) {
1327             dragPreview.customNode = dragPreview.buildFunc();
1328         }
1329         frameNode->SetDragPreview(dragPreview);
1330         dragPreviewInfo = dragPreview;
1331     }
1332     return dragDropInfo;
1333 }
1334 
GetUnifiedData(const std::string & frameTag,DragDropInfo & dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1335 RefPtr<UnifiedData> GestureEventHub::GetUnifiedData(
1336     const std::string& frameTag, DragDropInfo& dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1337 {
1338     auto eventHub = eventHub_.Upgrade();
1339     CHECK_NULL_RETURN(eventHub, nullptr);
1340     auto unifiedData = dragEvent->GetData();
1341     bool hasData = static_cast<bool>(unifiedData);
1342     if (!unifiedData && eventHub->HasDefaultOnDragStart()) {
1343         auto defaultDropInfo = eventHub->GetDefaultOnDragStart()(dragEvent, "");
1344         if (dragDropInfo.extraInfo.empty()) {
1345             dragDropInfo.extraInfo = defaultDropInfo.extraInfo;
1346         }
1347         CHECK_NULL_RETURN(dragEventActuator_, nullptr);
1348         dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1349         unifiedData = dragEvent->GetData();
1350     }
1351     auto defaultOnDragStart = eventHub->GetDefaultOnDragStart();
1352     CHECK_NULL_RETURN(defaultOnDragStart, unifiedData);
1353     if (hasData && IsTextCategoryComponent(frameTag) && !dragEventActuator_->IsDefaultOnDragStartExecuted()) {
1354         defaultOnDragStart(dragEvent, "");
1355     }
1356     return unifiedData;
1357 }
1358 
SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)1359 void GestureEventHub::SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)
1360 {
1361     isDragForbiddenForWholeSubTree_ = isDragForbiddenForWholeSubTree;
1362 }
1363 
IsDragForbidden() const1364 bool GestureEventHub::IsDragForbidden() const
1365 {
1366     return isDragForbiddenForWholeSubTree_;
1367 }
1368 
SetDragGatherPixelMaps(const GestureEvent & info)1369 void GestureEventHub::SetDragGatherPixelMaps(const GestureEvent& info)
1370 {
1371     CHECK_NULL_VOID(dragEventActuator_);
1372     if (!dragEventActuator_->IsNeedGather()) {
1373         return;
1374     }
1375     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1376         SetMouseDragGatherPixelMaps();
1377     } else {
1378         SetNotMouseDragGatherPixelMaps();
1379     }
1380 }
1381 
SetMouseDragGatherPixelMaps()1382 void GestureEventHub::SetMouseDragGatherPixelMaps()
1383 {
1384     auto frameNode = GetFrameNode();
1385     CHECK_NULL_VOID(frameNode);
1386     if (frameNode->GetDragPreviewOption().isMultiTiled && !dragEventActuator_->GetRestartDrag()) {
1387         return;
1388     }
1389     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1390     CHECK_NULL_VOID(pipeline);
1391     auto dragDropManager = pipeline->GetDragDropManager();
1392     CHECK_NULL_VOID(dragDropManager);
1393     dragDropManager->ClearGatherPixelMap();
1394     CHECK_NULL_VOID(dragEventActuator_);
1395     auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1396     CHECK_NULL_VOID(fatherNode);
1397     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1398     CHECK_NULL_VOID(scrollPattern);
1399     auto children = scrollPattern->GetVisibleSelectedItems();
1400     int cnt = 0;
1401     for (const auto& itemFrameNode : children) {
1402         if (itemFrameNode == frameNode) {
1403             continue;
1404         }
1405         CHECK_NULL_VOID(itemFrameNode);
1406         DragEventActuator::GetFrameNodePreviewPixelMap(itemFrameNode);
1407         auto gestureHub = itemFrameNode->GetOrCreateGestureEventHub();
1408         CHECK_NULL_VOID(gestureHub);
1409         auto itemPreviewPixelMap = gestureHub->GetDragPreviewPixelMap();
1410         if (!itemPreviewPixelMap) {
1411             continue;
1412         }
1413         dragDropManager->PushGatherPixelMap(itemPreviewPixelMap);
1414         cnt++;
1415         if (cnt > 1) {
1416             break;
1417         }
1418     }
1419 }
1420 
SetNotMouseDragGatherPixelMaps()1421 void GestureEventHub::SetNotMouseDragGatherPixelMaps()
1422 {
1423     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1424     CHECK_NULL_VOID(pipeline);
1425     auto dragDropManager = pipeline->GetDragDropManager();
1426     CHECK_NULL_VOID(dragDropManager);
1427     dragDropManager->ClearGatherPixelMap();
1428     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1429     CHECK_NULL_VOID(mainPipeline);
1430     auto overlayManager = mainPipeline->GetOverlayManager();
1431     CHECK_NULL_VOID(overlayManager);
1432     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
1433     int cnt = 0;
1434     for (auto iter = gatherNodeChildrenInfo.rbegin(); iter != gatherNodeChildrenInfo.rend(); ++iter) {
1435         auto imageNode = (*iter).imageNode.Upgrade();
1436         CHECK_NULL_VOID(imageNode);
1437         auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
1438         CHECK_NULL_VOID(imageLayoutProperty);
1439         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value_or(ImageSourceInfo());
1440         auto itemPreviewPixelMap = imageSourceInfo.GetPixmap();
1441         if (!itemPreviewPixelMap) {
1442             continue;
1443         }
1444         dragDropManager->PushGatherPixelMap(itemPreviewPixelMap);
1445         cnt++;
1446         if (cnt > 1) {
1447             break;
1448         }
1449     }
1450 }
1451 
GetSelectItemSize()1452 int32_t GestureEventHub::GetSelectItemSize()
1453 {
1454     CHECK_NULL_RETURN(dragEventActuator_, 0);
1455     if (!dragEventActuator_->IsNeedGather()) {
1456         return 0;
1457     }
1458     auto fatherNode = DragDropFuncWrapper::FindItemParentNode(GetFrameNode());
1459     CHECK_NULL_RETURN(fatherNode, 0);
1460     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1461     CHECK_NULL_RETURN(scrollPattern, 0);
1462     auto children = scrollPattern->GetVisibleSelectedItems();
1463     return children.size();
1464 }
1465 
FireCustomerOnDragEnd(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1466 void GestureEventHub::FireCustomerOnDragEnd(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1467 {
1468     DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1469     auto eventHub = hub.Upgrade();
1470     CHECK_NULL_VOID(eventHub);
1471     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1472     CHECK_NULL_VOID(pipeline);
1473     auto dragDropManager = pipeline->GetDragDropManager();
1474     CHECK_NULL_VOID(dragDropManager);
1475     dragDropManager->RemoveDeadlineTimer();
1476     auto dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1477     CHECK_NULL_VOID(dragEvent);
1478     dragEvent->SetResult(DragRet::DRAG_FAIL);
1479     dragEvent->SetDragBehavior(DragBehavior::UNKNOWN);
1480     dragDropManager->DoDragReset();
1481     dragDropManager->SetIsDragged(false);
1482     dragDropManager->ResetDragging();
1483     dragDropManager->SetDraggingPointer(-1);
1484     dragDropManager->SetDraggingPressedState(false);
1485     dragDropManager->ResetDragPreviewInfo();
1486     eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1487     if (eventHub->HasOnDragEnd()) {
1488         (eventHub->GetOnDragEnd())(dragEvent);
1489     }
1490 }
1491 
1492 #if defined(PIXEL_MAP_SUPPORTED)
PrintBuilderNode(const RefPtr<UINode> & customNode)1493 void GestureEventHub::PrintBuilderNode(const RefPtr<UINode>& customNode)
1494 {
1495     CHECK_NULL_VOID(customNode);
1496     bool hasImageNode = false;
1497     std::list<RefPtr<FrameNode>> imageNodes;
1498     int32_t depth = 1;
1499     PrintIfImageNode(customNode, depth, hasImageNode, imageNodes);
1500     CheckImageDecode(imageNodes);
1501     imageNodes.clear();
1502 }
1503 
PrintIfImageNode(const RefPtr<UINode> & builderNode,int32_t depth,bool & hasImageNode,std::list<RefPtr<FrameNode>> & imageNodes)1504 void GestureEventHub::PrintIfImageNode(
1505     const RefPtr<UINode>& builderNode, int32_t depth, bool& hasImageNode, std::list<RefPtr<FrameNode>>& imageNodes)
1506 {
1507     if (depth > MAX_BUILDER_DEPTH) {
1508         return;
1509     }
1510     if (builderNode->GetTag() == V2::IMAGE_ETS_TAG) {
1511         auto frameNode = AceType::DynamicCast<FrameNode>(builderNode);
1512         CHECK_NULL_VOID(frameNode);
1513         auto pattern = frameNode->GetPattern<ImagePattern>();
1514         CHECK_NULL_VOID(pattern);
1515         hasImageNode = true;
1516         imageNodes.push_back(frameNode);
1517         TAG_LOGI(AceLogTag::ACE_DRAG,
1518             "customNode has ImageNode, syncLoad: %{public}d, decode complete: %{public}d",
1519             pattern->GetSyncLoad(), pattern->GetCanvasImage() != nullptr);
1520     }
1521 
1522     auto children = builderNode->GetChildren();
1523     for (const auto& child : children) {
1524         PrintIfImageNode(child, depth + 1, hasImageNode, imageNodes);
1525     }
1526 }
1527 
CheckImageDecode(std::list<RefPtr<FrameNode>> & imageNodes)1528 void GestureEventHub::CheckImageDecode(std::list<RefPtr<FrameNode>>& imageNodes)
1529 {
1530     if (imageNodes.empty()) {
1531         return;
1532     }
1533 
1534     for (const auto& imageNode : imageNodes) {
1535         auto pattern = imageNode->GetPattern<ImagePattern>();
1536         CHECK_NULL_VOID(pattern);
1537         if (!pattern->GetCanvasImage()) {
1538             TAG_LOGW(AceLogTag::ACE_DRAG, "ImageNode did not complete decoding");
1539         }
1540     }
1541 }
1542 
StartDragForCustomBuilderSync(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)1543 bool GestureEventHub::StartDragForCustomBuilderSync(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
1544     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
1545 {
1546     SnapshotParam param;
1547     std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
1548     {
1549         ACE_SCOPED_TRACE("drag: try get builder snapshot sync");
1550         pixelMap = ComponentSnapshot::CreateSync(dragDropInfo.customNode, param);
1551     }
1552 
1553     if (pixelMap == nullptr) {
1554         // try failed, need fall back to use async way
1555         return false;
1556     }
1557 
1558     // get snapshot successfully, go ahead
1559     dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1560     OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
1561     return true;
1562 }
1563 
StartDragForCustomBuilder(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)1564 void GestureEventHub::StartDragForCustomBuilder(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
1565     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
1566 {
1567     if (StartDragForCustomBuilderSync(info, pipeline, frameNode, dragDropInfo, event)) {
1568         return;
1569     }
1570 
1571     TAG_LOGI(AceLogTag::ACE_DRAG, "Snapshot createSync failed, get thumbnail by async.");
1572     auto callback = [id = Container::CurrentId(), pipeline, info, gestureEventHubPtr = AceType::Claim(this), frameNode,
1573         dragDropInfo, event](std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()>
1574         finishCallback) mutable {
1575         ContainerScope scope(id);
1576         ACE_SCOPED_TRACE("drag: get snapshot async done, post task to UI for next handling");
1577         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail callback executed.");
1578         if (pixelMap != nullptr) {
1579             dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1580         } else {
1581             DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1582         }
1583         auto taskScheduler = pipeline->GetTaskExecutor();
1584         CHECK_NULL_VOID(taskScheduler);
1585         taskScheduler->PostTask(
1586             [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event, finishCallback]() {
1587                 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail finished, start drag.");
1588                 if (finishCallback) {
1589                     finishCallback();
1590                 }
1591                 CHECK_NULL_VOID(gestureEventHubPtr);
1592                 CHECK_NULL_VOID(frameNode);
1593                 gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
1594             },
1595             TaskExecutor::TaskType::UI, "ArkUIGestureDragStart");
1596     };
1597     SnapshotParam param;
1598     param.delay = CREATE_PIXELMAP_TIME;
1599     param.checkImageStatus = true;
1600     param.options.waitUntilRenderFinished = true;
1601     ACE_SCOPED_TRACE("drag: try sync failed, to get snapshot async");
1602     NG::ComponentSnapshot::Create(dragDropInfo.customNode, std::move(callback), true, param);
1603     PrintBuilderNode(dragDropInfo.customNode);
1604 }
1605 #endif
1606 
GetDragPreviewInitPositionToScreen(const RefPtr<PipelineBase> & context,PreparedInfoForDrag & data)1607 OffsetF GestureEventHub::GetDragPreviewInitPositionToScreen(
1608     const RefPtr<PipelineBase>& context, PreparedInfoForDrag& data)
1609 {
1610     auto frameNode = GetFrameNode();
1611     CHECK_NULL_RETURN(frameNode, OffsetF());
1612     OffsetF previewOffset;
1613     OffsetF pixelMapHalfSize = data.pixelMap ? OffsetF(data.pixelMap->GetWidth() / 2.0f,
1614         data.pixelMap->GetHeight() / 2.0f) : OffsetF();
1615     previewOffset = DragDropFuncWrapper::GetPaintRectCenterToScreen(frameNode) - pixelMapHalfSize;
1616     auto frameTag = frameNode->GetTag();
1617     if (IsPixelMapNeedScale() && GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1618         auto textDragPattern = frameNode->GetPattern<TextDragBase>();
1619         CHECK_NULL_RETURN(textDragPattern, previewOffset);
1620         auto dragNode = textDragPattern->MoveDragNode();
1621         if (dragNode) {
1622             previewOffset = DragDropFuncWrapper::GetPaintRectCenterToScreen(dragNode) - pixelMapHalfSize;
1623             return previewOffset;
1624         }
1625     }
1626 
1627     if (IsPixelMapNeedScale() && frameTag == V2::WEB_ETS_TAG) {
1628         auto offset = DragDropFuncWrapper::GetCurrentWindowOffset(context);
1629         return frameNodeOffset_ + offset;
1630     }
1631 
1632     if (data.isMenuShow) {
1633         OffsetF menuPreviewCenter = frameNodeOffset_ + OffsetF(frameNodeSize_.Width(), frameNodeSize_.Height()) / 2.0f;
1634         menuPreviewCenter += DragDropFuncWrapper::GetCurrentWindowOffset(context);
1635         if (data.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT && data.badgeNumber <= 1) {
1636             previewOffset = menuPreviewCenter - pixelMapHalfSize + data.dragMovePosition;
1637         } else if ((data.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
1638                        data.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) ||
1639                    data.badgeNumber > 1) {
1640             previewOffset = menuPreviewCenter - OffsetF(frameNodeSize_.Width(), frameNodeSize_.Height()) / 2.0f +
1641                             data.dragMovePosition;
1642         }
1643     }
1644     return previewOffset;
1645 }
1646 
UpdateMenuNode(const RefPtr<FrameNode> menuWrapperNode,PreparedInfoForDrag & data,const RefPtr<FrameNode> frameNode)1647 void GestureEventHub::UpdateMenuNode(
1648     const RefPtr<FrameNode> menuWrapperNode, PreparedInfoForDrag& data, const RefPtr<FrameNode> frameNode)
1649 {
1650     CHECK_NULL_VOID(frameNode);
1651     CHECK_NULL_VOID(menuWrapperNode);
1652     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
1653     CHECK_NULL_VOID(menuWrapperPattern);
1654     auto animationInfo = menuWrapperPattern->GetPreviewMenuAnimationInfo();
1655     auto rate = animationInfo.clipRate;
1656     auto menuNode = menuWrapperPattern->GetMenu();
1657     CHECK_NULL_VOID(menuNode);
1658     auto menuPattern = menuNode->GetPattern<MenuPattern>();
1659     CHECK_NULL_VOID(menuPattern);
1660     data.isMenuNotShow =
1661         menuWrapperPattern->GetMenuStatus() == MenuStatus::SHOW && rate == -1.0f && menuPattern->GetIsShowHoverImage();
1662     if (frameNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT ||
1663         menuWrapperPattern->HasTransitionEffect() || menuWrapperPattern->IsHide()) {
1664         return;
1665     }
1666     auto scrollNode = AceType::DynamicCast<FrameNode>(menuNode->GetChildByIndex(0));
1667     CHECK_NULL_VOID(scrollNode);
1668     data.scrollNode = scrollNode;
1669     auto menuGeometryNode = scrollNode->GetGeometryNode();
1670     CHECK_NULL_VOID(menuGeometryNode);
1671     auto menuNodeSize = menuGeometryNode->GetFrameRect();
1672     RefPtr<FrameNode> imageNode = menuWrapperPattern->GetPreview();
1673     RectF imageNodeSize;
1674     if (imageNode) {
1675         imageNodeSize = DragDropFuncWrapper::GetPaintRectToScreen(imageNode);
1676         data.frameNodeRect = imageNodeSize;
1677     } else {
1678         imageNode = frameNode;
1679         auto imageGeometryNode = imageNode->GetGeometryNode();
1680         CHECK_NULL_VOID(imageGeometryNode);
1681         imageNodeSize = imageGeometryNode->GetFrameRect();
1682         data.frameNodeRect = imageNodeSize;
1683     }
1684     auto imageNodeOffset = imageNode->GetPaintRectOffset(false, true);
1685     auto menuNodeOffset = scrollNode->GetPaintRectOffset(false, true);
1686     data.menuRect = menuNodeSize;
1687     data.menuPositionLeft = menuNodeOffset.GetX() - imageNodeOffset.GetX();
1688     data.menuPositionTop = menuNodeOffset.GetY() - imageNodeOffset.GetY();
1689     data.menuPositionRight =
1690         imageNodeOffset.GetX() + imageNodeSize.Width() - menuNodeOffset.GetX() - menuNodeSize.Width();
1691     data.menuPositionBottom =
1692         imageNodeOffset.GetY() + imageNodeSize.Height() - menuNodeOffset.GetY() - menuNodeSize.Height();
1693     auto menuParam = menuWrapperPattern->GetMenuParam();
1694     data.menuPosition = menuPattern->GetLastPlacement().value_or(Placement::NONE);
1695     auto newMenuNode = menuPattern->DuplicateMenuNode(menuNode, menuParam);
1696     CHECK_NULL_VOID(newMenuNode);
1697     data.menuNode = newMenuNode;
1698 }
1699 
GetBadgeNumber(const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1700 int32_t GestureEventHub::GetBadgeNumber(const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1701 {
1702     CHECK_NULL_RETURN(dragEvent, 1);
1703     auto frameNode = GetFrameNode();
1704     CHECK_NULL_RETURN(frameNode, 1);
1705     auto pattern = frameNode->GetPattern();
1706     CHECK_NULL_RETURN(pattern, 1);
1707     int32_t badgeNumber = 1;
1708     pattern->ResetDragOption();
1709     auto unifiedData = dragEvent->GetData();
1710     auto dataLoadParams = dragEvent->GetDataLoadParams();
1711     auto isUseDataLoadParams = dragEvent->IsUseDataLoadParams();
1712     if (pattern->GetDragRecordSize() >= 0) {
1713         badgeNumber = pattern->GetDragRecordSize();
1714     } else if (unifiedData && !isUseDataLoadParams) {
1715         auto recordSize = unifiedData->GetSize();
1716         badgeNumber = recordSize > 1 ? recordSize : 1;
1717     } else if (dataLoadParams && isUseDataLoadParams) {
1718         auto recodeCount = dataLoadParams->GetRecordCount();
1719         badgeNumber = (recodeCount == 0 || recodeCount > INT32_MAX) ? 1 : static_cast<int32_t>(recodeCount);
1720     }
1721 
1722     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
1723     auto customBadgeNumber = dragPreviewOptions.GetCustomerBadgeNumber();
1724     auto selectItemSize = GetSelectItemSize();
1725     if (customBadgeNumber.has_value()) {
1726         badgeNumber = customBadgeNumber.value();
1727         TAG_LOGI(AceLogTag::ACE_DRAG, "Use custom badge number, value is %{public}d", badgeNumber);
1728     } else if (selectItemSize > 1) {
1729         badgeNumber = selectItemSize;
1730         TAG_LOGI(AceLogTag::ACE_DRAG, "Use select item size, value is %{public}d", badgeNumber);
1731     }
1732     return badgeNumber;
1733 }
1734 
TryDoDragStartAnimation(const RefPtr<PipelineBase> & context,const RefPtr<Subwindow> & subWindow,const GestureEvent & info,PreparedInfoForDrag & data)1735 bool GestureEventHub::TryDoDragStartAnimation(const RefPtr<PipelineBase>& context, const RefPtr<Subwindow>& subWindow,
1736     const GestureEvent& info, PreparedInfoForDrag& data)
1737 {
1738     auto frameNode = GetFrameNode();
1739     auto container = Container::Current();
1740     auto eventHub = eventHub_.Upgrade();
1741     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1742     if (!subWindow || !frameNode || !container || !pipeline || !eventHub || !data.imageNode) {
1743         return false;
1744     }
1745 
1746     auto dragNodePipeline = frameNode->GetContextRefPtr();
1747     CHECK_NULL_RETURN(dragNodePipeline, false);
1748     auto overlayManager = dragNodePipeline->GetOverlayManager();
1749     CHECK_NULL_RETURN(overlayManager, false);
1750     auto isExpandDisplay = DragDropFuncWrapper::IsExpandDisplay(context);
1751     auto dragDropManager = DragDropFuncWrapper::GetDragDropManagerForDragAnimation(context, dragNodePipeline,
1752         subWindow, isExpandDisplay, container->GetInstanceId());
1753     CHECK_NULL_RETURN(dragDropManager, false);
1754     dragDropManager->SetIsDragWithContextMenu(data.isMenuShow);
1755     // create gatherNode
1756     auto originGatherNode = overlayManager->GetGatherNode();
1757     OffsetF positionToWindow = originGatherNode ? originGatherNode->GetPositionToWindowWithTransform() : OffsetF();
1758     std::vector<GatherNodeChildInfo> childrenInfo;
1759     auto gatherNode = DragAnimationHelper::GetOrCreateGatherNode(overlayManager, dragEventActuator_, childrenInfo);
1760     data.gatherNode = gatherNode;
1761     // creat textNode
1762     DragAnimationHelper::CreateTextNode(data);
1763     auto gatherNodeOffset = isExpandDisplay
1764             ? DragDropManager::GetTouchOffsetRelativeToSubwindow(dragNodePipeline->GetInstanceId()) + positionToWindow
1765             : positionToWindow;
1766     DragEventActuator::UpdateGatherAnimatePosition(childrenInfo, gatherNodeOffset);
1767 
1768     // mount node
1769     auto subWindowOverlayManager = subWindow->GetOverlayManager();
1770     CHECK_NULL_RETURN(subWindowOverlayManager, false);
1771     DragEventActuator::MountGatherNode(subWindowOverlayManager, frameNode, gatherNode, childrenInfo);
1772     DragAnimationHelper::MountPixelMap(
1773         subWindowOverlayManager, eventHub->GetOrCreateGestureEventHub(), data, true);
1774 
1775     HideMenu();
1776     // update position
1777     UpdateNodePositionBeforeStartAnimation(frameNode, data);
1778     pipeline->FlushSyncGeometryNodeTasks();
1779     overlayManager->RemovePixelMap();
1780     DragAnimationHelper::ShowBadgeAnimation(data.textNode);
1781     DragAnimationHelper::ShowMenuHideAnimation(data);
1782     DragAnimationHelper::HideDragNodeCopy(overlayManager);
1783 
1784     dragDropManager->DoDragStartAnimation(
1785         subWindowOverlayManager, info, eventHub->GetOrCreateGestureEventHub(), data);
1786     return true;
1787 }
1788 
UpdateNodePositionBeforeStartAnimation(const RefPtr<FrameNode> & frameNode,PreparedInfoForDrag & data)1789 void GestureEventHub::UpdateNodePositionBeforeStartAnimation(const RefPtr<FrameNode>& frameNode,
1790     PreparedInfoForDrag& data)
1791 {
1792     CHECK_NULL_VOID(frameNode);
1793     if (data.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT && !data.textRowNode) {
1794         DragDropFuncWrapper::UpdateNodePositionToScreen(data.imageNode, data.dragPreviewOffsetToScreen);
1795         DragAnimationHelper::PreLayout(data.imageNode);
1796     } else {
1797         DragDropFuncWrapper::UpdateNodePositionToScreen(data.relativeContainerNode, data.dragPreviewOffsetToScreen);
1798         DragAnimationHelper::PreLayout(data.relativeContainerNode);
1799     }
1800 }
1801 
CheckAllowDrag(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> & frameNode)1802 bool GestureEventHub::CheckAllowDrag(const GestureEvent& info, const RefPtr<PipelineBase>& context,
1803     const RefPtr<FrameNode>& frameNode)
1804 {
1805     auto eventHub = eventHub_.Upgrade();
1806     CHECK_NULL_RETURN(eventHub, false);
1807     CHECK_NULL_RETURN(frameNode, false);
1808     if (!eventHub->HasOnDragStart()) {
1809         TAG_LOGE(AceLogTag::ACE_DRAG, "FrameNode is not set onDragStart event.");
1810         return false;
1811     }
1812     if (!IsAllowedDrag(eventHub)) {
1813         auto pattern = frameNode->GetPattern();
1814         CHECK_NULL_RETURN(pattern, false);
1815         TAG_LOGE(AceLogTag::ACE_DRAG,
1816             "FrameNode is not allow drag, tag is %{public}s"
1817             "draggable is %{public}d, drag start event is %{public}d,"
1818             "default support drag is %{public}d, user set is %{public}d.",
1819             frameNode->GetTag().c_str(), frameNode->IsDraggable(), eventHub->HasOnDragStart(),
1820             pattern->DefaultSupportDrag(), frameNode->IsUserSet());
1821         return false;
1822     }
1823     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1824     CHECK_NULL_RETURN(pipeline, false);
1825     auto eventManager = pipeline->GetEventManager();
1826     CHECK_NULL_RETURN(eventManager, false);
1827     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && eventManager->IsLastMoveBeforeUp()) {
1828         TAG_LOGE(AceLogTag::ACE_DRAG, "Drag stop because user release mouse button");
1829         return false;
1830     }
1831 
1832     return true;
1833 }
1834 
CreateDragEvent(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> & frameNode)1835 RefPtr<OHOS::Ace::DragEvent> GestureEventHub::CreateDragEvent(const GestureEvent& info,
1836     const RefPtr<PipelineBase>& context, const RefPtr<FrameNode>& frameNode)
1837 {
1838     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1839     CHECK_NULL_RETURN(frameNode, event);
1840     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1841     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1842         CHECK_NULL_RETURN(pipeline, event);
1843         event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1844         event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1845     } else {
1846         event->SetX(info.GetGlobalPoint().GetX());
1847         event->SetY(info.GetGlobalPoint().GetY());
1848     }
1849     event->SetScreenX(info.GetScreenLocation().GetX());
1850     event->SetScreenY(info.GetScreenLocation().GetY());
1851     event->SetDisplayX(info.GetScreenLocation().GetX());
1852     event->SetDisplayY(info.GetScreenLocation().GetY());
1853     event->SetGlobalDisplayX(info.GetGlobalDisplayLocation().GetX());
1854     event->SetGlobalDisplayY(info.GetGlobalDisplayLocation().GetY());
1855     event->SetSourceTool(info.GetSourceTool());
1856     auto container = Container::Current();
1857     CHECK_NULL_RETURN(container, event);
1858     auto dragBundleName = container->GetBundleName();
1859     event->SetDragSource(dragBundleName);
1860     event->SetRemoteDev(false);
1861     event->SetDisplayId(info.GetTargetDisplayId());
1862     return event;
1863 }
1864 
SetMouseDragMonitorState(bool state)1865 void GestureEventHub::SetMouseDragMonitorState(bool state)
1866 {
1867     auto ret = InteractionInterface::GetInstance()->SetMouseDragMonitorState(state);
1868     if (ret != 0) {
1869         TAG_LOGW(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d failed, return value is %{public}d",
1870             state, ret);
1871         return;
1872     }
1873     TAG_LOGI(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d success", state);
1874 }
1875 
SetBindMenuStatus(bool setIsShow,bool isShow,MenuPreviewMode previewMode)1876 void GestureEventHub::SetBindMenuStatus(bool setIsShow, bool isShow, MenuPreviewMode previewMode)
1877 {
1878     if (setIsShow) {
1879         bindMenuStatus_.isBindCustomMenu = true;
1880         bindMenuStatus_.isShow = isShow;
1881         bindMenuStatus_.isShowPreviewMode = previewMode;
1882     } else {
1883         bindMenuStatus_.isBindLongPressMenu = true;
1884         bindMenuStatus_.longPressPreviewMode = previewMode;
1885     }
1886 }
1887 
AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)1888 void GestureEventHub::AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd)
1889 {
1890     if (!scrollableActuator_) {
1891         scrollableActuator_ = MakeRefPtr<ScrollableActuator>(WeakClaim(this));
1892     }
1893     scrollableActuator_->AddPreviewMenuHandleDragEnd(std::move(actionEnd));
1894 }
1895 
1896 // Set by user define, which will replace old one.
SetDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)1897 void GestureEventHub::SetDragEvent(
1898     const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance)
1899 {
1900     if (!dragEventActuator_ || dragEventActuator_->GetIsNewFwk()) {
1901         isDragNewFwk_ = false;
1902         dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
1903     }
1904     dragEventActuator_->ReplaceDragEvent(dragEvent);
1905 }
1906 
SetDragDropEvent()1907 void GestureEventHub::SetDragDropEvent()
1908 {
1909     if (!dragEventActuator_ || !dragEventActuator_->GetIsNewFwk()) {
1910         isDragNewFwk_ = true;
1911         dragEventActuator_ = MakeRefPtr<DragDropEventActuator>(WeakClaim(this));
1912     }
1913 }
1914 
SetCustomDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)1915 void GestureEventHub::SetCustomDragEvent(
1916     const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance)
1917 {
1918     if (!dragEventActuator_ || dragEventActuator_->GetIsNewFwk()) {
1919         isDragNewFwk_ = false;
1920         dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
1921     }
1922     dragEventActuator_->SetCustomDragEvent(dragEvent);
1923 }
1924 
HasDragEvent() const1925 bool GestureEventHub::HasDragEvent() const
1926 {
1927     return dragEventActuator_ && (dragEventActuator_->HasDragEvent() || dragEventActuator_->GetIsNewFwk());
1928 }
1929 
RemoveDragEvent()1930 void GestureEventHub::RemoveDragEvent()
1931 {
1932     if (!dragEventActuator_) {
1933         return;
1934     }
1935     if (dragEventActuator_->GetIsNewFwk()) {
1936         dragEventActuator_ = nullptr;
1937         return;
1938     }
1939     dragEventActuator_->ClearDragEvent();
1940 }
1941 
SetThumbnailCallback(std::function<void (Offset)> && callback)1942 void GestureEventHub::SetThumbnailCallback(std::function<void(Offset)>&& callback)
1943 {
1944     if (dragEventActuator_) {
1945         dragEventActuator_->SetThumbnailCallback(std::move(callback));
1946     }
1947 }
1948 
DragNodeDetachFromParent()1949 void GestureEventHub::DragNodeDetachFromParent()
1950 {
1951     if (dragEventActuator_) {
1952         dragEventActuator_->RemovePixelMap();
1953     }
1954 }
1955 
GetTextDraggable() const1956 bool GestureEventHub::GetTextDraggable() const
1957 {
1958     return textDraggable_;
1959 }
1960 
SetTextDraggable(bool draggable)1961 void GestureEventHub::SetTextDraggable(bool draggable)
1962 {
1963     textDraggable_ = draggable;
1964 }
1965 
SetIsTextDraggable(bool isTextDraggable)1966 void GestureEventHub::SetIsTextDraggable(bool isTextDraggable)
1967 {
1968     isTextDraggable_ = isTextDraggable;
1969 }
1970 
GetIsTextDraggable()1971 bool GestureEventHub::GetIsTextDraggable()
1972 {
1973     return isTextDraggable_;
1974 }
1975 
SetPreviewMode(MenuPreviewMode mode)1976 void GestureEventHub::SetPreviewMode(MenuPreviewMode mode)
1977 {
1978     previewMode_ = mode;
1979 }
1980 
GetPreviewMode()1981 MenuPreviewMode GestureEventHub::GetPreviewMode()
1982 {
1983     return previewMode_;
1984 }
1985 
SetContextMenuShowStatus(bool contextMenuShowStatus)1986 void GestureEventHub::SetContextMenuShowStatus(bool contextMenuShowStatus)
1987 {
1988     contextMenuShowStatus_ = contextMenuShowStatus;
1989 }
1990 
GetContextMenuShowStatus()1991 bool GestureEventHub::GetContextMenuShowStatus()
1992 {
1993     return contextMenuShowStatus_;
1994 }
1995 
SetMenuBindingType(MenuBindingType menuBindingType)1996 void GestureEventHub::SetMenuBindingType(MenuBindingType menuBindingType)
1997 {
1998     menuBindingType_ = menuBindingType;
1999 }
2000 
GetMenuBindingType()2001 MenuBindingType GestureEventHub::GetMenuBindingType()
2002 {
2003     return menuBindingType_;
2004 }
2005 
SetPixelMap(RefPtr<PixelMap> pixelMap)2006 void GestureEventHub::SetPixelMap(RefPtr<PixelMap> pixelMap)
2007 {
2008     pixelMap_ = pixelMap;
2009 }
2010 
GetPixelMap()2011 RefPtr<PixelMap> GestureEventHub::GetPixelMap()
2012 {
2013     return pixelMap_;
2014 }
2015 
SetDragPreviewPixelMap(RefPtr<PixelMap> pixelMap)2016 void GestureEventHub::SetDragPreviewPixelMap(RefPtr<PixelMap> pixelMap)
2017 {
2018     dragPreviewPixelMap_ = pixelMap;
2019 }
2020 
GetDragEventActuator()2021 RefPtr<DragEventActuator> GestureEventHub::GetDragEventActuator()
2022 {
2023     return dragEventActuator_;
2024 }
2025 
GetDragPreviewPixelMap()2026 RefPtr<PixelMap> GestureEventHub::GetDragPreviewPixelMap()
2027 {
2028     return dragPreviewPixelMap_;
2029 }
2030 
SetMenuPreviewScale(float menuPreviewScale)2031 void GestureEventHub::SetMenuPreviewScale(float menuPreviewScale)
2032 {
2033     menuPreviewScale_ = menuPreviewScale;
2034 }
2035 
GetMenuPreviewScale() const2036 float GestureEventHub::GetMenuPreviewScale() const
2037 {
2038     return menuPreviewScale_;
2039 }
2040 
GetBindMenuStatus() const2041 const BindMenuStatus& GestureEventHub::GetBindMenuStatus() const
2042 {
2043     return bindMenuStatus_;
2044 }
2045 
SetRecognizerDelayStatus(const RecognizerDelayStatus & recognizerDelayStatus)2046 void GestureEventHub::SetRecognizerDelayStatus(const RecognizerDelayStatus& recognizerDelayStatus)
2047 {
2048     auto pipeline = PipelineContext::GetCurrentContextPtrSafelyWithCheck();
2049     CHECK_NULL_VOID(pipeline);
2050     auto eventManager = pipeline->GetEventManager();
2051     CHECK_NULL_VOID(eventManager);
2052     auto refereeNG = eventManager->GetGestureRefereeNG(nullptr);
2053     CHECK_NULL_VOID(refereeNG);
2054     refereeNG->SetRecognizerDelayStatus(recognizerDelayStatus);
2055 }
2056 } // namespace OHOS::Ace::NG
2057