• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
17 
18 #include "core/common/ace_engine.h"
19 #include "core/common/udmf/udmf_client.h"
20 #include "core/components/common/layout/grid_system_manager.h"
21 #include "core/components/select/select_theme.h"
22 #include "core/components/theme/blur_style_theme.h"
23 #include "core/components/theme/shadow_theme.h"
24 #include "core/components_ng/base/inspector.h"
25 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
26 #include "core/components_ng/manager/drag_drop/drag_drop_global_controller.h"
27 #include "core/components_ng/pattern/grid/grid_item_pattern.h"
28 #include "core/components_ng/pattern/image/image_pattern.h"
29 #include "core/components_ng/pattern/list/list_item_pattern.h"
30 #include "core/components_ng/pattern/text/text_pattern.h"
31 #include "core/components_ng/render/adapter/component_snapshot.h"
32 
33 namespace OHOS::Ace::NG {
34 namespace {
35 constexpr float DEFAULT_OPACITY = 0.95f;
36 constexpr Dimension PREVIEW_BORDER_RADIUS = 12.0_vp;
37 constexpr float BLUR_SIGMA_SCALE = 0.57735f;
38 constexpr float SCALE_HALF = 0.5f;
39 constexpr float MIN_OPACITY { 0.0f };
40 constexpr float MAX_OPACITY { 1.0f };
41 using DragNotifyMsg = OHOS::Ace::DragNotifyMsg;
42 using OnDragCallback = std::function<void(const DragNotifyMsg&)>;
43 using StopDragCallback = std::function<void()>;
44 constexpr int32_t MOUSE_POINTER_ID = 1001;
45 constexpr int32_t SOURCE_TOOL_PEN = 2;
46 constexpr int32_t SOURCE_TYPE_TOUCH = 2;
47 constexpr int32_t PEN_POINTER_ID = 102;
48 constexpr int32_t SOURCE_TYPE_MOUSE = 1;
49 constexpr size_t SHORT_KEY_LENGTH = 8;
50 constexpr size_t PLAINTEXT_LENGTH = 4;
51 constexpr size_t  CONVERT_TIME_BASE = 1000;
52 #if defined(PIXEL_MAP_SUPPORTED)
53 constexpr int32_t CREATE_PIXELMAP_TIME = 80;
54 #endif
55 }
56 
CheckInternalDragging(const RefPtr<Container> & container)57 static bool CheckInternalDragging(const RefPtr<Container>& container)
58 {
59     CHECK_NULL_RETURN(container, false);
60     auto pipelineContext = container->GetPipelineContext();
61     if (!pipelineContext || !pipelineContext->IsDragging()) {
62         return false;
63     }
64     return true;
65 }
66 
GetShadowInfoArray(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::vector<ShadowInfoCore> & shadowInfos)67 void GetShadowInfoArray(
68     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, std::vector<ShadowInfoCore>& shadowInfos)
69 {
70     auto minScaleWidth = NG::DragDropFuncWrapper::GetScaleWidth(dragAction->instanceId);
71     for (auto& pixelMap : dragAction->pixelMapList) {
72         double scale = 1.0;
73         if (Referenced::RawPtr(pixelMap)) {
74             if (pixelMap->GetWidth() > minScaleWidth && dragAction->previewOption.isScaleEnabled) {
75                 scale = minScaleWidth / pixelMap->GetWidth();
76             }
77             auto pixelMapScale = dragAction->windowScale * scale;
78             pixelMap->Scale(pixelMapScale, pixelMapScale, AceAntiAliasingOption::HIGH);
79         }
80         int32_t width = pixelMap->GetWidth();
81         int32_t height = pixelMap->GetHeight();
82         double x = dragAction->touchPointX;
83         double y = dragAction->touchPointY;
84         if (!dragAction->hasTouchPoint) {
85             x = -width * PIXELMAP_WIDTH_RATE;
86             y = -height * PIXELMAP_HEIGHT_RATE;
87         }
88         ShadowInfoCore shadowInfo { pixelMap, -x, -y };
89         shadowInfos.push_back(shadowInfo);
90     }
91 }
92 
PostStopDrag(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container)93 void PostStopDrag(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, const RefPtr<Container>& container)
94 {
95     CHECK_NULL_VOID(container);
96     auto taskExecutor = container->GetTaskExecutor();
97     CHECK_NULL_VOID(taskExecutor);
98     auto windowId = container->GetWindowId();
99     taskExecutor->PostTask(
100         [dragAction, windowId]() {
101             CHECK_NULL_VOID(dragAction);
102             TAG_LOGI(AceLogTag::ACE_DRAG, "drag state is reject, stop drag, windowId is %{public}d.", windowId);
103             OHOS::Ace::DragDropRet dropResult { OHOS::Ace::DragRet::DRAG_CANCEL, false, windowId,
104                 OHOS::Ace::DragBehavior::UNKNOWN };
105             InteractionInterface::GetInstance()->StopDrag(dropResult);
106             InteractionInterface::GetInstance()->SetDragWindowVisible(false);
107         },
108         TaskExecutor::TaskType::UI, "ArkUIDragStop");
109 }
110 
ConfirmCurPointerEventInfo(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container)111 bool ConfirmCurPointerEventInfo(
112     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, const RefPtr<Container>& container)
113 {
114     CHECK_NULL_RETURN(dragAction, false);
115     CHECK_NULL_RETURN(container, false);
116     StopDragCallback stopDragCallback = [dragAction, container]() {
117         CHECK_NULL_VOID(dragAction);
118         CHECK_NULL_VOID(container);
119         bool needPostStopDrag = false;
120         if (dragAction->dragState == DragAdapterState::SENDING) {
121             needPostStopDrag = true;
122         }
123         {
124             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
125             dragAction->dragState = DragAdapterState::REJECT;
126         }
127         if (needPostStopDrag) {
128             PostStopDrag(dragAction, container);
129         }
130     };
131     bool getPointSuccess = container->GetCurPointerEventInfo(dragAction->dragPointerEvent,
132         std::move(stopDragCallback));
133     if (dragAction->dragPointerEvent.sourceType == SOURCE_TYPE_MOUSE) {
134         dragAction->dragPointerEvent.pointerId = MOUSE_POINTER_ID;
135     } else if (dragAction->dragPointerEvent.sourceType == SOURCE_TYPE_TOUCH &&
136         static_cast<int32_t>(dragAction->dragPointerEvent.sourceTool) == SOURCE_TOOL_PEN) {
137         dragAction->dragPointerEvent.pointerId = PEN_POINTER_ID;
138     }
139     return getPointSuccess;
140 }
141 
EnvelopedDragData(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,std::optional<DragDataCore> & dragData)142 void EnvelopedDragData(
143     std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction, std::optional<DragDataCore>& dragData)
144 {
145     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
146     CHECK_NULL_VOID(container);
147 
148     std::vector<ShadowInfoCore> shadowInfos;
149     GetShadowInfoArray(dragAction, shadowInfos);
150     if (shadowInfos.empty()) {
151         TAG_LOGE(AceLogTag::ACE_DRAG, "shadowInfo array is empty");
152         return;
153     }
154     auto pointerId = dragAction->dragPointerEvent.pointerId;
155     std::string udKey;
156     std::map<std::string, int64_t> summary;
157     int32_t dataSize = 1;
158     if (dragAction->unifiedData) {
159         int32_t ret = UdmfClient::GetInstance()->SetData(dragAction->unifiedData, udKey);
160         if (ret != 0) {
161             TAG_LOGI(AceLogTag::ACE_DRAG, "udmf set data failed, return value is %{public}d", ret);
162         } else {
163             ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
164             if (ret != 0) {
165                 TAG_LOGI(AceLogTag::ACE_DRAG, "get summary failed, return value is %{public}d", ret);
166             }
167         }
168         dataSize = static_cast<int32_t>(dragAction->unifiedData->GetSize());
169     }
170     int32_t recordSize = (dataSize != 0 ? dataSize : static_cast<int32_t>(shadowInfos.size()));
171     if (dragAction->previewOption.isNumber) {
172         recordSize = dragAction->previewOption.badgeNumber > 1 ? dragAction->previewOption.badgeNumber : 1;
173     } else if (!dragAction->previewOption.isShowBadge) {
174         recordSize = 1;
175     }
176     auto windowId = container->GetWindowId();
177     auto arkExtraInfoJson = JsonUtil::Create(true);
178     auto pipeline = container->GetPipelineContext();
179     CHECK_NULL_VOID(pipeline);
180     dragAction->dipScale = pipeline->GetDipScale();
181     arkExtraInfoJson->Put("dip_scale", dragAction->dipScale);
182     arkExtraInfoJson->Put("event_id", dragAction->dragPointerEvent.pointerEventId);
183     NG::DragDropFuncWrapper::UpdateExtraInfo(arkExtraInfoJson, dragAction->previewOption);
184     dragData = { shadowInfos, {}, udKey, dragAction->extraParams, arkExtraInfoJson->ToString(),
185         dragAction->dragPointerEvent.sourceType, recordSize, pointerId,
186         static_cast<int32_t>(dragAction->dragPointerEvent.sourceTool), dragAction->dragPointerEvent.displayX,
187         dragAction->dragPointerEvent.displayY, dragAction->dragPointerEvent.displayId, windowId, true, false,
188         summary };
189 }
190 
HandleCallback(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const OHOS::Ace::DragNotifyMsg & dragNotifyMsg,const DragAdapterStatus & dragStatus)191 void HandleCallback(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
192     const OHOS::Ace::DragNotifyMsg& dragNotifyMsg, const DragAdapterStatus& dragStatus)
193 {
194     TAG_LOGI(AceLogTag::ACE_DRAG, "drag notify message result is %{public}d.", dragNotifyMsg.result);
195     CHECK_NULL_VOID(dragAction);
196     bool hasHandle = false;
197     {
198         std::lock_guard<std::mutex> lock(dragAction->mutex);
199         hasHandle = dragAction->hasHandle;
200         dragAction->hasHandle = true;
201     }
202     if (hasHandle) {
203         return;
204     }
205     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
206     CHECK_NULL_VOID(container);
207     if (dragStatus == DragAdapterStatus::ENDED) {
208         auto pipelineContext = container->GetPipelineContext();
209         CHECK_NULL_VOID(pipelineContext);
210         pipelineContext->ResetDragging();
211     }
212     int32_t dragState = static_cast<int32_t>(dragStatus);
213     dragAction->callback(dragNotifyMsg, dragState);
214 }
215 
CheckStartAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,const RefPtr<Container> & container,const RefPtr<DragDropManager> & manager)216 int32_t CheckStartAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction,
217     const RefPtr<Container>& container, const RefPtr<DragDropManager>& manager)
218 {
219     if (CheckInternalDragging(container)) {
220         return -1;
221     }
222     {
223         std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
224         if (manager->GetDragAction() != nullptr && (manager->GetDragAction())->dragState == DragAdapterState::SENDING) {
225             return -1;
226         }
227         dragAction->dragState = DragAdapterState::SENDING;
228     }
229     DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(dragAction->previewOption);
230     auto isGetPointSuccess = ConfirmCurPointerEventInfo(dragAction, container);
231     if (!isGetPointSuccess) {
232         return -1;
233     }
234     return 0;
235 }
236 
StartDragAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)237 int32_t DragDropFuncWrapper::StartDragAction(std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)
238 {
239     CHECK_NULL_RETURN(dragAction, -1);
240     auto pipelineContext = PipelineContext::GetContextByContainerId(dragAction->instanceId);
241     CHECK_NULL_RETURN(pipelineContext, -1);
242     auto manager = pipelineContext->GetDragDropManager();
243     CHECK_NULL_RETURN(manager, -1);
244     auto container = AceEngine::Get().GetContainer(dragAction->instanceId);
245     CHECK_NULL_RETURN(container, -1);
246     auto windowScale = container->GetWindowScale();
247     CHECK_NULL_RETURN(windowScale, -1);
248     dragAction->windowScale = windowScale;
249     manager->SetDragAction(dragAction);
250     if (CheckStartAction(dragAction, container, manager) == -1) {
251         manager->GetDragAction()->dragState = DragAdapterState::INIT;
252         return -1;
253     }
254     std::optional<DragDataCore> dragData;
255     EnvelopedDragData(dragAction, dragData);
256     if (!dragData) {
257         {
258             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
259             manager->GetDragAction()->dragState = DragAdapterState::INIT;
260         }
261         return -1;
262     }
263     OnDragCallback callback = [dragAction, manager](const OHOS::Ace::DragNotifyMsg& dragNotifyMsg) {
264         {
265             std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
266             dragAction->dragState = DragAdapterState::INIT;
267             manager->SetDragAction(dragAction);
268         }
269         HandleCallback(dragAction, dragNotifyMsg, DragAdapterStatus::ENDED);
270     };
271     NG::DragDropFuncWrapper::SetDraggingPointerAndPressedState(
272         dragAction->dragPointerEvent.pointerId, dragAction->instanceId);
273     int32_t ret = InteractionInterface::GetInstance()->StartDrag(dragData.value(), callback);
274     if (ret != 0) {
275         manager->GetDragAction()->dragState = DragAdapterState::INIT;
276         DragNotifyMsg dragNotifyMsg;
277         dragNotifyMsg.result = DragRet::DRAG_CANCEL;
278         HandleCallback(dragAction, dragNotifyMsg, DragAdapterStatus::ENDED);
279         TAG_LOGE(AceLogTag::ACE_DRAG, "msdp start drag failed.");
280         return -1;
281     }
282     HandleCallback(dragAction, DragNotifyMsg {}, DragAdapterStatus::STARTED);
283     pipelineContext->SetIsDragging(true);
284     TAG_LOGI(AceLogTag::ACE_DRAG, "msdp start drag successfully.");
285     NG::DragDropFuncWrapper::HandleOnDragEvent(dragAction);
286     return 0;
287 }
288 
HandleOnDragEvent(const std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)289 void DragDropFuncWrapper::HandleOnDragEvent(
290     const std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> dragAction)
291 {
292     CHECK_NULL_VOID(dragAction);
293     auto pipelineContext = PipelineContext::GetContextByContainerId(dragAction->instanceId);
294     CHECK_NULL_VOID(pipelineContext);
295     std::lock_guard<std::mutex> lock(dragAction->dragStateMutex);
296     if (dragAction->dragState == DragAdapterState::SENDING) {
297         dragAction->dragState = DragAdapterState::SUCCESS;
298         InteractionInterface::GetInstance()->SetDragWindowVisible(true);
299         pipelineContext->OnDragEvent(
300             { dragAction->dragPointerEvent.displayX, dragAction->dragPointerEvent.displayY },
301             DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER);
302         NG::DragDropFuncWrapper::DecideWhetherToStopDragging(
303             { dragAction->dragPointerEvent.displayX, dragAction->dragPointerEvent.displayY }, dragAction->extraParams,
304             dragAction->dragPointerEvent.pointerId, dragAction->instanceId);
305     }
306 }
307 
SetDraggingPointerAndPressedState(int32_t currentPointerId,int32_t containerId)308 void DragDropFuncWrapper::SetDraggingPointerAndPressedState(int32_t currentPointerId, int32_t containerId)
309 {
310     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
311     CHECK_NULL_VOID(pipelineContext);
312     auto manager = pipelineContext->GetDragDropManager();
313     CHECK_NULL_VOID(manager);
314     manager->SetDraggingPointer(currentPointerId);
315     manager->SetDraggingPressedState(true);
316 }
317 
RequestDragEndPending()318 int32_t DragDropFuncWrapper::RequestDragEndPending()
319 {
320     if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
321         return -1;
322     }
323     static std::atomic<int32_t> gDragDropDelayEndRequestId;
324     int32_t id = gDragDropDelayEndRequestId.fetch_add(1);
325     return id;
326 }
327 
NotifyDragResult(int32_t requestId,int32_t result)328 int32_t DragDropFuncWrapper::NotifyDragResult(int32_t requestId, int32_t result)
329 {
330     if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
331         return -1;
332     }
333     return DragDropGlobalController::GetInstance().NotifyDragResult(requestId, result);
334 }
335 
NotifyDragEndPendingDone(int32_t requestId)336 int32_t DragDropFuncWrapper::NotifyDragEndPendingDone(int32_t requestId)
337 {
338     if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase()) {
339         return -1;
340     }
341     return DragDropGlobalController::GetInstance().NotifyDragEndPendingDone(requestId);
342 }
343 
DecideWhetherToStopDragging(const DragPointerEvent & pointerEvent,const std::string & extraParams,int32_t currentPointerId,int32_t containerId)344 void DragDropFuncWrapper::DecideWhetherToStopDragging(
345     const DragPointerEvent& pointerEvent, const std::string& extraParams, int32_t currentPointerId, int32_t containerId)
346 {
347     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
348     CHECK_NULL_VOID(pipelineContext);
349     auto manager = pipelineContext->GetDragDropManager();
350     CHECK_NULL_VOID(manager);
351     if (!manager->IsDraggingPressed(currentPointerId)) {
352         manager->OnDragEnd(pointerEvent, extraParams);
353     }
354 }
355 
UpdateDragPreviewOptionsFromModifier(std::function<void (WeakPtr<FrameNode>)> applyOnNodeSync,DragPreviewOption & option)356 void DragDropFuncWrapper::UpdateDragPreviewOptionsFromModifier(
357     std::function<void(WeakPtr<FrameNode>)> applyOnNodeSync, DragPreviewOption& option)
358 {
359     // create one temporary frame node for receiving the value from the modifier
360     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
361         []() { return AceType::MakeRefPtr<ImagePattern>(); });
362     CHECK_NULL_VOID(imageNode);
363 
364     // execute the modifier
365     CHECK_NULL_VOID(applyOnNodeSync);
366     applyOnNodeSync(AceType::WeakClaim(AceType::RawPtr(imageNode)));
367 
368     // get values from the temporary frame node
369     auto imageContext = imageNode->GetRenderContext();
370     CHECK_NULL_VOID(imageContext);
371     auto opacity = imageContext->GetOpacity();
372     if (opacity.has_value() && (opacity.value()) <= MAX_OPACITY && (opacity.value()) > MIN_OPACITY) {
373         option.options.opacity = opacity.value();
374     } else {
375         option.options.opacity = DEFAULT_OPACITY;
376     }
377 
378     auto shadow = imageContext->GetBackShadow();
379     if (shadow.has_value()) {
380         option.options.shadow = shadow.value();
381     }
382 
383     auto borderRadius = imageContext->GetBorderRadius();
384     if (borderRadius.has_value()) {
385         option.options.borderRadius = borderRadius;
386     }
387 
388     auto bgEffect = imageContext->GetBackgroundEffect();
389     if (bgEffect.has_value()) {
390         option.options.blurbgEffect.backGroundEffect = bgEffect.value();
391     } else {
392         auto blurstyletmp = imageContext->GetBackBlurStyle();
393         if (blurstyletmp.has_value()) {
394             bgEffect = BlurStyleToEffection(blurstyletmp);
395             if (bgEffect.has_value()) {
396                 option.options.blurbgEffect.backGroundEffect = bgEffect.value();
397             }
398         }
399     }
400 }
401 
UpdatePreviewOptionDefaultAttr(DragPreviewOption & option,bool isMultiSelectionEnabled)402 void DragDropFuncWrapper::UpdatePreviewOptionDefaultAttr(DragPreviewOption& option, bool isMultiSelectionEnabled)
403 {
404     option.options.opacity = DEFAULT_OPACITY;
405     if (option.isDefaultShadowEnabled) {
406         option.options.shadow = GetDefaultShadow();
407     } else {
408         option.options.shadow = std::nullopt;
409     }
410     if (option.isDefaultRadiusEnabled || isMultiSelectionEnabled) {
411         option.options.borderRadius = GetDefaultBorderRadius();
412     } else {
413         option.options.borderRadius = std::nullopt;
414     }
415 }
416 
UpdateExtraInfo(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)417 void DragDropFuncWrapper::UpdateExtraInfo(std::unique_ptr<JsonValue>& arkExtraInfoJson,
418     DragPreviewOption& option)
419 {
420     CHECK_NULL_VOID(arkExtraInfoJson);
421     double opacity = option.options.opacity;
422     arkExtraInfoJson->Put("dip_opacity", opacity);
423     if (option.options.blurbgEffect.backGroundEffect.radius.IsValid()) {
424         option.options.blurbgEffect.ToJsonValue(arkExtraInfoJson);
425     }
426     PrepareShadowParametersForDragData(arkExtraInfoJson, option);
427     PrepareRadiusParametersForDragData(arkExtraInfoJson, option);
428 }
429 
PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)430 void DragDropFuncWrapper::PrepareRadiusParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
431     DragPreviewOption& option)
432 {
433     CHECK_NULL_VOID(arkExtraInfoJson);
434     auto borderRadius = option.options.borderRadius;
435     if (borderRadius.has_value()) {
436         if (borderRadius.value().radiusTopLeft.has_value()) {
437             arkExtraInfoJson->Put("drag_corner_radius1", borderRadius.value().radiusTopLeft.value().Value());
438         }
439         if (borderRadius.value().radiusTopRight.has_value()) {
440             arkExtraInfoJson->Put("drag_corner_radius2", borderRadius.value().radiusTopRight.value().Value());
441         }
442         if (borderRadius.value().radiusBottomRight.has_value()) {
443             arkExtraInfoJson->Put("drag_corner_radius3", borderRadius.value().radiusBottomRight.value().Value());
444         }
445         if (borderRadius.value().radiusBottomLeft.has_value()) {
446             arkExtraInfoJson->Put("drag_corner_radius4", borderRadius.value().radiusBottomLeft.value().Value());
447         }
448     }
449 }
450 
PrepareShadowParametersForDragData(std::unique_ptr<JsonValue> & arkExtraInfoJson,DragPreviewOption & option)451 void DragDropFuncWrapper::PrepareShadowParametersForDragData(std::unique_ptr<JsonValue>& arkExtraInfoJson,
452     DragPreviewOption& option)
453 {
454     CHECK_NULL_VOID(arkExtraInfoJson);
455     auto shadow = option.options.shadow;
456     if (!shadow.has_value() || !shadow->IsValid()) {
457         arkExtraInfoJson->Put("shadow_enable", false);
458         return;
459     }
460     arkExtraInfoJson->Put("drag_type", "non-text");
461     arkExtraInfoJson->Put("shadow_enable", true);
462     ParseShadowInfo(shadow.value(), arkExtraInfoJson);
463 }
464 
ParseShadowInfo(Shadow & shadow,std::unique_ptr<JsonValue> & arkExtraInfoJson)465 void DragDropFuncWrapper::ParseShadowInfo(Shadow& shadow, std::unique_ptr<JsonValue>& arkExtraInfoJson)
466 {
467     CHECK_NULL_VOID(arkExtraInfoJson);
468     arkExtraInfoJson->Put("shadow_is_filled", shadow.GetIsFilled());
469     arkExtraInfoJson->Put("drag_shadow_OffsetX", shadow.GetOffset().GetX());
470     arkExtraInfoJson->Put("drag_shadow_OffsetY", shadow.GetOffset().GetY());
471     arkExtraInfoJson->Put("shadow_mask", shadow.GetShadowType() == ShadowType::BLUR);
472     int32_t argb = static_cast<int32_t>(shadow.GetColor().GetValue());
473     arkExtraInfoJson->Put("drag_shadow_argb", argb);
474     int32_t strategy = static_cast<int32_t>(shadow.GetShadowColorStrategy());
475     arkExtraInfoJson->Put("shadow_color_strategy", strategy);
476     arkExtraInfoJson->Put("shadow_corner", shadow.GetBlurRadius());
477     arkExtraInfoJson->Put("shadow_elevation", shadow.GetElevation());
478     arkExtraInfoJson->Put("shadow_is_hardwareacceleration", shadow.GetHardwareAcceleration());
479 }
480 
GetDefaultShadow()481 std::optional<Shadow> DragDropFuncWrapper::GetDefaultShadow()
482 {
483     auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
484     CHECK_NULL_RETURN(pipelineContext, std::nullopt);
485     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
486     CHECK_NULL_RETURN(shadowTheme, std::nullopt);
487     auto colorMode = pipelineContext->GetColorMode();
488     auto shadow = shadowTheme->GetShadow(ShadowStyle::OuterFloatingSM, colorMode);
489     shadow.SetIsFilled(true);
490     return shadow;
491 }
492 
GetDefaultBorderRadius()493 std::optional<BorderRadiusProperty> DragDropFuncWrapper::GetDefaultBorderRadius()
494 {
495     BorderRadiusProperty borderRadius;
496     borderRadius.SetRadius(PREVIEW_BORDER_RADIUS);
497     return borderRadius;
498 }
499 
RadiusToSigma(float radius)500 float DragDropFuncWrapper::RadiusToSigma(float radius)
501 {
502     return GreatNotEqual(radius, 0.0f) ? BLUR_SIGMA_SCALE * radius + SCALE_HALF : 0.0f;
503 }
504 
BlurStyleToEffection(const std::optional<BlurStyleOption> & blurStyleOp)505 std::optional<EffectOption> DragDropFuncWrapper::BlurStyleToEffection(
506     const std::optional<BlurStyleOption>& blurStyleOp)
507 {
508     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
509     CHECK_NULL_RETURN(pipeline, std::nullopt);
510     auto blurStyleTheme = pipeline->GetTheme<BlurStyleTheme>();
511     if (!blurStyleTheme) {
512         TAG_LOGW(AceLogTag::ACE_DRAG, "cannot find theme of blurStyle, create blurStyle failed");
513         return std::nullopt;
514     }
515     CHECK_NULL_RETURN(blurStyleOp, std::nullopt);
516     ThemeColorMode colorMode = blurStyleOp->colorMode;
517     if (blurStyleOp->colorMode == ThemeColorMode::SYSTEM) {
518         colorMode = pipeline->GetColorMode() == ColorMode::DARK ? ThemeColorMode::DARK : ThemeColorMode::LIGHT;
519     }
520     auto blurParam = blurStyleTheme->GetBlurParameter(blurStyleOp->blurStyle, colorMode);
521     CHECK_NULL_RETURN(blurParam, std::nullopt);
522     auto ratio = blurStyleOp->scale;
523     auto maskColor = blurParam->maskColor.BlendOpacity(ratio);
524     auto radiusPx = blurParam->radius * pipeline->GetDipScale();
525     auto radiusBlur = RadiusToSigma(radiusPx) * ratio;
526     auto saturation = (blurParam->saturation - 1) * ratio + 1.0;
527     auto brightness = (blurParam->brightness - 1) * ratio + 1.0;
528     Dimension dimen(radiusBlur);
529     EffectOption bgEffection = {dimen, saturation, brightness, maskColor,
530         blurStyleOp->adaptiveColor, blurStyleOp->blurOption};
531     return std::optional<EffectOption>(bgEffection);
532 }
533 
GetScaleWidth(int32_t containerId)534 [[maybe_unused]] double DragDropFuncWrapper::GetScaleWidth(int32_t containerId)
535 {
536     auto container = Container::GetContainer(containerId);
537     CHECK_NULL_RETURN(container, -1.0f);
538     auto pipeline = container->GetPipelineContext();
539     CHECK_NULL_RETURN(pipeline, -1.0f);
540     return DragDropManager::GetMaxWidthBaseOnGridSystem(pipeline);
541 }
542 
SetDragStartRequestStatus(DragStartRequestStatus dragStartRequestStatus)543 void DragDropFuncWrapper::SetDragStartRequestStatus(DragStartRequestStatus dragStartRequestStatus) noexcept
544 {
545     auto pipelineContext = PipelineContext::GetCurrentContext();
546     CHECK_NULL_VOID(pipelineContext);
547     auto dragDropManager = pipelineContext->GetDragDropManager();
548     CHECK_NULL_VOID(dragDropManager);
549     dragDropManager->HandleSyncOnDragStart(dragStartRequestStatus);
550 }
551 
SetExtraInfo(int32_t containerId,std::string extraInfo)552 void DragDropFuncWrapper::SetExtraInfo(int32_t containerId, std::string extraInfo)
553 {
554     auto pipelineContext = PipelineContext::GetContextByContainerId(containerId);
555     CHECK_NULL_VOID(pipelineContext);
556     auto manager = pipelineContext->GetDragDropManager();
557     CHECK_NULL_VOID(manager);
558     manager->SetExtraInfo(extraInfo);
559 }
560 
GetSummaryString(const std::map<std::string,int64_t> & summary)561 std::string DragDropFuncWrapper::GetSummaryString(const std::map<std::string, int64_t>& summary)
562 {
563     std::string summarys;
564     for (const auto& [udkey, recordSize] : summary) {
565         std::string str = udkey + "-" + std::to_string(recordSize) + ";";
566         summarys += str;
567     }
568 
569     return summarys;
570 }
571 
GetAnonyString(const std::string & fullString)572 std::string DragDropFuncWrapper::GetAnonyString(const std::string &fullString)
573 {
574     if (fullString.empty() || fullString.length() == 0) {
575         return "";
576     }
577     std::string middleStr = "******";
578     std::string anonyStr;
579     size_t strLen = fullString.length();
580     if (strLen <= SHORT_KEY_LENGTH) {
581         anonyStr += fullString[0];
582         anonyStr.append(middleStr);
583         anonyStr += fullString[strLen - 1];
584     } else {
585         anonyStr.append(fullString, 0, PLAINTEXT_LENGTH).append(middleStr)
586             .append(fullString, strLen - PLAINTEXT_LENGTH, PLAINTEXT_LENGTH);
587     }
588     return anonyStr;
589 }
590 
591 // returns a node's offset relative to window plus half of self rect size(w, h)
592 // and accumulate every ancestor node's graphic properties such as rotate and transform
593 // ancestor will NOT check boundary of window scene
GetPaintRectCenter(const RefPtr<FrameNode> & frameNode,bool checkWindowBoundary)594 OffsetF DragDropFuncWrapper::GetPaintRectCenter(const RefPtr<FrameNode>& frameNode, bool checkWindowBoundary)
595 {
596     CHECK_NULL_RETURN(frameNode, OffsetF());
597     auto context = frameNode->GetRenderContext();
598     CHECK_NULL_RETURN(context, OffsetF());
599     auto paintRect = context->GetPaintRectWithoutTransform();
600     auto offset = paintRect.GetOffset();
601     PointF pointNode(offset.GetX() + paintRect.Width() / 2.0f, offset.GetY() + paintRect.Height() / 2.0f);
602     context->GetPointTransformRotate(pointNode);
603     auto parent = frameNode->GetAncestorNodeOfFrame(false);
604     while (parent) {
605         if (checkWindowBoundary && parent->IsWindowBoundary()) {
606             break;
607         }
608         auto renderContext = parent->GetRenderContext();
609         CHECK_NULL_RETURN(renderContext, OffsetF());
610         offset = renderContext->GetPaintRectWithoutTransform().GetOffset();
611         pointNode.SetX(offset.GetX() + pointNode.GetX());
612         pointNode.SetY(offset.GetY() + pointNode.GetY());
613         renderContext->GetPointTransformRotate(pointNode);
614         parent = parent->GetAncestorNodeOfFrame(false);
615     }
616     return OffsetF(pointNode.GetX(), pointNode.GetY());
617 }
618 
619 // check if expand subwindow
IsExpandDisplay(const RefPtr<PipelineBase> & context)620 bool DragDropFuncWrapper::IsExpandDisplay(const RefPtr<PipelineBase>& context)
621 {
622     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
623     CHECK_NULL_RETURN(pipeline, false);
624     auto theme = pipeline->GetTheme<SelectTheme>();
625     CHECK_NULL_RETURN(theme, false);
626     if (theme->GetExpandDisplay()) {
627         return true;
628     }
629     auto containerId = pipeline->GetInstanceId();
630     containerId = containerId >= MIN_SUBCONTAINER_ID ?
631         SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId;
632     auto container = AceEngine::Get().GetContainer(containerId);
633     CHECK_NULL_RETURN(container, false);
634     return container->IsFreeMultiWindow();
635 }
636 
GetCurrentWindowOffset(const RefPtr<PipelineBase> & context)637 OffsetF DragDropFuncWrapper::GetCurrentWindowOffset(const RefPtr<PipelineBase>& context)
638 {
639     if (!IsExpandDisplay(context)) {
640         return OffsetF();
641     }
642     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
643     CHECK_NULL_RETURN(pipeline, OffsetF());
644     auto window = pipeline->GetWindow();
645     CHECK_NULL_RETURN(window, OffsetF());
646     auto windowOffset = window->GetCurrentWindowRect().GetOffset();
647     return OffsetF(windowOffset.GetX(), windowOffset.GetY());
648 }
649 
GetPaintRectCenterToScreen(const RefPtr<FrameNode> & frameNode)650 OffsetF DragDropFuncWrapper::GetPaintRectCenterToScreen(const RefPtr<FrameNode>& frameNode)
651 {
652     auto offset = GetPaintRectCenter(frameNode);
653     CHECK_NULL_RETURN(frameNode, offset);
654     offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
655     return offset;
656 }
657 
GetFrameNodeOffsetToScreen(const RefPtr<FrameNode> & frameNode)658 OffsetF DragDropFuncWrapper::GetFrameNodeOffsetToScreen(const RefPtr<FrameNode>& frameNode)
659 {
660     CHECK_NULL_RETURN(frameNode, OffsetF());
661     auto offset = frameNode->GetPositionToWindowWithTransform();
662     offset += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
663     return offset;
664 }
665 
GetPaintRectToScreen(const RefPtr<FrameNode> & frameNode)666 RectF DragDropFuncWrapper::GetPaintRectToScreen(const RefPtr<FrameNode>& frameNode)
667 {
668     CHECK_NULL_RETURN(frameNode, RectF());
669     RectF rect = frameNode->GetTransformRectRelativeToWindow();
670     rect += GetCurrentWindowOffset(frameNode->GetContextRefPtr());
671     return rect;
672 }
673 
UpdateNodePositionToScreen(const RefPtr<FrameNode> & frameNode,OffsetF offset)674 void DragDropFuncWrapper::UpdateNodePositionToScreen(const RefPtr<FrameNode>& frameNode, OffsetF offset)
675 {
676     CHECK_NULL_VOID(frameNode);
677     offset -= GetCurrentWindowOffset(frameNode->GetContextRefPtr());
678     UpdateNodePositionToWindow(frameNode, offset);
679 }
680 
UpdateNodePositionToWindow(const RefPtr<FrameNode> & frameNode,OffsetF offset)681 void DragDropFuncWrapper::UpdateNodePositionToWindow(const RefPtr<FrameNode>& frameNode, OffsetF offset)
682 {
683     CHECK_NULL_VOID(frameNode);
684     auto renderContext = frameNode->GetRenderContext();
685     CHECK_NULL_VOID(renderContext);
686     RefPtr<FrameNode> parentNode = frameNode->GetAncestorNodeOfFrame(true);
687     if (parentNode) {
688         offset -= parentNode->GetPositionToWindowWithTransform();
689     }
690     renderContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
691 }
692 
UpdatePositionFromFrameNode(const RefPtr<FrameNode> & targetNode,const RefPtr<FrameNode> & frameNode,float width,float height)693 void DragDropFuncWrapper::UpdatePositionFromFrameNode(const RefPtr<FrameNode>& targetNode,
694     const RefPtr<FrameNode>& frameNode, float width, float height)
695 {
696     CHECK_NULL_VOID(targetNode);
697     CHECK_NULL_VOID(frameNode);
698     auto paintRectCenter = GetPaintRectCenterToScreen(frameNode);
699     auto offset = paintRectCenter - OffsetF(width / 2.0f, height / 2.0f);
700     UpdateNodePositionToScreen(targetNode, offset);
701 }
702 
GetFrameNodeOffsetToWindow(const RefPtr<FrameNode> & targetNode,const RefPtr<FrameNode> & frameNode,float width,float height)703 OffsetF DragDropFuncWrapper::GetFrameNodeOffsetToWindow(const RefPtr<FrameNode>& targetNode,
704     const RefPtr<FrameNode>& frameNode, float width, float height)
705 {
706     CHECK_NULL_RETURN(targetNode, OffsetF());
707     CHECK_NULL_RETURN(frameNode, OffsetF());
708     auto paintRectCenter = GetPaintRectCenterToScreen(frameNode);
709     auto offset = paintRectCenter - OffsetF(width / 2.0f, height / 2.0f);
710     offset -= GetCurrentWindowOffset(targetNode->GetContextRefPtr());
711     auto renderContext = targetNode->GetRenderContext();
712     CHECK_NULL_RETURN(renderContext, OffsetF());
713     RefPtr<FrameNode> parentNode = targetNode->GetAncestorNodeOfFrame(true);
714     if (parentNode) {
715         offset -= parentNode->GetPositionToWindowWithTransform();
716     }
717     return offset;
718 }
719 
ConvertPointerEvent(const TouchEvent & touchPoint,DragPointerEvent & event)720 void DragDropFuncWrapper::ConvertPointerEvent(const TouchEvent& touchPoint, DragPointerEvent& event)
721 {
722     event.rawPointerEvent = touchPoint.GetTouchEventPointerEvent();
723     event.pointerEventId = touchPoint.touchEventId;
724     event.pointerId = touchPoint.id;
725     event.windowX = touchPoint.x;
726     event.windowY = touchPoint.y;
727     event.displayX = touchPoint.screenX;
728     event.displayY = touchPoint.screenY;
729     event.deviceId = touchPoint.deviceId;
730     event.x = event.windowX;
731     event.y = event.windowY;
732     event.pressedKeyCodes.clear();
733     for (const auto& curCode : touchPoint.pressedKeyCodes_) {
734         event.pressedKeyCodes.emplace_back(static_cast<KeyCode>(curCode));
735     }
736     GetPointerEventAction(touchPoint, event);
737 }
738 
GetPointerEventAction(const TouchEvent & touchPoint,DragPointerEvent & event)739 void DragDropFuncWrapper::GetPointerEventAction(const TouchEvent& touchPoint, DragPointerEvent& event)
740 {
741     auto orgAction = touchPoint.type;
742     switch (orgAction) {
743         case TouchType::CANCEL:
744             event.action = PointerAction::CANCEL;
745             break;
746         case TouchType::DOWN:
747             event.action = PointerAction::DOWN;
748             break;
749         case TouchType::MOVE:
750             event.action = PointerAction::MOVE;
751             break;
752         case TouchType::UP:
753             event.action = PointerAction::UP;
754             break;
755         case TouchType::PULL_MOVE:
756             event.action = PointerAction::PULL_MOVE;
757             break;
758         case TouchType::PULL_UP:
759             event.action = PointerAction::PULL_UP;
760             break;
761         case TouchType::PULL_IN_WINDOW:
762             event.action = PointerAction::PULL_IN_WINDOW;
763             break;
764         case TouchType::PULL_OUT_WINDOW:
765             event.action = PointerAction::PULL_OUT_WINDOW;
766             break;
767         default:
768             event.action = PointerAction::UNKNOWN;
769             break;
770     }
771 }
772 
GetFrameNodeByKey(const RefPtr<FrameNode> & root,const std::string & key)773 RefPtr<FrameNode> DragDropFuncWrapper::GetFrameNodeByKey(const RefPtr<FrameNode>& root, const std::string& key)
774 {
775     std::queue<RefPtr<UINode>> elements;
776     elements.push(root);
777     RefPtr<UINode> inspectorElement;
778     while (!elements.empty()) {
779         auto current = elements.front();
780         elements.pop();
781         if (key == current->GetInspectorId().value_or("")) {
782             return AceType::DynamicCast<FrameNode>(current);
783         }
784 
785         const auto& children = current->GetChildren();
786         for (const auto& child : children) {
787             elements.push(child);
788         }
789     }
790     return nullptr;
791 }
792 
GetPointRelativeToMainWindow(const Point & point)793 OffsetF DragDropFuncWrapper::GetPointRelativeToMainWindow(const Point& point)
794 {
795     OffsetF position (static_cast<float>(point.GetX()), static_cast<float>(point.GetY()));
796     auto currentPipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
797     CHECK_NULL_RETURN(currentPipeline, position);
798     auto mainPipeline = PipelineContext::GetMainPipelineContext();
799     CHECK_NULL_RETURN(mainPipeline, position);
800     if (mainPipeline != currentPipeline) {
801         position -= (GetCurrentWindowOffset(mainPipeline) -
802                      GetCurrentWindowOffset(currentPipeline));
803     }
804     return position;
805 }
806 
IsSelectedItemNode(const RefPtr<UINode> & uiNode)807 bool DragDropFuncWrapper::IsSelectedItemNode(const RefPtr<UINode>& uiNode)
808 {
809     auto frameNode = AceType::DynamicCast<FrameNode>(uiNode);
810     CHECK_NULL_RETURN(frameNode, false);
811     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
812     CHECK_NULL_RETURN(gestureHub, false);
813     auto eventHub = frameNode->GetEventHub<EventHub>();
814     CHECK_NULL_RETURN(eventHub, false);
815     auto dragPreview = frameNode->GetDragPreviewOption();
816     if (!dragPreview.isMultiSelectionEnabled) {
817         return false;
818     }
819     bool isAllowedDrag = gestureHub->IsAllowedDrag(eventHub);
820     if (!isAllowedDrag) {
821         return false;
822     }
823     if (frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG) {
824         auto itemPattern = frameNode->GetPattern<GridItemPattern>();
825         CHECK_NULL_RETURN(itemPattern, false);
826         if (itemPattern->IsSelected()) {
827             return true;
828         }
829     }
830     if (frameNode->GetTag() == V2::LIST_ITEM_ETS_TAG) {
831         auto itemPattern = frameNode->GetPattern<ListItemPattern>();
832         CHECK_NULL_RETURN(itemPattern, false);
833         if (itemPattern->IsSelected()) {
834             return true;
835         }
836     }
837     return false;
838 }
839 
840 /**
841  * Do some nessessary check before returning the gesture recognizer collection result
842  * to parent during the hittest process. For example, if there is one drag operation
843  * already in our system, it is not allowed to start new interation for drag operation.
844  */
IsGlobalStatusSuitableForDragging()845 bool DragDropFuncWrapper::IsGlobalStatusSuitableForDragging()
846 {
847     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
848     CHECK_NULL_RETURN(pipeline, false);
849     auto dragDropManager = pipeline->GetDragDropManager();
850     CHECK_NULL_RETURN(dragDropManager, false);
851     if (dragDropManager->IsDragging()) {
852         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, is dragging status");
853         return false;
854     }
855 
856     if (dragDropManager->IsMSDPDragging()) {
857         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, is msdp dragging status");
858         return false;
859     }
860 
861     return true;
862 }
863 
IsSelfAndParentDragForbidden(const RefPtr<FrameNode> & frameNode)864 bool DragDropFuncWrapper::IsSelfAndParentDragForbidden(const RefPtr<FrameNode>& frameNode)
865 {
866     auto parent = frameNode;
867     while (parent) {
868         auto eventHub = parent->GetEventHub<EventHub>();
869         parent = parent->GetAncestorNodeOfFrame(true);
870         if (!eventHub) {
871             continue;
872         }
873         auto gestureEventHub = eventHub->GetGestureEventHub();
874         if (!gestureEventHub) {
875             continue;
876         }
877         if (gestureEventHub->IsDragForbidden()) {
878             return true;
879         }
880     }
881     return false;
882 }
883 
IsBelongToMultiItemNode(const RefPtr<FrameNode> & frameNode)884 bool DragDropFuncWrapper::IsBelongToMultiItemNode(const RefPtr<FrameNode>& frameNode)
885 {
886     CHECK_NULL_RETURN(frameNode, false);
887     auto uiNode = frameNode->GetParent();
888     CHECK_NULL_RETURN(uiNode, false);
889     while (!IsSelectedItemNode(uiNode)) {
890         uiNode = uiNode->GetParent();
891         CHECK_NULL_RETURN(uiNode, false);
892     }
893     return true;
894 }
895 
CheckIsNeedGather(const RefPtr<FrameNode> & frameNode)896 bool DragDropFuncWrapper::CheckIsNeedGather(const RefPtr<FrameNode>& frameNode)
897 {
898     CHECK_NULL_RETURN(frameNode, false);
899     auto dragPreview = frameNode->GetDragPreviewOption();
900     if (!dragPreview.isMultiSelectionEnabled) {
901         return false;
902     }
903     return IsSelectedItemNode(frameNode);
904 }
905 
FindItemParentNode(const RefPtr<FrameNode> & frameNode)906 RefPtr<FrameNode> DragDropFuncWrapper::FindItemParentNode(const RefPtr<FrameNode>& frameNode)
907 {
908     CHECK_NULL_RETURN(frameNode, nullptr);
909     if (frameNode->GetTag() != V2::GRID_ITEM_ETS_TAG && frameNode->GetTag() != V2::LIST_ITEM_ETS_TAG) {
910         return nullptr;
911     }
912     auto parentType = frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG ? V2::GRID_ETS_TAG : V2::LIST_ETS_TAG;
913     auto uiNode = frameNode->GetParent();
914     CHECK_NULL_RETURN(uiNode, nullptr);
915     while (uiNode->GetTag() != parentType) {
916         uiNode = uiNode->GetParent();
917         CHECK_NULL_RETURN(uiNode, nullptr);
918     }
919     return AceType::DynamicCast<FrameNode>(uiNode);
920 }
921 
GetGatherNodePreviewPixelMap(const RefPtr<FrameNode> & frameNode)922 RefPtr<PixelMap> DragDropFuncWrapper::GetGatherNodePreviewPixelMap(const RefPtr<FrameNode>& frameNode)
923 {
924     CHECK_NULL_RETURN(frameNode, nullptr);
925     auto dragPreviewInfo = frameNode->GetDragPreview();
926     if (dragPreviewInfo.inspectorId != "") {
927         auto previewPixelMap = GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
928         return previewPixelMap;
929     }
930     if (dragPreviewInfo.pixelMap != nullptr) {
931         return dragPreviewInfo.pixelMap;
932     }
933     auto context = frameNode->GetRenderContext();
934     CHECK_NULL_RETURN(context, nullptr);
935     auto pixelMap = context->GetThumbnailPixelMap(true);
936     return pixelMap;
937 }
938 
TrySetDraggableStateAsync(const RefPtr<FrameNode> & frameNode,const TouchRestrict & touchRestrict)939 void DragDropFuncWrapper::TrySetDraggableStateAsync(
940     const RefPtr<FrameNode>& frameNode, const TouchRestrict& touchRestrict)
941 {
942     CHECK_NULL_VOID(frameNode);
943     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
944     CHECK_NULL_VOID(gestureHub);
945     if (frameNode->GetTag() == V2::TEXT_ETS_TAG && !gestureHub->GetIsTextDraggable()) {
946         return;
947     }
948     int64_t downTime = static_cast<int64_t>(touchRestrict.touchEvent.time.time_since_epoch().count());
949     if (DragDropGlobalController::GetInstance().IsAppGlobalDragEnabled()) {
950         InteractionInterface::GetInstance()->SetDraggableStateAsync(true, downTime / CONVERT_TIME_BASE);
951     }
952 }
953 
954 /**
955  * check the current node's status to decide if it can initiate one drag operation
956  */
IsCurrentNodeStatusSuitableForDragging(const RefPtr<FrameNode> & frameNode,const TouchRestrict & touchRestrict)957 bool DragDropFuncWrapper::IsCurrentNodeStatusSuitableForDragging(
958     const RefPtr<FrameNode>& frameNode, const TouchRestrict& touchRestrict)
959 {
960     CHECK_NULL_RETURN(frameNode, false);
961     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
962     CHECK_NULL_RETURN(gestureHub, false);
963 
964     if (gestureHub->IsDragForbidden() || (!frameNode->IsDraggable() && frameNode->IsCustomerSet()) ||
965         touchRestrict.inputEventType == InputEventType::AXIS) {
966         TAG_LOGI(AceLogTag::ACE_DRAG,
967             "No need to collect drag gestures result, drag forbidden set is %{public}d,"
968             "frameNode draggable is %{public}d, custom set is %{public}d",
969             gestureHub->IsDragForbidden(), frameNode->IsDraggable(), frameNode->IsCustomerSet());
970         return false;
971     }
972 
973     if (gestureHub->GetTextDraggable()) {
974         auto pattern = frameNode->GetPattern<TextBase>();
975         if (pattern && !pattern->IsSelected()) {
976             TrySetDraggableStateAsync(frameNode, touchRestrict);
977             TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, text is not selected.");
978             return false;
979         }
980     }
981 
982     if (IsSelfAndParentDragForbidden(frameNode)) {
983         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, parent is drag forbidden.");
984         return false;
985     }
986 
987     return true;
988 }
RecordMenuWrapperNodeForDrag(int32_t targetId)989 void DragDropFuncWrapper::RecordMenuWrapperNodeForDrag(int32_t targetId)
990 {
991     auto subWindow = SubwindowManager::GetInstance()->GetCurrentWindow();
992     CHECK_NULL_VOID(subWindow);
993     auto overlayManager = subWindow->GetOverlayManager();
994     CHECK_NULL_VOID(overlayManager);
995     auto menuWrapperNode = overlayManager->GetMenuNode(targetId);
996     if (!menuWrapperNode) {
997         auto rootNode = overlayManager->GetRootNode().Upgrade();
998         CHECK_NULL_VOID(rootNode);
999         for (const auto& child : rootNode->GetChildren()) {
1000             auto node = AceType::DynamicCast<FrameNode>(child);
1001             if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
1002                 menuWrapperNode = node;
1003                 break;
1004             }
1005         }
1006     }
1007     CHECK_NULL_VOID(menuWrapperNode);
1008 
1009     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1010     CHECK_NULL_VOID(pipeline);
1011     auto dragDropManager = pipeline->GetDragDropManager();
1012     CHECK_NULL_VOID(dragDropManager);
1013     dragDropManager->SetMenuWrapperNode(menuWrapperNode);
1014 
1015     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1016     CHECK_NULL_VOID(mainPipeline);
1017     auto dragMainDropManager = mainPipeline->GetDragDropManager();
1018     CHECK_NULL_VOID(dragMainDropManager);
1019     dragMainDropManager->SetMenuWrapperNode(menuWrapperNode);
1020 }
1021 
GetFrameNodeByInspectorId(const std::string & inspectorId)1022 RefPtr<FrameNode> DragDropFuncWrapper::GetFrameNodeByInspectorId(const std::string& inspectorId)
1023 {
1024     if (inspectorId.empty()) {
1025         return nullptr;
1026     }
1027 
1028     auto frameNode = Inspector::GetFrameNodeByKey(inspectorId);
1029     CHECK_NULL_RETURN(frameNode, nullptr);
1030     auto layoutProperty = frameNode->GetLayoutProperty();
1031     CHECK_NULL_RETURN(layoutProperty, nullptr);
1032 
1033     auto visibility = layoutProperty->GetVisibilityValue(VisibleType::VISIBLE);
1034     if (visibility == VisibleType::INVISIBLE || visibility == VisibleType::GONE) {
1035         return nullptr;
1036     }
1037 
1038     return frameNode;
1039 }
1040 
ApplyNewestOptionExecutedFromModifierToNode(const RefPtr<FrameNode> & optionHolderNode,const RefPtr<FrameNode> & targetNode)1041 void DragDropFuncWrapper::ApplyNewestOptionExecutedFromModifierToNode(
1042     const RefPtr<FrameNode>& optionHolderNode, const RefPtr<FrameNode>& targetNode)
1043 {
1044     auto optionsFromModifier = targetNode->GetDragPreviewOption().options;
1045     ACE_UPDATE_NODE_RENDER_CONTEXT(Opacity, optionsFromModifier.opacity, targetNode);
1046     if (optionsFromModifier.blurbgEffect.backGroundEffect.radius.IsValid()) {
1047         ACE_UPDATE_NODE_RENDER_CONTEXT(BackgroundEffect, optionsFromModifier.blurbgEffect.backGroundEffect, targetNode);
1048     }
1049     if (optionsFromModifier.shadow.has_value()) {
1050         // if shadow is unfilled, set shadow after animation
1051         if (optionsFromModifier.shadow->GetIsFilled()) {
1052             ACE_UPDATE_NODE_RENDER_CONTEXT(BackShadow, optionsFromModifier.shadow.value(), targetNode);
1053         }
1054     }
1055 
1056     const auto& target = targetNode->GetRenderContext();
1057     if (optionsFromModifier.borderRadius.has_value()) {
1058         target->UpdateBorderRadius(optionsFromModifier.borderRadius.value());
1059         target->UpdateClipEdge(true);
1060     }
1061 }
1062 
ResetNode(const RefPtr<FrameNode> & frameNode)1063 void DragDropFuncWrapper::ResetNode(const RefPtr<FrameNode>& frameNode)
1064 {
1065     CHECK_NULL_VOID(frameNode);
1066     bool defaultAnimationBeforeLifting = frameNode->GetDragPreviewOption().defaultAnimationBeforeLifting;
1067     if (!defaultAnimationBeforeLifting) {
1068         return;
1069     }
1070     auto frameContext = frameNode->GetRenderContext();
1071     CHECK_NULL_VOID(frameContext);
1072     frameContext->UpdateTransformScale({ 1.0f, 1.0f });
1073     auto layoutProperty = frameNode->GetLayoutProperty();
1074     if (layoutProperty) {
1075         layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
1076     }
1077 }
1078 
GetDragFrameNodeBorderRadius(const RefPtr<FrameNode> & frameNode)1079 BorderRadiusProperty DragDropFuncWrapper::GetDragFrameNodeBorderRadius(const RefPtr<FrameNode>& frameNode)
1080 {
1081     Dimension defaultDimension(0);
1082     BorderRadiusProperty borderRadius = { defaultDimension, defaultDimension, defaultDimension, defaultDimension };
1083     auto dragPreviewInfo = frameNode->GetDragPreview();
1084     if (dragPreviewInfo.pixelMap != nullptr) {
1085         return borderRadius;
1086     }
1087     RefPtr<FrameNode> targetNode = frameNode;
1088     if (!dragPreviewInfo.inspectorId.empty()) {
1089         targetNode = DragDropFuncWrapper::GetFrameNodeByInspectorId(dragPreviewInfo.inspectorId);
1090         CHECK_NULL_RETURN(targetNode, borderRadius);
1091     } else if (dragPreviewInfo.customNode != nullptr) {
1092         targetNode = AceType::DynamicCast<FrameNode>(dragPreviewInfo.customNode);
1093         CHECK_NULL_RETURN(targetNode, borderRadius);
1094     }
1095     auto targetNodeContext = targetNode->GetRenderContext();
1096     CHECK_NULL_RETURN(targetNodeContext, borderRadius);
1097     if (targetNodeContext->GetBorderRadius().has_value()) {
1098         borderRadius.UpdateWithCheck(targetNodeContext->GetBorderRadius().value());
1099     }
1100     return borderRadius;
1101 }
1102 
1103 /* Retrieves a preview PixelMap for a given drag event action.
1104  * This function attempts to obtain a screenshot of a frameNode associated with an inspector ID.
1105  * If the frameNode with the given ID does not exist or hasn't been rendered,
1106  * it falls back to taking a screenshot of the provided frame node.
1107  *
1108  * @param inspectorId A string representing the unique identifier for the frameNode's ID.
1109  * @param selfFrameNode A RefPtr to the frame node associated with the drag event.
1110  * @return A RefPtr to a PixelMap containing the preview image, or nullptr if not found.
1111  */
GetPreviewPixelMap(const std::string & inspectorId,const RefPtr<FrameNode> & selfFrameNode)1112 RefPtr<PixelMap> DragDropFuncWrapper::GetPreviewPixelMap(
1113     const std::string& inspectorId, const RefPtr<FrameNode>& selfFrameNode)
1114 {
1115     // Attempt to retrieve the PixelMap using the inspector ID.
1116     auto previewPixelMap = GetPreviewPixelMapByInspectorId(inspectorId, selfFrameNode);
1117     // If a preview PixelMap was found, return it.
1118     if (previewPixelMap != nullptr) {
1119         return previewPixelMap;
1120     }
1121     // If not found by inspector ID, attempt to get a screenshot of the frame node.
1122     return GetScreenShotPixelMap(selfFrameNode);
1123 }
1124 
1125 /* Retrieves a preview PixelMap based on an inspector ID.
1126  * This function attempts to find a frame node associated with the given inspector ID and then takes a screenshot of it.
1127  *
1128  * @param inspectorId The unique identifier for a frameNode.
1129  * @return A RefPtr to a PixelMap containing the preview image, or nullptr if not found or the ID is empty.
1130  */
GetPreviewPixelMapByInspectorId(const std::string & inspectorId,const RefPtr<FrameNode> & frameNode)1131 RefPtr<PixelMap> DragDropFuncWrapper::GetPreviewPixelMapByInspectorId(
1132     const std::string& inspectorId, const RefPtr<FrameNode>& frameNode)
1133 {
1134     // Check for an empty inspector ID and return nullptr if it is empty.
1135     if (inspectorId == "") {
1136         return nullptr;
1137     }
1138 
1139     CHECK_NULL_RETURN(frameNode, nullptr);
1140     auto pipeLine = frameNode->GetContextRefPtr();
1141     CHECK_NULL_RETURN(pipeLine, nullptr);
1142     auto rootNode = pipeLine->GetRootElement();
1143     CHECK_NULL_RETURN(rootNode, nullptr);
1144     // Retrieve the frame node using the inspector's ID.
1145     auto dragPreviewFrameNode = DragDropFuncWrapper::GetFrameNodeByKey(rootNode, inspectorId);
1146     CHECK_NULL_RETURN(dragPreviewFrameNode, nullptr);
1147 
1148     auto layoutProperty = dragPreviewFrameNode->GetLayoutProperty();
1149     CHECK_NULL_RETURN(layoutProperty, nullptr);
1150 
1151     auto visibility = layoutProperty->GetVisibilityValue(VisibleType::VISIBLE);
1152     if (visibility == VisibleType::INVISIBLE || visibility == VisibleType::GONE) {
1153         return nullptr;
1154     }
1155 
1156     // Take a screenshot of the frame node and return it as a PixelMap.
1157     return GetScreenShotPixelMap(dragPreviewFrameNode);
1158 }
1159 
1160 /* Captures a screenshot of the specified frame node and encapsulates it in a PixelMap.
1161  *
1162  * @param frameNode A RefPtr reference to the frame node from which to capture the screenshot.
1163  * @return A RefPtr to a PixelMap containing the screenshot.
1164  */
GetScreenShotPixelMap(const RefPtr<FrameNode> & frameNode)1165 RefPtr<PixelMap> DragDropFuncWrapper::GetScreenShotPixelMap(const RefPtr<FrameNode>& frameNode)
1166 {
1167     // Ensure the frame node is not nulls before proceeding.
1168     CHECK_NULL_RETURN(frameNode, nullptr);
1169 
1170     // Obtain the rendering context from the frame node.
1171     auto context = frameNode->GetRenderContext();
1172 
1173     // If the rendering context is not available, return nullptr.
1174     CHECK_NULL_RETURN(context, nullptr);
1175 
1176     // Capture and return the thumbnail PixelMap from the rendering context.
1177     return context->GetThumbnailPixelMap(true);
1178 }
1179 
CheckIfNeedGetThumbnailPixelMap(const RefPtr<FrameNode> & frameNode,int32_t fingerId)1180 bool DragDropFuncWrapper::CheckIfNeedGetThumbnailPixelMap(const RefPtr<FrameNode>& frameNode, int32_t fingerId)
1181 {
1182     CHECK_NULL_RETURN(frameNode, false);
1183     auto pipeline = frameNode->GetContextRefPtr();
1184     CHECK_NULL_RETURN(pipeline, false);
1185     auto eventManager = pipeline->GetEventManager();
1186     CHECK_NULL_RETURN(eventManager, false);
1187     RefPtr<LongPressRecognizer> recognizer;
1188     auto gestureReferee = eventManager->GetGestureRefereeNG(recognizer);
1189     CHECK_NULL_RETURN(gestureReferee, false);
1190     if (gestureReferee->IsAnySucceedRecognizerExist(fingerId)) {
1191         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to get thumbnail pixelmap with success recognizer.");
1192         return true;
1193     }
1194     return false;
1195 }
1196 
CreateTiledPixelMap(const RefPtr<FrameNode> & frameNode)1197 RefPtr<PixelMap> DragDropFuncWrapper::CreateTiledPixelMap(const RefPtr<FrameNode>& frameNode)
1198 {
1199     CHECK_NULL_RETURN(frameNode, nullptr);
1200     auto pipelineContext = frameNode->GetContextRefPtr();
1201     CHECK_NULL_RETURN(pipelineContext, nullptr);
1202     auto manager = pipelineContext->GetOverlayManager();
1203     CHECK_NULL_RETURN(manager, nullptr);
1204     auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1205     CHECK_NULL_RETURN(fatherNode, nullptr);
1206     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1207     CHECK_NULL_RETURN(scrollPattern, nullptr);
1208     auto children = scrollPattern->GetVisibleSelectedItems();
1209     auto pixelMapinfo = GetTiledPixelMapInfo(children);
1210     RefPtr<PixelMap> tiledPixelMap = nullptr;
1211 #if defined(PIXEL_MAP_SUPPORTED)
1212     CHECK_NULL_RETURN(pixelMapinfo, nullptr);
1213     InitializationOptions opts;
1214     opts.size.SetWidth(pixelMapinfo->pixelMapRect.GetSize().Width());
1215     opts.size.SetHeight(pixelMapinfo->pixelMapRect.GetSize().Height());
1216     opts.srcPixelFormat = pixelMapinfo->srcPixelFormat;
1217     opts.pixelFormat = pixelMapinfo->pixelFormat;
1218     opts.editable = true;
1219     opts.alphaType = pixelMapinfo->alphaType;
1220     tiledPixelMap = PixelMap::Create(opts);
1221 #endif
1222     DrawTiledPixelMap(tiledPixelMap, children, pixelMapinfo->pixelMapRect);
1223     CHECK_NULL_RETURN(tiledPixelMap, nullptr);
1224     return tiledPixelMap;
1225 }
1226 
GetTiledPixelMapInfo(const std::vector<RefPtr<FrameNode>> & children)1227 std::shared_ptr<PixelMapInfo> DragDropFuncWrapper::GetTiledPixelMapInfo(const std::vector<RefPtr<FrameNode>>& children)
1228 {
1229     CHECK_NULL_RETURN(children.size(), nullptr);
1230     auto minX = std::numeric_limits<float>::max();
1231     auto minY = std::numeric_limits<float>::max();
1232     auto maxX = std::numeric_limits<float>::lowest();
1233     auto maxY = std::numeric_limits<float>::lowest();
1234 
1235     for (auto& node : children) {
1236         auto context = node->GetRenderContext();
1237         CHECK_NULL_RETURN(context, nullptr);
1238         auto pixelMap = context->GetThumbnailPixelMap();
1239         auto gestureHub = node->GetOrCreateGestureEventHub();
1240         gestureHub->SetDragPreviewPixelMap(pixelMap);
1241         CHECK_NULL_RETURN(pixelMap, nullptr);
1242         auto offset = node->GetPositionToWindowWithTransform();
1243         minX = std::min(minX, offset.GetX());
1244         minY = std::min(minY, offset.GetY());
1245         maxX = std::max(maxX, offset.GetX() + pixelMap->GetWidth());
1246         maxY = std::max(maxY, offset.GetY() + pixelMap->GetHeight());
1247     }
1248     auto gestureHub = children.front()->GetOrCreateGestureEventHub();
1249     CHECK_NULL_RETURN(gestureHub, nullptr);
1250     auto dragPreviewPixelMap = gestureHub->GetDragPreviewPixelMap();
1251     CHECK_NULL_RETURN(dragPreviewPixelMap, nullptr);
1252     std::shared_ptr<PixelMapInfo> pixelMapInfo = std::make_shared<PixelMapInfo>();
1253     pixelMapInfo->srcPixelFormat = dragPreviewPixelMap->GetPixelFormat();
1254     pixelMapInfo->pixelFormat = dragPreviewPixelMap->GetPixelFormat();
1255     pixelMapInfo->alphaType = dragPreviewPixelMap->GetAlphaType();
1256     pixelMapInfo->pixelMapRect.SetLeft(minX);
1257     pixelMapInfo->pixelMapRect.SetTop(minY);
1258     pixelMapInfo->pixelMapRect.SetHeight(maxY - minY);
1259     pixelMapInfo->pixelMapRect.SetWidth(maxX - minX);
1260     return pixelMapInfo;
1261 }
1262 
DrawTiledPixelMap(const RefPtr<PixelMap> & tiledPixelMap,const std::vector<RefPtr<FrameNode>> & children,const Rect & pixelMapRect)1263 void DragDropFuncWrapper::DrawTiledPixelMap(
1264     const RefPtr<PixelMap>& tiledPixelMap, const std::vector<RefPtr<FrameNode>>& children, const Rect& pixelMapRect)
1265 {
1266     CHECK_NULL_VOID(tiledPixelMap);
1267     for (auto& node : children) {
1268         auto gestureHub = node->GetOrCreateGestureEventHub();
1269         CHECK_NULL_VOID(gestureHub);
1270         auto pixelMap = gestureHub->GetDragPreviewPixelMap();
1271         CHECK_NULL_VOID(pixelMap);
1272         auto offset = node->GetPositionToWindowWithTransform();
1273         auto offsetX = offset.GetX();
1274         auto offsetY = offset.GetY();
1275         auto result =
1276             tiledPixelMap->WritePixels({ pixelMap->GetPixels(), pixelMap->GetByteCount(), 0, pixelMap->GetRowStride(),
1277                 { offsetX - pixelMapRect.GetOffset().GetX(), offsetY - pixelMapRect.GetOffset().GetY(),
1278                     pixelMap->GetWidth(), pixelMap->GetHeight() },
1279                 pixelMap->GetPixelFormat() });
1280         if (result != 0) {
1281             TAG_LOGW(AceLogTag::ACE_DRAG, "Tiled pixelmap Write is failed, the result is %{public}d", result);
1282             return;
1283         }
1284     }
1285     return;
1286 }
1287 
IsNeedCreateTiledPixelMap(const RefPtr<FrameNode> & frameNode,const RefPtr<DragEventActuator> dragEventActuator,SourceType type)1288 bool DragDropFuncWrapper::IsNeedCreateTiledPixelMap(
1289     const RefPtr<FrameNode>& frameNode, const RefPtr<DragEventActuator> dragEventActuator, SourceType type)
1290 {
1291     CHECK_NULL_RETURN(frameNode, false);
1292     CHECK_NULL_RETURN(dragEventActuator, false);
1293     auto fatherNode = DragDropFuncWrapper::FindItemParentNode(frameNode);
1294     CHECK_NULL_RETURN(fatherNode, false);
1295     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1296     CHECK_NULL_RETURN(scrollPattern, false);
1297     if (frameNode->GetDragPreviewOption().isMultiTiled && scrollPattern->GetVisibleSelectedItems().size() > 1 &&
1298         DragDropFuncWrapper::IsSelectedItemNode(frameNode) && !dragEventActuator->GetRestartDrag() &&
1299         type == SourceType::MOUSE) {
1300         return true;
1301     }
1302     return false;
1303 }
1304 
GetThumbnailPixelMapForCustomNodeSync(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback)1305 void DragDropFuncWrapper::GetThumbnailPixelMapForCustomNodeSync(
1306     const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback)
1307 {
1308 #if defined(PIXEL_MAP_SUPPORTED)
1309     CHECK_NULL_VOID(gestureHub);
1310     auto frameNode = gestureHub->GetFrameNode();
1311     CHECK_NULL_VOID(frameNode);
1312     auto dragPreviewInfo = frameNode->GetDragPreview();
1313     SnapshotParam param;
1314     auto pixelMap = ComponentSnapshot::CreateSync(dragPreviewInfo.customNode, param);
1315     CHECK_NULL_VOID(pixelMap);
1316     auto previewPixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1317     gestureHub->SetPixelMap(previewPixelMap);
1318     gestureHub->SetDragPreviewPixelMap(previewPixelMap);
1319     pixelMapCallback(previewPixelMap, false);
1320 #endif
1321 }
1322 
GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub> & gestureHub)1323 void DragDropFuncWrapper::GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub>& gestureHub)
1324 {
1325     CHECK_NULL_VOID(gestureHub);
1326     auto callback = [id = Container::CurrentId(), weakGestureHub = AceType::WeakClaim(AceType::RawPtr(gestureHub))](
1327                         const RefPtr<PixelMap>& pixelMap) {
1328         ContainerScope scope(id);
1329         if (pixelMap != nullptr) {
1330             auto taskScheduler = Container::CurrentTaskExecutor();
1331             CHECK_NULL_VOID(taskScheduler);
1332             auto gestureHub = weakGestureHub.Upgrade();
1333             CHECK_NULL_VOID(gestureHub);
1334             taskScheduler->PostTask(
1335                 [gestureHub, pixelMap]() {
1336                     CHECK_NULL_VOID(gestureHub);
1337                     gestureHub->SetPixelMap(pixelMap);
1338                     TAG_LOGI(AceLogTag::ACE_DRAG, "Set thumbnail pixelMap async success.");
1339                 },
1340                 TaskExecutor::TaskType::UI, "ArkUIDragSetPixelMap");
1341         }
1342     };
1343     auto frameNode = gestureHub->GetFrameNode();
1344     CHECK_NULL_VOID(frameNode);
1345     auto context = frameNode->GetRenderContext();
1346     CHECK_NULL_VOID(context);
1347     if (!context->CreateThumbnailPixelMapAsyncTask(true, std::move(callback))) {
1348         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1349         TAG_LOGW(AceLogTag::ACE_DRAG, "Create thumbnail pixelMap async task failed!");
1350     }
1351 }
1352 
GetThumbnailPixelMapForCustomNode(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback)1353 void DragDropFuncWrapper::GetThumbnailPixelMapForCustomNode(
1354     const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback)
1355 {
1356 #if defined(PIXEL_MAP_SUPPORTED)
1357     CHECK_NULL_VOID(gestureHub);
1358     auto frameNode = gestureHub->GetFrameNode();
1359     CHECK_NULL_VOID(frameNode);
1360     auto dragPreviewInfo = frameNode->GetDragPreview();
1361     auto pipeline = PipelineContext::GetCurrentContext();
1362     CHECK_NULL_VOID(pipeline);
1363     auto callback = [id = Container::CurrentId(), pipeline, gestureHub, pixelMapCallback](
1364                         std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()> finishCallback) {
1365         ContainerScope scope(id);
1366         CHECK_NULL_VOID(pipeline);
1367         auto taskScheduler = pipeline->GetTaskExecutor();
1368         CHECK_NULL_VOID(taskScheduler);
1369         taskScheduler->PostTask(
1370             [finishCallback]() {
1371                 if (finishCallback) {
1372                     finishCallback();
1373                 }
1374             },
1375             TaskExecutor::TaskType::UI, "ArkUIDragRemoveCustomNode");
1376         if (pixelMap != nullptr) {
1377             auto customPixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1378             taskScheduler->PostTask(
1379                 [gestureHub, customPixelMap, pixelMapCallback]() {
1380                     CHECK_NULL_VOID(gestureHub);
1381                     gestureHub->SetPixelMap(customPixelMap);
1382                     gestureHub->SetDragPreviewPixelMap(customPixelMap);
1383                     pixelMapCallback(customPixelMap, true);
1384                 },
1385                 TaskExecutor::TaskType::UI, "ArkUIDragSetCustomPixelMap");
1386         } else {
1387             TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap is null.");
1388             DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
1389         }
1390     };
1391     SnapshotParam param;
1392     param.delay = CREATE_PIXELMAP_TIME;
1393     param.checkImageStatus = true;
1394     param.options.waitUntilRenderFinished = true;
1395     OHOS::Ace::NG::ComponentSnapshot::Create(dragPreviewInfo.customNode, std::move(callback), true, param);
1396     gestureHub->PrintBuilderNode(dragPreviewInfo.customNode);
1397 #endif
1398 }
1399 
GetThumbnailPixelMap(const RefPtr<GestureEventHub> & gestureHub,PixelMapFinishCallback pixelMapCallback,bool isSync)1400 void DragDropFuncWrapper::GetThumbnailPixelMap(
1401     const RefPtr<GestureEventHub>& gestureHub, PixelMapFinishCallback pixelMapCallback, bool isSync)
1402 {
1403     CHECK_NULL_VOID(gestureHub);
1404     auto frameNode = gestureHub->GetFrameNode();
1405     CHECK_NULL_VOID(frameNode);
1406     auto dragPreviewInfo = frameNode->GetDragPreview();
1407     if (dragPreviewInfo.inspectorId != "") {
1408         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through inspectorId.");
1409         auto previewPixelMap = GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
1410         gestureHub->SetPixelMap(previewPixelMap);
1411         gestureHub->SetDragPreviewPixelMap(previewPixelMap);
1412         pixelMapCallback(previewPixelMap, false);
1413     } else if (dragPreviewInfo.pixelMap != nullptr) {
1414         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through pixelMap.");
1415         gestureHub->SetPixelMap(dragPreviewInfo.pixelMap);
1416         gestureHub->SetDragPreviewPixelMap(dragPreviewInfo.pixelMap);
1417         pixelMapCallback(dragPreviewInfo.pixelMap, false);
1418     } else if (dragPreviewInfo.customNode || (dragPreviewInfo.delayCreating && dragPreviewInfo.buildFunc)) {
1419         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through customNode.");
1420         if (!dragPreviewInfo.customNode && dragPreviewInfo.delayCreating && dragPreviewInfo.buildFunc) {
1421             dragPreviewInfo.customNode = dragPreviewInfo.buildFunc();
1422         }
1423         frameNode->SetDragPreview(dragPreviewInfo);
1424         if (isSync) {
1425             GetThumbnailPixelMapForCustomNodeSync(gestureHub, pixelMapCallback);
1426         } else {
1427             GetThumbnailPixelMapForCustomNode(gestureHub, pixelMapCallback);
1428         }
1429     } else {
1430         GetThumbnailPixelMapAsync(gestureHub);
1431     }
1432 }
1433 
GetPixelMapScale(const RefPtr<FrameNode> & frameNode)1434 float DragDropFuncWrapper::GetPixelMapScale(const RefPtr<FrameNode>& frameNode)
1435 {
1436     float scale = 1.0f;
1437     CHECK_NULL_RETURN(frameNode, scale);
1438     auto pixelMap = frameNode->GetDragPixelMap();
1439     CHECK_NULL_RETURN(pixelMap, scale);
1440     auto width = pixelMap->GetWidth();
1441     auto height = pixelMap->GetHeight();
1442     auto gestureEvent = frameNode->GetOrCreateGestureEventHub();
1443     CHECK_NULL_RETURN(gestureEvent, scale);
1444     if (frameNode->GetDragPreviewOption().isScaleEnabled && width > 0 && height > 0) {
1445         auto scaleData = DragDropManager::GetScaleInfo(width, height, gestureEvent->GetTextDraggable());
1446         CHECK_NULL_RETURN(scaleData, scale);
1447         scale = scaleData->scale;
1448     }
1449     return scale;
1450 }
1451 
IsTextCategoryComponent(const std::string & frameTag)1452 bool DragDropFuncWrapper::IsTextCategoryComponent(const std::string& frameTag)
1453 {
1454     return frameTag == V2::TEXTAREA_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
1455            frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG ||
1456            frameTag == V2::RICH_EDITOR_ETS_TAG;
1457 }
1458 
GetDragDropManagerForDragAnimation(const RefPtr<PipelineBase> & context,const RefPtr<PipelineBase> & nodeContext,const RefPtr<Subwindow> & subWindow,bool isExpandDisplay,int32_t instanceId)1459 RefPtr<DragDropManager> DragDropFuncWrapper::GetDragDropManagerForDragAnimation(
1460     const RefPtr<PipelineBase>& context, const RefPtr<PipelineBase>& nodeContext,
1461     const RefPtr<Subwindow>& subWindow, bool isExpandDisplay, int32_t instanceId)
1462 {
1463     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1464     CHECK_NULL_RETURN(pipeline, nullptr);
1465     auto dragDropManager = pipeline->GetDragDropManager();
1466     auto nodePipeline = AceType::DynamicCast<PipelineContext>(nodeContext);
1467     CHECK_NULL_RETURN(nodePipeline, dragDropManager);
1468     if (nodePipeline == pipeline || isExpandDisplay) {
1469         return dragDropManager;
1470     }
1471     auto mainContainerId = instanceId >= MIN_SUBCONTAINER_ID ?
1472         SubwindowManager::GetInstance()->GetParentContainerId(instanceId) : instanceId;
1473     auto container = Container::GetContainer(mainContainerId);
1474     CHECK_NULL_RETURN(container, dragDropManager);
1475     if (!container->IsScenceBoardWindow()) {
1476         return dragDropManager;
1477     }
1478     CHECK_NULL_RETURN(subWindow, dragDropManager);
1479     subWindow->SetWindowTouchable(false);
1480     auto pixelMapOffset = dragDropManager->GetPixelMapOffset();
1481     dragDropManager = nodePipeline->GetDragDropManager();
1482     dragDropManager->SetPixelMapOffset(pixelMapOffset);
1483     return dragDropManager;
1484 }
1485 
SetMenuSubWindowTouchable(bool touchable)1486 void DragDropFuncWrapper::SetMenuSubWindowTouchable(bool touchable)
1487 {
1488     auto containerId = Container::CurrentId();
1489     auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(containerId);
1490     CHECK_NULL_VOID(subwindow);
1491     subwindow->SetWindowTouchable(touchable);
1492 }
1493 } // namespace OHOS::Ace::NG
1494