• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "core/components_ng/manager/drag_drop/drag_drop_manager.h"
17 
18 #include "base/geometry/point.h"
19 #include "base/geometry/rect.h"
20 #include "base/log/ace_trace.h"
21 #include "base/utils/system_properties.h"
22 #include "base/utils/time_util.h"
23 #include "base/utils/utils.h"
24 #include "core/common/interaction/interaction_data.h"
25 #include "core/common/interaction/interaction_interface.h"
26 #include "core/common/udmf/udmf_client.h"
27 #include "core/components/common/layout/grid_column_info.h"
28 #include "core/components/common/layout/grid_system_manager.h"
29 #include "core/components_ng/base/frame_node.h"
30 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
31 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
32 #include "core/components_ng/manager/drag_drop/drag_drop_global_controller.h"
33 #include "core/components_ng/pattern/grid/grid_event_hub.h"
34 #include "core/components_ng/pattern/list/list_event_hub.h"
35 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
36 #include "core/components_ng/pattern/root/root_pattern.h"
37 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
38 #include "core/components_v2/inspector/inspector_constants.h"
39 #include "core/pipeline_ng/pipeline_context.h"
40 
41 namespace OHOS::Ace::NG {
42 namespace {
43 int64_t g_proxyId = 0;
44 constexpr Dimension PRESERVE_HEIGHT = 8.0_vp;
45 constexpr float FIRST_PIXELMAP_OPACITY = 0.6f;
46 constexpr float SECOND_PIXELMAP_OPACITY = 0.3f;
47 constexpr float FIRST_PIXELMAP_ANGLE = 8.0f;
48 constexpr float SECOND_PIXELMAP_ANGLE = -8.0f;
49 constexpr int32_t FIRST_GATHER_PIXEL_MAP = 1;
50 constexpr int32_t SECOND_GATHER_PIXEL_MAP = 2;
51 constexpr int32_t SQUARE_NUMBER = 2;
52 constexpr float TOUCH_DRAG_PIXELMAP_SCALE = 1.05f;
53 constexpr int32_t MAX_RETRY_TIMES = 3;
54 constexpr int32_t MAX_RETRY_DURATION = 800;
55 constexpr float MOVE_DISTANCE_LIMIT = 20.0f;
56 constexpr uint64_t MOVE_TIME_LIMIT = 6L;
57 constexpr float MAX_DISTANCE_TO_PRE_POINTER = 3.0f;
58 constexpr float DEFAULT_SPRING_RESPONSE = 0.347f;
59 constexpr float MIN_SPRING_RESPONSE = 0.05f;
60 constexpr float DEL_SPRING_RESPONSE = 0.005f;
61 constexpr float MIN_UI_EXTENSION_BOUNDARY_DISTANCE = 5.0f;
62 constexpr float MIN_FOLDER_SUBWINDOW_BOUNDARY_DISTANCE = 5.0f;
63 constexpr int32_t RESERVED_DEVICEID_1 = 0xAAAAAAFF;
64 constexpr int32_t RESERVED_DEVICEID_2 = 0xAAAAAAFE;
65 constexpr uint32_t TASK_DELAY_TIME = 5 * 1000;
66 constexpr uint32_t DROP_DELAY_TIME = 2 * 1000;
67 constexpr double DEVICE_TYPE_UNKOWN = 0.0;
68 constexpr double DEVICE_TYPE_SMALL = 600.0;
69 constexpr double DEVICE_TYPE_MEDIUM = 840.0;
70 constexpr int32_t SCALE_TYPE_FIRST = 2;
71 constexpr int32_t SCALE_TYPE_SECOND = 3;
72 constexpr int32_t SCALE_TYPE_THIRD = 4;
73 const RefPtr<InterpolatingSpring> DRAG_TRANSITION_ANIMATION_CURVE =
74     AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 380.0f, 34.0f);
75 } // namespace
76 
GetMenuRenderContextFromMenuWrapper(const RefPtr<FrameNode> & menuWrapperNode)77 RefPtr<RenderContext> GetMenuRenderContextFromMenuWrapper(const RefPtr<FrameNode>& menuWrapperNode)
78 {
79     CHECK_NULL_RETURN(menuWrapperNode, nullptr);
80     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
81     CHECK_NULL_RETURN(menuWrapperPattern, nullptr);
82     auto menuNode = menuWrapperPattern->GetMenu();
83     CHECK_NULL_RETURN(menuNode, nullptr);
84     return menuNode->GetRenderContext();
85 }
86 
GetMenuWrapperNodeFromDrag()87 RefPtr<FrameNode> GetMenuWrapperNodeFromDrag()
88 {
89     auto pipelineContext = PipelineContext::GetMainPipelineContext();
90     CHECK_NULL_RETURN(pipelineContext, nullptr);
91     auto mainDragDropManager = pipelineContext->GetDragDropManager();
92     CHECK_NULL_RETURN(mainDragDropManager, nullptr);
93     return mainDragDropManager->GetMenuWrapperNode();
94 }
95 
DragDropManager()96 DragDropManager::DragDropManager()
97 {
98     if (DragDropGlobalController::GetInstance().IsAlreadyGetAppGlobalDrag()) {
99         return;
100     }
101     bool state = false;
102     auto result = InteractionInterface::GetInstance()->GetAppDragSwitchState(state);
103     if (result != 0) {
104         TAG_LOGI(AceLogTag::ACE_DRAG, "get app drag switch state failed!");
105         return;
106     }
107     DragDropGlobalController::GetInstance().SetIsAppGlobalDragEnabled(state);
108 }
109 
GetDragMoveLastPointByCurrentPointer(int32_t pointerId)110 const Point DragDropManager::GetDragMoveLastPointByCurrentPointer(int32_t pointerId)
111 {
112     return fingerPointInfo_[pointerId];
113 }
114 
UpdatePointInfoForFinger(int32_t pointerId,Point point)115 void DragDropManager::UpdatePointInfoForFinger(int32_t pointerId, Point point)
116 {
117     fingerPointInfo_[pointerId] = point;
118 }
119 
SetDelayDragCallBack(const std::function<void ()> & cb)120 void DragDropManager::SetDelayDragCallBack(const std::function<void()>& cb) noexcept
121 {
122     DragDropGlobalController::GetInstance().SetAsyncDragCallback(cb);
123 }
124 
ExecuteDeadlineTimer()125 void DragDropManager::ExecuteDeadlineTimer()
126 {
127     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
128     CHECK_NULL_VOID(pipeline);
129     auto taskScheduler = pipeline->GetTaskExecutor();
130     CHECK_NULL_VOID(taskScheduler);
131     taskScheduler->PostDelayedTask(
132         [weakManager = WeakClaim(this)]() {
133             auto dragDropManager = weakManager.Upgrade();
134             CHECK_NULL_VOID(dragDropManager);
135             if (DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
136                 DragDropGlobalController::GetInstance().GetAsyncDragCallback()();
137             }
138             dragDropManager->RemoveDeadlineTimer();
139         },
140         TaskExecutor::TaskType::UI, TASK_DELAY_TIME, "ArkUIDragDeadlineTimer");
141 }
142 
RemoveDeadlineTimer()143 void DragDropManager::RemoveDeadlineTimer()
144 {
145     DragDropGlobalController::GetInstance().SetAsyncDragCallback(nullptr);
146     DragDropGlobalController::GetInstance().SetDragStartRequestStatus(DragStartRequestStatus::READY);
147     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
148     CHECK_NULL_VOID(pipeline);
149     auto taskScheduler = pipeline->GetTaskExecutor();
150     CHECK_NULL_VOID(taskScheduler);
151     taskScheduler->RemoveTask(TaskExecutor::TaskType::UI, "ArkUIDragDeadlineTimer");
152 }
153 
HandleSyncOnDragStart(DragStartRequestStatus dragStartRequestStatus)154 void DragDropManager::HandleSyncOnDragStart(DragStartRequestStatus dragStartRequestStatus)
155 {
156     if (dragStartRequestStatus == DragStartRequestStatus::WAITING) {
157         ExecuteDeadlineTimer();
158         DragDropGlobalController::GetInstance().SetDragStartRequestStatus(dragStartRequestStatus);
159     }
160     if (dragStartRequestStatus == DragStartRequestStatus::READY &&
161         DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
162         DragDropGlobalController::GetInstance().SetDragStartRequestStatus(dragStartRequestStatus);
163         DragDropGlobalController::GetInstance().GetAsyncDragCallback()();
164         RemoveDeadlineTimer();
165     }
166 }
167 
CreateAndShowItemDragOverlay(const RefPtr<PixelMap> & pixelMap,const GestureEvent & info,const RefPtr<EventHub> & eventHub)168 RefPtr<DragDropProxy> DragDropManager::CreateAndShowItemDragOverlay(
169     const RefPtr<PixelMap>& pixelMap, const GestureEvent& info, const RefPtr<EventHub>& eventHub)
170 {
171     CHECK_NULL_RETURN(pixelMap, nullptr);
172     // create Image for drag
173     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
174         []() { return AceType::MakeRefPtr<ImagePattern>(); });
175     CHECK_NULL_RETURN(imageNode, nullptr);
176     auto imagePattern = imageNode->GetPattern<ImagePattern>();
177     CHECK_NULL_RETURN(imagePattern, nullptr);
178     imagePattern->SetSyncLoad(true);
179     auto prop = imageNode->GetLayoutProperty<ImageLayoutProperty>();
180     CHECK_NULL_RETURN(prop, nullptr);
181     prop->UpdateAutoResize(false);
182     prop->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
183     auto targetSize = CalcSize(NG::CalcLength(pixelMap->GetWidth()), NG::CalcLength(pixelMap->GetHeight()));
184     prop->UpdateUserDefinedIdealSize(targetSize);
185     auto renderProp = imageNode->GetPaintProperty<ImageRenderProperty>();
186     renderProp->UpdateImageInterpolation(ImageInterpolation::HIGH);
187     imageNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
188     imageNode->MarkModifyDone();
189     imageNode->SetLayoutDirtyMarked(true);
190     imageNode->SetActive(true);
191     auto context = imageNode->GetContext();
192     if (context) {
193         context->FlushUITaskWithSingleDirtyNode(imageNode);
194     }
195     auto imageContext = imageNode->GetRenderContext();
196     CHECK_NULL_RETURN(imageContext, nullptr);
197     imageContext->UpdatePosition(
198         OffsetT<Dimension>(Dimension(info.GetGlobalPoint().GetX() - pixelMap->GetWidth() / 2), // 2: Average factor.
199             Dimension(info.GetGlobalPoint().GetY() - pixelMap->GetHeight() / 2)));             // 2: Average factor.
200     imageContext->OnModifyDone();
201 
202     AddItemDrag(imageNode, eventHub);
203 
204     itemDragOverlayNode_ = imageNode;
205     SetIsDragged(true);
206     isDragCancel_ = false;
207     currentId_ = ++g_proxyId;
208     return MakeRefPtr<DragDropProxy>(currentId_);
209 }
210 
CreateAndShowItemDragOverlay(const RefPtr<UINode> & customNode,const GestureEvent & info,const RefPtr<EventHub> & eventHub)211 RefPtr<DragDropProxy> DragDropManager::CreateAndShowItemDragOverlay(
212     const RefPtr<UINode>& customNode, const GestureEvent& info, const RefPtr<EventHub>& eventHub)
213 {
214     auto frameNode = DynamicCast<FrameNode>(customNode);
215     CHECK_NULL_RETURN(frameNode, nullptr);
216     auto renderContext = frameNode->GetRenderContext();
217     CHECK_NULL_RETURN(renderContext, nullptr);
218     auto geometryNode = frameNode->GetGeometryNode();
219     CHECK_NULL_RETURN(geometryNode, nullptr);
220     auto frameRect = geometryNode->GetFrameSize();
221     renderContext->UpdatePosition(
222         OffsetT<Dimension>(Dimension(info.GetGlobalPoint().GetX() - frameRect.Width() / 2), // 2: Average factor.
223             Dimension(info.GetGlobalPoint().GetY() - frameRect.Height() / 2)));             // 2: Average factor.
224     renderContext->OnModifyDone();
225     AddItemDrag(frameNode, eventHub);
226     itemDragOverlayNode_ = frameNode;
227     SetIsDragged(true);
228     isDragCancel_ = false;
229     currentId_ = ++g_proxyId;
230     return MakeRefPtr<DragDropProxy>(currentId_);
231 }
232 
CreateTextDragDropProxy()233 RefPtr<DragDropProxy> DragDropManager::CreateTextDragDropProxy()
234 {
235     SetIsDragged(true);
236     isDragCancel_ = false;
237     currentId_ = ++g_proxyId;
238     return MakeRefPtr<DragDropProxy>(currentId_);
239 }
240 
GetWindowId()241 int32_t DragDropManager::GetWindowId()
242 {
243     auto windowId = -1;
244     auto container = Container::Current();
245     CHECK_NULL_RETURN(container, windowId);
246 
247     if (!container->IsSceneBoardEnabled()) {
248         isDragWindowSubWindow_ = false;
249         return windowId;
250     }
251 
252     if (!container->IsMainWindow()) {
253         // The window manager currently does not support creating child windows within child windows,
254         // so the root main window is used here
255         container = Container::GetContainer(CONTAINER_ID_DIVIDE_SIZE);
256         CHECK_NULL_RETURN(container, windowId);
257         if (!container->IsMainWindow()) {
258             isDragWindowSubWindow_ = false;
259             return windowId;
260         }
261     }
262 
263     windowId = static_cast<int32_t>(container->GetWindowId());
264     isDragWindowSubWindow_ = true;
265 
266     return windowId;
267 }
268 
CreateDragRootNode(const RefPtr<UINode> & customNode)269 RefPtr<FrameNode> DragDropManager::CreateDragRootNode(const RefPtr<UINode>& customNode)
270 {
271     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
272     CHECK_NULL_RETURN(pipeline, nullptr);
273 
274     auto rootNode = FrameNode::CreateFrameNodeWithTree(
275         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
276     rootNode->SetActive(true);
277     rootNode->SetHostRootId(pipeline->GetInstanceId());
278     rootNode->SetHostPageId(-1);
279     rootNode->AddChild(customNode);
280     rootNode->AttachToMainTree(false, AceType::RawPtr(pipeline));
281     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
282     pipeline->FlushUITasks();
283     return rootNode;
284 }
285 
AddItemDrag(const RefPtr<FrameNode> & frameNode,const RefPtr<EventHub> & eventHub)286 void DragDropManager::AddItemDrag(const RefPtr<FrameNode>& frameNode, const RefPtr<EventHub>& eventHub)
287 {
288     auto pipeline = frameNode->GetContext();
289     CHECK_NULL_VOID(pipeline);
290     auto rootNode = pipeline->GetRootElement();
291     auto container = Container::Current();
292     if (container && container->IsScenceBoardWindow()) {
293         auto host = eventHub->GetFrameNode();
294         CHECK_NULL_VOID(host);
295         auto overlayManager = pipeline->GetOverlayManager();
296         CHECK_NULL_VOID(overlayManager);
297         rootNode = DynamicCast<FrameNode>(overlayManager->FindWindowScene(host));
298     }
299     CHECK_NULL_VOID(rootNode);
300     frameNode->MountToParent(rootNode);
301     frameNode->OnMountToParentDone();
302     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
303 }
304 
RemoveItemDrag()305 void DragDropManager::RemoveItemDrag()
306 {
307     CHECK_NULL_VOID(itemDragOverlayNode_);
308     auto rootNode = itemDragOverlayNode_->GetParent();
309     CHECK_NULL_VOID(rootNode);
310     rootNode->RemoveChild(itemDragOverlayNode_);
311     rootNode->RebuildRenderContextTree();
312     rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
313 }
314 
UpdateItemDragPosition(int32_t globalX,int32_t globalY)315 void DragDropManager::UpdateItemDragPosition(int32_t globalX, int32_t globalY)
316 {
317     CHECK_NULL_VOID(itemDragOverlayNode_);
318     auto rect = itemDragOverlayNode_->GetTransformRectRelativeToWindow();
319     auto pipeline = itemDragOverlayNode_->GetContext();
320     CHECK_NULL_VOID(pipeline);
321     const Rect windowRect = pipeline->GetDisplayWindowRectInfo();
322     auto maxX = static_cast<float>(windowRect.Width() - rect.Width());
323     auto maxY = static_cast<float>(windowRect.Height() - rect.Height());
324     auto renderContext = itemDragOverlayNode_->GetRenderContext();
325     CHECK_NULL_VOID(renderContext);
326     renderContext->UpdatePosition(
327         OffsetT<Dimension>(Dimension(std::min(std::max(globalX - rect.Width() / 2, 0.0f), maxX)), // 2: Average factor.
328             Dimension(std::min(std::max(globalY - rect.Height() / 2, 0.0f), maxY))));             // 2: Average factor.
329     renderContext->OnModifyDone();
330 }
331 
HideDragPreviewOverlay()332 void DragDropManager::HideDragPreviewOverlay()
333 {
334     auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
335     CHECK_NULL_VOID(pipeline);
336     auto manager = pipeline->GetOverlayManager();
337     CHECK_NULL_VOID(manager);
338     manager->RemovePixelMap();
339     manager->RemoveGatherNode();
340     manager->RemoveDragPixelMap();
341     SubwindowManager::GetInstance()->HidePreviewNG();
342 }
343 
HideDragPreviewWindow(int32_t containerId)344 void DragDropManager::HideDragPreviewWindow(int32_t containerId)
345 {
346     auto overlayManager = GetDragAnimationOverlayManager(containerId);
347     CHECK_NULL_VOID(overlayManager);
348     overlayManager->RemovePixelMap();
349     overlayManager->RemoveGatherNode();
350     overlayManager->RemoveDragPixelMap();
351     SubwindowManager::GetInstance()->HidePreviewNG();
352 }
353 
FindTargetInChildNodes(const RefPtr<UINode> parentNode,std::vector<RefPtr<FrameNode>> hitFrameNodes,bool findDrop)354 RefPtr<FrameNode> DragDropManager::FindTargetInChildNodes(
355     const RefPtr<UINode> parentNode, std::vector<RefPtr<FrameNode>> hitFrameNodes, bool findDrop)
356 {
357     CHECK_NULL_RETURN(parentNode, nullptr);
358     auto parentFrameNode = AceType::DynamicCast<FrameNode>(parentNode);
359     if (parentFrameNode && (!parentFrameNode->IsActive() || !parentFrameNode->IsVisible())) {
360         return nullptr;
361     }
362     auto children = parentFrameNode->GetFrameChildren();
363 
364     for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
365         auto child = iter->Upgrade();
366         if (child == nullptr) {
367             continue;
368         }
369         auto childNode = AceType::DynamicCast<UINode>(child);
370         auto childFindResult = FindTargetInChildNodes(childNode, hitFrameNodes, findDrop);
371         if (childFindResult) {
372             return childFindResult;
373         }
374     }
375 
376     CHECK_NULL_RETURN(parentFrameNode, nullptr);
377     for (auto iter : hitFrameNodes) {
378         if (parentFrameNode == iter) {
379             auto eventHub = parentFrameNode->GetEventHub<EventHub>();
380             if (!eventHub) {
381                 continue;
382             }
383             if ((eventHub->HasOnDrop()) || (eventHub->HasOnItemDrop()) || (eventHub->HasCustomerOnDrop())) {
384                 return parentFrameNode;
385             }
386             if ((V2::UI_EXTENSION_COMPONENT_ETS_TAG == parentFrameNode->GetTag() ||
387                 V2::EMBEDDED_COMPONENT_ETS_TAG == parentFrameNode->GetTag()) &&
388                 (!IsUIExtensionShowPlaceholder(parentFrameNode))) {
389                 return parentFrameNode;
390             }
391         }
392     }
393     return nullptr;
394 }
395 
CheckFrameNodeCanDrop(const RefPtr<FrameNode> & node)396 bool DragDropManager::CheckFrameNodeCanDrop(const RefPtr<FrameNode>& node)
397 {
398     CHECK_NULL_RETURN(node, false);
399     auto eventHub = node->GetEventHub<EventHub>();
400     CHECK_NULL_RETURN(eventHub, false);
401     if ((eventHub->HasOnDrop()) || (eventHub->HasOnItemDrop()) || (eventHub->HasCustomerOnDrop())) {
402         return true;
403     }
404     if ((V2::UI_EXTENSION_COMPONENT_ETS_TAG == node->GetTag() ||
405         V2::EMBEDDED_COMPONENT_ETS_TAG == node->GetTag()) &&
406         (!IsUIExtensionShowPlaceholder(node))) {
407         return true;
408     }
409 
410     return false;
411 }
412 
FindTargetDropNode(const RefPtr<UINode> parentNode,PointF localPoint)413 RefPtr<FrameNode> DragDropManager::FindTargetDropNode(const RefPtr<UINode> parentNode, PointF localPoint)
414 {
415     CHECK_NULL_RETURN(parentNode, nullptr);
416     auto parentFrameNode = AceType::DynamicCast<FrameNode>(parentNode);
417     CHECK_NULL_RETURN(parentFrameNode, nullptr);
418     if (!parentFrameNode->IsActive() || !parentFrameNode->IsVisible()) {
419         return nullptr;
420     }
421     auto renderContext = parentFrameNode->GetRenderContext();
422     CHECK_NULL_RETURN(renderContext, nullptr);
423     auto paintRect = renderContext->GetPaintRectWithoutTransform();
424     FrameNode::MapPointTo(localPoint, parentFrameNode->GetOrRefreshMatrixFromCache().revertMatrix);
425     auto subLocalPoint = localPoint - paintRect.GetOffset();
426 
427     auto children = parentFrameNode->GetFrameChildren();
428     for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
429         auto child = iter->Upgrade();
430         if (child == nullptr) {
431             continue;
432         }
433         auto childNode = AceType::DynamicCast<UINode>(child);
434         auto childFindResult = FindTargetDropNode(childNode, subLocalPoint);
435         if (childFindResult) {
436             return childFindResult;
437         }
438     }
439 
440     if (paintRect.IsInRegion(localPoint)) {
441         if (parentFrameNode->GetDragHitTestBlock()) {
442             return parentFrameNode;
443         }
444         if (CheckFrameNodeCanDrop(parentFrameNode)) {
445             return parentFrameNode;
446         }
447     }
448     return nullptr;
449 }
450 
FilterSubwindowDragRootNode(const RefPtr<FrameNode> & node)451 RefPtr<FrameNode> DragDropManager::FilterSubwindowDragRootNode(const RefPtr<FrameNode>& node)
452 {
453     auto rootNode = node;
454     auto container = Container::Current();
455     CHECK_NULL_RETURN(container, rootNode);
456     auto containerId = container->GetInstanceId();
457     auto pipeline = PipelineContext::GetMainPipelineContext();
458     CHECK_NULL_RETURN(pipeline, rootNode);
459     if (isReDragStart_ && !DragDropFuncWrapper::IsExpandDisplay(pipeline) && containerId >= MIN_SUBCONTAINER_ID) {
460         rootNode = pipeline->GetRootElement();
461     }
462     return rootNode;
463 }
464 
FindDragFrameNodeByPosition(float globalX,float globalY,const RefPtr<FrameNode> & node)465 RefPtr<FrameNode> DragDropManager::FindDragFrameNodeByPosition(float globalX, float globalY,
466     const RefPtr<FrameNode>& node)
467 {
468     auto rootNode = node;
469     if (!rootNode) {
470         auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
471         CHECK_NULL_RETURN(pipeline, nullptr);
472         rootNode = pipeline->GetRootElement();
473     }
474 
475     auto result = FindTargetDropNode(rootNode, {globalX, globalY});
476     if (result) {
477         if (CheckFrameNodeCanDrop(result)) {
478             return result;
479         }
480     }
481     return nullptr;
482 }
483 
CheckDragDropProxy(int64_t id) const484 bool DragDropManager::CheckDragDropProxy(int64_t id) const
485 {
486     return currentId_ == id;
487 }
488 
UpdateDragAllowDrop(const RefPtr<FrameNode> & dragFrameNode,const DragBehavior dragBehavior,const int32_t eventId,bool isCapi)489 void DragDropManager::UpdateDragAllowDrop(
490     const RefPtr<FrameNode>& dragFrameNode, const DragBehavior dragBehavior, const int32_t eventId, bool isCapi)
491 {
492     if (!IsDropAllowed(dragFrameNode)) {
493         // simplified specifications for drag cursor style, no longer showing forbidden drag cursor
494         UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
495         return;
496     }
497 
498     // drop allowed
499     CHECK_NULL_VOID(dragFrameNode);
500     const auto& dragFrameNodeAllowDrop = dragFrameNode->GetAllowDrop();
501     // special handling for no drag data present situation, always show as move
502     // For CAPI ,no ENABLE_DROP and DISABLE_DROP state, skip the judgment and consider it allowed to drop into. Continue
503     // to set dragBehavior.
504     if (!isCapi && (dragFrameNodeAllowDrop.empty() || summaryMap_.empty())) {
505         UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
506         return;
507     }
508 
509     //other case, check drag behavior
510     switch (dragBehavior) {
511         case DragBehavior::UNKNOWN: {
512             // the application does not config the drag behavior, use move when moving within
513             // draggedFrameNode or frameNode is disabled, otherwise use copy
514             auto eventHub = dragFrameNode->GetEventHub<EventHub>();
515             if (draggedFrameNode_ == dragFrameNode || !(eventHub && eventHub->IsEnabled()) ||
516                 CheckExtraSituation(dragFrameNode)) {
517                 UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
518             } else {
519                 UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
520             }
521             break;
522         }
523         case DragBehavior::MOVE: {
524             UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
525             break;
526         }
527         case DragBehavior::COPY: {
528             UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
529             break;
530         }
531         default: {
532             UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
533             break;
534         }
535     }
536 }
537 
CheckExtraSituation(const RefPtr<FrameNode> & dragFrameNode) const538 bool DragDropManager::CheckExtraSituation(const RefPtr<FrameNode>& dragFrameNode) const
539 {
540     return CheckInRichEditor(dragFrameNode);
541 }
542 
CheckInRichEditor(const RefPtr<FrameNode> & dragFrameNode) const543 bool DragDropManager::CheckInRichEditor(const RefPtr<FrameNode>& dragFrameNode) const
544 {
545     CHECK_NULL_RETURN(dragFrameNode && draggedFrameNode_, false);
546     auto parent = draggedFrameNode_->GetAncestorNodeOfFrame(false);
547     CHECK_NULL_RETURN(parent && parent->GetTag() == V2::RICH_EDITOR_ETS_TAG, false);
548     return dragFrameNode == parent;
549 }
550 
UpdateDragStyle(const DragCursorStyleCore & dragStyle,int32_t eventId)551 void DragDropManager::UpdateDragStyle(const DragCursorStyleCore& dragStyle, int32_t eventId)
552 {
553     if (dragStyle != dragCursorStyleCore_) {
554         ACE_SCOPED_TRACE("drag: update drag style %d", dragStyle);
555         TAG_LOGI(
556             AceLogTag::ACE_DRAG, "Update DragStyle to %{public}d, pointerEventId: %{public}d.", dragStyle, eventId);
557         auto ret = InteractionInterface::GetInstance()->UpdateDragStyle(dragStyle, eventId);
558         if (ret != 0) {
559             TAG_LOGI(AceLogTag::ACE_DRAG,
560                 "Update DragStyle to %{public}d failed, keep %{public}d. pointerEventId: %{public}d. ret = %{public}d",
561                 dragStyle, dragCursorStyleCore_, eventId, ret);
562         } else {
563             dragCursorStyleCore_ = dragStyle;
564         }
565     }
566 }
567 
CheckParentVisible(const RefPtr<FrameNode> & frameNode)568 bool CheckParentVisible(const RefPtr<FrameNode>& frameNode)
569 {
570     CHECK_NULL_RETURN(frameNode, false);
571     bool isVisible = frameNode->IsVisible();
572     if (!isVisible) {
573         return false;
574     }
575     auto parent = frameNode->GetParent();
576     while (parent && parent->GetDepth() != 1) {
577         auto parentFrameNode = AceType::DynamicCast<FrameNode>(parent);
578         if (parentFrameNode && !parentFrameNode->IsVisible()) {
579             isVisible = false;
580             break;
581         }
582         parent = parent->GetParent();
583     }
584     return isVisible;
585 }
586 
FindHitFrameNodes(const Point & point)587 std::unordered_set<int32_t> DragDropManager::FindHitFrameNodes(const Point& point)
588 {
589     std::unordered_set<int32_t> frameNodeList;
590     for (auto iter = nodesForDragNotify_.begin(); iter != nodesForDragNotify_.end(); iter++) {
591         auto frameNode = iter->second.Upgrade();
592         if (!frameNode || !frameNode->IsActive() || !frameNode->IsVisible() || !frameNode->IsOnMainTree()) {
593             continue;
594         }
595         auto geometryNode = frameNode->GetGeometryNode();
596         if (!geometryNode) {
597             continue;
598         }
599         auto globalFrameRect = geometryNode->GetFrameRect();
600         globalFrameRect.SetOffset(frameNode->GetTransformRelativeOffset());
601         if (globalFrameRect.IsInRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
602             frameNodeList.emplace(frameNode->GetId());
603         }
604     }
605     return frameNodeList;
606 }
607 
UpdateDragListener(const Point & point)608 void DragDropManager::UpdateDragListener(const Point& point)
609 {
610     auto hitNodes = FindHitFrameNodes(point);
611     std::unordered_map<int32_t, WeakPtr<FrameNode>> dragEnterNodes;
612     std::unordered_map<int32_t, WeakPtr<FrameNode>> dragMoveNodes;
613     std::unordered_map<int32_t, WeakPtr<FrameNode>> dragLeaveNodes;
614     for (auto iter = nodesForDragNotify_.begin(); iter != nodesForDragNotify_.end(); iter++) {
615         auto localHitResult = hitNodes.find(iter->first) != hitNodes.end();
616         auto preHitResult = parentHitNodes_.find(iter->first) != parentHitNodes_.end();
617         if (localHitResult && preHitResult) {
618             dragMoveNodes[iter->first] = iter->second;
619         }
620         if (localHitResult && !preHitResult) {
621             dragEnterNodes[iter->first] = iter->second;
622         }
623         if (!localHitResult && preHitResult) {
624             dragLeaveNodes[iter->first] = iter->second;
625         }
626     }
627     RefPtr<NotifyDragEvent> notifyEvent = AceType::MakeRefPtr<NotifyDragEvent>();
628     CHECK_NULL_VOID(notifyEvent);
629     UpdateNotifyDragEvent(notifyEvent, point, DragEventType::MOVE);
630 
631     NotifyDragRegisterFrameNode(dragMoveNodes, DragEventType::MOVE, notifyEvent);
632     NotifyDragRegisterFrameNode(dragEnterNodes, DragEventType::ENTER, notifyEvent);
633     NotifyDragRegisterFrameNode(dragLeaveNodes, DragEventType::LEAVE, notifyEvent);
634     parentHitNodes_ = std::move(hitNodes);
635 }
636 
NotifyDragRegisterFrameNode(std::unordered_map<int32_t,WeakPtr<FrameNode>> nodes,DragEventType dragEventType,RefPtr<NotifyDragEvent> & notifyEvent)637 void DragDropManager::NotifyDragRegisterFrameNode(std::unordered_map<int32_t, WeakPtr<FrameNode>> nodes,
638     DragEventType dragEventType, RefPtr<NotifyDragEvent>& notifyEvent)
639 {
640     for (auto iter = nodes.begin(); iter != nodes.end(); iter++) {
641         auto frameNode = iter->second.Upgrade();
642         if (!frameNode) {
643             continue;
644         }
645         auto eventHub = frameNode->GetEventHub<EventHub>();
646         if (!CheckParentVisible(frameNode) || (eventHub && !eventHub->IsEnabled())) {
647             continue;
648         }
649         auto pattern = frameNode->GetPattern<Pattern>();
650         if (!pattern) {
651             continue;
652         }
653         pattern->HandleOnDragStatusCallback(dragEventType, notifyEvent);
654     }
655 }
656 
NotifyDragFrameNode(const Point & point,const DragEventType & dragEventType,const DragRet & dragRet)657 void DragDropManager::NotifyDragFrameNode(
658     const Point& point, const DragEventType& dragEventType, const DragRet& dragRet)
659 {
660     RefPtr<NotifyDragEvent> notifyEvent = AceType::MakeRefPtr<NotifyDragEvent>();
661     CHECK_NULL_VOID(notifyEvent);
662     UpdateNotifyDragEvent(notifyEvent, point, dragEventType);
663     notifyEvent->SetResult(dragRet);
664     NotifyDragRegisterFrameNode(nodesForDragNotify_, dragEventType, notifyEvent);
665 }
666 
GetRootNode()667 RefPtr<FrameNode> DragDropManager::GetRootNode()
668 {
669     auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
670     CHECK_NULL_RETURN(pipeline, nullptr);
671     return pipeline->GetRootElement();
672 }
673 
OnDragStart(const Point & point,const RefPtr<FrameNode> & frameNode)674 void DragDropManager::OnDragStart(const Point& point, const RefPtr<FrameNode>& frameNode)
675 {
676     dragDropState_ = DragDropMgrState::DRAGGING;
677     NotifyDragFrameNode(point, DragEventType::START);
678     CHECK_NULL_VOID(frameNode);
679     preTargetFrameNode_ = frameNode;
680     draggedFrameNode_ = preTargetFrameNode_;
681     preMovePoint_ = point;
682     parentHitNodes_.emplace(frameNode->GetId());
683 
684     // Reset hover status when drag start.
685     auto pipeline = frameNode->GetContextRefPtr();
686     CHECK_NULL_VOID(pipeline);
687     auto eventManager = pipeline->GetEventManager();
688     CHECK_NULL_VOID(eventManager);
689     eventManager->CleanHoverStatusForDragBegin();
690 }
691 
OnDragStart(const Point & point)692 void DragDropManager::OnDragStart(const Point& point)
693 {
694     dragDropState_ = DragDropMgrState::DRAGGING;
695     NotifyDragFrameNode(point, DragEventType::START);
696 
697     // Reset hover status when drag start.
698     auto pipeline = PipelineContext::GetCurrentContext();
699     CHECK_NULL_VOID(pipeline);
700     auto eventManager = pipeline->GetEventManager();
701     CHECK_NULL_VOID(eventManager);
702     eventManager->CleanHoverStatusForDragBegin();
703 }
704 
PrintDragFrameNode(const OHOS::Ace::DragPointerEvent & pointerEvent,const RefPtr<FrameNode> & dragFrameNode)705 void DragDropManager::PrintDragFrameNode(
706     const OHOS::Ace::DragPointerEvent& pointerEvent, const RefPtr<FrameNode>& dragFrameNode)
707 {
708     CHECK_NULL_VOID(dragFrameNode);
709     auto container = Container::Current();
710     CHECK_NULL_VOID(container);
711     if (preTargetFrameNode_) {
712         TAG_LOGI(AceLogTag::ACE_DRAG,
713             "Current windowId is %{public}d, pointerEventId is %{public}d, "
714             "PreTargetFrameNode is %{public}s, depth is %{public}d, New find "
715             "targetNode is %{public}s, depth is %{public}d.",
716             container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
717             preTargetFrameNode_->GetDepth(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
718     } else {
719         TAG_LOGI(AceLogTag::ACE_DRAG,
720             "Current windowId is %{public}d, pointerEventId is %{public}d, "
721             "PreTargetFrameNode is nullptr, New find targetNode is %{public}s, depth is %{public}d",
722             container->GetWindowId(), pointerEvent.pointerEventId, dragFrameNode->GetTag().c_str(),
723             dragFrameNode->GetDepth());
724     }
725 }
726 
PrintGridDragFrameNode(const float globalX,const float globalY,const RefPtr<FrameNode> & dragFrameNode)727 void DragDropManager::PrintGridDragFrameNode(
728     const float globalX, const float globalY, const RefPtr<FrameNode>& dragFrameNode)
729 {
730     CHECK_NULL_VOID(dragFrameNode);
731     auto container = Container::Current();
732     CHECK_NULL_VOID(container);
733     if (preGridTargetFrameNode_) {
734         TAG_LOGI(AceLogTag::ACE_DRAG,
735             "Current windowId is %{public}d"
736             "PreTargetFrameNode is %{public}s, depth is %{public}d,"
737             "New find targetNode is %{public}s, depth is %{public}d.",
738             container->GetWindowId(), preGridTargetFrameNode_->GetTag().c_str(),
739             preGridTargetFrameNode_->GetDepth(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
740     } else {
741         TAG_LOGI(AceLogTag::ACE_DRAG,
742             "Current windowId is %{public}d, "
743             "PreTargetFrameNode is nullptr, New find targetNode is %{public}s, depth is %{public}d.",
744             container->GetWindowId(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
745     }
746 }
747 
TransDragWindowToDragFwk(int32_t windowContainerId)748 void DragDropManager::TransDragWindowToDragFwk(int32_t windowContainerId)
749 {
750     if (isDragFwkShow_) {
751         return;
752     }
753     TAG_LOGI(AceLogTag::ACE_DRAG, "TransDragWindowToDragFwk is %{public}d", isDragFwkShow_);
754     ACE_SCOPED_TRACE("drag: set drag window visible by transfer");
755     if (draggedFrameNode_) {
756         auto gestureHub = draggedFrameNode_->GetOrCreateGestureEventHub();
757         CHECK_NULL_VOID(gestureHub);
758         auto dragEventActuator = gestureHub->GetDragEventActuator();
759         CHECK_NULL_VOID(dragEventActuator);
760         dragEventActuator->NotifyTransDragWindowToFwk();
761     }
762     InteractionInterface::GetInstance()->SetDragWindowVisible(true);
763     DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
764     isDragFwkShow_ = true;
765     auto overlayManager = GetDragAnimationOverlayManager(windowContainerId);
766     CHECK_NULL_VOID(overlayManager);
767     overlayManager->RemoveDragPixelMap();
768     overlayManager->RemoveGatherNode();
769     SubwindowManager::GetInstance()->HidePreviewNG();
770     info_.scale = -1.0;
771     dampingOverflowCount_ = 0;
772 }
773 
OnDragMoveOut(const DragPointerEvent & pointerEvent)774 void DragDropManager::OnDragMoveOut(const DragPointerEvent& pointerEvent)
775 {
776     Point point = pointerEvent.GetPoint();
777     auto container = Container::Current();
778     if (container && container->IsScenceBoardWindow()) {
779         if (IsDragged() && IsWindowConsumed()) {
780             SetIsWindowConsumed(false);
781             return;
782         }
783     }
784     isReDragStart_ = false;
785     SetIsWindowConsumed(false);
786     UpdateVelocityTrackerPoint(point, false);
787     UpdateDragListener(Point(-1, -1));
788     NotifyPullEventListener(pointerEvent);
789     if (preTargetFrameNode_) {
790         TAG_LOGI(AceLogTag::ACE_DRAG, "Leave the current window, windowId is %{public}d,"
791             " pointerEventId is %{public}d. PreTargetFrameNode is %{public}s, depth is %{public}d.",
792             container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
793             preTargetFrameNode_->GetDepth());
794         FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo_);
795         preTargetFrameNode_ = nullptr;
796     }
797     if (IsNeedDisplayInSubwindow() || isDragWithContextMenu_) {
798         TransDragWindowToDragFwk(Container::CurrentId());
799     }
800 }
801 
isDistanceLimited(const Point & point)802 bool DragDropManager::isDistanceLimited(const Point& point)
803 {
804     auto distance = sqrt(pow(point.GetX() - preMovePoint_.GetX(), 2) + pow(point.GetY() - preMovePoint_.GetY(), 2));
805     TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, distance: %{public}f", distance);
806     if (distance < MOVE_DISTANCE_LIMIT) {
807         TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, distance is less than limit");
808         return true;
809     }
810     return false;
811 }
812 
isTimeLimited(const DragPointerEvent & pointerEvent,const Point & point)813 bool DragDropManager::isTimeLimited(const DragPointerEvent& pointerEvent, const Point& point)
814 {
815     uint64_t currentTimeStamp = static_cast<uint64_t>(
816         std::chrono::duration_cast<std::chrono::milliseconds>(pointerEvent.time.time_since_epoch()).count());
817     if (currentTimeStamp > preTimeStamp_ && currentTimeStamp - preTimeStamp_ < MOVE_TIME_LIMIT) {
818         TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, time is less than limit");
819         return true;
820     }
821     return false;
822 }
823 
ReachMoveLimit(const DragPointerEvent & pointerEvent,const Point & point)824 bool DragDropManager::ReachMoveLimit(const DragPointerEvent& pointerEvent, const Point& point)
825 {
826     if (pointerEvent.sourceTool == SourceTool::MOUSE) {
827         if (isTimeLimited(pointerEvent, point) && isDistanceLimited(point)) {
828             return true;
829         }
830     }
831     return false;
832 }
833 
HandleOnDragMove(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & dragFrameNode)834 void DragDropManager::HandleOnDragMove(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
835     const RefPtr<FrameNode>& dragFrameNode)
836 {
837     CHECK_NULL_VOID(dragFrameNode);
838 
839     if (dragFrameNode == preTargetFrameNode_) {
840         FireOnDragEvent(dragFrameNode, pointerEvent, DragEventType::MOVE, extraInfo);
841         return;
842     }
843 
844     FireOnDragLeave(preTargetFrameNode_, pointerEvent, extraInfo);
845     PrintDragFrameNode(pointerEvent, dragFrameNode);
846     FireOnDragEvent(dragFrameNode, pointerEvent, DragEventType::ENTER, extraInfo);
847     preTargetFrameNode_ = dragFrameNode;
848 }
849 
OnDragMove(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & node)850 void DragDropManager::OnDragMove(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
851     const RefPtr<FrameNode>& node)
852 {
853     RequireSummaryIfNecessary(pointerEvent);
854     Point point = pointerEvent.GetPoint();
855     auto container = Container::Current();
856     CHECK_NULL_VOID(container);
857     if (container && container->IsScenceBoardWindow()) {
858         if (IsDragged() && IsWindowConsumed()) {
859             SetIsWindowConsumed(false);
860             return;
861         }
862     }
863     if (ReachMoveLimit(pointerEvent, point)) {
864         return;
865     }
866     NotifyPullEventListener(pointerEvent);
867     preMovePoint_ = point;
868     preDragPointerEvent_ = pointerEvent;
869     preTimeStamp_ = static_cast<uint64_t>(
870         std::chrono::duration_cast<std::chrono::milliseconds>(pointerEvent.time.time_since_epoch()).count());
871     SetIsWindowConsumed(false);
872     if (isDragFwkShow_) {
873         auto menuWrapper = GetMenuWrapperNodeFromDrag();
874         if (menuWrapper) {
875             auto menuPosition = DragDropFuncWrapper::GetPointRelativeToMainWindow(point);
876             SubwindowManager::GetInstance()->UpdateHideMenuOffsetNG(
877                 menuPosition, 1.0, false, menuWrapper ? menuWrapper->GetId() : -1);
878         }
879     }
880     UpdateVelocityTrackerPoint(point, false);
881     UpdateDragListener(point);
882     auto dragFrameNode = FindDragFrameNodeByPosition(
883         static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), node);
884     if (!dragFrameNode) {
885         if (preTargetFrameNode_) {
886             TAG_LOGI(AceLogTag::ACE_DRAG,
887                 "Not find drag target node, current windowId is %{public}d, pointerEventId is %{public}d, "
888                 "PreTargetFrameNode is %{public}s, depth is %{public}d.",
889                 container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
890                 preTargetFrameNode_->GetDepth());
891             FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo);
892             preTargetFrameNode_ = nullptr;
893         }
894 
895         if (!isMouseDragged_ || isDragWindowShow_) {
896             UpdateDragStyle(DragCursorStyleCore::MOVE, pointerEvent.pointerEventId);
897         }
898         return;
899     }
900     HandleOnDragMove(pointerEvent, extraInfo, dragFrameNode);
901 }
902 
ResetDragDropStatus(const Point & point,const DragDropRet & dragDropRet,int32_t windowId)903 void DragDropManager::ResetDragDropStatus(const Point& point, const DragDropRet& dragDropRet, int32_t windowId)
904 {
905     ACE_SCOPED_TRACE("drag: reset drag %d, %d", dragDropRet.result, dragDropRet.hasCustomAnimation);
906     if (dragDropRet.result != DragRet::DRAG_FAIL || !isMouseDragged_) {
907         InteractionInterface::GetInstance()->SetDragWindowVisible(!dragDropRet.hasCustomAnimation);
908     }
909     InteractionInterface::GetInstance()->StopDrag(dragDropRet);
910     NotifyDragFrameNode(point, DragEventType::DROP, dragDropRet.result);
911     ResetPullId();
912     dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
913     isReDragStart_ = false;
914 }
915 
ResetPreTargetFrameNode(int32_t instanceId)916 void DragDropManager::ResetPreTargetFrameNode(int32_t instanceId)
917 {
918     auto container = Container::GetContainer(instanceId);
919     if (container && (container->IsScenceBoardWindow() || container->IsUIExtensionWindow())) {
920         return;
921     }
922     // pull-in subwindow, need to notify showMenu and update menu offset.
923     if (instanceId > MIN_SUBCONTAINER_ID) {
924         isDragFwkShow_ = true;
925     }
926     preTargetFrameNode_ = nullptr;
927 }
928 
ResetDragEndOption(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent,int32_t currentId)929 void DragDropManager::ResetDragEndOption(
930     const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent, int32_t currentId)
931 {
932     SetDragResult(notifyMessage, dragEvent);
933     SetDragBehavior(notifyMessage, dragEvent);
934     DoDragReset();
935     SetIsDragged(false);
936     SetDraggingPointer(-1);
937     SetDraggingPressedState(false);
938     ResetDragPreviewInfo();
939     HideDragPreviewWindow(currentId);
940     CHECK_NULL_VOID(dragEvent);
941     dragEvent->SetPressedKeyCodes(GetDragDropPointerEvent().pressedKeyCodes);
942 }
943 
DoDragReset()944 void DragDropManager::DoDragReset()
945 {
946     dragDropState_ = DragDropMgrState::IDLE;
947     preTargetFrameNode_ = nullptr;
948     draggedFrameNode_ = nullptr;
949     menuWrapperNode_ = nullptr;
950     preMovePoint_ = Point(0, 0);
951     hasNotifiedTransformation_ = false;
952     badgeNumber_ = -1;
953     isDragWithContextMenu_ = false;
954     dampingOverflowCount_ = 0;
955     isDragNodeNeedClean_ = false;
956     isAnyDraggableHit_ = false;
957     fingerPointInfo_.clear();
958     DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
959 }
960 
ResetDraggingStatus(const TouchEvent & touchPoint)961 void DragDropManager::ResetDraggingStatus(const TouchEvent& touchPoint)
962 {
963     if (IsDraggingPressed(touchPoint.id)) {
964         SetDraggingPressedState(false);
965     }
966     DragPointerEvent dragPointerEvent;
967     DragDropFuncWrapper::ConvertPointerEvent(touchPoint, dragPointerEvent);
968     if (!IsItemDragging() && IsDragging() && IsSameDraggingPointer(touchPoint.id)) {
969         TAG_LOGI(AceLogTag::ACE_DRAG, "Reset dragging status, stop drag. pointerId: %{public}d", touchPoint.id);
970         SetIsDisableDefaultDropAnimation(true);
971         OnDragEnd(dragPointerEvent, "");
972     }
973     if (touchPoint.type == TouchType::CANCEL) {
974         if (IsUIExtensionComponent(preTargetFrameNode_)) {
975             HandleUIExtensionDragEvent(preTargetFrameNode_, dragPointerEvent, DragEventType::LEAVE);
976         }
977         NotifyDragFrameNode(dragPointerEvent.GetPoint(), DragEventType::LEAVE);
978     }
979 }
980 
HandleOnDragEnd(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & dragFrameNode)981 void DragDropManager::HandleOnDragEnd(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
982     const RefPtr<FrameNode>& dragFrameNode)
983 {
984     CHECK_NULL_VOID(dragFrameNode);
985     Point point = pointerEvent.GetPoint();
986     auto container = Container::Current();
987     CHECK_NULL_VOID(container);
988     if (!IsDropAllowed(dragFrameNode)) {
989         TAG_LOGI(AceLogTag::ACE_DRAG,
990             "DragDropManager onDragEnd, target data is not allowed to fall into. WindowId is %{public}d, "
991             "pointerEventId is %{public}d.",
992             container->GetWindowId(), pointerEvent.pointerEventId);
993         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_REFUSE_DATA);
994         ACE_SCOPED_TRACE("drag: stop drag, not allowed to drop");
995         ResetDragDrop(container->GetWindowId(), point);
996         return;
997     }
998     TAG_LOGI(AceLogTag::ACE_DRAG, "Current windowId is %{public}d, pointerEventId is %{public}d, "
999         "TargetNode is %{public}s.",
1000         container->GetWindowId(), pointerEvent.pointerEventId, dragFrameNode->GetTag().c_str());
1001     if (IsUIExtensionComponent(dragFrameNode)) {
1002         auto pattern = dragFrameNode->GetPattern<Pattern>();
1003         pattern->HandleDragEvent(pointerEvent);
1004         NotifyDragFrameNode(point, DragEventType::DROP);
1005         return;
1006     }
1007 
1008     RequestDragSummaryInfoAndPrivilege();
1009     std::string udKey;
1010     InteractionInterface::GetInstance()->GetUdKey(udKey);
1011     auto eventHub = dragFrameNode->GetEventHub<EventHub>();
1012     CHECK_NULL_VOID(eventHub);
1013     if (!eventHub->GetDisableDataPrefetch()) {
1014         if (!CheckRemoteData(dragFrameNode, pointerEvent, udKey)) {
1015             auto unifiedData = RequestUDMFDataWithUDKey(udKey);
1016             DoDropAction(dragFrameNode, pointerEvent, unifiedData, udKey);
1017         }
1018     } else {
1019         DoDropAction(dragFrameNode, pointerEvent, nullptr, udKey);
1020     }
1021 }
1022 
OnDragEnd(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & node,const bool keyEscape)1023 void DragDropManager::OnDragEnd(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1024     const RefPtr<FrameNode>& node, const bool keyEscape)
1025 {
1026     RemoveDeadlineTimer();
1027     Point point = pointerEvent.GetPoint();
1028     dragDropPointerEvent_ = pointerEvent;
1029     auto preTargetFrameNode = preTargetFrameNode_;
1030     DoDragReset();
1031     auto container = Container::Current();
1032     auto containerId = container->GetInstanceId();
1033     DragDropBehaviorReporter::GetInstance().UpdateContainerId(containerId);
1034     if (container && container->IsScenceBoardWindow()) {
1035         if (IsDragged() && IsWindowConsumed()) {
1036             TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager is dragged or window consumed. WindowId is %{public}d",
1037                 container->GetWindowId());
1038             return;
1039         }
1040     }
1041     UpdateVelocityTrackerPoint(point, true);
1042     auto dragFrameNode = FindDragFrameNodeByPosition(
1043         static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), FilterSubwindowDragRootNode(node));
1044     if (HandleUIExtensionComponentDragCancel(preTargetFrameNode, dragFrameNode, keyEscape, pointerEvent, point)) {
1045         return;
1046     }
1047     if (isDragCancel_) {
1048         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
1049         TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropManager is dragCancel, finish drag. WindowId is %{public}d, "
1050             "pointerEventId is %{public}d.",
1051             container->GetWindowId(), pointerEvent.pointerEventId);
1052         ACE_SCOPED_TRACE("drag: drag cancelled");
1053         DragDropRet dragDropRet { DragRet::DRAG_CANCEL, false, container->GetWindowId(), DragBehavior::UNKNOWN };
1054         ResetDragDropStatus(point, dragDropRet, container->GetWindowId());
1055         FireOnDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE, extraInfo);
1056         ClearVelocityInfo();
1057         return;
1058     }
1059     if (IsUIExtensionComponent(preTargetFrameNode) && preTargetFrameNode != dragFrameNode) {
1060         HandleUIExtensionDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE);
1061     }
1062     if (!dragFrameNode) {
1063         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_DATA_UNSUPPORT);
1064         TAG_LOGI(AceLogTag::ACE_DRAG,
1065             "DragDropManager onDragEnd, not find drop target, stop drag. WindowId is %{public}d, "
1066             "pointerEventId is %{public}d.",
1067             container->GetWindowId(), pointerEvent.pointerEventId);
1068         ACE_SCOPED_TRACE("drag: drag stop, not find drop target");
1069         ResetDragDrop(container->GetWindowId(), point);
1070         return;
1071     }
1072     HandleOnDragEnd(pointerEvent, extraInfo, dragFrameNode);
1073 }
1074 
HandleUIExtensionComponentDragCancel(const RefPtr<FrameNode> & preTargetFrameNode,const RefPtr<FrameNode> & dragFrameNode,const bool keyEscape,const DragPointerEvent & pointerEvent,const Point & point)1075 bool DragDropManager::HandleUIExtensionComponentDragCancel(const RefPtr<FrameNode>& preTargetFrameNode,
1076     const RefPtr<FrameNode>& dragFrameNode, const bool keyEscape, const DragPointerEvent& pointerEvent,
1077     const Point& point)
1078 {
1079     if (!isDragCancel_) {
1080         return false;
1081     }
1082     if (keyEscape && IsUIExtensionComponent(preTargetFrameNode)) {
1083         HandleUIExtensionDragEvent(preTargetFrameNode, pointerEvent, DragEventType::PULL_CANCEL);
1084         NotifyDragFrameNode(point, DragEventType::DROP);
1085         return true;
1086     }
1087     if (IsUIExtensionComponent(dragFrameNode)) {
1088         auto pattern = dragFrameNode->GetPattern<Pattern>();
1089         CHECK_NULL_RETURN(pattern, true);
1090         pattern->HandleDragEvent(pointerEvent);
1091         NotifyDragFrameNode(point, DragEventType::DROP);
1092         return true;
1093     }
1094     return false;
1095 }
1096 
OnDragPullCancel(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & node)1097 void DragDropManager::OnDragPullCancel(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1098     const RefPtr<FrameNode>& node)
1099 {
1100     RemoveDeadlineTimer();
1101     Point point = pointerEvent.GetPoint();
1102     auto container = Container::Current();
1103     auto containerId = container->GetInstanceId();
1104     DragDropBehaviorReporter::GetInstance().UpdateContainerId(containerId);
1105     DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
1106     TAG_LOGI(AceLogTag::ACE_DRAG, "Drag is canceled, finish drag. WindowId is %{public}d, "
1107         "pointerEventId is %{public}d.",
1108         container->GetWindowId(), pointerEvent.pointerEventId);
1109     if (preTargetFrameNode_) {
1110         TAG_LOGI(AceLogTag::ACE_DRAG, "Cancel from the current window, windowId is %{public}d,"
1111             " pointerEventId is %{public}d. PreTargetFrameNode is %{public}s, depth is %{public}d.",
1112             container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
1113             preTargetFrameNode_->GetDepth());
1114         FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo_);
1115         preTargetFrameNode_ = nullptr;
1116     }
1117     DragDropRet dragDropRet { DragRet::DRAG_CANCEL, false, container->GetWindowId(), DragBehavior::UNKNOWN };
1118     ResetDragDropStatus(point, dragDropRet, container->GetWindowId());
1119     ClearVelocityInfo();
1120     DoDragReset();
1121 }
1122 
IsDropAllowed(const RefPtr<FrameNode> & dragFrameNode)1123 bool DragDropManager::IsDropAllowed(const RefPtr<FrameNode>& dragFrameNode)
1124 {
1125     CHECK_NULL_RETURN(dragFrameNode, false);
1126     // application passed in null to indicate refusing all drag data forcedly
1127     bool isDisallowDropForcedly = dragFrameNode->GetDisallowDropForcedly();
1128     if (isDisallowDropForcedly) {
1129         return false;
1130     }
1131     const auto& dragFrameNodeAllowDrop = dragFrameNode->GetAllowDrop();
1132     // if application does not set allow drop or set with empty, treat as all data types is allowed
1133     if (dragFrameNodeAllowDrop.empty() || summaryMap_.empty()) {
1134         return true;
1135     }
1136     DragDropBehaviorReporter::GetInstance().UpdateAllowDropType(dragFrameNodeAllowDrop);
1137     for (const auto& it : summaryMap_) {
1138         // if one matched found, allow drop
1139         if (dragFrameNodeAllowDrop.find(it.first) != dragFrameNodeAllowDrop.end()) {
1140             return true;
1141         }
1142     }
1143     return false;
1144 }
1145 
RequestDragSummaryInfoAndPrivilege()1146 void DragDropManager::RequestDragSummaryInfoAndPrivilege()
1147 {
1148     RequireSummary();
1149     int ret = InteractionInterface::GetInstance()->AddPrivilege();
1150     if (ret != 0 && SystemProperties::GetDebugEnabled()) {
1151         TAG_LOGD(AceLogTag::ACE_DRAG, "Interaction AddPrivilege in DragEnd with code:%{public}d", ret);
1152     }
1153     ShadowOffsetData shadowOffsetData { -1, -1, -1, -1 };
1154     ret = InteractionInterface::GetInstance()->GetShadowOffset(shadowOffsetData);
1155     if (ret == 0) {
1156         previewRect_ =
1157             Rect(shadowOffsetData.offsetX, shadowOffsetData.offsetY, shadowOffsetData.width, shadowOffsetData.height);
1158     } else {
1159         TAG_LOGD(AceLogTag::ACE_DRAG, "Interaction GetShadowOffset in DragEnd with code:%{public}d", ret);
1160     }
1161 }
1162 
DoDropAction(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<UnifiedData> & unifiedData,const std::string & udKey)1163 void DragDropManager::DoDropAction(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1164     const RefPtr<UnifiedData>& unifiedData, const std::string& udKey)
1165 {
1166     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1167     CHECK_NULL_VOID(event);
1168     if (!udKey.empty()) {
1169         event->SetUdKey(udKey);
1170     }
1171     if (unifiedData == nullptr) {
1172         event->SetIsGetDataSuccess(false);
1173     } else {
1174         DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
1175         event->SetData(unifiedData);
1176         event->SetIsGetDataSuccess(true);
1177     }
1178 
1179     OnDragDrop(event, dragFrameNode, pointerEvent);
1180 }
1181 
RequestUDMFDataWithUDKey(const std::string & udKey)1182 RefPtr<UnifiedData> DragDropManager::RequestUDMFDataWithUDKey(const std::string& udKey)
1183 {
1184     if (udKey.empty()) {
1185         TAG_LOGI(AceLogTag::ACE_DRAG, "udKey is empty");
1186         return nullptr;
1187     }
1188     ACE_SCOPED_TRACE("drag: get drag data from udmf");
1189     RefPtr<UnifiedData> udData = UdmfClient::GetInstance()->CreateUnifiedData();
1190     auto ret = UdmfClient::GetInstance()->GetData(udData, udKey);
1191     if (ret != 0) {
1192         TAG_LOGI(AceLogTag::ACE_DRAG, "Get udmfData failed");
1193         return nullptr;
1194     }
1195     return udData;
1196 }
1197 
TryGetDataBackGround(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const std::string & udKey,int32_t count)1198 void DragDropManager::TryGetDataBackGround(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1199     const std::string& udKey, int32_t count)
1200 {
1201     auto pipeline = PipelineContext::GetCurrentContext();
1202     CHECK_NULL_VOID(pipeline);
1203     auto taskScheduler = pipeline->GetTaskExecutor();
1204     CHECK_NULL_VOID(taskScheduler);
1205     taskScheduler->PostTask(
1206         [id = Container::CurrentId(), pipeline, dragFrameNode, pointerEvent, udKey, count,
1207         weakManager = WeakClaim(this)]() {
1208             ContainerScope scope(id);
1209             auto dragDropManager = weakManager.Upgrade();
1210             CHECK_NULL_VOID(dragDropManager);
1211             auto taskScheduler = pipeline->GetTaskExecutor();
1212             CHECK_NULL_VOID(taskScheduler);
1213             auto result = dragDropManager->RequestUDMFDataWithUDKey(udKey);
1214             if (result != nullptr || count >= MAX_RETRY_TIMES) {
1215                 taskScheduler->PostTask(
1216                     [dragFrameNode, pointerEvent, weakManager, result, udKey]() {
1217                         auto dragDropManager = weakManager.Upgrade();
1218                         CHECK_NULL_VOID(dragDropManager);
1219                         dragDropManager->DoDropAction(dragFrameNode, pointerEvent, result, udKey);
1220                     },
1221                     TaskExecutor::TaskType::UI, "ArkUIDragDropAction");
1222             } else {
1223                 // first temp get udmfData failed, prepare to retryGetData.
1224                 taskScheduler->PostDelayedTask(
1225                     [dragFrameNode, pointerEvent, weakManager, count, udKey]() {
1226                         auto dragDropManager = weakManager.Upgrade();
1227                         CHECK_NULL_VOID(dragDropManager);
1228                         dragDropManager->TryGetDataBackGround(dragFrameNode, pointerEvent, udKey, count + 1);
1229                     },
1230                     TaskExecutor::TaskType::UI, MAX_RETRY_DURATION, "ArkUIDragDropRetryGetData");
1231             }
1232         },
1233         TaskExecutor::TaskType::BACKGROUND, "ArkUIDragDropGetDataBackground");
1234 }
1235 
CheckRemoteData(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const std::string & udKey)1236 bool DragDropManager::CheckRemoteData(
1237     const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent, const std::string& udKey)
1238 {
1239     if (udKey.empty()) {
1240         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::GET_UDKEY_FAIL);
1241         return false;
1242     }
1243     std::string remoteUdKey = udKey;
1244     auto isRemoteData = UdmfClient::GetInstance()->GetRemoteStatus(remoteUdKey);
1245     if (isRemoteData) {
1246         TAG_LOGI(AceLogTag::ACE_DRAG, "Stop drag with motion drag action.");
1247         TryGetDataBackGround(dragFrameNode, pointerEvent, udKey);
1248         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::GET_UDKEY_FAIL);
1249         DragDropBehaviorReporter::GetInstance().UpdateIsCrossing(CrossingEnd::IS_CROSSING);
1250         return isRemoteData;
1251     }
1252     DragDropBehaviorReporter::GetInstance().UpdateIsCrossing(CrossingEnd::NOT_CROSSING);
1253     return isRemoteData;
1254 }
1255 
OnDragDrop(RefPtr<OHOS::Ace::DragEvent> & event,const RefPtr<FrameNode> & dragFrameNode,const OHOS::Ace::DragPointerEvent & pointerEvent)1256 void DragDropManager::OnDragDrop(RefPtr<OHOS::Ace::DragEvent>& event, const RefPtr<FrameNode>& dragFrameNode,
1257     const OHOS::Ace::DragPointerEvent& pointerEvent)
1258 {
1259     auto point = pointerEvent.GetPoint();
1260     CHECK_NULL_VOID(dragFrameNode);
1261     auto eventHub = dragFrameNode->GetEventHub<EventHub>();
1262     CHECK_NULL_VOID(eventHub);
1263     UpdateDragEvent(event, pointerEvent);
1264     auto extraParams = eventHub->GetDragExtraParams(extraInfo_, point, DragEventType::DROP);
1265     DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(true);
1266     eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event, extraParams);
1267     if (event->IsDragEndPending() && event->GetRequestIdentify() != -1) {
1268         if (PostStopDrag(dragFrameNode, pointerEvent, event, extraParams)) {
1269             return;
1270         }
1271     }
1272     HandleStopDrag(dragFrameNode, pointerEvent, event, extraParams);
1273     DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(false);
1274 }
1275 
HandleStopDrag(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1276 void DragDropManager::HandleStopDrag(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1277     const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1278 {
1279     auto point = pointerEvent.GetPoint();
1280     CHECK_NULL_VOID(dragFrameNode);
1281     auto eventHub = dragFrameNode->GetEventHub<EventHub>();
1282     CHECK_NULL_VOID(eventHub);
1283     eventHub->HandleInternalOnDrop(event, extraParams);
1284     ClearVelocityInfo();
1285     SetIsDragged(false);
1286     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1287     CHECK_NULL_VOID(pipeline);
1288     auto dragResult = event->GetResult();
1289     if (dragResult == DragRet::DRAG_FAIL) {
1290         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_RECEIVE_FAIL);
1291     } else if (dragResult == DragRet::DRAG_CANCEL) {
1292         DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
1293     }
1294     auto useCustomAnimation = event->IsUseCustomAnimation();
1295     auto dragBehavior = event->GetDragBehavior();
1296     auto container = Container::Current();
1297     CHECK_NULL_VOID(container);
1298     auto windowId = container->GetWindowId();
1299     ExecuteStopDrag(event, dragResult, useCustomAnimation, windowId, dragBehavior, pointerEvent);
1300     NotifyDragFrameNode(point, DragEventType::DROP, event->GetResult());
1301     dragFrameNode->MarkDirtyNode();
1302     ResetPullId();
1303     dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
1304     pipeline->RequestFrame();
1305 }
1306 
PostStopDrag(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1307 bool DragDropManager::PostStopDrag(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1308     const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1309 {
1310     CHECK_NULL_RETURN(dragFrameNode, false);
1311     CHECK_NULL_RETURN(event, false);
1312     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1313     CHECK_NULL_RETURN(pipeline, false);
1314     auto taskScheduler = pipeline->GetTaskExecutor();
1315     CHECK_NULL_RETURN(taskScheduler, false);
1316     taskScheduler->PostDelayedTask(
1317         [pointerEvent, event, extraParams, nodeWeak = WeakClaim(AceType::RawPtr(dragFrameNode)),
1318             weakManager = WeakClaim(this)]() {
1319             if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase() || !event) {
1320                 return;
1321             }
1322             auto dragDropManager = weakManager.Upgrade();
1323             if (dragDropManager) {
1324                 auto frameNode = nodeWeak.Upgrade();
1325                 event->SetResult(DragRet::DRAG_FAIL);
1326                 dragDropManager->HandleStopDrag(frameNode, pointerEvent, event, extraParams);
1327             }
1328             DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(false);
1329         },
1330         TaskExecutor::TaskType::UI, DROP_DELAY_TIME, "ArkUIStopDragDeadlineTimer");
1331     return DragDropGlobalController::GetInstance().RequestDragEndCallback(event->GetRequestIdentify(),
1332         event->GetResult(), GetStopDragCallBack(dragFrameNode, pointerEvent, event, extraParams));
1333 }
1334 
GetStopDragCallBack(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1335 std::function<void(const DragRet&)> DragDropManager::GetStopDragCallBack(const RefPtr<FrameNode>& dragFrameNode,
1336     const DragPointerEvent& pointerEvent, const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1337 {
1338     auto callback = [id = Container::CurrentId(), pointerEvent, event, extraParams,
1339         nodeWeak = WeakClaim(AceType::RawPtr(dragFrameNode)),
1340         weakManager = WeakClaim(this)] (const DragRet& dragResult) {
1341         ContainerScope scope(id);
1342         auto dragDropManager = weakManager.Upgrade();
1343         CHECK_NULL_VOID(dragDropManager);
1344         CHECK_NULL_VOID(event);
1345         event->SetResult(dragResult);
1346         auto frameNode = nodeWeak.Upgrade();
1347         dragDropManager->HandleStopDrag(frameNode, pointerEvent, event, extraParams);
1348     };
1349     return callback;
1350 }
1351 
ExecuteStopDrag(const RefPtr<OHOS::Ace::DragEvent> & event,DragRet dragResult,bool useCustomAnimation,int32_t windowId,DragBehavior dragBehavior,const OHOS::Ace::DragPointerEvent & pointerEvent)1352 void DragDropManager::ExecuteStopDrag(const RefPtr<OHOS::Ace::DragEvent>& event, DragRet dragResult,
1353     bool useCustomAnimation, int32_t windowId, DragBehavior dragBehavior,
1354     const OHOS::Ace::DragPointerEvent& pointerEvent)
1355 {
1356     if (useCustomAnimation && event->HasDropAnimation()) {
1357         ExecuteCustomDropAnimation(event, DragDropRet { dragResult, useCustomAnimation, windowId, dragBehavior });
1358         return;
1359     }
1360     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1361     CHECK_NULL_VOID(pipeline);
1362     auto overlayManager = GetDragAnimationOverlayManager(pipeline->GetInstanceId());
1363     if (overlayManager && !isDragFwkShow_) {
1364         overlayManager->RemoveDragPixelMap();
1365         overlayManager->RemoveFilter();
1366         pipeline->FlushMessages();
1367     }
1368     pipeline->AddAfterRenderTask([dragResult, useCustomAnimation, windowId, dragBehavior,
1369                                      pointerEventId = pointerEvent.pointerEventId, weak = WeakClaim(this)]() mutable {
1370         auto manager = weak.Upgrade();
1371         if (manager) {
1372             manager->HideDragPreviewOverlay();
1373             useCustomAnimation = manager->IsDisableDefaultDropAnimation() ? true : useCustomAnimation;
1374         }
1375         TAG_LOGI(AceLogTag::ACE_DRAG,
1376             "Stop drag, start do drop animation. useCustomAnimation is %{public}d,"
1377             "WindowId is %{public}d, pointerEventId is %{public}d.",
1378             useCustomAnimation, windowId, pointerEventId);
1379         InteractionInterface::GetInstance()->SetDragWindowVisible(!useCustomAnimation);
1380         DragDropRet dragDropRet { dragResult, useCustomAnimation, windowId, dragBehavior };
1381         InteractionInterface::GetInstance()->StopDrag(dragDropRet);
1382     });
1383 }
1384 
ExecuteCustomDropAnimation(const RefPtr<OHOS::Ace::DragEvent> & event,DragDropRet dragDropRet)1385 void DragDropManager::ExecuteCustomDropAnimation(const RefPtr<OHOS::Ace::DragEvent>& event, DragDropRet dragDropRet)
1386 {
1387     CHECK_NULL_VOID(event);
1388     event->ExecuteDropAnimation();
1389     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1390     CHECK_NULL_VOID(pipeline);
1391     auto overlayManager = GetDragAnimationOverlayManager(pipeline->GetInstanceId());
1392     if (overlayManager) {
1393         overlayManager->RemoveDragPixelMap();
1394         overlayManager->RemoveFilter();
1395     }
1396     InteractionInterface::GetInstance()->SetDragWindowVisible(false);
1397     pipeline->FlushMessages();
1398     InteractionInterface::GetInstance()->StopDrag(dragDropRet);
1399 }
1400 
RequireSummary()1401 void DragDropManager::RequireSummary()
1402 {
1403     std::map<std::string, int64_t> summary;
1404     int32_t ret = InteractionInterface::GetInstance()->GetDragSummary(summary);
1405     if (ret != 0) {
1406         TAG_LOGI(AceLogTag::ACE_DRAG, "RequireSummary: Interaction GetSummary failed: %{public}d", ret);
1407     } else {
1408         std::string summarys;
1409         for (const auto& [udkey, recordSize] : summary) {
1410             std::string str = udkey + "-" + std::to_string(recordSize) + ";";
1411             summarys += str;
1412         }
1413         TAG_LOGI(AceLogTag::ACE_DRAG, "require summary: %{public}s", summarys.c_str());
1414         DragDropBehaviorReporter::GetInstance().UpdateSummaryType(summarys);
1415     }
1416     std::string extraInfo;
1417     ret = InteractionInterface::GetInstance()->GetDragExtraInfo(extraInfo);
1418     if (ret != 0) {
1419         TAG_LOGI(AceLogTag::ACE_DRAG, "GetExtraInfo: Interaction GetExtraInfo failed: %{public}d", ret);
1420     }
1421     previewRect_ = Rect(-1, -1, -1, -1);
1422     extraInfo_ = extraInfo;
1423     summaryMap_ = summary;
1424 }
1425 
ResetRecordSize(uint32_t recordSize)1426 void DragDropManager::ResetRecordSize(uint32_t recordSize)
1427 {
1428     recordSize_ = recordSize;
1429 }
1430 
GetRecordSize() const1431 uint32_t DragDropManager::GetRecordSize() const
1432 {
1433     return recordSize_;
1434 }
1435 
GetDragWindowRect(const Point & point)1436 Rect DragDropManager::GetDragWindowRect(const Point& point)
1437 {
1438     if (!previewRect_.IsValid()) {
1439         ShadowOffsetData shadowOffsetData { -1, -1, -1, -1 };
1440         int ret = InteractionInterface::GetInstance()->GetShadowOffset(shadowOffsetData);
1441         if (ret == 0) {
1442             previewRect_ = Rect(
1443                 shadowOffsetData.offsetX,
1444                 shadowOffsetData.offsetY,
1445                 shadowOffsetData.width,
1446                 shadowOffsetData.height);
1447         }
1448     }
1449     return previewRect_ + Offset(point.GetX(), point.GetY());
1450 }
1451 
ClearSummary()1452 void DragDropManager::ClearSummary()
1453 {
1454     previewRect_ = Rect(-1, -1, -1, -1);
1455     ResetPullId();
1456     ResetRecordSize();
1457 }
1458 
OnTextDragEnd(float globalX,float globalY,const std::string & extraInfo)1459 void DragDropManager::OnTextDragEnd(float globalX, float globalY, const std::string& extraInfo)
1460 {
1461     dragDropState_ = DragDropMgrState::IDLE;
1462     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1463     if (dragFrameNode) {
1464         auto textFieldPattern = dragFrameNode->GetPattern<TextFieldPattern>();
1465         if (textFieldPattern) {
1466             textFieldPattern->InsertValue(extraInfo);
1467         }
1468     }
1469     SetIsDragged(false);
1470     currentId_ = -1;
1471 }
1472 
onDragCancel()1473 void DragDropManager::onDragCancel()
1474 {
1475     preTargetFrameNode_ = nullptr;
1476     draggedFrameNode_ = nullptr;
1477 }
1478 
FireOnDragEventWithDragType(const RefPtr<EventHub> & eventHub,DragEventType type,RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1479 void DragDropManager::FireOnDragEventWithDragType(const RefPtr<EventHub>& eventHub, DragEventType type,
1480     RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1481 {
1482     switch (type) {
1483         case DragEventType::ENTER: {
1484             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_ENTER, event, extraParams);
1485             eventHub->FireOnDragEnter(event, extraParams);
1486             break;
1487         }
1488         case DragEventType::MOVE: {
1489             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_MOVE, event, extraParams);
1490             eventHub->FireOnDragMove(event, extraParams);
1491             break;
1492         }
1493         case DragEventType::LEAVE: {
1494             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_LEAVE, event, extraParams);
1495             eventHub->FireOnDragLeave(event, extraParams);
1496             break;
1497         }
1498         case DragEventType::DROP: {
1499             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event, extraParams);
1500             eventHub->HandleInternalOnDrop(event, extraParams);
1501             break;
1502         }
1503         default:
1504             break;
1505     }
1506 }
1507 
FireOnDragEvent(const RefPtr<FrameNode> & frameNode,const DragPointerEvent & pointerEvent,DragEventType type,const std::string & extraInfo)1508 void DragDropManager::FireOnDragEvent(
1509     const RefPtr<FrameNode>& frameNode, const DragPointerEvent& pointerEvent,
1510     DragEventType type, const std::string& extraInfo)
1511 {
1512     CHECK_NULL_VOID(frameNode);
1513     if (IsUIExtensionComponent(frameNode)) {
1514         HandleUIExtensionDragEvent(frameNode, pointerEvent, type);
1515         return;
1516     }
1517     auto eventHub = frameNode->GetEventHub<EventHub>();
1518     CHECK_NULL_VOID(eventHub);
1519     if (!eventHub->HasOnDrop() && !eventHub->HasOnItemDrop() && !eventHub->HasCustomerOnDrop()) {
1520         return;
1521     }
1522     auto point = pointerEvent.GetPoint();
1523     auto extraParams = eventHub->GetDragExtraParams(extraInfo_.empty() ? extraInfo : extraInfo_, point, type);
1524     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1525     CHECK_NULL_VOID(event);
1526     UpdateDragEvent(event, pointerEvent);
1527 
1528     FireOnEditableTextComponent(frameNode, type);
1529     FireOnDragEventWithDragType(eventHub, type, event, extraParams);
1530 
1531     if (isMouseDragged_ && !isDragWindowShow_) {
1532         return;
1533     }
1534     UpdateDragCursorStyle(frameNode, event, pointerEvent.pointerEventId);
1535 }
1536 
UpdateDragCursorStyle(const RefPtr<FrameNode> & frameNode,const RefPtr<OHOS::Ace::DragEvent> & event,const int32_t eventId)1537 void DragDropManager::UpdateDragCursorStyle(const RefPtr<FrameNode>& frameNode,
1538     const RefPtr<OHOS::Ace::DragEvent>& event, const int32_t eventId)
1539 {
1540     if (event->GetResult() == DragRet::ENABLE_DROP) {
1541         if (event->GetDragBehavior() == DragBehavior::MOVE) {
1542             UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
1543         } else {
1544             UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
1545         }
1546     } else if (event->GetResult() == DragRet::DISABLE_DROP) {
1547         // simplified specifications for drag cursor style, no longer showing forbidden drag cursor
1548         UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
1549     } else {
1550         UpdateDragAllowDrop(frameNode, event->GetDragBehavior(), eventId, event->IsCapi());
1551     }
1552 }
1553 
OnItemDragStart(float globalX,float globalY,const RefPtr<FrameNode> & frameNode)1554 void DragDropManager::OnItemDragStart(float globalX, float globalY, const RefPtr<FrameNode>& frameNode)
1555 {
1556     dragDropState_ = DragDropMgrState::DRAGGING;
1557     preGridTargetFrameNode_ = frameNode;
1558     draggedGridFrameNode_ = frameNode;
1559 }
1560 
OnItemDragMove(float globalX,float globalY,int32_t draggedIndex,DragType dragType)1561 void DragDropManager::OnItemDragMove(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
1562 {
1563     auto container = Container::Current();
1564     CHECK_NULL_VOID(container);
1565 
1566     UpdateItemDragPosition(globalX, globalY);
1567 
1568     OHOS::Ace::ItemDragInfo itemDragInfo;
1569     itemDragInfo.SetX(globalX);
1570     itemDragInfo.SetY(globalY);
1571 
1572     // use -1 for grid item not in eventGrid
1573     auto getDraggedIndex = [draggedGrid = draggedGridFrameNode_, draggedIndex, dragType](
1574                                const RefPtr<FrameNode>& eventGrid) {
1575         return (dragType == DragType::GRID) ? (eventGrid == draggedGrid ? draggedIndex : -1) : draggedIndex;
1576     };
1577 
1578     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1579     if (!dragFrameNode) {
1580         if (preGridTargetFrameNode_) {
1581             TAG_LOGI(AceLogTag::ACE_DRAG, "Not find drag target node, current windowId is %{public}d,"
1582                 "PreGridTargetFrameNode is %{public}s, depth is %{public}d.",
1583                 container->GetWindowId(), preGridTargetFrameNode_->GetTag().c_str(),
1584                 preGridTargetFrameNode_->GetDepth());
1585             FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
1586                 getDraggedIndex(preGridTargetFrameNode_));
1587             preGridTargetFrameNode_ = nullptr;
1588         }
1589         return;
1590     }
1591 
1592     if (dragFrameNode == preGridTargetFrameNode_) {
1593         int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY);
1594         FireOnItemDragEvent(
1595             dragFrameNode, dragType, itemDragInfo, DragEventType::MOVE, getDraggedIndex(dragFrameNode), insertIndex);
1596         return;
1597     }
1598 
1599     if (preGridTargetFrameNode_) {
1600         FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
1601             getDraggedIndex(preGridTargetFrameNode_));
1602     }
1603 
1604     PrintGridDragFrameNode(globalX, globalY, dragFrameNode);
1605     FireOnItemDragEvent(dragFrameNode, dragType, itemDragInfo, DragEventType::ENTER, getDraggedIndex(dragFrameNode));
1606     preGridTargetFrameNode_ = dragFrameNode;
1607 }
1608 
GetWindowScale() const1609 float DragDropManager::GetWindowScale() const
1610 {
1611     float scale = 1.0f;
1612     auto container = Container::Current();
1613     CHECK_NULL_RETURN(container, scale);
1614     scale = container->GetWindowScale();
1615     return scale;
1616 }
1617 
OnItemDragEnd(float globalX,float globalY,int32_t draggedIndex,DragType dragType)1618 void DragDropManager::OnItemDragEnd(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
1619 {
1620     dragDropState_ = DragDropMgrState::IDLE;
1621     auto windowScale = isDragWindowSubWindow_ ? 1.0f : GetWindowScale();
1622     auto windowX = globalX * windowScale;
1623     auto windowY = globalY * windowScale;
1624 
1625     OHOS::Ace::ItemDragInfo itemDragInfo;
1626     itemDragInfo.SetX(windowX);
1627     itemDragInfo.SetY(windowY);
1628 
1629     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1630     if (!dragFrameNode) {
1631         // drag on one grid and drop on other area
1632         if (draggedGridFrameNode_) {
1633             if (dragType == DragType::GRID) {
1634                 auto eventHub = draggedGridFrameNode_->GetEventHub<GridEventHub>();
1635                 CHECK_NULL_VOID(eventHub);
1636                 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
1637             } else {
1638                 auto eventHub = draggedGridFrameNode_->GetEventHub<ListEventHub>();
1639                 CHECK_NULL_VOID(eventHub);
1640                 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
1641             }
1642         }
1643     } else {
1644         int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY);
1645         // drag and drop on the same grid
1646         if (dragFrameNode == draggedGridFrameNode_) {
1647             FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, draggedIndex, insertIndex, true);
1648         } else {
1649             // drag and drop on different grid
1650             bool isSuccess = FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, -1, insertIndex, true);
1651             if (draggedGridFrameNode_) {
1652                 FireOnItemDropEvent(draggedGridFrameNode_, dragType, itemDragInfo, draggedIndex, -1, isSuccess);
1653             }
1654         }
1655     }
1656 
1657     preGridTargetFrameNode_ = nullptr;
1658     draggedGridFrameNode_ = nullptr;
1659 }
1660 
onItemDragCancel()1661 void DragDropManager::onItemDragCancel()
1662 {
1663     dragDropState_ = DragDropMgrState::IDLE;
1664     preGridTargetFrameNode_ = nullptr;
1665     draggedGridFrameNode_ = nullptr;
1666 }
1667 
FireOnItemDragEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,DragEventType type,int32_t draggedIndex,int32_t insertIndex)1668 void DragDropManager::FireOnItemDragEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
1669     const OHOS::Ace::ItemDragInfo& itemDragInfo, DragEventType type, int32_t draggedIndex, int32_t insertIndex)
1670 {
1671     CHECK_NULL_VOID(frameNode);
1672     if (dragType == DragType::GRID) {
1673         auto eventHub = frameNode->GetEventHub<GridEventHub>();
1674         CHECK_NULL_VOID(eventHub);
1675         switch (type) {
1676             case DragEventType::ENTER:
1677                 eventHub->FireOnItemDragEnter(itemDragInfo);
1678                 break;
1679             case DragEventType::MOVE:
1680                 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
1681                 break;
1682             case DragEventType::LEAVE:
1683                 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
1684                 break;
1685             default:
1686                 break;
1687         }
1688     } else if (dragType == DragType::LIST) {
1689         auto eventHub = frameNode->GetEventHub<ListEventHub>();
1690         CHECK_NULL_VOID(eventHub);
1691         switch (type) {
1692             case DragEventType::ENTER:
1693                 eventHub->FireOnItemDragEnter(itemDragInfo);
1694                 break;
1695             case DragEventType::MOVE:
1696                 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
1697                 break;
1698             case DragEventType::LEAVE:
1699                 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
1700                 break;
1701             default:
1702                 break;
1703         }
1704     }
1705 }
1706 
FireOnItemDropEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,int32_t draggedIndex,int32_t insertIndex,bool isSuccess)1707 bool DragDropManager::FireOnItemDropEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
1708     const OHOS::Ace::ItemDragInfo& itemDragInfo, int32_t draggedIndex, int32_t insertIndex, bool isSuccess)
1709 {
1710     CHECK_NULL_RETURN(frameNode, false);
1711     if (dragType == DragType::GRID) {
1712         auto eventHub = frameNode->GetEventHub<GridEventHub>();
1713         CHECK_NULL_RETURN(eventHub, false);
1714         return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
1715     } else if (dragType == DragType::LIST) {
1716         auto eventHub = frameNode->GetEventHub<ListEventHub>();
1717         CHECK_NULL_RETURN(eventHub, false);
1718         return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
1719     }
1720     return false;
1721 }
1722 
GetItemIndex(const RefPtr<FrameNode> & frameNode,DragType dragType,float globalX,float globalY)1723 int32_t DragDropManager::GetItemIndex(
1724     const RefPtr<FrameNode>& frameNode, DragType dragType, float globalX, float globalY)
1725 {
1726     CHECK_NULL_RETURN(frameNode, -1);
1727     if (dragType == DragType::GRID) {
1728         auto eventHub = frameNode->GetEventHub<GridEventHub>();
1729         CHECK_NULL_RETURN(eventHub, -1);
1730         if (frameNode != draggedGridFrameNode_) {
1731             return eventHub->GetInsertPosition(globalX, globalY);
1732         }
1733         auto itemFrameNode = frameNode->FindChildByPositionWithoutChildTransform(globalX, globalY);
1734         if (!itemFrameNode) {
1735             if (eventHub->CheckPostionInGrid(globalX, globalY)) {
1736                 return eventHub->GetFrameNodeChildSize();
1737             }
1738         } else {
1739             return eventHub->GetGridItemIndex(itemFrameNode);
1740         }
1741     } else if (dragType == DragType::LIST) {
1742         auto eventHub = frameNode->GetEventHub<ListEventHub>();
1743         CHECK_NULL_RETURN(eventHub, -1);
1744         return eventHub->GetListItemIndexByPosition(globalX, globalY);
1745     }
1746     return -1;
1747 }
1748 
AddDataToClipboard(const std::string & extraInfo)1749 void DragDropManager::AddDataToClipboard(const std::string& extraInfo)
1750 {
1751     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1752     CHECK_NULL_VOID(pipeline);
1753     if (!extraInfo.empty()) {
1754         if (!newData_) {
1755             newData_ = JsonUtil::Create(true);
1756             newData_->Put("customDragInfo", extraInfo.c_str());
1757         } else {
1758             newData_->Replace("customDragInfo", extraInfo.c_str());
1759         }
1760     } else {
1761         return;
1762     }
1763     if (!clipboard_) {
1764         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
1765     }
1766     if (!addDataCallback_) {
1767         auto callback = [weakManager = WeakClaim(this)](const std::string& data) {
1768             auto dragDropManager = weakManager.Upgrade();
1769             CHECK_NULL_VOID(dragDropManager);
1770             auto addData = dragDropManager->newData_->ToString();
1771             auto clipboardAllData = JsonUtil::Create(true);
1772             clipboardAllData->Put("preData", data.c_str());
1773             clipboardAllData->Put("newData", addData.c_str());
1774             dragDropManager->clipboard_->SetData(clipboardAllData->ToString(), CopyOptions::Local, true);
1775         };
1776         addDataCallback_ = callback;
1777     }
1778     if (clipboard_) {
1779         clipboard_->GetData(addDataCallback_, true);
1780     }
1781 }
1782 
GetExtraInfoFromClipboard(std::string & extraInfo)1783 void DragDropManager::GetExtraInfoFromClipboard(std::string& extraInfo)
1784 {
1785     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1786     CHECK_NULL_VOID(pipeline);
1787 
1788     if (!clipboard_) {
1789         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
1790     }
1791 
1792     if (!getDataCallback_) {
1793         auto callback = [weak = WeakClaim(this)](const std::string& data) {
1794             auto manager = weak.Upgrade();
1795             CHECK_NULL_VOID(manager);
1796             auto json = JsonUtil::ParseJsonString(data);
1797             auto newData = JsonUtil::ParseJsonString(json->GetString("newData"));
1798             manager->extraInfo_ = newData->GetString("customDragInfo");
1799         };
1800         getDataCallback_ = callback;
1801     }
1802 
1803     if (getDataCallback_ && clipboard_) {
1804         clipboard_->GetData(getDataCallback_, true);
1805     }
1806 
1807     extraInfo = extraInfo_;
1808 }
1809 
RestoreClipboardData()1810 void DragDropManager::RestoreClipboardData()
1811 {
1812     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1813     CHECK_NULL_VOID(pipeline);
1814 
1815     if (!clipboard_) {
1816         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
1817     }
1818 
1819     if (!deleteDataCallback_) {
1820         auto callback = [weakManager = WeakClaim(this)](const std::string& data) {
1821             auto dragDropManager = weakManager.Upgrade();
1822             CHECK_NULL_VOID(dragDropManager);
1823             auto json = JsonUtil::ParseJsonString(data);
1824             if (json->Contains("preData")) {
1825                 dragDropManager->clipboard_->SetData(json->GetString("preData"));
1826             }
1827         };
1828         deleteDataCallback_ = callback;
1829     }
1830     if (clipboard_) {
1831         clipboard_->GetData(deleteDataCallback_, true);
1832     }
1833 }
1834 
DestroyDragWindow()1835 void DragDropManager::DestroyDragWindow()
1836 {
1837     ResetRecordSize();
1838     if (itemDragOverlayNode_) {
1839         RemoveItemDrag();
1840         itemDragOverlayNode_ = nullptr;
1841     }
1842     SetIsDragged(false);
1843     SetIsDragWindowShow(false);
1844     previewRect_ = Rect(-1, -1, -1, -1);
1845     isMouseDragged_ = false;
1846     currentId_ = -1;
1847 }
1848 
CancelItemDrag()1849 void DragDropManager::CancelItemDrag()
1850 {
1851     if (draggedGridFrameNode_) {
1852         auto listEventHub = draggedGridFrameNode_->GetEventHub<ListEventHub>();
1853         if (listEventHub) {
1854             listEventHub->HandleOnItemDragCancel();
1855             return;
1856         }
1857         auto gridEventHub = draggedGridFrameNode_->GetEventHub<GridEventHub>();
1858         if (gridEventHub) {
1859             gridEventHub->HandleOnItemDragCancel();
1860             return;
1861         }
1862     }
1863 }
1864 
CreateFrameworkDragDropProxy()1865 RefPtr<DragDropProxy> DragDropManager::CreateFrameworkDragDropProxy()
1866 {
1867     SetIsDragged(true);
1868     isDragCancel_ = false;
1869     currentId_ = ++g_proxyId;
1870     return MakeRefPtr<DragDropProxy>(currentId_);
1871 }
1872 
UpdateNotifyDragEvent(RefPtr<NotifyDragEvent> & notifyEvent,const Point & point,const DragEventType dragEventType)1873 void DragDropManager::UpdateNotifyDragEvent(
1874     RefPtr<NotifyDragEvent>& notifyEvent, const Point& point, const DragEventType dragEventType)
1875 {
1876     CHECK_NULL_VOID(notifyEvent);
1877     notifyEvent->SetX((double)point.GetX());
1878     notifyEvent->SetY((double)point.GetY());
1879     notifyEvent->SetScreenX((double)point.GetScreenX());
1880     notifyEvent->SetScreenY((double)point.GetScreenY());
1881     if (dragEventType != DragEventType::START) {
1882         if (dragEventType != DragEventType::DROP) {
1883             notifyEvent->SetVelocity(velocityTracker_.GetVelocity());
1884         }
1885         notifyEvent->SetSummary(summaryMap_);
1886         notifyEvent->SetPreviewRect(GetDragWindowRect(point));
1887     }
1888 }
1889 
UpdateDragEvent(RefPtr<OHOS::Ace::DragEvent> & event,const OHOS::Ace::DragPointerEvent & pointerEvent)1890 void DragDropManager::UpdateDragEvent(
1891     RefPtr<OHOS::Ace::DragEvent>& event, const OHOS::Ace::DragPointerEvent& pointerEvent)
1892 {
1893     auto point = pointerEvent.GetPoint();
1894     event->SetX(point.GetX());
1895     event->SetY(point.GetY());
1896     event->SetScreenX(point.GetScreenX());
1897     event->SetScreenY(point.GetScreenY());
1898     event->SetDisplayX((double)pointerEvent.GetDisplayX());
1899     event->SetDisplayY((double)pointerEvent.GetDisplayY());
1900     event->SetVelocity(velocityTracker_.GetVelocity());
1901     event->SetSummary(summaryMap_);
1902     event->SetPreviewRect(GetDragWindowRect(point));
1903     event->SetPressedKeyCodes(pointerEvent.pressedKeyCodes);
1904     event->SetSourceTool(pointerEvent.sourceTool);
1905 }
1906 
GetExtraInfo()1907 std::string DragDropManager::GetExtraInfo()
1908 {
1909     return extraInfo_;
1910 }
1911 
SetExtraInfo(const std::string & extraInfo)1912 void DragDropManager::SetExtraInfo(const std::string& extraInfo)
1913 {
1914     extraInfo_ = extraInfo;
1915 }
1916 
ClearExtraInfo()1917 void DragDropManager::ClearExtraInfo()
1918 {
1919     extraInfo_.clear();
1920 }
1921 
IsMSDPDragging() const1922 bool DragDropManager::IsMSDPDragging() const
1923 {
1924     ACE_SCOPED_TRACE("drag: get drag state from msdp");
1925     DragState dragState;
1926     InteractionInterface::GetInstance()->GetDragState(dragState);
1927     return dragState == DragState::START;
1928 }
1929 
ClearVelocityInfo()1930 void DragDropManager::ClearVelocityInfo()
1931 {
1932     velocityTracker_.Reset();
1933 }
1934 
UpdateVelocityTrackerPoint(const Point & point,bool isEnd)1935 void DragDropManager::UpdateVelocityTrackerPoint(const Point& point, bool isEnd)
1936 {
1937     std::chrono::microseconds microseconds(GetMicroTickCount());
1938     TimeStamp curTime(microseconds);
1939     velocityTracker_.UpdateTrackerPoint(point.GetX(), point.GetY(), curTime, isEnd);
1940 }
1941 
GetDragPreviewInfo(const RefPtr<OverlayManager> & overlayManager,DragPreviewInfo & dragPreviewInfo,const RefPtr<GestureEventHub> & gestureHub,PreparedInfoForDrag & data)1942 bool DragDropManager::GetDragPreviewInfo(const RefPtr<OverlayManager>& overlayManager, DragPreviewInfo& dragPreviewInfo,
1943     const RefPtr<GestureEventHub>& gestureHub, PreparedInfoForDrag& data)
1944 {
1945     CHECK_NULL_RETURN(overlayManager, false);
1946     if (!overlayManager->GetHasDragPixelMap()) {
1947         return false;
1948     }
1949     auto imageNode = overlayManager->GetDragPixelMapContentNode();
1950     CHECK_NULL_RETURN(imageNode, false);
1951     auto badgeNode = overlayManager->GetDragPixelMapBadgeNode();
1952     if (badgeNode) {
1953         dragPreviewInfo.textNode = badgeNode;
1954     }
1955     CHECK_NULL_RETURN(gestureHub, false);
1956     dragPreviewInfo.isMenuShow = data.isMenuShow;
1957     dragPreviewInfo.dragPreviewRect = data.dragPreviewRect;
1958     auto frameNode = gestureHub->GetFrameNode();
1959     CHECK_NULL_RETURN(frameNode, false);
1960     auto previewOption = imageNode->GetDragPreviewOption();
1961     auto gestureEvent = frameNode->GetOrCreateGestureEventHub();
1962     CHECK_NULL_RETURN(gestureEvent, false);
1963     RectF finalRect = GetFinalDragPreviewRect(imageNode, dragPreviewInfo, overlayManager);
1964     auto width = finalRect.Width();
1965     auto height = finalRect.Height();
1966     auto scaleData = DragDropManager::GetScaleInfo(width, height, gestureEvent->GetTextDraggable());
1967     CHECK_NULL_RETURN(scaleData, false);
1968     dragPreviewInfo.scale =
1969         (imageNode->GetTag() != V2::WEB_ETS_TAG && width > 0 && height > 0 && previewOption.isScaleEnabled)
1970             ? scaleData->scale : 1.0f;
1971     if (!isMouseDragged_ && dragPreviewInfo.scale == 1.0f) {
1972         dragPreviewInfo.scale = TOUCH_DRAG_PIXELMAP_SCALE;
1973     }
1974     // set menu preview scale only for no scale menu preview.
1975     if (isDragWithContextMenu_ && (!previewOption.isScaleEnabled || !scaleData->isNeedScale)) {
1976         auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
1977         if (imageGestureEventHub) {
1978             auto menuPreviewScale = imageGestureEventHub->GetMenuPreviewScale();
1979             dragPreviewInfo.scale =
1980                 GreatNotEqual(menuPreviewScale, 0.0f) ? menuPreviewScale : TOUCH_DRAG_PIXELMAP_SCALE;
1981         }
1982     }
1983     dragPreviewInfo.height = static_cast<double>(height);
1984     dragPreviewInfo.width = static_cast<double>(width);
1985     dragPreviewInfo.maxWidth = scaleData->shortSide;
1986     dragPreviewInfo.imageNode = imageNode;
1987     dragPreviewInfo.originOffset = imageNode->GetPositionToWindowWithTransform();
1988     dragPreviewInfo.originScale = imageNode->GetTransformScale();
1989     dragPreviewInfo.menuPreviewNode = data.menuPreviewNode;
1990     dragPreviewInfo.menuPreviewRect = data.menuPreviewRect;
1991     return true;
1992 }
1993 
IsNeedDoDragMoveAnimate(const DragPointerEvent & pointerEvent)1994 bool DragDropManager::IsNeedDoDragMoveAnimate(const DragPointerEvent& pointerEvent)
1995 {
1996     if (isDragFwkShow_) {
1997         return false;
1998     }
1999     auto x = pointerEvent.GetPoint().GetX();
2000     auto y = pointerEvent.GetPoint().GetY();
2001     curPointerOffset_ = { x, y };
2002     return true;
2003 }
2004 
IsNeedScaleDragPreview()2005 bool DragDropManager::IsNeedScaleDragPreview()
2006 {
2007     return info_.scale > 0 && info_.scale < 1.0f;
2008 }
2009 // calculate the touch position relative to the sub-window which will be used to do animation on,
2010 // the input [x, y] is the position relative to the window which is receiving the touch event,
2011 // and the position is contain the floatTitle offset.
GetTouchOffsetRelativeToSubwindow(int32_t containerId,int32_t x,int32_t y)2012 OffsetF DragDropManager::GetTouchOffsetRelativeToSubwindow(int32_t containerId, int32_t x, int32_t y)
2013 {
2014     auto touchOffset = OffsetF(x, y);
2015     auto pipeline = PipelineContext::GetContextByContainerId(containerId);
2016     CHECK_NULL_RETURN(pipeline, OffsetF(x, y));
2017     auto window = pipeline->GetWindow();
2018     CHECK_NULL_RETURN(window, OffsetF(x, y));
2019     auto windowOffset = window->GetCurrentWindowRect().GetOffset();
2020     touchOffset.SetX(touchOffset.GetX() + windowOffset.GetX());
2021     touchOffset.SetY(touchOffset.GetY() + windowOffset.GetY());
2022     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId >= MIN_SUBCONTAINER_ID ?
2023         SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId, SubwindowType::TYPE_MENU);
2024     CHECK_NULL_RETURN(subwindow, OffsetF(x, y));
2025     auto subwindowOffset = subwindow->GetWindowRect().GetOffset();
2026     touchOffset.SetX(touchOffset.GetX() - subwindowOffset.GetX());
2027     touchOffset.SetY(touchOffset.GetY() - subwindowOffset.GetY());
2028     return touchOffset;
2029 }
2030 
CalcDragPreviewDistanceWithPoint(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2031 double DragDropManager::CalcDragPreviewDistanceWithPoint(
2032     const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2033 {
2034     CHECK_NULL_RETURN(info.imageNode, 0.0);
2035     auto nodeOffset = info.imageNode->GetTransformRelativeOffset();
2036     auto renderContext = info.imageNode->GetRenderContext();
2037     CHECK_NULL_RETURN(renderContext, 0.0);
2038     nodeOffset -= pixelMapOffset_;
2039     auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2040     // calculate distance, so need to pow 2.
2041     return sqrt(pow(nodeOffset.GetX() - touchOffset.GetX(), 2) + pow(nodeOffset.GetY() - touchOffset.GetY(), 2));
2042 }
2043 
CalcDragMoveOffset(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2044 Offset DragDropManager::CalcDragMoveOffset(
2045     const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2046 {
2047     auto originPoint = info.originOffset;
2048     originPoint.SetX(originPoint.GetX() - pixelMapOffset_.GetX() +
2049         (info.originScale.x - info.scale) * info.width / 2.0f);
2050     originPoint.SetY(originPoint.GetY() - pixelMapOffset_.GetY() +
2051         (info.originScale.y - info.scale) * info.height / 2.0f);
2052     auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2053     Offset newOffset { touchOffset.GetX() - originPoint.GetX(), touchOffset.GetY() - originPoint.GetY() };
2054     return newOffset;
2055 }
2056 
CalcContentTrationOffset(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2057 Offset DragDropManager::CalcContentTrationOffset(
2058     const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2059 {
2060     auto originPoint = info.originOffset;
2061     auto scalX = info.dragPreviewRect.Width() / info.menuPreviewRect.Width() * info.scale;
2062     originPoint.SetX(originPoint.GetX() - pixelMapOffset_.GetX() + info.menuPreviewRect.Width() * (1 - scalX));
2063     originPoint.SetY(originPoint.GetY() - pixelMapOffset_.GetY());
2064     auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2065     Offset newOffset { touchOffset.GetX() - originPoint.GetX(), touchOffset.GetY() - originPoint.GetY() };
2066     return newOffset;
2067 }
2068 
CalculateNewOffset(const RefPtr<FrameNode> & frameNode,const GestureEvent & event,bool isDragStartPending)2069 Offset DragDropManager::CalculateNewOffset(
2070     const RefPtr<FrameNode>& frameNode, const GestureEvent& event, bool isDragStartPending)
2071 {
2072     Offset newOffset = { 0, 0 };
2073     CHECK_NULL_RETURN(frameNode, newOffset);
2074     auto dragMoveLastPoint = GetDragMoveLastPointByCurrentPointer(event.GetPointerId());
2075     if (frameNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT || !info_.isMenuShow) {
2076         newOffset = isDragStartPending
2077                         ? CalcDragMoveOffset(PRESERVE_HEIGHT, static_cast<int32_t>(dragMoveLastPoint.GetX()),
2078                                              static_cast<int32_t>(dragMoveLastPoint.GetY()), info_)
2079                         : CalcDragMoveOffset(PRESERVE_HEIGHT, static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2080                                              static_cast<int32_t>(event.GetGlobalLocation().GetY()), info_);
2081     }
2082     if ((frameNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2083             frameNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) &&
2084         info_.isMenuShow) {
2085         newOffset =
2086             isDragStartPending
2087                 ? CalcContentTrationOffset(PRESERVE_HEIGHT, static_cast<int32_t>(dragMoveLastPoint.GetX()),
2088                                            static_cast<int32_t>(dragMoveLastPoint.GetY()), info_)
2089                 : CalcContentTrationOffset(PRESERVE_HEIGHT, static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2090                                            static_cast<int32_t>(event.GetGlobalLocation().GetY()), info_);
2091     }
2092     return newOffset;
2093 }
2094 
UpdateDragMovePositionFinished(bool needDoDragMoveAnimate,bool isMenuShow,const Offset & newOffset,int32_t containerId)2095 bool DragDropManager::UpdateDragMovePositionFinished(
2096     bool needDoDragMoveAnimate, bool isMenuShow, const Offset& newOffset, int32_t containerId)
2097 {
2098     if (!isDragWithContextMenu_) {
2099         return false;
2100     }
2101 
2102     CHECK_NULL_RETURN(info_.imageNode, false);
2103     auto renderContext = info_.imageNode->GetRenderContext();
2104     CHECK_NULL_RETURN(renderContext, false);
2105     SubwindowManager::GetInstance()->ContextMenuSwitchDragPreviewAnimation(info_.imageNode,
2106         OffsetF(newOffset.GetX(), newOffset.GetY()));
2107     if (!needDoDragMoveAnimate) {
2108         renderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2109         if (!isMenuShow) {
2110             TransDragWindowToDragFwk(containerId);
2111         }
2112         return true;
2113     }
2114     return false;
2115 }
2116 
GetCurrentDistance(float x,float y)2117 float DragDropManager::GetCurrentDistance(float x, float y)
2118 {
2119     auto distance = sqrt(pow(curPointerOffset_.GetX() - x, 2) + pow(curPointerOffset_.GetY() - y, 2));
2120     CHECK_NULL_RETURN(info_.imageNode, distance);
2121     auto containerId = Container::CurrentId();
2122     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId, SubwindowType::TYPE_MENU);
2123     CHECK_NULL_RETURN(subwindow, distance);
2124     auto overlayManager = subwindow->GetOverlayManager();
2125     auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenter(info_.imageNode);
2126     auto gatherDistance = CalcGatherNodeMaxDistanceWithPoint(overlayManager,
2127         gatherNodeCenter.GetX(), gatherNodeCenter.GetY());
2128     return std::max(distance, gatherDistance);
2129 }
2130 
DoDragMoveAnimate(const DragPointerEvent & pointerEvent)2131 void DragDropManager::DoDragMoveAnimate(const DragPointerEvent& pointerEvent)
2132 {
2133     bool needDoDragMoveAnimate = IsNeedDoDragMoveAnimate(pointerEvent);
2134     if (!needDoDragMoveAnimate) {
2135         return;
2136     }
2137     isPullMoveReceivedForCurrentDrag_ = true;
2138     CHECK_NULL_VOID(info_.imageNode);
2139     auto containerId = Container::CurrentId();
2140     auto x = pointerEvent.GetDisplayX();
2141     auto y = pointerEvent.GetDisplayY();
2142     if (CheckIsUIExtensionBoundary(x, y, containerId) || CheckIsFolderSubwindowBoundary(x, y, containerId)) {
2143         SetStartAnimation(false);
2144         TransDragWindowToDragFwk(containerId);
2145         return;
2146     }
2147     auto overlayManager = GetDragAnimationOverlayManager(containerId);
2148     CHECK_NULL_VOID(overlayManager);
2149     auto point = pointerEvent.GetPoint();
2150     Offset newOffset = { 0, 0 };
2151     if (info_.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT ||
2152         !info_.isMenuShow) {
2153         newOffset = CalcDragMoveOffset(PRESERVE_HEIGHT, point.GetX(), point.GetY(), info_);
2154     }
2155     if ((info_.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2156             info_.imageNode->GetDragPreviewOption().sizeChangeEffect ==
2157             DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) &&
2158         info_.isMenuShow) {
2159         newOffset = CalcContentTrationOffset(PRESERVE_HEIGHT, point.GetX(), point.GetY(), info_);
2160     }
2161     bool isMenuShow = overlayManager->IsMenuShow();
2162     if (UpdateDragMovePositionFinished(needDoDragMoveAnimate, isMenuShow, newOffset, containerId) ||
2163         !needDoDragMoveAnimate) {
2164         return;
2165     }
2166     DragMoveAnimation(newOffset, overlayManager, point);
2167 }
2168 
DragMoveAnimation(const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,Point point)2169 void DragDropManager::DragMoveAnimation(
2170     const Offset& newOffset, const RefPtr<OverlayManager>& overlayManager, Point point)
2171 {
2172     auto containerId = Container::CurrentId();
2173     bool isMenuShow = overlayManager->IsMenuShow();
2174     AnimationOption option;
2175     auto springResponse =
2176         std::max(DEFAULT_SPRING_RESPONSE - DEL_SPRING_RESPONSE * allAnimationCnt_, MIN_SPRING_RESPONSE);
2177     const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(springResponse, 0.99f, 0.0f);
2178     constexpr int32_t animateDuration = 30;
2179     option.SetCurve(curve);
2180     option.SetDuration(animateDuration);
2181     bool dragWithContextMenu = isDragWithContextMenu_;
2182     AddNewDragAnimation();
2183     option.SetOnFinishEvent([weakManager = WeakClaim(this), containerId, dragWithContextMenu, isMenuShow,
2184                                 x = point.GetX(), y = point.GetY()]() {
2185         auto dragDropManager = weakManager.Upgrade();
2186         CHECK_NULL_VOID(dragDropManager);
2187         if ((dragDropManager->IsAllAnimationFinished() ||
2188                 dragDropManager->GetCurrentDistance(x, y) < MAX_DISTANCE_TO_PRE_POINTER) &&
2189             (!dragWithContextMenu || !isMenuShow) && dragDropManager->IsStartAnimationFInished()) {
2190             dragDropManager->SetStartAnimation(false);
2191             dragDropManager->TransDragWindowToDragFwk(containerId);
2192         }
2193     });
2194     auto renderContext = info_.imageNode->GetRenderContext();
2195     CHECK_NULL_VOID(renderContext);
2196     auto offset = OffsetF(point.GetX(), point.GetY());
2197     auto menuWrapperNode = GetMenuWrapperNodeFromDrag();
2198     auto menuPosition = overlayManager->CalculateMenuPosition(menuWrapperNode, offset);
2199     auto menuRenderContext = GetMenuRenderContextFromMenuWrapper(menuWrapperNode);
2200     AnimationUtils::Animate(
2201         option,
2202         [renderContext, localPoint = newOffset, info = info_, overlayManager, menuRenderContext, menuPosition]() {
2203             if (menuRenderContext && !menuPosition.NonOffset()) {
2204                 menuRenderContext->UpdatePosition(
2205                     OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
2206             }
2207             if (info.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT ||
2208                 !info.isMenuShow) {
2209                 renderContext->UpdateTransformTranslate({ localPoint.GetX(), localPoint.GetY(), 0.0f });
2210                 UpdateTextNodePosition(info.textNode, localPoint);
2211                 UpdateGatherNodePosition(overlayManager, info.imageNode);
2212             }
2213         },
2214         option.GetOnFinishEvent());
2215     if (info_.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT ||
2216         !info_.isMenuShow) {
2217         return;
2218     }
2219     DragDropManager::DragMoveTransitionAnimation(overlayManager, info_, option, newOffset);
2220 }
2221 
DragMoveTransitionAnimation(const RefPtr<OverlayManager> & overlayManager,const DragPreviewInfo & info,AnimationOption option,const Offset & newOffset)2222 void DragDropManager::DragMoveTransitionAnimation(const RefPtr<OverlayManager>& overlayManager,
2223     const DragPreviewInfo& info, AnimationOption option, const Offset& newOffset)
2224 {
2225     AddNewDragAnimation();
2226     option.SetCurve(DRAG_TRANSITION_ANIMATION_CURVE);
2227     AnimationUtils::Animate(
2228         option,
2229         [overlayManager, info, newOffset]() {
2230             CHECK_NULL_VOID(overlayManager);
2231             auto relativeContainerNodeRenderContext = info.relativeContainerNode->GetRenderContext();
2232             CHECK_NULL_VOID(relativeContainerNodeRenderContext);
2233             relativeContainerNodeRenderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2234             UpdateGatherNodePosition(overlayManager, info.imageNode);
2235         },
2236         option.GetOnFinishEvent());
2237 }
2238 
UpdateDragPreviewScale()2239 void DragDropManager::UpdateDragPreviewScale()
2240 {
2241     CHECK_NULL_VOID(info_.imageNode);
2242     if (IsNeedDisplayInSubwindow()) {
2243         return;
2244     }
2245     auto renderContext = info_.imageNode->GetRenderContext();
2246     CHECK_NULL_VOID(renderContext);
2247     renderContext->UpdateTransformScale({ info_.scale, info_.scale });
2248 }
2249 
InitDragAnimationPointerEvent(const GestureEvent & event,bool isDragStartPending)2250 void DragDropManager::InitDragAnimationPointerEvent(const GestureEvent& event, bool isDragStartPending)
2251 {
2252     if (isDragStartPending) {
2253         auto dragMoveLastPoint = GetDragMoveLastPointByCurrentPointer(event.GetPointerId());
2254         dragAnimationPointerEvent_ = DragPointerEvent(dragMoveLastPoint.GetX(),
2255             dragMoveLastPoint.GetY(), dragMoveLastPoint.GetScreenX(), dragMoveLastPoint.GetScreenY());
2256         return;
2257     }
2258     dragAnimationPointerEvent_ = DragPointerEvent(event.GetGlobalLocation().GetX(),
2259         event.GetGlobalLocation().GetY(), event.GetScreenLocation().GetX(), event.GetScreenLocation().GetY());
2260 }
2261 
DoDragStartAnimation(const RefPtr<OverlayManager> & overlayManager,const GestureEvent & event,const RefPtr<GestureEventHub> & gestureHub,PreparedInfoForDrag & data)2262 void DragDropManager::DoDragStartAnimation(const RefPtr<OverlayManager>& overlayManager, const GestureEvent& event,
2263     const RefPtr<GestureEventHub>& gestureHub, PreparedInfoForDrag& data)
2264 {
2265     auto containerId = Container::CurrentId();
2266     auto deviceId = static_cast<int32_t>(event.GetDeviceId());
2267     if (deviceId == RESERVED_DEVICEID_1 || deviceId == RESERVED_DEVICEID_2) {
2268         isDragFwkShow_ = false;
2269         TAG_LOGI(AceLogTag::ACE_DRAG, "Do not need animation.");
2270         TransDragWindowToDragFwk(containerId);
2271         return;
2272     }
2273     CHECK_NULL_VOID(overlayManager);
2274     CHECK_NULL_VOID(gestureHub);
2275     bool isDragStartPending = DragDropGlobalController::GetInstance().GetAsyncDragCallback() != nullptr;
2276     if (!(GetDragPreviewInfo(overlayManager, info_, gestureHub, data)) ||
2277         (!IsNeedDisplayInSubwindow() && !data.isMenuShow && !isDragWithContextMenu_ && !isDragStartPending)) {
2278         if (isDragWithContextMenu_) {
2279             UpdateDragPreviewScale();
2280             isDragFwkShow_ = false;
2281         }
2282         return;
2283     }
2284     CHECK_NULL_VOID(info_.imageNode);
2285     isDragFwkShow_ = false;
2286     InitDragAnimationPointerEvent(event, isDragStartPending);
2287     ResetPullMoveReceivedForCurrentDrag();
2288     auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenter(info_.imageNode);
2289     Point point = { static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2290         static_cast<int32_t>(event.GetGlobalLocation().GetY()) };
2291     auto frameNode = gestureHub->GetFrameNode();
2292     Offset newOffset = CalculateNewOffset(frameNode, event, isDragStartPending);
2293     curPointerOffset_ = { newOffset.GetX(), newOffset.GetY() };
2294     currentAnimationCnt_ = 0;
2295     allAnimationCnt_ = 0;
2296     isStartAnimationFinished_ = false;
2297     DragStartAnimation(newOffset, overlayManager, gatherNodeCenter, data, point);
2298 }
2299 
DragStartAnimation(const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,const OffsetF & gatherNodeCenter,PreparedInfoForDrag & data,Point point)2300 void DragDropManager::DragStartAnimation(const Offset& newOffset, const RefPtr<OverlayManager>& overlayManager,
2301     const OffsetF& gatherNodeCenter, PreparedInfoForDrag& data, Point point)
2302 {
2303     CHECK_NULL_VOID(data.imageNode);
2304     auto containerId = Container::CurrentId();
2305     AnimationOption option;
2306     SetDragStartAnimationOption(option, containerId);
2307     AddNewDragStartAnimation();
2308     auto renderContext = info_.imageNode->GetRenderContext();
2309     CHECK_NULL_VOID(renderContext);
2310     auto offset = OffsetF(point.GetX(), point.GetY());
2311     auto menuWrapperNode = GetMenuWrapperNodeFromDrag();
2312     auto menuPosition = overlayManager->CalculateMenuPosition(menuWrapperNode, offset);
2313     auto menuRenderContext = GetMenuRenderContextFromMenuWrapper(menuWrapperNode);
2314     auto callback = [weakManager = WeakClaim(this)](float rate) {
2315         auto dragDropManager = weakManager.Upgrade();
2316         CHECK_NULL_VOID(dragDropManager);
2317         dragDropManager->SetDragStartAnimationRate(rate);
2318     };
2319     auto animateProperty = AceType::MakeRefPtr<NodeAnimatablePropertyFloat>(-1.0, std::move(callback));
2320     CHECK_NULL_VOID(animateProperty);
2321     renderContext->AttachNodeAnimatableProperty(animateProperty);
2322     animateProperty->Set(0.0f);
2323     dragStartAnimationRate_ = 0.0f;
2324     AnimationUtils::Animate(
2325         option,
2326         [data, renderContext, info = info_, newOffset, overlayManager, gatherNodeCenter, menuRenderContext,
2327             menuPosition, animateProperty]() {
2328             CHECK_NULL_VOID(renderContext);
2329             if (menuRenderContext && !menuPosition.NonOffset()) {
2330                 menuRenderContext->UpdatePosition(
2331                     OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
2332             }
2333             if (data.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT ||
2334                 !info.isMenuShow) {
2335                 renderContext->UpdateTransformScale({ info.scale, info.scale });
2336                 renderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2337                 UpdateGatherNodePosition(overlayManager, info.imageNode);
2338                 UpdateTextNodePosition(info.textNode, newOffset);
2339             }
2340             GatherAnimationInfo gatherAnimationInfo = { info.scale, info.width, info.height, gatherNodeCenter,
2341                 renderContext->GetBorderRadius() };
2342             UpdateGatherNodeAttr(overlayManager, gatherAnimationInfo);
2343             if (animateProperty) {
2344                 animateProperty->Set(1.0f);
2345             }
2346         },
2347         option.GetOnFinishEvent());
2348     DragStartTransitionAnimation(data, newOffset, info_, option);
2349 }
2350 
SetDragStartAnimationOption(AnimationOption & option,int32_t containerId)2351 void DragDropManager::SetDragStartAnimationOption(AnimationOption& option, int32_t containerId)
2352 {
2353     const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
2354     constexpr int32_t animateDuration = 300;
2355     option.SetCurve(curve);
2356     option.SetDuration(animateDuration);
2357     option.SetOnFinishEvent([weakManager = WeakClaim(this), containerId]() {
2358         auto dragDropManager = weakManager.Upgrade();
2359         CHECK_NULL_VOID(dragDropManager);
2360         dragDropManager->HandleStartDragAnimationFinish(containerId);
2361     });
2362 }
2363 
HandleStartDragAnimationFinish(int32_t containerId)2364 void DragDropManager::HandleStartDragAnimationFinish(int32_t containerId)
2365 {
2366     if (IsAllStartAnimationFinished()) {
2367         SetStartAnimation(true);
2368     }
2369     if (IsPullMoveReceivedForCurrentDrag()) {
2370         TransDragWindowToDragFwk(containerId);
2371     }
2372     auto overlayManager = GetDragAnimationOverlayManager(containerId);
2373     CHECK_NULL_VOID(overlayManager);
2374     auto gatherNode = overlayManager->GetGatherNode();
2375     CHECK_NULL_VOID(gatherNode);
2376     auto info = overlayManager->GetGatherNodeChildrenInfo();
2377     int cnt = 0;
2378     for (auto iter = info.rbegin(); iter != info.rend(); iter++) {
2379         auto imageNode = (*iter).imageNode.Upgrade();
2380         if (cnt > 1) {
2381             gatherNode->RemoveChild(imageNode);
2382         }
2383         cnt++;
2384     }
2385 }
2386 
DragStartTransitionAnimation(PreparedInfoForDrag & data,const Offset & newOffset,const DragPreviewInfo & info,AnimationOption option)2387 void DragDropManager::DragStartTransitionAnimation(
2388     PreparedInfoForDrag& data, const Offset& newOffset, const DragPreviewInfo& info, AnimationOption option)
2389 {
2390     CHECK_NULL_VOID(data.imageNode);
2391     if ((data.imageNode->GetDragPreviewOption().sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2392             data.imageNode->GetDragPreviewOption().sizeChangeEffect ==
2393             DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) && info_.isMenuShow) {
2394             AddNewDragStartAnimation();
2395             option.SetCurve(DRAG_TRANSITION_ANIMATION_CURVE);
2396             AddNewDragAnimation();
2397             auto callback = [data, relativeContainerNode = data.relativeContainerNode, newOffset, info]() {
2398                 auto relativeContainerRenderContext = relativeContainerNode->GetRenderContext();
2399                 CHECK_NULL_VOID(relativeContainerRenderContext);
2400                 relativeContainerRenderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2401                 auto stack = AceType::DynamicCast<FrameNode>(relativeContainerNode->GetChildAtIndex(0));
2402                 CHECK_NULL_VOID(stack);
2403                 auto stackLayoutProperty = stack->GetLayoutProperty();
2404                 CHECK_NULL_VOID(stackLayoutProperty);
2405                 stackLayoutProperty->UpdateUserDefinedIdealSize({ CalcLength(info.width * info.scale,
2406                     DimensionUnit::PX), CalcLength(info.height * info.scale, DimensionUnit::PX) });
2407                 auto stackRenderContext = stack->GetRenderContext();
2408                 CHECK_NULL_VOID(stackRenderContext);
2409                 if (data.imageNode->GetDragPreviewOption().options.borderRadius.has_value()) {
2410                     stackRenderContext->UpdateBorderRadius(
2411                         data.imageNode->GetDragPreviewOption().options.borderRadius.value());
2412                 } else {
2413                     stackRenderContext->UpdateBorderRadius(BorderRadiusProperty(0.0_vp));
2414                 }
2415                 if (relativeContainerNode->GetDragPreviewOption().sizeChangeEffect ==
2416                     DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) {
2417                     auto stackNode = AceType::DynamicCast<FrameNode>(relativeContainerNode->GetChildByIndex(0));
2418                     CHECK_NULL_VOID(stackNode);
2419                     auto menuPreviewNode = AceType::DynamicCast<FrameNode>(stack->GetChildAtIndex(1));
2420                     CHECK_NULL_VOID(menuPreviewNode);
2421                     auto menuPreviewRenderContext = menuPreviewNode->GetRenderContext();
2422                     CHECK_NULL_VOID(menuPreviewRenderContext);
2423                     menuPreviewRenderContext->UpdateOpacity(0.0f);
2424                     CHECK_NULL_VOID(data.imageNode);
2425                     auto dragPreviewRenderContext = data.imageNode->GetRenderContext();
2426                     CHECK_NULL_VOID(dragPreviewRenderContext);
2427                     dragPreviewRenderContext->UpdateOpacity(data.imageNode->GetDragPreviewOption().options.opacity);
2428                 }
2429                 auto stackContext = stack->GetContext();
2430                 CHECK_NULL_VOID(stackContext);
2431                 stack->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
2432             };
2433             auto pipeline = data.relativeContainerNode->GetContext();
2434             CHECK_NULL_VOID(pipeline);
2435             pipeline->Animate(option, option.GetCurve(), callback, option.GetOnFinishEvent());
2436     }
2437 }
2438 
NotifyEnterTextEditorArea()2439 void DragDropManager::NotifyEnterTextEditorArea()
2440 {
2441     auto ret = InteractionInterface::GetInstance()->EnterTextEditorArea(true);
2442     if (ret != 0) {
2443         TAG_LOGW(AceLogTag::ACE_DRAG, "Fail to notify entering text editor erea.");
2444         return;
2445     }
2446 
2447     hasNotifiedTransformation_ = true;
2448 }
2449 
FireOnEditableTextComponent(const RefPtr<FrameNode> & frameNode,DragEventType type)2450 void DragDropManager::FireOnEditableTextComponent(const RefPtr<FrameNode>& frameNode,
2451     DragEventType type)
2452 {
2453     CHECK_NULL_VOID(frameNode);
2454     auto frameTag = frameNode->GetTag();
2455     auto eventHub = frameNode->GetEventHub<EventHub>();
2456     if (!IsEditableTextComponent(frameTag) || !(eventHub && eventHub->IsEnabled()) || !isDragFwkShow_) {
2457         return;
2458     }
2459 
2460     // When moving in an editable text component whithout animation, and has not notified msdp yet, notify msdp.
2461     if (type == DragEventType::MOVE && IsEditableTextComponent(frameTag) && isDragFwkShow_ &&
2462         !hasNotifiedTransformation_) {
2463         NotifyEnterTextEditorArea();
2464         return;
2465     }
2466     if (type != DragEventType::ENTER && type != DragEventType::LEAVE) {
2467         TAG_LOGD(AceLogTag::ACE_DRAG, "It is an invalid drag type %{public}d", type);
2468         return;
2469     }
2470 
2471     if (type == DragEventType::LEAVE) {
2472         TAG_LOGI(AceLogTag::ACE_DRAG, "The current control has been dragged away.");
2473         hasNotifiedTransformation_ = false;
2474         return;
2475     }
2476 
2477     if (hasNotifiedTransformation_) {
2478         TAG_LOGI(AceLogTag::ACE_DRAG, "Coordinates have been transformed.");
2479         return;
2480     }
2481 
2482     NotifyEnterTextEditorArea();
2483 }
2484 
SetDragResult(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)2485 void DragDropManager::SetDragResult(
2486     const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
2487 {
2488     DragRet result = DragRet::DRAG_FAIL;
2489     switch (notifyMessage.result) {
2490         case DragRet::DRAG_SUCCESS:
2491             result = DragRet::DRAG_SUCCESS;
2492             break;
2493         case DragRet::DRAG_FAIL:
2494             result = DragRet::DRAG_FAIL;
2495             break;
2496         case DragRet::DRAG_CANCEL:
2497             result = DragRet::DRAG_CANCEL;
2498             break;
2499         default:
2500             break;
2501     }
2502     CHECK_NULL_VOID(dragEvent);
2503     dragEvent->SetResult(result);
2504 }
2505 
SetDragBehavior(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)2506 void DragDropManager::SetDragBehavior(
2507     const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
2508 {
2509     DragBehavior dragBehavior = DragBehavior::UNKNOWN;
2510     switch (notifyMessage.dragBehavior) {
2511         case DragBehavior::COPY:
2512             dragBehavior = DragBehavior::COPY;
2513             break;
2514         case DragBehavior::MOVE:
2515             dragBehavior = DragBehavior::MOVE;
2516             break;
2517         default:
2518             break;
2519     }
2520     CHECK_NULL_VOID(dragEvent);
2521     dragEvent->SetDragBehavior(dragBehavior);
2522 }
2523 
UpdateGatherNodeAttr(const RefPtr<OverlayManager> & overlayManager,const GatherAnimationInfo & info)2524 void DragDropManager::UpdateGatherNodeAttr(const RefPtr<OverlayManager>& overlayManager,
2525     const GatherAnimationInfo& info)
2526 {
2527     CHECK_NULL_VOID(overlayManager);
2528     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
2529     BorderRadiusProperty borderRadius;
2530     if (info.borderRadius.has_value()) {
2531         borderRadius = info.borderRadius.value();
2532     }
2533     borderRadius.multiValued = false;
2534     int32_t cnt = static_cast<int>(gatherNodeChildrenInfo.size());
2535     auto scale = info.scale <= 0.0f ? 1.0f : info.scale;
2536     std::vector<std::pair<float, float>> props(cnt, { 0.0, 0.0 });
2537     if (cnt > 0) {
2538         props[cnt - FIRST_GATHER_PIXEL_MAP] = { FIRST_PIXELMAP_ANGLE, FIRST_PIXELMAP_OPACITY };
2539     }
2540     if (cnt > 1) {
2541         props[cnt - SECOND_GATHER_PIXEL_MAP] = { SECOND_PIXELMAP_ANGLE, SECOND_PIXELMAP_OPACITY };
2542     }
2543     for (int32_t i = 0; i < cnt; ++i) {
2544         auto imageNode = gatherNodeChildrenInfo[i].imageNode.Upgrade();
2545         CHECK_NULL_VOID(imageNode);
2546         auto imageContext = imageNode->GetRenderContext();
2547         CHECK_NULL_VOID(imageContext);
2548         auto& childInfo = gatherNodeChildrenInfo[i];
2549         auto updateScale = scale;
2550         if (((childInfo.width > info.width) || (childInfo.height > info.height)) &&
2551             !NearZero(childInfo.width) && !NearZero(childInfo.height)) {
2552             updateScale *= std::min(info.width / childInfo.width, info.height / childInfo.height);
2553         }
2554         imageContext->UpdateTransformScale({ updateScale, updateScale });
2555         imageContext->UpdateBorderRadius(borderRadius);
2556         imageContext->UpdateOpacity(props[i].second);
2557         Vector5F rotate = Vector5F(0.0f, 0.0f, 1.0f, props[i].first, 0.0f);
2558         imageContext->UpdateTransformRotate(rotate);
2559     }
2560 }
2561 
UpdateGatherNodePosition(const RefPtr<OverlayManager> & overlayManager,const RefPtr<FrameNode> & imageNode)2562 void DragDropManager::UpdateGatherNodePosition(const RefPtr<OverlayManager>& overlayManager,
2563     const RefPtr<FrameNode>& imageNode)
2564 {
2565     CHECK_NULL_VOID(imageNode);
2566     CHECK_NULL_VOID(overlayManager);
2567     auto gatherNode = overlayManager->GetGatherNode();
2568     CHECK_NULL_VOID(gatherNode);
2569     auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenterToScreen(imageNode);
2570     gatherNodeCenter -= DragDropFuncWrapper::GetCurrentWindowOffset(gatherNode->GetContextRefPtr());
2571     OffsetF offset;
2572     auto info = overlayManager->GetGatherNodeChildrenInfo();
2573     for (auto iter = info.rbegin(); iter != info.rend(); iter++) {
2574         auto& child = (*iter);
2575         auto imageNode = child.imageNode.Upgrade();
2576         CHECK_NULL_VOID(imageNode);
2577         offset.SetX(gatherNodeCenter.GetX() - child.halfWidth);
2578         offset.SetY(gatherNodeCenter.GetY() - child.halfHeight);
2579         DragDropFuncWrapper::UpdateNodePositionToWindow(imageNode, offset);
2580     }
2581 }
2582 
UpdateTextNodePosition(const RefPtr<FrameNode> & textNode,const Offset & localPoint)2583 void DragDropManager::UpdateTextNodePosition(const RefPtr<FrameNode>& textNode, const Offset& localPoint)
2584 {
2585     CHECK_NULL_VOID(textNode);
2586     auto textRenderContext = textNode->GetRenderContext();
2587     CHECK_NULL_VOID(textRenderContext);
2588     textRenderContext->UpdateTransformTranslate({ localPoint.GetX(), localPoint.GetY(), 0.0f });
2589 }
2590 
CalcGatherNodeMaxDistanceWithPoint(const RefPtr<OverlayManager> & overlayManager,int32_t x,int32_t y)2591 double DragDropManager::CalcGatherNodeMaxDistanceWithPoint(const RefPtr<OverlayManager>& overlayManager,
2592     int32_t x, int32_t y)
2593 {
2594     CHECK_NULL_RETURN(overlayManager, 0.0f);
2595     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
2596     double maxDistance = 0.0;
2597     for (const auto& child : gatherNodeChildrenInfo) {
2598         auto imageNode = child.imageNode.Upgrade();
2599         CHECK_NULL_RETURN(imageNode, 0.0f);
2600         auto imageContext = imageNode->GetRenderContext();
2601         CHECK_NULL_RETURN(imageContext, 0.0f);
2602         auto renderPosition = imageContext->GetPropertyOfPosition();
2603         double dis = sqrt(pow(renderPosition.GetX() + child.halfWidth - x, SQUARE_NUMBER) +
2604             pow(renderPosition.GetY() + child.halfHeight - y, SQUARE_NUMBER));
2605         maxDistance = std::max(maxDistance, dis);
2606     }
2607     return maxDistance;
2608 }
2609 
IsNeedDisplayInSubwindow()2610 bool DragDropManager::IsNeedDisplayInSubwindow()
2611 {
2612     if (IsNeedScaleDragPreview()) {
2613         return true;
2614     }
2615     auto overlayManager = GetDragAnimationOverlayManager(Container::CurrentId());
2616     CHECK_NULL_RETURN(overlayManager, false);
2617     auto gatherNode = overlayManager->GetGatherNode();
2618     return gatherNode != nullptr;
2619 }
2620 
PushGatherPixelMap(const RefPtr<PixelMap> & pixelMap)2621 void DragDropManager::PushGatherPixelMap(const RefPtr<PixelMap>& pixelMap)
2622 {
2623     gatherPixelMaps_.push_back(pixelMap);
2624 }
2625 
GetGatherPixelMap(DragDataCore & dragData,float scale,float previewWidth,float previewHeight)2626 void DragDropManager::GetGatherPixelMap(
2627     DragDataCore& dragData, float scale, float previewWidth, float previewHeight)
2628 {
2629     for (const auto& gatherPixelMap : gatherPixelMaps_) {
2630         RefPtr<PixelMap> pixelMapDuplicated = gatherPixelMap;
2631 #if defined(PIXEL_MAP_SUPPORTED)
2632         pixelMapDuplicated = PixelMap::CopyPixelMap(gatherPixelMap);
2633         if (!pixelMapDuplicated) {
2634             TAG_LOGW(AceLogTag::ACE_DRAG, "Copy PixelMap is failure!");
2635             pixelMapDuplicated = gatherPixelMap;
2636         }
2637 #endif
2638         CHECK_NULL_VOID(pixelMapDuplicated);
2639         auto width = pixelMapDuplicated->GetWidth() * scale;
2640         auto height = pixelMapDuplicated->GetHeight() * scale;
2641         auto updateScale = scale;
2642         if (((width > previewWidth) || (height > previewHeight)) && !NearZero(width) && !NearZero(height)) {
2643             updateScale *= std::min(previewWidth / width, previewHeight / height);
2644         }
2645         pixelMapDuplicated->Scale(updateScale, updateScale, AceAntiAliasingOption::HIGH);
2646         dragData.shadowInfos.push_back({pixelMapDuplicated, 0.0f, 0.0f});
2647     }
2648     gatherPixelMaps_.clear();
2649     return;
2650 }
2651 
ResetDragDrop(int32_t windowId,const Point & point)2652 void DragDropManager::ResetDragDrop(int32_t windowId, const Point& point)
2653 {
2654     DragDropRet dragDropRet { DragRet::DRAG_FAIL, isMouseDragged_, windowId, DragBehavior::UNKNOWN };
2655     HideDragPreviewOverlay();
2656     ClearVelocityInfo();
2657     ResetDragDropStatus(point, dragDropRet, windowId);
2658     dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
2659 }
2660 
FireOnDragLeave(const RefPtr<FrameNode> & preTargetFrameNode,const DragPointerEvent & pointerEvent,const std::string & extraInfo)2661 void DragDropManager::FireOnDragLeave(
2662     const RefPtr<FrameNode>& preTargetFrameNode, const DragPointerEvent& pointerEvent, const std::string& extraInfo)
2663 {
2664     auto point = pointerEvent.GetPoint();
2665     if (preTargetFrameNode) {
2666         auto preRect = preTargetFrameNode->GetTransformRectRelativeToWindow();
2667         // If the point is out of the pre node, it means we are totally inside a new node, notify leave anyway
2668         if (!preRect.IsInnerRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
2669             FireOnDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE, extraInfo);
2670             return;
2671         }
2672 
2673         // If reach here, it means we are entering one new node's area, but without leaving the area of the pre
2674         // one, this usually happens when moving from parent into its child.
2675         // Check the configuration to decide the notify to parent node.
2676         if (eventStrictReportingEnabled_) {
2677             FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo);
2678         }
2679     }
2680 }
2681 
IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode> & node)2682 bool DragDropManager::IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode>& node)
2683 {
2684 #ifdef WINDOW_SCENE_SUPPORTED
2685     CHECK_NULL_RETURN(node, true);
2686     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2687     CHECK_NULL_RETURN(pipeline, true);
2688     auto manager = pipeline->GetUIExtensionManager();
2689     CHECK_NULL_RETURN(manager, true);
2690     return manager->IsShowPlaceholder(node->GetId());
2691 #endif
2692     return true;
2693 }
2694 
UpdateDragMovePosition(const NG::OffsetF & offset,bool isRedragStart)2695 void DragDropManager::UpdateDragMovePosition(const NG::OffsetF& offset, bool isRedragStart)
2696 {
2697     if (isRedragStart) {
2698         ResetContextMenuRedragPosition();
2699     }
2700     lastDragMovePosition_ = dragMovePosition_;
2701     dragMovePosition_ = offset;
2702     if (lastDragMovePosition_.NonOffset()) {
2703         return;
2704     }
2705     dragTotalMovePosition_ += (dragMovePosition_ - lastDragMovePosition_);
2706 }
2707 
IsUIExtensionComponent(const RefPtr<NG::UINode> & node)2708 bool DragDropManager::IsUIExtensionComponent(const RefPtr<NG::UINode>& node)
2709 {
2710     CHECK_NULL_RETURN(node, false);
2711     return (V2::UI_EXTENSION_COMPONENT_ETS_TAG == node->GetTag() || V2::EMBEDDED_COMPONENT_ETS_TAG == node->GetTag()) &&
2712            (!IsUIExtensionShowPlaceholder(node));
2713 }
2714 
HandleUIExtensionDragEvent(const RefPtr<FrameNode> & frameNode,const DragPointerEvent & pointerEvent,DragEventType type)2715 void DragDropManager::HandleUIExtensionDragEvent(
2716     const RefPtr<FrameNode>& frameNode, const DragPointerEvent& pointerEvent, DragEventType type)
2717 {
2718     CHECK_NULL_VOID(frameNode);
2719     auto pattern = frameNode->GetPattern<Pattern>();
2720     CHECK_NULL_VOID(pattern);
2721 
2722     auto dragEvent = pointerEvent;
2723     if (type == DragEventType::ENTER) {
2724         dragEvent.action = PointerAction::PULL_IN_WINDOW;
2725     } else if (type == DragEventType::LEAVE) {
2726         dragEvent.action = PointerAction::PULL_OUT_WINDOW;
2727     } else if (type == DragEventType::PULL_CANCEL) {
2728         dragEvent.action = PointerAction::PULL_CANCEL;
2729     }
2730     pattern->HandleDragEvent(dragEvent);
2731 }
2732 
GetMenuPreviewRect()2733 RectF DragDropManager::GetMenuPreviewRect()
2734 {
2735     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
2736     CHECK_NULL_RETURN(pipelineContext, RectF());
2737     auto dragDropManager = pipelineContext->GetDragDropManager();
2738     CHECK_NULL_RETURN(dragDropManager, RectF());
2739     auto menuWrapperNode = dragDropManager->GetMenuWrapperNode();
2740     CHECK_NULL_RETURN(menuWrapperNode, RectF());
2741     auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
2742     CHECK_NULL_RETURN(menuWrapperPattern, RectF());
2743     auto menuPreview = menuWrapperPattern->GetPreview();
2744     CHECK_NULL_RETURN(menuPreview, RectF());
2745     auto previewPaintRect = DragDropFuncWrapper::GetPaintRectToScreen(menuPreview);
2746     previewPaintRect -= DragDropFuncWrapper::GetCurrentWindowOffset(pipelineContext);
2747     return previewPaintRect;
2748 }
2749 
GetMaxWidthBaseOnGridSystem(const RefPtr<PipelineBase> & pipeline)2750 double DragDropManager::GetMaxWidthBaseOnGridSystem(const RefPtr<PipelineBase>& pipeline)
2751 {
2752     auto context = DynamicCast<NG::PipelineContext>(pipeline);
2753     CHECK_NULL_RETURN(context, -1.0f);
2754     auto dragDropMgr = context->GetDragDropManager();
2755     CHECK_NULL_RETURN(dragDropMgr, -1.0f);
2756     auto& columnInfo = dragDropMgr->columnInfo_;
2757     if (!columnInfo) {
2758         columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::DRAG_PANEL);
2759         auto gridContainer = columnInfo->GetParent();
2760         if (gridContainer) {
2761             auto rootWidth = context->GetRootWidth();
2762             if (LessOrEqual(rootWidth, 0.0)) {
2763                 auto mainPipeline = PipelineContext::GetMainPipelineContext();
2764                 rootWidth = GridSystemManager::GetInstance().GetScreenWidth(mainPipeline);
2765             }
2766             // cannot handle multi-screen
2767             gridContainer->BuildColumnWidth(rootWidth);
2768         }
2769         dragDropMgr->columnInfo_ = columnInfo;
2770     }
2771 
2772     auto gridSizeType = GridSystemManager::GetInstance().GetCurrentSize();
2773     if (gridSizeType > GridSizeType::LG) {
2774         gridSizeType = GridSizeType::LG;
2775     }
2776     if (gridSizeType < GridSizeType::SM) {
2777         gridSizeType = GridSizeType::SM;
2778     }
2779     auto columns = columnInfo->GetColumns(gridSizeType);
2780     double maxWidth = columnInfo->GetWidth(columns);
2781     return maxWidth;
2782 }
2783 
GetScaleInfo(float width,float height,bool textDraggable)2784 std::shared_ptr<ScaleDataInfo> DragDropManager::GetScaleInfo(float width, float height, bool textDraggable)
2785 {
2786     auto scaleDataInfo = std::make_shared<ScaleDataInfo>();
2787     CHECK_NULL_RETURN(scaleDataInfo, nullptr);
2788     scaleDataInfo->shortSide = fmin(SystemProperties::GetDeviceHeight(), SystemProperties::GetDeviceWidth());
2789     auto shortSide = PipelineBase::Px2VpWithCurrentDensity(scaleDataInfo->shortSide);
2790     if (shortSide <= DEVICE_TYPE_UNKOWN) {
2791         return scaleDataInfo;
2792     } else if (shortSide <= DEVICE_TYPE_SMALL) {
2793         scaleDataInfo = DragDropManager::CalculateScale(width, height,
2794             textDraggable ? scaleDataInfo->shortSide : scaleDataInfo->shortSide / SCALE_TYPE_FIRST,
2795             scaleDataInfo->shortSide / SCALE_TYPE_FIRST);
2796     } else if (shortSide <= DEVICE_TYPE_MEDIUM) {
2797         scaleDataInfo = CalculateScale(width, height,
2798             textDraggable ? scaleDataInfo->shortSide / SCALE_TYPE_FIRST : scaleDataInfo->shortSide / SCALE_TYPE_THIRD,
2799             scaleDataInfo->shortSide / SCALE_TYPE_THIRD);
2800     } else {
2801         scaleDataInfo = CalculateScale(width, height,
2802             textDraggable ? scaleDataInfo->shortSide * SCALE_TYPE_FIRST / SCALE_TYPE_SECOND
2803                           : scaleDataInfo->shortSide / SCALE_TYPE_SECOND,
2804             scaleDataInfo->shortSide / SCALE_TYPE_SECOND);
2805     }
2806     return scaleDataInfo;
2807 }
2808 
CalculateScale(float width,float height,float widthLimit,float heightLimit)2809 std::shared_ptr<ScaleDataInfo> DragDropManager::CalculateScale(
2810     float width, float height, float widthLimit, float heightLimit)
2811 {
2812     auto scaleDataInfo = std::make_shared<ScaleDataInfo>();
2813     CHECK_NULL_RETURN(scaleDataInfo, nullptr);
2814     if ((width > 0 && height > 0) && (width > widthLimit || height > heightLimit)) {
2815         scaleDataInfo->scale = fmin(widthLimit / width, heightLimit / height);
2816         scaleDataInfo->isNeedScale = true;
2817     }
2818     return scaleDataInfo;
2819 }
2820 
GetDragAnimationOverlayManager(int32_t containerId)2821 const RefPtr<NG::OverlayManager> DragDropManager::GetDragAnimationOverlayManager(int32_t containerId)
2822 {
2823     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId >= MIN_SUBCONTAINER_ID ?
2824         SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId, SubwindowType::TYPE_MENU);
2825     CHECK_NULL_RETURN(subwindow, nullptr);
2826     return subwindow->GetOverlayManager();
2827 }
2828 
RemoveDragFrameNode(int32_t id)2829 void DragDropManager::RemoveDragFrameNode(int32_t id)
2830 {
2831     dragFrameNodes_.erase(id);
2832     gridDragFrameNodes_.erase(id);
2833     listDragFrameNodes_.erase(id);
2834     textFieldDragFrameNodes_.erase(id);
2835 }
2836 
SetIsDragged(bool isDragged)2837 void DragDropManager::SetIsDragged(bool isDragged)
2838 {
2839     if (isDragged && isDragged_ != isDragged && notifyInDraggedCallback_) {
2840         notifyInDraggedCallback_();
2841     }
2842     isDragged_ = isDragged;
2843 }
2844 
RegisterDragStatusListener(int32_t nodeId,const WeakPtr<FrameNode> & node)2845 void DragDropManager::RegisterDragStatusListener(int32_t nodeId, const WeakPtr<FrameNode>& node)
2846 {
2847     auto ret = nodesForDragNotify_.try_emplace(nodeId, node);
2848     if (!ret.second) {
2849         nodesForDragNotify_[nodeId] = node;
2850     }
2851 }
2852 
RegisterPullEventListener(int32_t uniqueIdentify,std::function<void (const DragPointerEvent &)> callback)2853 void DragDropManager::RegisterPullEventListener(
2854     int32_t uniqueIdentify, std::function<void(const DragPointerEvent&)> callback)
2855 {
2856     pullEventListener_[uniqueIdentify] = callback;
2857 }
2858 
UnRegisterPullEventListener(int32_t uniqueIdentify)2859 void DragDropManager::UnRegisterPullEventListener(int32_t uniqueIdentify)
2860 {
2861     auto it = pullEventListener_.find(uniqueIdentify);
2862     if (it != pullEventListener_.end()) {
2863         pullEventListener_.erase(it);
2864     }
2865 }
2866 
NotifyPullEventListener(const DragPointerEvent & pointerEvent)2867 void DragDropManager::NotifyPullEventListener(const DragPointerEvent& pointerEvent)
2868 {
2869     if (pullEventListener_.empty()) {
2870         return;
2871     }
2872     for (const auto& pair : pullEventListener_) {
2873         if (pair.second) {
2874             pair.second(pointerEvent);
2875         }
2876     }
2877 }
2878 
IsDraggingPressed(int32_t currentPointerId) const2879 bool DragDropManager::IsDraggingPressed(int32_t currentPointerId) const
2880 {
2881     if (currentPointerId_ == currentPointerId) {
2882         return draggingPressedState_;
2883     }
2884     return false;
2885 }
2886 
ResetContextMenuDragPosition()2887 void DragDropManager::ResetContextMenuDragPosition()
2888 {
2889     dragMovePosition_.Reset();
2890     lastDragMovePosition_.Reset();
2891     dragTotalMovePosition_.Reset();
2892 }
2893 
ResetContextMenuRedragPosition()2894 void DragDropManager::ResetContextMenuRedragPosition()
2895 {
2896     dragMovePosition_.Reset();
2897     lastDragMovePosition_.Reset();
2898 }
2899 
AddNewDragAnimation()2900 void DragDropManager::AddNewDragAnimation()
2901 {
2902     currentAnimationCnt_++;
2903     allAnimationCnt_++;
2904 }
2905 
AddNewDragStartAnimation()2906 void DragDropManager::AddNewDragStartAnimation()
2907 {
2908     currentStartAnimationCnt_++;
2909     allStartAnimationCnt_++;
2910 }
2911 
IsAllAnimationFinished()2912 bool DragDropManager::IsAllAnimationFinished()
2913 {
2914     currentAnimationCnt_--;
2915     return currentAnimationCnt_ == 0;
2916 }
2917 
IsAllStartAnimationFinished()2918 bool DragDropManager::IsAllStartAnimationFinished()
2919 {
2920     currentStartAnimationCnt_--;
2921     return currentStartAnimationCnt_ == 0;
2922 }
2923 
CheckIsNewDrag(const DragPointerEvent & pointerEvent) const2924 bool DragDropManager::CheckIsNewDrag(const DragPointerEvent& pointerEvent) const
2925 {
2926     return (pointerEvent.pullId != -1) && (pointerEvent.pullId != currentPullId_);
2927 }
2928 
RequireSummaryIfNecessary(const DragPointerEvent & pointerEvent)2929 void DragDropManager::RequireSummaryIfNecessary(const DragPointerEvent& pointerEvent)
2930 {
2931     if (CheckIsNewDrag(pointerEvent)) {
2932         currentPullId_ = pointerEvent.pullId;
2933         RequireSummary();
2934     }
2935 }
2936 
IsAnyDraggableHit(const RefPtr<PipelineBase> & pipeline,int32_t pointId)2937 bool DragDropManager::IsAnyDraggableHit(const RefPtr<PipelineBase>& pipeline, int32_t pointId)
2938 {
2939     if (isAnyDraggableHit_) {
2940         return true;
2941     }
2942 
2943     auto pipelineContext = AceType::DynamicCast<PipelineContext>(pipeline);
2944     CHECK_NULL_RETURN(pipelineContext, false);
2945     auto eventManager = pipelineContext->GetEventManager();
2946     CHECK_NULL_RETURN(eventManager, false);
2947     auto touchTestResults = eventManager->touchTestResults_;
2948     const auto iter = touchTestResults.find(pointId);
2949     if (iter == touchTestResults.end() || iter->second.empty()) {
2950         TAG_LOGI(AceLogTag::ACE_DRAG, "touch test result is empty.");
2951         return false;
2952     }
2953     for (const auto& touchTestResult : iter->second) {
2954         auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(touchTestResult);
2955         if (recognizer) {
2956             continue;
2957         }
2958         auto node = touchTestResult->GetAttachedNode().Upgrade();
2959         CHECK_NULL_RETURN(node, false);
2960         if (IsUIExtensionComponent(node)) {
2961             return true;
2962         }
2963     }
2964     return false;
2965 }
2966 
CancelUDMFDataLoading(const std::string & key)2967 int32_t DragDropManager::CancelUDMFDataLoading(const std::string& key)
2968 {
2969     return UdmfClient::GetInstance()->Cancel(key);
2970 }
2971 
CheckIsFolderSubwindowBoundary(float x,float y,int32_t instanceId)2972 bool DragDropManager::CheckIsFolderSubwindowBoundary(float x, float y, int32_t instanceId)
2973 {
2974     if (!SystemProperties::IsSuperFoldDisplayDevice() || NearZero(info_.scale)) {
2975         return false;
2976     }
2977     auto mainContainerId = instanceId >= MIN_SUBCONTAINER_ID ?
2978         SubwindowManager::GetInstance()->GetParentContainerId(instanceId) : instanceId;
2979     auto container = Container::GetContainer(mainContainerId);
2980     CHECK_NULL_RETURN(container, false);
2981     if (container->GetCurrentFoldStatus() == FoldStatus::EXPAND) {
2982         return false;
2983     }
2984     auto isCrossWindow = container->IsCrossAxisWindow();
2985     auto isScenceBoard = container->IsScenceBoardWindow();
2986     if (isCrossWindow || isScenceBoard) {
2987         return false;
2988     }
2989     auto subwindow = SubwindowManager::GetInstance()->GetCurrentWindow();
2990     CHECK_NULL_RETURN(subwindow, false);
2991     auto rect = subwindow->GetWindowRect();
2992     auto scale = dragStartAnimationRate_ * (info_.scale - info_.originScale.y) + info_.originScale.y;
2993     OffsetF pixelMapOffset = pixelMapOffset_ / info_.scale * scale;
2994     float top = y + pixelMapOffset.GetY();
2995     float bottom = y + pixelMapOffset.GetY() + info_.height * scale;
2996     float distance = std::min(top - rect.Top(), rect.Bottom() - bottom);
2997     return distance < MIN_FOLDER_SUBWINDOW_BOUNDARY_DISTANCE;
2998 }
2999 
CheckIsUIExtensionBoundary(float x,float y,int32_t instanceId)3000 bool DragDropManager::CheckIsUIExtensionBoundary(float x, float y, int32_t instanceId)
3001 {
3002     auto container = Container::GetContainer(instanceId);
3003     CHECK_NULL_RETURN(container, false);
3004     if (!container->IsUIExtensionWindow()) {
3005         return false;
3006     }
3007     auto pipeline = container->GetPipelineContext();
3008     CHECK_NULL_RETURN(pipeline, false);
3009     auto rect = pipeline->GetCurrentWindowRect();
3010     auto distance = std::min(std::min(x - rect.Left(), rect.Right() - x),
3011         std::min(y - rect.Top(), rect.Bottom() - y));
3012     return distance < MIN_UI_EXTENSION_BOUNDARY_DISTANCE;
3013 }
3014 
GetFinalDragPreviewRect(const RefPtr<FrameNode> & imageNode,DragPreviewInfo & dragPreviewInfo,const RefPtr<OverlayManager> & overlayManager)3015 RectF DragDropManager::GetFinalDragPreviewRect(const RefPtr<FrameNode>& imageNode,
3016     DragPreviewInfo& dragPreviewInfo, const RefPtr<OverlayManager>& overlayManager)
3017 {
3018     RectF finalRect;
3019     CHECK_NULL_RETURN(overlayManager, finalRect);
3020     CHECK_NULL_RETURN(imageNode, finalRect);
3021     auto dragPreviewOption = imageNode->GetDragPreviewOption();
3022     if (dragPreviewOption.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT || !dragPreviewInfo.isMenuShow) {
3023         finalRect = imageNode->GetGeometryNode()->GetFrameRect();
3024     } else if ((dragPreviewOption.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
3025                    dragPreviewOption.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) &&
3026                dragPreviewInfo.isMenuShow) {
3027         auto relativeContainerNode = overlayManager->GetRelativeContainerNode();
3028         CHECK_NULL_RETURN(relativeContainerNode, finalRect);
3029         dragPreviewInfo.relativeContainerNode = relativeContainerNode;
3030         finalRect = info_.dragPreviewRect;
3031     }
3032     return finalRect;
3033 }
3034 } // namespace OHOS::Ace::NG
3035