1/*
2 * Copyright (c) 2023-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 "drag_drawing.h"
17
18#include <atomic>
19#include <cstdint>
20#include <fstream>
21#include <limits>
22#include <string>
23#include <unistd.h>
24
25#include <dlfcn.h>
26
27#include "include/core/SkTextBlob.h"
28#include "image_source.h"
29#include "image_type.h"
30#include "image_utils.h"
31#include "input_manager.h"
32#ifndef OHOS_BUILD_ENABLE_ARKUI_X
33#include "parameters.h"
34#endif // OHOS_BUILD_ENABLE_ARKUI_X
35#include "pointer_event.h"
36#include "pointer_style.h"
37#include "render/rs_filter.h"
38#ifndef OHOS_BUILD_ENABLE_ARKUI_X
39#include "screen_manager.h"
40#endif // OHOS_BUILD_ENABLE_ARKUI_X
41#include "string_ex.h"
42#include "transaction/rs_interfaces.h"
43#include "ui/rs_surface_extractor.h"
44#include "ui/rs_surface_node.h"
45#include "ui/rs_ui_director.h"
46
47#include "animation_curve.h"
48#include "devicestatus_define.h"
49#include "drag_data_manager.h"
50#ifdef MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
51#include "drag_hisysevent.h"
52#endif // MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
53#include "include/util.h"
54
55#undef LOG_TAG
56#define LOG_TAG "DragDrawing"
57
58namespace OHOS {
59namespace Msdp {
60namespace DeviceStatus {
61namespace {
62constexpr int32_t BASELINE_DENSITY { 160 };
63constexpr int32_t DEVICE_INDEPENDENT_PIXEL { 40 };
64constexpr int32_t MAGIC_INDEPENDENT_PIXEL { 25 };
65constexpr int32_t MAGIC_STYLE_OPT { 1 };
66constexpr int32_t DRAG_NUM_ONE { 1 };
67constexpr int32_t STRING_PX_LENGTH { 2 };
68constexpr int32_t EIGHT_SIZE { 8 };
69constexpr int32_t TWELVE_SIZE { 12 };
70constexpr int64_t START_TIME { 181154000809 };
71constexpr int64_t INTERVAL_TIME { 16666667 };
72constexpr int32_t SVG_WIDTH { 40 };
73constexpr float SCALE_THRESHOLD_EIGHT { 1.0F * INT32_MAX / (SVG_WIDTH + EIGHT_SIZE) };
74constexpr float SCALE_THRESHOLD_TWELVE { 1.0F * INT32_MAX / (SVG_WIDTH + TWELVE_SIZE) };
75constexpr int32_t SUCCESS_ANIMATION_DURATION { 300 };
76constexpr int32_t ANIMATION_DURATION { 400 };
77constexpr int32_t VIEW_BOX_POS { 2 };
78constexpr int32_t BACKGROUND_FILTER_INDEX { 0 };
79constexpr int32_t ASYNC_ROTATE_TIME { 150 };
80constexpr int32_t PIXEL_MAP_INDEX { 1 };
81constexpr int32_t DRAG_STYLE_INDEX { 2 };
82constexpr int32_t MOUSE_ICON_INDEX { 3 };
83constexpr int32_t SHORT_DURATION { 55 };
84constexpr int32_t LONG_DURATION { 90 };
85constexpr int32_t FIRST_PIXELMAP_INDEX { 0 };
86constexpr int32_t SECOND_PIXELMAP_INDEX { 1 };
87constexpr int32_t LAST_SECOND_PIXELMAP { 2 };
88constexpr int32_t LAST_THIRD_PIXELMAP { 3 };
89constexpr size_t TOUCH_NODE_MIN_COUNT { 3 };
90constexpr size_t MOUSE_NODE_MIN_COUNT { 4 };
91constexpr float DEFAULT_SCALING { 1.0f };
92constexpr float BEGIN_ALPHA { 1.0f };
93constexpr float END_ALPHA { 0.0f };
94constexpr float START_STYLE_ALPHA { 1.0f };
95constexpr float END_STYLE_ALPHA { 0.0f };
96constexpr float BEGIN_SCALE { 1.0f };
97constexpr float END_SCALE_FAIL { 1.2f };
98constexpr float END_SCALE_SUCCESS { 0.0f };
99constexpr float DEFAULT_PIVOT { 0.0f };
100constexpr float HALF_PIVOT { 0.5f };
101constexpr float START_STYLE_SCALE { 1.0f };
102constexpr float STYLE_CHANGE_SCALE { 1.1f };
103constexpr float STYLE_MAX_SCALE { 1.2f };
104constexpr float STYLE_END_SCALE { 1.0f };
105constexpr float SVG_ORIGINAL_SIZE { 40.0f };
106constexpr float DEFAULT_POSITION_X { 0.0f };
107constexpr float BLUR_SIGMA_SCALE { 0.57735f };
108constexpr float RADIUS_VP { 23.0f };
109constexpr float DEFAULT_SATURATION { 1.05f };
110constexpr float DEFAULT_BRIGHTNESS { 1.05f };
111constexpr float INCREASE_RATIO { 1.22f };
112constexpr float DRAG_WINDOW_POSITION_Z { 6999.0f };
113constexpr float DEFAULT_ANGLE { 0.0f };
114constexpr float POSITIVE_ANGLE { 8.0f };
115constexpr float NEGATIVE_ANGLE { -8.0f };
116constexpr float DEFAULT_ALPHA { 1.0f };
117constexpr float FIRST_PIXELMAP_ALPHA { 0.6f };
118constexpr float SECOND_PIXELMAP_ALPHA { 0.3f };
119constexpr float HALF_RATIO { 0.5f };
120constexpr float ROTATION_0 { 0.0f };
121constexpr float ROTATION_90 { 90.0f };
122constexpr float ROTATION_360 { 360.0f };
123constexpr float ROTATION_270 { 270.0f };
124constexpr uint32_t TRANSPARENT_COLOR_ARGB { 0x00000000 };
125constexpr int32_t DEFAULT_MOUSE_SIZE { 1 };
126constexpr int32_t DEFAULT_COLOR_VALUE { 0 };
127constexpr int32_t INVALID_COLOR_VALUE { -1 };
128constexpr int32_t GLOBAL_WINDOW_ID { -1 };
129constexpr int32_t MOUSE_DRAG_CURSOR_CIRCLE_STYLE { 41 };
130constexpr int32_t CURSOR_CIRCLE_MIDDLE { 2 };
131constexpr int32_t TWICE_SIZE { 2 };
132constexpr int32_t NUM_ONE { 1 };
133constexpr int32_t NUM_TWO { 2 };
134constexpr int32_t NUM_FOUR { 4 };
135constexpr int32_t HEX_FF { 0xFF };
136const Rosen::RSAnimationTimingCurve SPRING = Rosen::RSAnimationTimingCurve::CreateSpring(0.347f, 0.99f, 0.0f);
137const std::string RENDER_THREAD_NAME { "os_dargRenderRunner" };
138constexpr float BEZIER_000 { 0.00f };
139constexpr float BEZIER_020 { 0.20f };
140constexpr float BEZIER_030 { 0.30f };
141constexpr float BEZIER_033 { 0.33f };
142constexpr float BEZIER_040 { 0.40f };
143constexpr float BEZIER_060 { 0.60f };
144constexpr float BEZIER_067 { 0.67f };
145constexpr float BEZIER_100 { 1.00f };
146constexpr float MIN_OPACITY { 0.0f };
147constexpr float MAX_OPACITY { 1.0f };
148constexpr int32_t TIME_DRAG_CHANGE_STYLE { 50 };
149constexpr int32_t TIME_DRAG_STYLE { 100 };
150constexpr int32_t TIME_STOP_FAIL_WINDOW { 125 };
151constexpr int32_t TIME_STOP_SUCCESS_WINDOW { 250 };
152constexpr int32_t TIME_STOP_SUCCESS_STYLE { 150 };
153constexpr int32_t TIME_STOP { 0 };
154constexpr int64_t TIME_SLEEP { 30000 };
155constexpr int32_t INTERRUPT_SCALE { 15 };
156constexpr int32_t TIMEOUT_MS { 500 };
157constexpr float MAX_SCREEN_WIDTH_SM { 320.0f };
158constexpr float MAX_SCREEN_WIDTH_MD { 600.0f };
159constexpr float MAX_SCREEN_WIDTH_LG { 840.0f };
160constexpr float MAX_SCREEN_WIDTH_XL { 1024.0f };
161constexpr float SCALE_SM { 3.0f / 4 };
162constexpr float SCALE_MD { 4.0f / 8 };
163constexpr float SCALE_LG { 5.0f / 12 };
164const std::string THREAD_NAME { "os_AnimationEventRunner" };
165const std::string SUPER_HUB_THREAD_NAME { "os_SuperHubEventRunner" };
166#ifndef OHOS_BUILD_ENABLE_ARKUI_X
167const std::string COPY_DRAG_PATH { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
168const std::string COPY_ONE_DRAG_PATH { "/system/etc/device_status/drag_icon/Copy_One_Drag.svg" };
169const std::string FORBID_DRAG_PATH { "/system/etc/device_status/drag_icon/Forbid_Drag.svg" };
170const std::string FORBID_ONE_DRAG_PATH { "/system/etc/device_status/drag_icon/Forbid_One_Drag.svg" };
171const std::string MOVE_DRAG_PATH { "/system/etc/device_status/drag_icon/Move_Drag.svg" };
172#else
173const std::string COPY_DRAG_NAME { "/base/media/Copy_Drag.svg" };
174const std::string COPY_ONE_DRAG_NAME { "/base/media/Copy_One_Drag.svg" };
175const std::string FORBID_DRAG_NAME { "/base/media/Forbid_Drag.svg" };
176const std::string FORBID_ONE_DRAG_NAME { "/base/media/Forbid_One_Drag.svg" };
177const std::string MOVE_DRAG_NAME { "/base/media/Move_Drag.svg" };
178#endif // OHOS_BUILD_ENABLE_ARKUI_X
179const std::string MOUSE_DRAG_DEFAULT_PATH { "/system/etc/device_status/drag_icon/Mouse_Drag_Default.svg" };
180const std::string MOUSE_DRAG_MAGIC_DEFAULT_PATH { "/system/etc/device_status/drag_icon/Mouse_Drag_Magic_Default.svg" };
181const std::string MOUSE_DRAG_CURSOR_CIRCLE_PATH { "/system/etc/device_status/drag_icon/Mouse_Drag_Cursor_Circle.png" };
182const std::string DRAG_DROP_EXTENSION_SO_PATH { "/system/lib64/drag_drop_ext/libdrag_drop_ext.z.so" };
183const std::string BIG_FOLDER_LABEL { "scb_folder" };
184struct DrawingInfo g_drawingInfo;
185struct DragData g_dragData;
186
187bool CheckNodesValid()
188{
189    FI_HILOGD("enter");
190    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
191        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
192        return false;
193    } else if (g_drawingInfo.nodes.empty() || g_drawingInfo.nodes[DRAG_STYLE_INDEX] == nullptr) {
194        FI_HILOGE("Nodes invalid");
195        return false;
196    }
197    if ((g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
198        (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT)) {
199        FI_HILOGE("Nodes size invalid when mouse type, node size:%{public}zu", g_drawingInfo.nodes.size());
200        return false;
201    }
202    if ((g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
203        (g_drawingInfo.nodes.size() < TOUCH_NODE_MIN_COUNT)) {
204        FI_HILOGE("Nodes size invalid when touchscreen type, node size:%{public}zu", g_drawingInfo.nodes.size());
205        return false;
206    }
207    return true;
208}
209
210float GetScaling()
211{
212    if (g_drawingInfo.isExistScalingValue) {
213        return g_drawingInfo.scalingValue;
214    }
215#ifndef OHOS_BUILD_ENABLE_ARKUI_X
216    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
217    if (display == nullptr) {
218        FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
219        display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
220        if (display == nullptr) {
221            FI_HILOGE("Get display info failed, display is nullptr");
222            return DEFAULT_SCALING;
223        }
224    }
225
226    int32_t deviceDpi = display->GetDpi();
227#else
228    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
229    if (display == nullptr) {
230        FI_HILOGE("Get display info failed, display is nullptr");
231        return DEFAULT_SCALING;
232    }
233    sptr<Rosen::DisplayInfo> info = display->GetDisplayInfo();
234    if (info == nullptr) {
235        FI_HILOGE("Get info failed, info is nullptr");
236        return DEFAULT_SCALING;
237    }
238    int32_t deviceDpi = info->GetDensityDpi();
239#endif // OHOS_BUILD_ENABLE_ARKUI_X
240    FI_HILOGD("displayId:%{public}d, deviceDpi:%{public}d", g_drawingInfo.displayId, deviceDpi);
241    if (deviceDpi < -std::numeric_limits<float>::epsilon()) {
242        FI_HILOGE("Invalid deviceDpi:%{public}d", deviceDpi);
243        return DEFAULT_SCALING;
244    }
245    g_drawingInfo.scalingValue = (1.0 * deviceDpi * DEVICE_INDEPENDENT_PIXEL / BASELINE_DENSITY) / SVG_ORIGINAL_SIZE;
246    g_drawingInfo.isExistScalingValue = true;
247    return g_drawingInfo.scalingValue;
248}
249} // namespace
250
251#ifndef OHOS_BUILD_ENABLE_ARKUI_X
252int32_t DragDrawing::Init(const DragData &dragData, IContext* context)
253#else
254int32_t DragDrawing::Init(const DragData &dragData)
255#endif // OHOS_BUILD_ENABLE_ARKUI_X
256{
257    FI_HILOGI("enter");
258    int32_t checkDragDataResult = CheckDragData(dragData);
259    if (INIT_SUCCESS != checkDragDataResult) {
260        return checkDragDataResult;
261    }
262    InitDrawingInfo(dragData);
263    g_dragData = dragData;
264    CreateWindow();
265    CHKPR(g_drawingInfo.surfaceNode, INIT_FAIL);
266    if (InitLayer() != RET_OK) {
267        FI_HILOGE("Init layer failed");
268        return INIT_FAIL;
269    }
270    DragAnimationData dragAnimationData;
271    if (!CheckNodesValid() || InitDragAnimationData(dragAnimationData) != RET_OK) {
272        FI_HILOGE("Init drag animation data or check nodes valid failed");
273        return INIT_FAIL;
274    }
275    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX || g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX) {
276        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
277        return INIT_FAIL;
278    }
279    std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
280    CHKPR(shadowNode, INIT_FAIL);
281    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
282    CHKPR(dragStyleNode, INIT_FAIL);
283#ifndef OHOS_BUILD_ENABLE_ARKUI_X
284    LoadDragDropLib();
285#endif // OHOS_BUILD_ENABLE_ARKUI_X
286    OnStartDrag(dragAnimationData, shadowNode, dragStyleNode);
287    if (!g_drawingInfo.multiSelectedNodes.empty()) {
288        g_drawingInfo.isCurrentDefaultStyle = true;
289        UpdateDragStyle(DragCursorStyle::MOVE);
290    }
291#ifndef OHOS_BUILD_ENABLE_ARKUI_X
292    context_ = context;
293#endif // OHOS_BUILD_ENABLE_ARKUI_X
294    CHKPR(rsUiDirector_, INIT_FAIL);
295    if (g_drawingInfo.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
296        rsUiDirector_->SendMessages();
297        return INIT_SUCCESS;
298    }
299    if (DrawMouseIcon() != RET_OK) {
300        FI_HILOGE("Draw mouse icon failed");
301        return INIT_FAIL;
302    }
303    rsUiDirector_->SendMessages();
304    FI_HILOGI("leave");
305    return INIT_SUCCESS;
306}
307
308int32_t DragDrawing::CheckDragData(const DragData &dragData)
309{
310    if (g_drawingInfo.isRunning) {
311        FI_HILOGE("Drag drawing is running, can not init again");
312        return INIT_CANCEL;
313    }
314    if (dragData.shadowInfos.empty()) {
315        FI_HILOGE("ShadowInfos is empty");
316        return INIT_FAIL;
317    }
318    for (const auto &shadowInfo : dragData.shadowInfos) {
319        CHKPR(shadowInfo.pixelMap, INIT_FAIL);
320    }
321    if ((dragData.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
322        (dragData.sourceType != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN)) {
323        FI_HILOGE("Invalid sourceType:%{public}d", dragData.sourceType);
324        return INIT_FAIL;
325    }
326    if (dragData.dragNum < 0) {
327        FI_HILOGE("Invalid dragNum:%{public}d", dragData.dragNum);
328        return INIT_FAIL;
329    }
330    return INIT_SUCCESS;
331}
332
333void DragDrawing::Draw(int32_t displayId, int32_t displayX, int32_t displayY, bool isNeedAdjustDisplayXY,
334    bool isMultiSelectedAnimation)
335{
336    if (isRunningRotateAnimation_) {
337        FI_HILOGD("Doing rotate drag window animate, ignore draw drag window");
338        return;
339    }
340    if (displayId < 0) {
341        FI_HILOGE("Invalid displayId:%{public}d", displayId);
342        return;
343    }
344    int32_t mousePositionX = displayX;
345    int32_t mousePositionY = displayY;
346    if (isNeedAdjustDisplayXY) {
347        RotateDisplayXY(displayX, displayY);
348        mousePositionX = displayX;
349        mousePositionY = displayY;
350        g_drawingInfo.currentPositionX = static_cast<float>(displayX);
351        g_drawingInfo.currentPositionY = static_cast<float>(displayY);
352        AdjustRotateDisplayXY(displayX, displayY);
353    }
354    g_drawingInfo.displayId = displayId;
355    g_drawingInfo.displayX = displayX;
356    g_drawingInfo.displayY = displayY;
357    if (displayX < 0) {
358        g_drawingInfo.displayX = 0;
359    }
360    if (displayY < 0) {
361        g_drawingInfo.displayY = 0;
362    }
363    int32_t adjustSize = TWELVE_SIZE * GetScaling();
364    int32_t positionX = g_drawingInfo.displayX + g_drawingInfo.pixelMapX;
365    int32_t positionY = g_drawingInfo.displayY + g_drawingInfo.pixelMapY - adjustSize;
366    CHKPV(g_drawingInfo.parentNode);
367    CHKPV(g_drawingInfo.pixelMap);
368    g_drawingInfo.parentNode->SetBounds(positionX, positionY, g_drawingInfo.pixelMap->GetWidth(),
369        g_drawingInfo.pixelMap->GetHeight() + adjustSize);
370    g_drawingInfo.parentNode->SetFrame(positionX, positionY, g_drawingInfo.pixelMap->GetWidth(),
371        g_drawingInfo.pixelMap->GetHeight() + adjustSize);
372    if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
373        DoDrawMouse(mousePositionX, mousePositionY);
374    }
375    if (!g_drawingInfo.multiSelectedNodes.empty() && !g_drawingInfo.multiSelectedPixelMaps.empty()) {
376        MultiSelectedAnimation(positionX, positionY, adjustSize, isMultiSelectedAnimation);
377    }
378    Rosen::RSTransaction::FlushImplicitTransaction();
379}
380
381void DragDrawing::UpdateDragPosition(int32_t displayId, float displayX, float displayY)
382{
383    if (displayId < 0) {
384        FI_HILOGE("Invalid displayId:%{public}d", displayId);
385        return;
386    }
387    RotatePosition(displayX, displayY);
388    g_drawingInfo.currentPositionX = displayX;
389    g_drawingInfo.currentPositionY = displayY;
390    g_drawingInfo.displayId = displayId;
391    g_drawingInfo.displayX = static_cast<int32_t>(displayX);
392    g_drawingInfo.displayY = static_cast<int32_t>(displayY);
393    float mousePositionX = displayX;
394    float mousePositionY = displayY;
395    AdjustRotateDisplayXY(displayX, displayY);
396    g_drawingInfo.x = displayX;
397    g_drawingInfo.y = displayY;
398    if (displayX < 0) {
399        g_drawingInfo.displayX = 0;
400    }
401    if (displayY < 0) {
402        g_drawingInfo.displayY = 0;
403    }
404    float adjustSize = TWELVE_SIZE * GetScaling();
405    float positionX = g_drawingInfo.x + g_drawingInfo.pixelMapX;
406    float positionY = g_drawingInfo.y + g_drawingInfo.pixelMapY - adjustSize;
407    auto parentNode = g_drawingInfo.parentNode;
408    auto pixelMap  = g_drawingInfo.pixelMap;
409    CHKPV(parentNode);
410    CHKPV(pixelMap);
411    parentNode->SetBounds(positionX, positionY, pixelMap->GetWidth(),
412        pixelMap->GetHeight() + adjustSize);
413    parentNode->SetFrame(positionX, positionY, pixelMap->GetWidth(),
414        pixelMap->GetHeight() + adjustSize);
415    if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
416        UpdateMousePosition(mousePositionX, mousePositionY);
417    }
418    if (!g_drawingInfo.multiSelectedNodes.empty() && !g_drawingInfo.multiSelectedPixelMaps.empty()) {
419        DoMultiSelectedAnimation(positionX, positionY, adjustSize);
420    }
421    if (rsUiDirector_ != nullptr) {
422        rsUiDirector_->SendMessages();
423    } else {
424        FI_HILOGE("rsUiDirector_ is nullptr");
425    }
426}
427
428void DragDrawing::DoMultiSelectedAnimation(float positionX, float positionY, float adjustSize,
429    bool isMultiSelectedAnimation)
430{
431    size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
432    size_t multiSelectedPixelMapsSize = g_drawingInfo.multiSelectedPixelMaps.size();
433    for (size_t i = 0; (i < multiSelectedNodesSize) && (i < multiSelectedPixelMapsSize); ++i) {
434        std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
435        std::shared_ptr<Media::PixelMap> multiSelectedPixelMap = g_drawingInfo.multiSelectedPixelMaps[i];
436        auto pixelMap  = g_drawingInfo.pixelMap;
437        CHKPV(pixelMap);
438        CHKPV(multiSelectedNode);
439        CHKPV(multiSelectedPixelMap);
440        float multiSelectedPositionX = positionX + (static_cast<float>(pixelMap->GetWidth()) / TWICE_SIZE) -
441            (static_cast<float>(multiSelectedPixelMap->GetWidth()) / TWICE_SIZE);
442        float multiSelectedPositionY = positionY + (static_cast<float>(pixelMap->GetHeight()) / TWICE_SIZE) -
443            (static_cast<float>(multiSelectedPixelMap->GetHeight()) / TWICE_SIZE - adjustSize);
444        if (isMultiSelectedAnimation) {
445            Rosen::RSAnimationTimingProtocol protocol;
446            if (i == FIRST_PIXELMAP_INDEX) {
447                protocol.SetDuration(SHORT_DURATION);
448            } else {
449                protocol.SetDuration(LONG_DURATION);
450            }
451            Rosen::RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
452                multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
453                    multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
454                multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
455                    multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
456            }, []() { FI_HILOGD("DoMultiSelectedAnimation end"); });
457        } else {
458            multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
459                multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
460            multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
461                multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
462        }
463    }
464}
465
466int32_t DragDrawing::UpdateDragStyle(DragCursorStyle style)
467{
468    FI_HILOGD("style:%{public}d", style);
469    if ((style < DragCursorStyle::DEFAULT) || (style > DragCursorStyle::MOVE)) {
470#ifndef OHOS_BUILD_ENABLE_ARKUI_X
471#ifdef MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
472        DragDFX::WriteUpdateDragStyle(style, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
473#endif // MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
474#endif // OHOS_BUILD_ENABLE_ARKUI_X
475        FI_HILOGE("Invalid style:%{public}d", style);
476        return RET_ERR;
477    }
478    if ((style == DragCursorStyle::DEFAULT) ||
479        ((style == DragCursorStyle::MOVE) && (g_drawingInfo.currentDragNum == DRAG_NUM_ONE))) {
480        return UpdateDefaultDragStyle(style);
481    }
482    return UpdateValidDragStyle(style);
483}
484
485int32_t DragDrawing::UpdateShadowPic(const ShadowInfo &shadowInfo)
486{
487    FI_HILOGD("enter");
488    CHKPR(shadowInfo.pixelMap, RET_ERR);
489    g_drawingInfo.pixelMap = shadowInfo.pixelMap;
490    g_drawingInfo.pixelMapX = shadowInfo.x;
491    g_drawingInfo.pixelMapY = shadowInfo.y;
492    if (!CheckNodesValid()) {
493        FI_HILOGE("Check nodes valid failed");
494        return RET_ERR;
495    }
496    if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX) {
497        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
498        return RET_ERR;
499    }
500    std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
501    CHKPR(shadowNode, RET_ERR);
502    DrawShadow(shadowNode);
503    float scalingValue = GetScaling();
504    if (SCALE_THRESHOLD_TWELVE < scalingValue || fabsf(SCALE_THRESHOLD_TWELVE - scalingValue) < EPSILON) {
505        FI_HILOGE("Invalid scalingValue:%{public}f", scalingValue);
506        return RET_ERR;
507    }
508    if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
509        DrawMouseIcon();
510    }
511    ProcessFilter();
512    Draw(g_drawingInfo.displayId, g_drawingInfo.displayX, g_drawingInfo.displayY, false);
513    RotateDragWindow(rotation_);
514    Rosen::RSTransaction::FlushImplicitTransaction();
515    CHKPR(rsUiDirector_, RET_ERR);
516    rsUiDirector_->SendMessages();
517    FI_HILOGD("leave");
518    return RET_OK;
519}
520
521int32_t DragDrawing::UpdatePixelMapsAngleAndAlpha()
522{
523    FI_HILOGD("enter");
524    size_t mulNodesSize = g_drawingInfo.multiSelectedNodes.size();
525    if (mulNodesSize <= 0) {
526        FI_HILOGE("No pixelmap add");
527        return RET_ERR;
528    }
529    if (mulNodesSize == 1) {
530        g_drawingInfo.multiSelectedNodes.front()->SetRotation(POSITIVE_ANGLE);
531        g_drawingInfo.multiSelectedNodes.front()->SetAlpha(FIRST_PIXELMAP_ALPHA);
532    } else if (mulNodesSize == LAST_SECOND_PIXELMAP) {
533        g_drawingInfo.multiSelectedNodes.back()->SetRotation(NEGATIVE_ANGLE);
534        g_drawingInfo.multiSelectedNodes.back()->SetAlpha(SECOND_PIXELMAP_ALPHA);
535    } else {
536        g_drawingInfo.rootNode->RemoveChild(g_drawingInfo.multiSelectedNodes[mulNodesSize - LAST_THIRD_PIXELMAP]);
537        g_drawingInfo.multiSelectedNodes[mulNodesSize - LAST_SECOND_PIXELMAP ]->SetRotation(POSITIVE_ANGLE);
538        g_drawingInfo.multiSelectedNodes[mulNodesSize - LAST_SECOND_PIXELMAP ]->SetAlpha(FIRST_PIXELMAP_ALPHA);
539        g_drawingInfo.multiSelectedNodes.back()->SetRotation(NEGATIVE_ANGLE);
540        g_drawingInfo.multiSelectedNodes.back()->SetAlpha(SECOND_PIXELMAP_ALPHA);
541    }
542    FI_HILOGD("leave");
543    return RET_OK;
544}
545
546int32_t DragDrawing::UpdatePixeMapDrawingOrder()
547{
548    FI_HILOGD("enter");
549    std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
550    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
551    CHKPR(pixelMapNode, RET_ERR);
552    CHKPR(dragStyleNode, RET_ERR);
553    CHKPR(g_drawingInfo.parentNode, RET_ERR);
554    CHKPR(g_drawingInfo.rootNode, RET_ERR);
555    g_drawingInfo.multiSelectedNodes.emplace_back(pixelMapNode);
556    g_drawingInfo.parentNode->RemoveChild(dragStyleNode);
557    g_drawingInfo.parentNode->RemoveChild(pixelMapNode);
558
559    int32_t adjustSize = TWELVE_SIZE * GetScaling();
560    int32_t positionX = g_drawingInfo.displayX + g_drawingInfo.pixelMapX;
561    int32_t positionY = g_drawingInfo.displayY + g_drawingInfo.pixelMapY - adjustSize;
562    int32_t pixelMapWidth = g_drawingInfo.pixelMap->GetWidth();
563    int32_t pixelMapHeight = g_drawingInfo.pixelMap->GetHeight();
564    pixelMapNode->SetBounds(positionX, positionY + adjustSize, pixelMapWidth, pixelMapHeight);
565    pixelMapNode->SetFrame(positionX, positionY + adjustSize, pixelMapWidth, pixelMapHeight);
566
567    std::shared_ptr<Rosen::RSCanvasNode> addSelectedNode = Rosen::RSCanvasNode::Create();
568    CHKPR(addSelectedNode, RET_ERR);
569    g_drawingInfo.nodes[PIXEL_MAP_INDEX] = addSelectedNode;
570    g_drawingInfo.parentNode->AddChild(addSelectedNode);
571    g_drawingInfo.parentNode->AddChild(dragStyleNode);
572    g_drawingInfo.rootNode->AddChild(g_drawingInfo.multiSelectedNodes.back());
573    g_drawingInfo.rootNode->RemoveChild(g_drawingInfo.parentNode);
574    g_drawingInfo.rootNode->AddChild(g_drawingInfo.parentNode);
575
576    if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
577        std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
578        CHKPR(mouseIconNode, RET_ERR);
579        g_drawingInfo.rootNode->RemoveChild(mouseIconNode);
580        g_drawingInfo.rootNode->AddChild(mouseIconNode);
581    }
582
583    if (UpdatePixelMapsAngleAndAlpha() != RET_OK) {
584        FI_HILOGE("setPixelMapsAngleAndAlpha failed");
585        return RET_ERR;
586    }
587    DrawShadow(pixelMapNode);
588    FI_HILOGD("leave");
589    return RET_OK;
590}
591
592int32_t DragDrawing::AddSelectedPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
593{
594    FI_HILOGD("enter");
595    CHKPR(pixelMap, RET_ERR);
596    if (!CheckNodesValid()) {
597        FI_HILOGE("Check nodes valid failed");
598        return RET_ERR;
599    }
600
601    g_drawingInfo.multiSelectedPixelMaps.emplace_back(g_drawingInfo.pixelMap);
602    g_drawingInfo.pixelMap = pixelMap;
603    if (UpdatePixeMapDrawingOrder() != RET_OK) {
604        FI_HILOGE("Update pixeMap drawing order failed");
605        return RET_ERR;
606    }
607    Draw(g_drawingInfo.displayId, g_drawingInfo.displayX, g_drawingInfo.displayY, false);
608    g_drawingInfo.currentDragNum = g_drawingInfo.multiSelectedPixelMaps.size() + 1;
609    if (UpdateDragStyle(g_drawingInfo.currentStyle) != RET_OK) {
610        FI_HILOGE("Update drag style failed");
611        return RET_ERR;
612    }
613    Rosen::RSTransaction::FlushImplicitTransaction();
614    FI_HILOGD("leave");
615    return RET_OK;
616}
617
618#ifndef OHOS_BUILD_ENABLE_ARKUI_X
619void DragDrawing::OnDragSuccess(IContext* context)
620#else
621void DragDrawing::OnDragSuccess()
622#endif // OHOS_BUILD_ENABLE_ARKUI_X
623{
624    FI_HILOGI("enter");
625    if (!CheckNodesValid()) {
626        FI_HILOGE("Check nodes valid failed");
627        return;
628    }
629    if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX || g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
630        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
631        return;
632    }
633    std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
634    CHKPV(shadowNode);
635    std::shared_ptr<Rosen::RSCanvasNode> styleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
636    CHKPV(styleNode);
637#ifndef OHOS_BUILD_ENABLE_ARKUI_X
638    g_drawingInfo.context = context;
639#endif // OHOS_BUILD_ENABLE_ARKUI_X
640    OnStopDragSuccess(shadowNode, styleNode);
641    FI_HILOGI("leave");
642}
643
644#ifndef OHOS_BUILD_ENABLE_ARKUI_X
645void DragDrawing::OnDragFail(IContext* context)
646#else
647void DragDrawing::OnDragFail()
648#endif // OHOS_BUILD_ENABLE_ARKUI_X
649{
650    FI_HILOGI("enter");
651    std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode = g_drawingInfo.surfaceNode;
652    CHKPV(surfaceNode);
653    std::shared_ptr<Rosen::RSNode> rootNode = g_drawingInfo.rootNode;
654    CHKPV(rootNode);
655#ifndef OHOS_BUILD_ENABLE_ARKUI_X
656    g_drawingInfo.context = context;
657#endif // OHOS_BUILD_ENABLE_ARKUI_X
658    OnStopDragFail(surfaceNode, rootNode);
659    FI_HILOGI("leave");
660}
661
662void DragDrawing::EraseMouseIcon()
663{
664    FI_HILOGI("enter");
665    if (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT) {
666        FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
667        return;
668    }
669    if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
670        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
671        return;
672    }
673    std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
674    CHKPV(mouseIconNode);
675    if (drawMouseIconModifier_ != nullptr) {
676        mouseIconNode->RemoveModifier(drawMouseIconModifier_);
677        drawMouseIconModifier_ = nullptr;
678    }
679    CHKPV(g_drawingInfo.rootNode);
680    g_drawingInfo.rootNode->RemoveChild(mouseIconNode);
681    CHKPV(rsUiDirector_);
682    rsUiDirector_->SendMessages();
683    FI_HILOGI("leave");
684}
685
686void DragDrawing::DestroyDragWindow()
687{
688    FI_HILOGI("enter");
689    ResetParameter();
690    RemoveModifier();
691    ClearMultiSelectedData();
692    if (!g_drawingInfo.nodes.empty()) {
693        g_drawingInfo.nodes.clear();
694        g_drawingInfo.nodes.shrink_to_fit();
695    }
696    if (g_drawingInfo.parentNode != nullptr) {
697        g_drawingInfo.parentNode->ClearChildren();
698        g_drawingInfo.parentNode.reset();
699        g_drawingInfo.parentNode = nullptr;
700    }
701    if (g_drawingInfo.rootNode != nullptr) {
702        g_drawingInfo.rootNode->ClearChildren();
703        g_drawingInfo.rootNode.reset();
704        g_drawingInfo.rootNode = nullptr;
705    }
706    if (g_drawingInfo.surfaceNode != nullptr) {
707        g_drawingInfo.surfaceNode->DetachToDisplay(screenId_);
708        screenId_ = 0;
709        g_drawingInfo.displayId = -1;
710        g_drawingInfo.surfaceNode = nullptr;
711        Rosen::RSTransaction::FlushImplicitTransaction();
712    }
713#ifdef OHOS_BUILD_ENABLE_ARKUI_X
714    CHKPV(callback_);
715    callback_();
716    window_ = nullptr;
717    g_dragData = {};
718    g_drawingInfo.pixelMap = nullptr;
719#endif // OHOS_BUILD_ENABLE_ARKUI_X
720    CHKPV(rsUiDirector_);
721    rsUiDirector_->SetRoot(-1);
722    rsUiDirector_->SendMessages();
723    FI_HILOGI("leave");
724}
725
726void DragDrawing::UpdateDrawingState()
727{
728    FI_HILOGD("enter");
729    g_drawingInfo.isRunning = false;
730    FI_HILOGD("leave");
731}
732
733void DragDrawing::UpdateDragWindowState(bool visible)
734{
735    CHKPV(g_drawingInfo.surfaceNode);
736    if (visible) {
737        g_drawingInfo.surfaceNode->SetVisible(true);
738        FI_HILOGI("Drag surfaceNode show success");
739    } else {
740        g_drawingInfo.surfaceNode->SetVisible(false);
741        FI_HILOGI("Drag surfaceNode hide success");
742    }
743    Rosen::RSTransaction::FlushImplicitTransaction();
744}
745
746void DragDrawing::OnStartDrag(const DragAnimationData &dragAnimationData,
747    std::shared_ptr<Rosen::RSCanvasNode> shadowNode, std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
748{
749    FI_HILOGI("enter");
750    CHKPV(shadowNode);
751    if (DrawShadow(shadowNode) != RET_OK) {
752        FI_HILOGE("Draw shadow failed");
753        return;
754    }
755    g_drawingInfo.isCurrentDefaultStyle = true;
756#ifndef OHOS_BUILD_ENABLE_ARKUI_X
757    if (dragExtHandler_ == nullptr) {
758        FI_HILOGE("Fail to open drag drop extension library");
759        return;
760    }
761    auto dragDropStartExtFunc = reinterpret_cast<DragStartExtFunc>(dlsym(dragExtHandler_, "OnStartDragExt"));
762    if (dragDropStartExtFunc == nullptr) {
763        FI_HILOGE("Fail to get drag drop extension function");
764        CHKPV(dragExtHandler_);
765        dlclose(dragExtHandler_);
766        dragExtHandler_ = nullptr;
767        return;
768    }
769#ifdef OHOS_DRAG_ENABLE_ANIMATION
770    if (!GetSuperHubHandler()->PostTask([dragDropStartExtFunc] { return dragDropStartExtFunc(g_dragData); })) {
771        FI_HILOGE("Start style animation failed");
772    }
773#endif // OHOS_DRAG_ENABLE_ANIMATION
774#endif // OHOS_BUILD_ENABLE_ARKUI_X
775    FI_HILOGI("leave");
776}
777
778#ifndef OHOS_BUILD_ENABLE_ARKUI_X
779void DragDrawing::NotifyDragInfo(const std::string &sourceName, const std::string &targetName)
780{
781    FI_HILOGI("NotifyDragInfo");
782    if (dragExtHandler_ == nullptr) {
783        FI_HILOGE("Fail to open drag drop extension library");
784        return;
785    }
786    auto dragDropExtFunc = reinterpret_cast<DragNotifyExtFunc>(dlsym(dragExtHandler_, "OnNotifyDragInfo"));
787    if (dragDropExtFunc == nullptr) {
788        FI_HILOGE("Fail to get drag drop extension function");
789        CHKPV(dragExtHandler_);
790        dlclose(dragExtHandler_);
791        dragExtHandler_ = nullptr;
792        return;
793    }
794    struct DragEventInfo dragEventInfo;
795    dragEventInfo.sourcePkgName = sourceName;
796    dragEventInfo.targetPkgName = targetName;
797    if (!GetSuperHubHandler()->PostTask([dragDropExtFunc, dragEventInfo] ()
798        mutable { return dragDropExtFunc(dragEventInfo); })) {
799        FI_HILOGE("notify drag info failed");
800    }
801}
802
803std::shared_ptr<AppExecFwk::EventHandler> DragDrawing::GetSuperHubHandler()
804{
805    if (superHubHandler_ == nullptr) {
806        auto runner = AppExecFwk::EventRunner::Create(SUPER_HUB_THREAD_NAME);
807        superHubHandler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
808    }
809    return superHubHandler_;
810}
811
812void DragDrawing::ResetSuperHubHandler()
813{
814    if (superHubHandler_ != nullptr) {
815        superHubHandler_->RemoveAllEvents();
816        superHubHandler_ = nullptr;
817    }
818}
819#endif // OHOS_BUILD_ENABLE_ARKUI_X
820
821float DragDrawing::AdjustDoubleValue(double doubleValue)
822{
823    FI_HILOGI("doubleValue is %{public}f", doubleValue);
824    float dragOriginDpi = DRAG_DATA_MGR.GetDragOriginDpi();
825    if (dragOriginDpi > EPSILON) {
826        float scalingValue = GetScaling() / dragOriginDpi;
827        doubleValue = doubleValue * scalingValue;
828        if (fabs(scalingValue - 1.0f) > EPSILON) {
829            float widthScale = CalculateWidthScale();
830            doubleValue = doubleValue * widthScale;
831        }
832    }
833    float floatValue = static_cast<float>(doubleValue);
834    FI_HILOGI("floatValue is %{public}f", floatValue);
835    return floatValue;
836}
837
838void DragDrawing::CheckStyleNodeModifier(std::shared_ptr<Rosen::RSCanvasNode> styleNode)
839{
840    FI_HILOGD("enter");
841    CHKPV(styleNode);
842    if (drawStyleChangeModifier_ != nullptr) {
843        styleNode->RemoveModifier(drawStyleChangeModifier_);
844        drawStyleChangeModifier_ = nullptr;
845    }
846    if (drawStyleScaleModifier_ != nullptr && hasRunningScaleAnimation_) {
847        needBreakStyleScaleAnimation_ = true;
848    }
849    styleNode->RemoveAllAnimations();
850    FI_HILOGD("leave");
851}
852
853void DragDrawing::RemoveStyleNodeModifier(std::shared_ptr<Rosen::RSCanvasNode> styleNode)
854{
855    FI_HILOGD("enter");
856    CHKPV(styleNode);
857    if (drawStyleChangeModifier_ != nullptr) {
858        styleNode->RemoveModifier(drawStyleChangeModifier_);
859        drawStyleChangeModifier_ = nullptr;
860    }
861    if (drawStyleScaleModifier_ != nullptr) {
862        styleNode->RemoveModifier(drawStyleScaleModifier_);
863        drawStyleScaleModifier_ = nullptr;
864    }
865    FI_HILOGD("leave");
866}
867
868void DragDrawing::UpdateAnimationProtocol(Rosen::RSAnimationTimingProtocol protocol)
869{
870    FI_HILOGD("enter");
871    g_drawingInfo.startNum = START_TIME;
872    interruptNum_ = START_TIME * INTERRUPT_SCALE;
873    hasRunningAnimation_ = true;
874    bool stopSignal = true;
875    CHKPV(rsUiDirector_);
876    while (hasRunningAnimation_) {
877        hasRunningAnimation_ = rsUiDirector_->FlushAnimation(g_drawingInfo.startNum);
878        rsUiDirector_->FlushModifier();
879        rsUiDirector_->SendMessages();
880        if ((g_drawingInfo.startNum >= interruptNum_) && stopSignal) {
881            protocol.SetDuration(TIME_STOP);
882            stopSignal = false;
883        }
884        g_drawingInfo.startNum += INTERVAL_TIME;
885        usleep(TIME_SLEEP);
886    }
887    FI_HILOGD("leave");
888}
889
890void DragDrawing::StartStyleAnimation(float startScale, float endScale, int32_t duration)
891{
892    FI_HILOGI("StartStyleAnimation, startScale is %{public}lf", startScale);
893    if (!CheckNodesValid() || needBreakStyleScaleAnimation_ || hasRunningStopAnimation_) {
894        FI_HILOGE("needBreakStyleScaleAnimation_ or hasRunningStopAnimation_, return");
895        return;
896    }
897    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
898        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
899        return;
900    }
901    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
902    CHKPV(dragStyleNode);
903    RemoveStyleNodeModifier(dragStyleNode);
904    drawStyleScaleModifier_ = std::make_shared<DrawStyleScaleModifier>();
905    dragStyleNode->AddModifier(drawStyleScaleModifier_);
906    CHKPV(drawStyleScaleModifier_);
907    drawStyleScaleModifier_->SetScale(startScale);
908    Rosen::RSAnimationTimingProtocol protocol;
909    protocol.SetDuration(duration);
910    auto springCurveStyle = endScale == STYLE_END_SCALE
911        ? Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_030, BEZIER_000, BEZIER_040, BEZIER_100)
912        : Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_020, BEZIER_000, BEZIER_060, BEZIER_100);
913    Rosen::RSNode::Animate(protocol, springCurveStyle, [&]() {
914        if (drawStyleScaleModifier_ != nullptr) {
915            drawStyleScaleModifier_->SetScale(endScale);
916        }
917    }, []() { FI_HILOGD("StartStyleAnimation end"); });
918    UpdateAnimationProtocol(protocol);
919    if (endScale == STYLE_CHANGE_SCALE) {
920        if (drawStyleChangeModifier_ != nullptr) {
921            dragStyleNode->RemoveModifier(drawStyleChangeModifier_);
922            drawStyleChangeModifier_ = nullptr;
923        }
924        if (drawStyleScaleModifier_ != nullptr) {
925            dragStyleNode->RemoveModifier(drawStyleScaleModifier_);
926            drawStyleScaleModifier_ = nullptr;
927        }
928        drawStyleChangeModifier_ = std::make_shared<DrawStyleChangeModifier>(g_drawingInfo.stylePixelMap);
929        dragStyleNode->AddModifier(drawStyleChangeModifier_);
930    }
931    if (endScale == STYLE_END_SCALE && drawStyleScaleModifier_ != nullptr) {
932        dragStyleNode->RemoveModifier(drawStyleScaleModifier_);
933        drawStyleScaleModifier_ = nullptr;
934    }
935}
936
937void DragDrawing::ChangeStyleAnimation()
938{
939    FI_HILOGD("enter");
940    hasRunningScaleAnimation_ = true;
941    StartStyleAnimation(START_STYLE_SCALE, STYLE_CHANGE_SCALE, TIME_DRAG_CHANGE_STYLE);
942    StartStyleAnimation(STYLE_CHANGE_SCALE, STYLE_MAX_SCALE, TIME_DRAG_CHANGE_STYLE);
943    StartStyleAnimation(STYLE_MAX_SCALE, STYLE_END_SCALE, TIME_DRAG_STYLE);
944    needBreakStyleScaleAnimation_ = false;
945    hasRunningScaleAnimation_ = false;
946    FI_HILOGD("leave");
947}
948
949void DragDrawing::OnDragStyleAnimation()
950{
951    FI_HILOGD("enter");
952    if (!CheckNodesValid()) {
953        FI_HILOGE("Check nodes valid failed");
954        return;
955    }
956    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
957        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
958        return;
959    }
960    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
961    CHKPV(dragStyleNode);
962    needBreakStyleScaleAnimation_ = false;
963    if (g_drawingInfo.isPreviousDefaultStyle == true || g_drawingInfo.isCurrentDefaultStyle == true) {
964        FI_HILOGE("Has DefaultStyle, change style and return");
965        CheckStyleNodeModifier(dragStyleNode);
966        drawStyleChangeModifier_ = std::make_shared<DrawStyleChangeModifier>(g_drawingInfo.stylePixelMap);
967        dragStyleNode->AddModifier(drawStyleChangeModifier_);
968        return;
969    }
970#ifndef OHOS_BUILD_ENABLE_ARKUI_X
971    if (handler_ == nullptr) {
972        auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
973        handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
974    }
975#endif // OHOS_BUILD_ENABLE_ARKUI_X
976    CheckStyleNodeModifier(dragStyleNode);
977#ifndef OHOS_BUILD_ENABLE_ARKUI_X
978    handler_->PostTask(std::bind(&DragDrawing::ChangeStyleAnimation, this));
979#else
980    ChangeStyleAnimation();
981#endif
982    FI_HILOGD("leave");
983}
984
985void DragDrawing::OnDragStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,
986    std::shared_ptr<Media::PixelMap> stylePixelMap)
987{
988    FI_HILOGD("enter");
989    CHKPV(dragStyleNode);
990    CHKPV(stylePixelMap);
991#ifdef OHOS_DRAG_ENABLE_ANIMATION
992    if (handler_ == nullptr) {
993        auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
994        CHKPV(runner);
995        handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
996    }
997    if (drawSVGModifier_ != nullptr) {
998        dragStyleNode->RemoveModifier(drawSVGModifier_);
999        drawSVGModifier_ = nullptr;
1000    }
1001    if (!handler_->PostTask([this] { this->OnDragStyleAnimation(); })) {
1002        FI_HILOGE("Drag style animation failed");
1003        DrawStyle(dragStyleNode, stylePixelMap);
1004    }
1005#else // OHOS_DRAG_ENABLE_ANIMATION
1006    DrawStyle(dragStyleNode, stylePixelMap);
1007#endif // OHOS_DRAG_ENABLE_ANIMATION
1008    FI_HILOGD("leave");
1009}
1010
1011void DragDrawing::OnStopAnimationSuccess()
1012{
1013    FI_HILOGI("enter");
1014    if (!CheckNodesValid()) {
1015        FI_HILOGE("Check nodes valid failed");
1016        return;
1017    }
1018    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
1019        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1020        return;
1021    }
1022    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1023    if (dragStyleNode != nullptr && drawStyleScaleModifier_ != nullptr) {
1024        dragStyleNode->RemoveModifier(drawStyleScaleModifier_);
1025        dragStyleNode->RemoveAllAnimations();
1026        drawStyleScaleModifier_ = nullptr;
1027        needBreakStyleScaleAnimation_ = true;
1028    }
1029    CHKPV(g_drawingInfo.rootNode);
1030    hasRunningStopAnimation_ = true;
1031    if (drawDragStopModifier_ != nullptr) {
1032        g_drawingInfo.rootNode->RemoveModifier(drawDragStopModifier_);
1033        drawDragStopModifier_ = nullptr;
1034    }
1035    drawDragStopModifier_ = std::make_shared<DrawDragStopModifier>();
1036    g_drawingInfo.rootNode->AddModifier(drawDragStopModifier_);
1037    drawDragStopModifier_->SetAlpha(BEGIN_ALPHA);
1038    drawDragStopModifier_->SetScale(BEGIN_SCALE);
1039    drawDragStopModifier_->SetStyleScale(START_STYLE_SCALE);
1040    drawDragStopModifier_->SetStyleAlpha(START_STYLE_ALPHA);
1041    Rosen::RSAnimationTimingProtocol windowProtocol;
1042    Rosen::RSAnimationTimingProtocol styleProtocol;
1043    windowProtocol.SetDuration(TIME_STOP_SUCCESS_WINDOW);
1044    styleProtocol.SetDuration(TIME_STOP_SUCCESS_STYLE);
1045    auto springCurveSuccessWindow = Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_040, BEZIER_000,
1046        BEZIER_100, BEZIER_100);
1047    auto springCurveSuccessStyle = Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_000, BEZIER_000,
1048        BEZIER_100, BEZIER_100);
1049    Rosen::RSNode::Animate(windowProtocol, springCurveSuccessWindow, [&]() {
1050        drawDragStopModifier_->SetAlpha(BEGIN_ALPHA);
1051        drawDragStopModifier_->SetScale(END_SCALE_SUCCESS);
1052        Rosen::RSNode::Animate(styleProtocol, springCurveSuccessStyle, [&]() {
1053            drawDragStopModifier_->SetStyleAlpha(END_STYLE_ALPHA);
1054            drawDragStopModifier_->SetStyleScale(START_STYLE_SCALE);
1055        });
1056    }, []() { FI_HILOGD("OnStopAnimationSuccess end"); });
1057    DoEndAnimation();
1058    FI_HILOGI("leave");
1059}
1060
1061void DragDrawing::OnStopDragSuccess(std::shared_ptr<Rosen::RSCanvasNode> shadowNode,
1062    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
1063{
1064    FI_HILOGD("enter");
1065    auto animateCb = [this] { return this->InitVSync(END_ALPHA, END_SCALE_SUCCESS); };
1066#ifdef OHOS_DRAG_ENABLE_ANIMATION
1067    ResetAnimationParameter();
1068    auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
1069    CHKPV(runner);
1070    handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1071    if (!handler_->PostTask([this] { return this->OnStopAnimationSuccess(); })) {
1072        FI_HILOGE("Failed to stop style animation");
1073        RunAnimation(animateCb);
1074    }
1075#else // OHOS_DRAG_ENABLE_ANIMATION
1076    RunAnimation(animateCb);
1077#endif // OHOS_DRAG_ENABLE_ANIMATION
1078    FI_HILOGD("leave");
1079}
1080
1081void DragDrawing::OnStopAnimationFail()
1082{
1083    FI_HILOGI("enter");
1084    if (!CheckNodesValid()) {
1085        FI_HILOGE("Check nodes valid failed");
1086        return;
1087    }
1088    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
1089        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1090        return;
1091    }
1092    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1093    if (dragStyleNode != nullptr && drawStyleScaleModifier_ != nullptr) {
1094        dragStyleNode->RemoveModifier(drawStyleScaleModifier_);
1095        dragStyleNode->RemoveAllAnimations();
1096        drawStyleScaleModifier_ = nullptr;
1097        needBreakStyleScaleAnimation_ = true;
1098    }
1099    CHKPV(g_drawingInfo.rootNode);
1100    if (drawDragStopModifier_ != nullptr) {
1101        g_drawingInfo.rootNode->RemoveModifier(drawDragStopModifier_);
1102        drawDragStopModifier_ = nullptr;
1103    }
1104    drawDragStopModifier_ = std::make_shared<DrawDragStopModifier>();
1105    hasRunningStopAnimation_ = true;
1106    g_drawingInfo.rootNode->AddModifier(drawDragStopModifier_);
1107    drawDragStopModifier_->SetAlpha(BEGIN_ALPHA);
1108    drawDragStopModifier_->SetScale(BEGIN_SCALE);
1109    drawDragStopModifier_->SetStyleScale(START_STYLE_SCALE);
1110    drawDragStopModifier_->SetStyleAlpha(START_STYLE_ALPHA);
1111    Rosen::RSAnimationTimingProtocol protocol;
1112    protocol.SetDuration(TIME_STOP_FAIL_WINDOW);
1113    auto springCurveFail = Rosen::RSAnimationTimingCurve::CreateCubicCurve(BEZIER_033, BEZIER_000,
1114        BEZIER_067, BEZIER_100);
1115    Rosen::RSNode::Animate(protocol, springCurveFail, [&]() {
1116        drawDragStopModifier_->SetAlpha(END_ALPHA);
1117        drawDragStopModifier_->SetScale(END_SCALE_FAIL);
1118        drawDragStopModifier_->SetStyleScale(START_STYLE_SCALE);
1119        drawDragStopModifier_->SetStyleAlpha(END_STYLE_ALPHA);
1120    }, []() { FI_HILOGD("OnStopAnimationFail end"); });
1121    DoEndAnimation();
1122    FI_HILOGI("leave");
1123}
1124
1125void DragDrawing::OnStopDragFail(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,
1126    std::shared_ptr<Rosen::RSNode> rootNode)
1127{
1128    FI_HILOGD("enter");
1129    auto animateCb = [this] { return this->InitVSync(END_ALPHA, END_SCALE_FAIL); };
1130#ifdef OHOS_DRAG_ENABLE_ANIMATION
1131    ResetAnimationParameter();
1132    auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
1133    CHKPV(runner);
1134    handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1135    if (!handler_->PostTask([this] { this->OnStopAnimationFail(); })) {
1136        FI_HILOGE("Failed to stop style animation");
1137        RunAnimation(animateCb);
1138    }
1139#else // OHOS_DRAG_ENABLE_ANIMATION
1140    RunAnimation(animateCb);
1141#endif // OHOS_DRAG_ENABLE_ANIMATION
1142    FI_HILOGD("leave");
1143}
1144
1145void DragDrawing::OnStopAnimation()
1146{
1147    FI_HILOGD("enter");
1148}
1149
1150int32_t DragDrawing::RunAnimation(std::function<int32_t()> cb)
1151{
1152    FI_HILOGD("enter");
1153    ResetAnimationParameter();
1154#ifndef IOS_PLATFORM
1155    auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
1156#else
1157    auto runner = AppExecFwk::EventRunner::Current(); // IOS animation can run main thread
1158#endif // IOS_PLATFORM
1159    CHKPR(runner, RET_ERR);
1160    handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
1161    if (!handler_->PostTask(cb)) {
1162        FI_HILOGE("Send vsync event failed");
1163        return RET_ERR;
1164    }
1165    FI_HILOGD("leave");
1166    return RET_OK;
1167}
1168
1169int32_t DragDrawing::DrawShadow(std::shared_ptr<Rosen::RSCanvasNode> shadowNode)
1170{
1171    FI_HILOGD("enter");
1172    CHKPR(shadowNode, RET_ERR);
1173    if (drawPixelMapModifier_ != nullptr) {
1174        shadowNode->RemoveModifier(drawPixelMapModifier_);
1175        drawPixelMapModifier_ = nullptr;
1176    }
1177    drawPixelMapModifier_ = std::make_shared<DrawPixelMapModifier>();
1178    shadowNode->AddModifier(drawPixelMapModifier_);
1179    FilterInfo filterInfo = g_drawingInfo.filterInfo;
1180    Rosen::Vector4f cornerRadiusVector = { filterInfo.cornerRadius1, filterInfo.cornerRadius2,
1181        filterInfo.cornerRadius3, filterInfo.cornerRadius4 };
1182    shadowNode->SetCornerRadius(cornerRadiusVector * filterInfo.dipScale * filterInfo.scale);
1183    shadowNode->SetAlpha(filterInfo.opacity);
1184    FI_HILOGD("leave");
1185    return RET_OK;
1186}
1187
1188int32_t DragDrawing::DrawMouseIcon()
1189{
1190    FI_HILOGD("enter");
1191    if (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT) {
1192        FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
1193        return RET_ERR;
1194    }
1195    if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
1196        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1197        return RET_ERR;
1198    }
1199    std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
1200    CHKPR(mouseIconNode, RET_ERR);
1201    if (drawMouseIconModifier_ != nullptr) {
1202        mouseIconNode->RemoveModifier(drawMouseIconModifier_);
1203        drawMouseIconModifier_ = nullptr;
1204    }
1205#ifndef OHOS_BUILD_ENABLE_ARKUI_X
1206    int32_t ret = MMI::InputManager::GetInstance()->GetPointerStyle(GLOBAL_WINDOW_ID, pointerStyle_);
1207    if (ret != RET_OK) {
1208        FI_HILOGE("Get pointer style failed, ret:%{public}d", ret);
1209        return RET_ERR;
1210    }
1211    drawMouseIconModifier_ = std::make_shared<DrawMouseIconModifier>(pointerStyle_);
1212    mouseIconNode->AddModifier(drawMouseIconModifier_);
1213#endif // OHOS_BUILD_ENABLE_ARKUI_X
1214    FI_HILOGD("leave");
1215    return RET_OK;
1216}
1217
1218void DragDrawing::FlushDragPosition(uint64_t nanoTimestamp)
1219{
1220#ifndef OHOS_BUILD_ENABLE_ARKUI_X
1221    if (rsUiDirector_ != nullptr) {
1222        rsUiDirector_->SetTimeStamp(nanoTimestamp, RENDER_THREAD_NAME);
1223    } else {
1224        FI_HILOGE("rsUiDirector_ is nullptr");
1225    }
1226    DragMoveEvent event = dragSmoothProcessor_.SmoothMoveEvent(nanoTimestamp,
1227        vSyncStation_.GetVSyncPeriod());
1228    FI_HILOGD("Move position x:%{private}f, y:%{private}f, timestamp:%{public}" PRId64
1229        "displayId:%{public}d", event.displayX, event.displayY, event.timestamp, event.displayId);
1230    UpdateDragPosition(event.displayId, event.displayX, event.displayY);
1231#endif // OHOS_BUILD_ENABLE_ARKUI_X
1232}
1233
1234void DragDrawing::OnDragMove(int32_t displayId, int32_t displayX, int32_t displayY, int64_t actionTime)
1235{
1236    if (isRunningRotateAnimation_) {
1237        FI_HILOGD("Doing rotate drag window animate, ignore draw drag window");
1238        return;
1239    }
1240#ifdef IOS_PLATFORM
1241    actionTime_ = actionTime;
1242#endif // IOS_PLATFORM
1243#ifndef OHOS_BUILD_ENABLE_ARKUI_X
1244    std::chrono::microseconds microseconds(actionTime);
1245    TimeStamp time(microseconds);
1246    uint64_t actionTimeCount = static_cast<uint64_t>(time.time_since_epoch().count());
1247    DragMoveEvent event = {
1248        .displayX = displayX,
1249        .displayY = displayY,
1250        .displayId = displayId,
1251        .timestamp = actionTimeCount,
1252    };
1253    dragSmoothProcessor_.InsertEvent(event);
1254    if (frameCallback_ == nullptr) {
1255        frameCallback_ = std::make_shared<DragFrameCallback>([this](uint64_t nanoTimestamp) {
1256            this->FlushDragPosition(nanoTimestamp);
1257        });
1258    }
1259    vSyncStation_.RequestFrame(TYPE_FLUSH_DRAG_POSITION, frameCallback_);
1260#else
1261    UpdateDragPosition(displayId, displayX, displayY);
1262#endif // OHOS_BUILD_ENABLE_ARKUI_X
1263}
1264
1265int32_t DragDrawing::DrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,
1266    std::shared_ptr<Media::PixelMap> stylePixelMap)
1267{
1268    FI_HILOGD("enter");
1269    CHKPR(dragStyleNode, RET_ERR);
1270    CHKPR(stylePixelMap, RET_ERR);
1271    if (drawSVGModifier_ != nullptr) {
1272        dragStyleNode->RemoveModifier(drawSVGModifier_);
1273        drawSVGModifier_ = nullptr;
1274    }
1275    drawSVGModifier_ = std::make_shared<DrawSVGModifier>(stylePixelMap);
1276    dragStyleNode->AddModifier(drawSVGModifier_);
1277    FI_HILOGD("leave");
1278    return RET_OK;
1279}
1280
1281int32_t DragDrawing::InitVSync(float endAlpha, float endScale)
1282{
1283    FI_HILOGD("enter");
1284    CHKPR(g_drawingInfo.rootNode, RET_ERR);
1285    if (drawDynamicEffectModifier_ != nullptr) {
1286        g_drawingInfo.rootNode->RemoveModifier(drawDynamicEffectModifier_);
1287        drawDynamicEffectModifier_ = nullptr;
1288    }
1289    drawDynamicEffectModifier_ = std::make_shared<DrawDynamicEffectModifier>();
1290    g_drawingInfo.rootNode->AddModifier(drawDynamicEffectModifier_);
1291    drawDynamicEffectModifier_->SetAlpha(BEGIN_ALPHA);
1292    drawDynamicEffectModifier_->SetScale(BEGIN_SCALE);
1293
1294    Rosen::RSAnimationTimingProtocol protocol;
1295    protocol.SetDuration(SUCCESS_ANIMATION_DURATION);
1296    Rosen::RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
1297        drawDynamicEffectModifier_->SetAlpha(endAlpha);
1298        drawDynamicEffectModifier_->SetScale(endScale);
1299    }, []() { FI_HILOGD("InitVSync end"); });
1300    Rosen::RSTransaction::FlushImplicitTransaction();
1301    DoEndAnimation();
1302    FI_HILOGD("leave");
1303    return RET_OK;
1304}
1305
1306int32_t DragDrawing::StartVsync()
1307{
1308    FI_HILOGI("enter");
1309    if (receiver_ == nullptr) {
1310        CHKPR(handler_, RET_ERR);
1311        receiver_ = Rosen::RSInterfaces::GetInstance().CreateVSyncReceiver("DragDrawing", handler_);
1312        CHKPR(receiver_, RET_ERR);
1313    }
1314#ifdef IOS_PLATFORM
1315    rsUiDirector_->FlushAnimation(g_drawingInfo.startNum);
1316#endif // IOS_PLATFORM
1317    int32_t ret = receiver_->Init();
1318    if (ret != RET_OK) {
1319        FI_HILOGE("Receiver init failed");
1320        return RET_ERR;
1321    }
1322    Rosen::VSyncReceiver::FrameCallback fcb = {
1323        .userData_ = this,
1324        .callback_ = [this](int64_t parm1, void *parm2) { this->OnVsync(); }
1325    };
1326    ret = receiver_->RequestNextVSync(fcb);
1327    if (ret != RET_OK) {
1328        FI_HILOGE("Request next vsync failed");
1329    }
1330    FI_HILOGI("leave");
1331    return ret;
1332}
1333
1334void DragDrawing::OnVsync()
1335{
1336    FI_HILOGD("enter");
1337    CHKPV(rsUiDirector_);
1338    bool hasRunningAnimation = rsUiDirector_->FlushAnimation(g_drawingInfo.startNum);
1339    rsUiDirector_->FlushModifier();
1340    rsUiDirector_->SendMessages();
1341    if (!hasRunningAnimation) {
1342        FI_HILOGI("Stop runner, hasRunningAnimation:%{public}d, needDestroyDragWindow:%{public}d",
1343            hasRunningAnimation, g_drawingInfo.needDestroyDragWindow.load());
1344        if (g_drawingInfo.needDestroyDragWindow) {
1345            ResetAnimationFlag();
1346        }
1347        return;
1348    }
1349    Rosen::VSyncReceiver::FrameCallback fcb = {
1350        .userData_ = this,
1351        .callback_ = [this](int64_t parm1, void *parm2) { this->OnVsync(); }
1352    };
1353    CHKPV(receiver_);
1354    int32_t ret = receiver_->RequestNextVSync(fcb);
1355    if (ret != RET_OK) {
1356        FI_HILOGE("Request next vsync failed");
1357    }
1358    rsUiDirector_->SendMessages();
1359    g_drawingInfo.startNum += INTERVAL_TIME;
1360    FI_HILOGD("leave");
1361}
1362
1363void DragDrawing::InitDrawingInfo(const DragData &dragData)
1364{
1365    g_drawingInfo.isRunning = true;
1366    if (dragData.shadowInfos.empty()) {
1367        FI_HILOGE("ShadowInfos is empty");
1368        return;
1369    }
1370    g_drawingInfo.pixelMap = dragData.shadowInfos.front().pixelMap;
1371    g_drawingInfo.pixelMapX = dragData.shadowInfos.front().x;
1372    g_drawingInfo.pixelMapY = dragData.shadowInfos.front().y;
1373    float dragOriginDpi = DRAG_DATA_MGR.GetDragOriginDpi();
1374    if (dragOriginDpi > EPSILON) {
1375        float scalingValue = GetScaling() / dragOriginDpi;
1376        CHKPV(g_drawingInfo.pixelMap);
1377        g_drawingInfo.pixelMap->scale(scalingValue, scalingValue, Media::AntiAliasingOption::HIGH);
1378        g_drawingInfo.pixelMapX = g_drawingInfo.pixelMapX * scalingValue;
1379        g_drawingInfo.pixelMapY = g_drawingInfo.pixelMapY * scalingValue;
1380        if (fabs(scalingValue - 1.0f) > EPSILON) {
1381            float widthScale = CalculateWidthScale();
1382            CHKPV(g_drawingInfo.pixelMap);
1383            g_drawingInfo.pixelMap->scale(widthScale, widthScale, Media::AntiAliasingOption::HIGH);
1384            g_drawingInfo.pixelMapX = g_drawingInfo.pixelMapX * widthScale;
1385            g_drawingInfo.pixelMapY = g_drawingInfo.pixelMapY * widthScale;
1386        }
1387    }
1388    g_drawingInfo.currentDragNum = dragData.dragNum;
1389    g_drawingInfo.sourceType = dragData.sourceType;
1390    g_drawingInfo.displayId = dragData.displayId;
1391    g_drawingInfo.displayX = dragData.displayX;
1392    g_drawingInfo.displayY = dragData.displayY;
1393    RotateDisplayXY(g_drawingInfo.displayX, g_drawingInfo.displayY);
1394    if (!ParserExtraInfo(dragData.extraInfo, g_drawingInfo.extraInfo)) {
1395        FI_HILOGI("No parser valid extraInfo data");
1396    }
1397    if (!ParserFilterInfo(dragData.filterInfo, g_drawingInfo.filterInfo)) {
1398        FI_HILOGI("No parser valid filterInfo data");
1399    }
1400    size_t shadowInfosSize = dragData.shadowInfos.size();
1401    for (size_t i = 1; i < shadowInfosSize; ++i) {
1402        std::shared_ptr<Media::PixelMap> pixelMap = dragData.shadowInfos[i].pixelMap;
1403        if (dragOriginDpi > EPSILON) {
1404            float scalingValue = GetScaling() / dragOriginDpi;
1405            CHKPV(pixelMap);
1406            pixelMap->scale(scalingValue, scalingValue, Media::AntiAliasingOption::HIGH);
1407        }
1408        g_drawingInfo.multiSelectedPixelMaps.emplace_back(pixelMap);
1409    }
1410}
1411
1412int32_t DragDrawing::InitDragAnimationData(DragAnimationData &dragAnimationData)
1413{
1414    CHKPR(g_drawingInfo.pixelMap, RET_ERR);
1415    dragAnimationData.pixelMap = g_drawingInfo.pixelMap;
1416    dragAnimationData.displayX = g_drawingInfo.displayX;
1417    dragAnimationData.displayY = g_drawingInfo.displayY;
1418    dragAnimationData.offsetX = g_drawingInfo.pixelMapX;
1419    dragAnimationData.offsetY = g_drawingInfo.pixelMapY;
1420    return RET_OK;
1421}
1422
1423int32_t DragDrawing::InitLayer()
1424{
1425    FI_HILOGI("enter");
1426    if (g_drawingInfo.surfaceNode == nullptr) {
1427        FI_HILOGE("Init layer failed, surfaceNode is nullptr");
1428        return RET_ERR;
1429    }
1430#ifndef OHOS_BUILD_ENABLE_ARKUI_X
1431    auto surface = g_drawingInfo.surfaceNode->GetSurface();
1432    if (surface == nullptr) {
1433        g_drawingInfo.surfaceNode->DetachToDisplay(g_drawingInfo.displayId);
1434        g_drawingInfo.surfaceNode = nullptr;
1435        FI_HILOGE("Init layer failed, surface is nullptr");
1436        Rosen::RSTransaction::FlushImplicitTransaction();
1437        return RET_ERR;
1438    }
1439#endif // OHOS_BUILD_ENABLE_ARKUI_X
1440    if (g_drawingInfo.isInitUiDirector) {
1441        g_drawingInfo.isInitUiDirector = false;
1442        rsUiDirector_ = Rosen::RSUIDirector::Create();
1443        CHKPR(rsUiDirector_, RET_ERR);
1444        rsUiDirector_->Init();
1445        rsUiDirector_->SetUITaskRunner([this](const std::function<void()> &task, uint32_t delay = 0) {
1446            CHKPV(this->handler_);
1447            this->handler_->PostTask(task, delay);
1448        });
1449    }
1450    rsUiDirector_->SetRSSurfaceNode(g_drawingInfo.surfaceNode);
1451#ifndef OHOS_BUILD_ENABLE_ARKUI_X
1452    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
1453    if (display == nullptr) {
1454        FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
1455        display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
1456        if (display == nullptr) {
1457            FI_HILOGE("Get display info failed, display is nullptr");
1458            return RET_ERR;
1459        }
1460    }
1461    int32_t rootNodeSize = std::max(display->GetWidth(), display->GetHeight());
1462    InitCanvas(rootNodeSize, rootNodeSize);
1463#else
1464    CHKPR(window_, RET_ERR);
1465    InitCanvas(window_->GetRect().width_, window_->GetRect().height_);
1466#endif // OHOS_BUILD_ENABLE_ARKUI_X
1467    if (rotation_ != Rosen::Rotation::ROTATION_0) {
1468        RotateDragWindow(rotation_);
1469    } else {
1470        DragWindowRotateInfo_.rotation = ROTATION_0;
1471    }
1472    Rosen::RSTransaction::FlushImplicitTransaction();
1473    FI_HILOGI("leave");
1474    return RET_OK;
1475}
1476
1477void DragDrawing::InitCanvas(int32_t width, int32_t height)
1478{
1479    FI_HILOGI("enter");
1480    if (g_drawingInfo.rootNode == nullptr) {
1481        g_drawingInfo.rootNode = Rosen::RSRootNode::Create();
1482        CHKPV(g_drawingInfo.rootNode);
1483    }
1484    g_drawingInfo.rootNode->SetBounds(0, 0, width, height);
1485    g_drawingInfo.rootNode->SetFrame(0, 0, width, height);
1486    g_drawingInfo.rootNode->SetBackgroundColor(SK_ColorTRANSPARENT);
1487    std::shared_ptr<Rosen::RSCanvasNode> filterNode = Rosen::RSCanvasNode::Create();
1488    CHKPV(filterNode);
1489    g_drawingInfo.nodes.emplace_back(filterNode);
1490    ProcessFilter();
1491    std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = Rosen::RSCanvasNode::Create();
1492    CHKPV(pixelMapNode);
1493    pixelMapNode->SetForegroundColor(TRANSPARENT_COLOR_ARGB);
1494    pixelMapNode->SetGrayScale(g_drawingInfo.filterInfo.dragNodeGrayscale);
1495    g_drawingInfo.nodes.emplace_back(pixelMapNode);
1496    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = Rosen::RSCanvasNode::Create();
1497    CHKPV(dragStyleNode);
1498    g_drawingInfo.nodes.emplace_back(dragStyleNode);
1499    if (g_drawingInfo.parentNode == nullptr) {
1500        g_drawingInfo.parentNode = Rosen::RSCanvasNode::Create();
1501        CHKPV(g_drawingInfo.parentNode);
1502    }
1503    g_drawingInfo.parentNode->AddChild(filterNode);
1504    g_drawingInfo.parentNode->AddChild(pixelMapNode);
1505    if (!g_drawingInfo.multiSelectedPixelMaps.empty()) {
1506        InitMultiSelectedNodes();
1507        if (!g_drawingInfo.multiSelectedNodes.empty()) {
1508            size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
1509            for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
1510                g_drawingInfo.rootNode->AddChild(g_drawingInfo.multiSelectedNodes[i]);
1511            }
1512        }
1513    }
1514    g_drawingInfo.rootNode->AddChild(g_drawingInfo.parentNode);
1515    CHKPV(rsUiDirector_);
1516    if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
1517        std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = Rosen::RSCanvasNode::Create();
1518        CHKPV(mouseIconNode);
1519        g_drawingInfo.nodes.emplace_back(mouseIconNode);
1520        g_drawingInfo.rootNode->AddChild(mouseIconNode);
1521        rsUiDirector_->SetRoot(g_drawingInfo.rootNode->GetId());
1522        return;
1523    }
1524    rsUiDirector_->SetRoot(g_drawingInfo.rootNode->GetId());
1525    FI_HILOGI("leave");
1526}
1527
1528void DragDrawing::CreateWindow()
1529{
1530#ifndef OHOS_BUILD_ENABLE_ARKUI_X
1531    FI_HILOGD("Parameter screen number:%{public}llu", static_cast<unsigned long long>(screenId_));
1532    Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
1533    surfaceNodeConfig.SurfaceNodeName = "drag window";
1534    Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
1535    g_drawingInfo.surfaceNode = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
1536    CHKPV(g_drawingInfo.surfaceNode);
1537    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
1538    if (display == nullptr) {
1539        FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
1540        display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
1541        if (display == nullptr) {
1542            FI_HILOGE("Get display info failed, display is nullptr");
1543            return;
1544        }
1545    }
1546    uint64_t rsScreenId = screenId_;
1547    sptr<Rosen::Screen> screen = Rosen::ScreenManager::GetInstance().GetScreenById(screenId_);
1548    if ((screen != nullptr) && (!screen->IsReal())) {
1549        if (!Rosen::DisplayManager::GetInstance().ConvertScreenIdToRsScreenId(screenId_, rsScreenId)) {
1550            FI_HILOGE("ConvertScreenIdToRsScreenId failed");
1551            return;
1552        }
1553    }
1554    screenId_ = rsScreenId;
1555    int32_t surfaceNodeSize = std::max(display->GetWidth(), display->GetHeight());
1556    g_drawingInfo.surfaceNode->SetBounds(0, 0, surfaceNodeSize, surfaceNodeSize);
1557#else
1558    CHKPV(window_);
1559    g_drawingInfo.surfaceNode = window_->GetSurfaceNode();
1560    CHKPV(g_drawingInfo.surfaceNode);
1561    g_drawingInfo.surfaceNode->SetBounds(0, 0, window_->GetRect().width_, window_->GetRect().height_);
1562#endif // OHOS_BUILD_ENABLE_ARKUI_X
1563    g_drawingInfo.surfaceNode->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
1564    g_drawingInfo.surfaceNode->SetPositionZ(DRAG_WINDOW_POSITION_Z);
1565    g_drawingInfo.surfaceNode->SetBackgroundColor(SK_ColorTRANSPARENT);
1566#ifndef OHOS_BUILD_ENABLE_ARKUI_X
1567    g_drawingInfo.surfaceNode->AttachToDisplay(rsScreenId);
1568#endif // OHOS_BUILD_ENABLE_ARKUI_X
1569    g_drawingInfo.surfaceNode->SetVisible(false);
1570    Rosen::RSTransaction::FlushImplicitTransaction();
1571}
1572
1573void DragDrawing::RemoveModifier()
1574{
1575    FI_HILOGD("enter");
1576    if ((g_drawingInfo.nodes.size() < TOUCH_NODE_MIN_COUNT)) {
1577        FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
1578        return;
1579    }
1580
1581    if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX || g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
1582        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
1583        return;
1584    }
1585    std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
1586    CHKPV(pixelMapNode);
1587    if (drawPixelMapModifier_ != nullptr) {
1588        pixelMapNode->RemoveModifier(drawPixelMapModifier_);
1589        drawPixelMapModifier_ = nullptr;
1590    }
1591    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1592    CHKPV(dragStyleNode);
1593    if (drawSVGModifier_ != nullptr) {
1594        dragStyleNode->RemoveModifier(drawSVGModifier_);
1595        drawSVGModifier_ = nullptr;
1596    }
1597    FI_HILOGD("leave");
1598}
1599
1600int32_t DragDrawing::UpdateSvgNodeInfo(xmlNodePtr curNode, int32_t extendSvgWidth)
1601{
1602    FI_HILOGD("enter");
1603    if (xmlStrcmp(curNode->name, BAD_CAST "svg")) {
1604        FI_HILOGE("Svg format invalid");
1605        return RET_ERR;
1606    }
1607    std::ostringstream oStrStream;
1608    oStrStream << xmlGetProp(curNode, BAD_CAST "width");
1609    std::string srcSvgWidth = oStrStream.str();
1610    if (srcSvgWidth.length() < STRING_PX_LENGTH) {
1611        FI_HILOGE("Svg width invalid, srcSvgWidth:%{public}s", srcSvgWidth.c_str());
1612        return RET_ERR;
1613    }
1614    srcSvgWidth = srcSvgWidth.substr(0, srcSvgWidth.length() - STRING_PX_LENGTH);
1615    if (!IsNum(srcSvgWidth)) {
1616        FI_HILOGE("srcSvgWidth is not digital, srcSvgWidth:%{public}s", srcSvgWidth.c_str());
1617        return RET_ERR;
1618    }
1619    int32_t number = std::stoi(srcSvgWidth) + extendSvgWidth;
1620    std::string tgtSvgWidth = std::to_string(number);
1621    tgtSvgWidth.append("px");
1622    xmlSetProp(curNode, BAD_CAST "width", BAD_CAST tgtSvgWidth.c_str());
1623    oStrStream.str("");
1624    oStrStream << xmlGetProp(curNode, BAD_CAST "viewBox");
1625    std::string srcViewBox = oStrStream.str();
1626    std::istringstream iStrStream(srcViewBox);
1627    std::string tmpString;
1628    std::string tgtViewBox;
1629    int32_t i = 0;
1630    while (iStrStream >> tmpString) {
1631        if (i == VIEW_BOX_POS) {
1632            if (!IsNum(tmpString)) {
1633                FI_HILOGE("tmpString is not digital, tmpString:%{public}s", tmpString.c_str());
1634                return RET_ERR;
1635            }
1636            number = std::stoi(tmpString) + extendSvgWidth;
1637            tmpString = std::to_string(number);
1638        }
1639        tgtViewBox.append(tmpString);
1640        tgtViewBox += " ";
1641        ++i;
1642    }
1643
1644    xmlSetProp(curNode, BAD_CAST "viewBox", BAD_CAST tgtViewBox.c_str());
1645    FI_HILOGD("leave");
1646    return RET_OK;
1647}
1648
1649xmlNodePtr DragDrawing::GetRectNode(xmlNodePtr curNode)
1650{
1651    FI_HILOGD("enter");
1652    curNode = curNode->xmlChildrenNode;
1653    while (curNode != nullptr) {
1654        if (!xmlStrcmp(curNode->name, BAD_CAST "g")) {
1655            while (!xmlStrcmp(curNode->name, BAD_CAST "g")) {
1656                curNode = curNode->xmlChildrenNode;
1657            }
1658            break;
1659        }
1660        curNode = curNode->next;
1661    }
1662    FI_HILOGD("leave");
1663    return curNode;
1664}
1665
1666xmlNodePtr DragDrawing::UpdateRectNode(int32_t extendSvgWidth, xmlNodePtr curNode)
1667{
1668    FI_HILOGD("enter");
1669    while (curNode != nullptr) {
1670        if (!xmlStrcmp(curNode->name, BAD_CAST "rect")) {
1671            std::ostringstream oStrStream;
1672            oStrStream << xmlGetProp(curNode, BAD_CAST "width");
1673            std::string srcRectWidth = oStrStream.str();
1674            if (!IsNum(srcRectWidth)) {
1675                FI_HILOGE("srcRectWidth is not digital, srcRectWidth:%{public}s", srcRectWidth.c_str());
1676                return nullptr;
1677            }
1678            int32_t number = std::stoi(srcRectWidth) + extendSvgWidth;
1679            xmlSetProp(curNode, BAD_CAST "width", BAD_CAST std::to_string(number).c_str());
1680        }
1681        if (!xmlStrcmp(curNode->name, BAD_CAST "text")) {
1682            return curNode->xmlChildrenNode;
1683        }
1684        curNode = curNode->next;
1685    }
1686    FI_HILOGE("Empty node of XML");
1687    return nullptr;
1688}
1689
1690void DragDrawing::UpdateTspanNode(xmlNodePtr curNode)
1691{
1692    FI_HILOGD("enter");
1693    while (curNode != nullptr) {
1694        if (!xmlStrcmp(curNode->name, BAD_CAST "tspan")) {
1695            xmlNodeSetContent(curNode, BAD_CAST std::to_string(g_drawingInfo.currentDragNum).c_str());
1696        }
1697        curNode = curNode->next;
1698    }
1699    FI_HILOGD("leave");
1700}
1701
1702int32_t DragDrawing::ParseAndAdjustSvgInfo(xmlNodePtr curNode)
1703{
1704    FI_HILOGD("enter");
1705    CHKPR(curNode, RET_ERR);
1706    std::string strStyle = std::to_string(g_drawingInfo.currentDragNum);
1707    if (strStyle.empty()) {
1708        FI_HILOGE("strStyle size:%{public}zu invalid", strStyle.size());
1709        return RET_ERR;
1710    }
1711    int32_t extendSvgWidth = (static_cast<int32_t>(strStyle.size()) - 1) * EIGHT_SIZE;
1712    xmlKeepBlanksDefault(0);
1713    int32_t ret = UpdateSvgNodeInfo(curNode, extendSvgWidth);
1714    if (ret != RET_OK) {
1715        FI_HILOGE("Update svg node info failed, ret:%{public}d", ret);
1716        return RET_ERR;
1717    }
1718    curNode = GetRectNode(curNode);
1719    CHKPR(curNode, RET_ERR);
1720    curNode = UpdateRectNode(extendSvgWidth, curNode);
1721    CHKPR(curNode, RET_ERR);
1722    UpdateTspanNode(curNode);
1723    FI_HILOGD("leave");
1724    return RET_OK;
1725}
1726
1727std::shared_ptr<Media::PixelMap> DragDrawing::DecodeSvgToPixelMap(
1728    const std::string &filePath)
1729{
1730    FI_HILOGD("enter");
1731    xmlDocPtr xmlDoc = xmlReadFile(filePath.c_str(), 0, XML_PARSE_NOBLANKS);
1732    if (NeedAdjustSvgInfo()) {
1733        xmlNodePtr node = xmlDocGetRootElement(xmlDoc);
1734        CHKPP(node);
1735        int32_t ret = ParseAndAdjustSvgInfo(node);
1736        if (ret != RET_OK) {
1737            FI_HILOGE("Parse and adjust svg info failed, ret:%{public}d", ret);
1738            return nullptr;
1739        }
1740    }
1741    xmlChar *xmlbuff = nullptr;
1742    int32_t buffersize = 0;
1743    xmlDocDumpFormatMemory(xmlDoc, &xmlbuff, &buffersize, 1);
1744    std::ostringstream oStrStream;
1745    oStrStream << xmlbuff;
1746    std::string content = oStrStream.str();
1747    xmlFree(xmlbuff);
1748    xmlFreeDoc(xmlDoc);
1749    Media::SourceOptions opts;
1750    opts.formatHint = "image/svg+xml";
1751    uint32_t errCode = 0;
1752    auto imageSource = Media::ImageSource::CreateImageSource(reinterpret_cast<const uint8_t*>(content.c_str()),
1753        content.size(), opts, errCode);
1754    CHKPP(imageSource);
1755    Media::DecodeOptions decodeOpts;
1756    SetDecodeOptions(decodeOpts);
1757    std::shared_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
1758    FI_HILOGD("leave");
1759    return pixelMap;
1760}
1761
1762bool DragDrawing::NeedAdjustSvgInfo()
1763{
1764    FI_HILOGD("enter");
1765    if (g_drawingInfo.currentStyle == DragCursorStyle::DEFAULT) {
1766        return false;
1767    }
1768    if ((g_drawingInfo.currentStyle == DragCursorStyle::COPY) &&
1769        (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1770        return false;
1771    }
1772    if ((g_drawingInfo.currentStyle == DragCursorStyle::MOVE) &&
1773        (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1774        return false;
1775    }
1776    if ((g_drawingInfo.currentStyle == DragCursorStyle::FORBIDDEN) &&
1777        (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1778        return false;
1779    }
1780    FI_HILOGD("leave");
1781    return true;
1782}
1783
1784#ifndef OHOS_BUILD_ENABLE_ARKUI_X
1785int32_t DragDrawing::GetFilePath(std::string &filePath)
1786{
1787    FI_HILOGD("enter");
1788    switch (g_drawingInfo.currentStyle) {
1789        case DragCursorStyle::COPY: {
1790            if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
1791                filePath = COPY_ONE_DRAG_PATH;
1792            } else {
1793                filePath = COPY_DRAG_PATH;
1794            }
1795            break;
1796        }
1797        case DragCursorStyle::MOVE: {
1798            filePath = MOVE_DRAG_PATH;
1799            break;
1800        }
1801        case DragCursorStyle::FORBIDDEN: {
1802            if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
1803                filePath = FORBID_ONE_DRAG_PATH;
1804            } else {
1805                filePath = FORBID_DRAG_PATH;
1806            }
1807            break;
1808        }
1809        case DragCursorStyle::DEFAULT:
1810        default: {
1811            FI_HILOGW("Not need draw svg style, DragCursorStyle:%{public}d", g_drawingInfo.currentStyle);
1812            break;
1813        }
1814    }
1815    FI_HILOGD("leave");
1816    return RET_OK;
1817}
1818#else
1819int32_t DragDrawing::GetFilePath(std::string &filePath)
1820{
1821    FI_HILOGD("enter");
1822    switch (g_drawingInfo.currentStyle) {
1823        case DragCursorStyle::COPY: {
1824            if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
1825                filePath = svgFilePath_ + COPY_ONE_DRAG_NAME;
1826            } else {
1827                filePath = svgFilePath_ + COPY_DRAG_NAME;
1828            }
1829            break;
1830        }
1831        case DragCursorStyle::MOVE: {
1832            filePath = svgFilePath_ + MOVE_DRAG_NAME;
1833            break;
1834        }
1835        case DragCursorStyle::FORBIDDEN: {
1836            if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
1837                filePath = svgFilePath_ + FORBID_ONE_DRAG_NAME;
1838            } else {
1839                filePath = svgFilePath_ + FORBID_DRAG_NAME;
1840            }
1841            break;
1842        }
1843        case DragCursorStyle::DEFAULT:
1844        default: {
1845            FI_HILOGW("Not need draw svg style, DragCursorStyle:%{public}d", g_drawingInfo.currentStyle);
1846            break;
1847        }
1848    }
1849    FI_HILOGD("leave");
1850    return RET_OK;
1851}
1852#endif // OHOS_BUILD_ENABLE_ARKUI_X
1853
1854void DragDrawing::SetDecodeOptions(Media::DecodeOptions &decodeOpts)
1855{
1856    FI_HILOGD("enter");
1857    std::string strStyle = std::to_string(g_drawingInfo.currentDragNum);
1858    if (strStyle.empty()) {
1859        FI_HILOGE("strStyle size:%{public}zu invalid", strStyle.size());
1860        return;
1861    }
1862    int32_t extendSvgWidth = (static_cast<int32_t>(strStyle.size()) - 1) * EIGHT_SIZE;
1863    if ((g_drawingInfo.currentStyle == DragCursorStyle::COPY) && (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1864        decodeOpts.desiredSize = {
1865            .width = DEVICE_INDEPENDENT_PIXEL * GetScaling(),
1866            .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1867        };
1868    } else {
1869        decodeOpts.desiredSize = {
1870            .width = (DEVICE_INDEPENDENT_PIXEL + extendSvgWidth) * GetScaling(),
1871            .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1872        };
1873    }
1874    FI_HILOGD("leave");
1875}
1876
1877void DragDrawing::ParserDragShadowInfo(cJSON* filterInfoParser, FilterInfo &filterInfo)
1878{
1879    CHKPV(filterInfoParser);
1880    cJSON *offsetX = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "drag_shadow_offsetX");
1881    if (cJSON_IsNumber(offsetX)) {
1882        filterInfo.offsetX = static_cast<float>(offsetX->valuedouble);
1883    }
1884    cJSON *offsetY = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "drag_shadow_offsetY");
1885    if (cJSON_IsNumber(offsetY)) {
1886        filterInfo.offsetY = static_cast<float>(offsetY->valuedouble);
1887    }
1888    cJSON *argb = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "drag_shadow_argb");
1889    if (cJSON_IsNumber(argb)) {
1890        filterInfo.argb = static_cast<uint32_t>(argb->valueint);
1891    }
1892    cJSON *shadowIsFilled   = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_is_filled");
1893    if (cJSON_IsBool(shadowIsFilled)) {
1894        filterInfo.shadowIsFilled = cJSON_IsTrue(shadowIsFilled);
1895    }
1896    cJSON *shadowMask   = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_mask");
1897    if (cJSON_IsBool(shadowMask)) {
1898        filterInfo.shadowMask = cJSON_IsTrue(shadowMask);
1899    }
1900    cJSON *shadowColorStrategy  = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_color_strategy");
1901    if (cJSON_IsNumber(shadowColorStrategy)) {
1902        filterInfo.shadowColorStrategy = shadowColorStrategy->valueint;
1903    }
1904    cJSON *isHardwareAcceleration  = cJSON_GetObjectItemCaseSensitive(
1905        filterInfoParser, "shadow_is_hardwareacceleration");
1906    if (cJSON_IsBool(isHardwareAcceleration)) {
1907        filterInfo.isHardwareAcceleration = cJSON_IsTrue(isHardwareAcceleration);
1908    }
1909    if (filterInfo.isHardwareAcceleration) {
1910        cJSON *elevation  = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_elevation");
1911        if (cJSON_IsNumber(elevation)) {
1912            filterInfo.elevation = static_cast<float>(elevation->valuedouble);
1913        }
1914    } else {
1915        cJSON *shadowCorner = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "shadow_corner");
1916        if (cJSON_IsNumber(shadowCorner)) {
1917            filterInfo.shadowCorner = static_cast<float>(shadowCorner->valuedouble);
1918        }
1919    }
1920}
1921
1922void DragDrawing::ParserTextDragShadowInfo(cJSON* filterInfoParser, FilterInfo &filterInfo)
1923{
1924    CHKPV(filterInfoParser);
1925    cJSON *path = cJSON_GetObjectItemCaseSensitive(filterInfoParser, "drag_shadow_path");
1926    if (cJSON_IsString(path)) {
1927        float dragOriginDpi = DRAG_DATA_MGR.GetDragOriginDpi();
1928        if (dragOriginDpi > EPSILON) {
1929            filterInfo.path = "";
1930        } else {
1931            filterInfo.path = path->valuestring;
1932        }
1933    }
1934}
1935
1936void DragDrawing::PrintDragShadowInfo()
1937{
1938    FilterInfo filterInfo = g_drawingInfo.filterInfo;
1939    if (!filterInfo.shadowEnable) {
1940        FI_HILOGI("Not supported shadow");
1941        return;
1942    }
1943    FI_HILOGI("dragType:%{public}s, shadowIsFilled:%{public}s, shadowMask:%{public}s, shadowColorStrategy :%{public}d, "
1944        "shadowCorner:%{public}f, offsetX:%{private}f, offsetY:%{private}f, argb:%{public}u, elevation:%{public}f, "
1945        "isHardwareAcceleration:%{public}s", filterInfo.dragType.c_str(),
1946        filterInfo.shadowIsFilled ? "true" : "false", filterInfo.shadowMask ? "true" : "false",
1947        filterInfo.shadowColorStrategy, filterInfo.shadowCorner, filterInfo.offsetX, filterInfo.offsetY,
1948        filterInfo.argb, filterInfo.elevation, filterInfo.isHardwareAcceleration ? "true" : "false");
1949    if (!filterInfo.path.empty()) {
1950        FI_HILOGI("path:%{private}s", filterInfo.path.c_str());
1951    }
1952}
1953
1954bool DragDrawing::ParserFilterInfo(const std::string &filterInfoStr, FilterInfo &filterInfo)
1955{
1956    FI_HILOGD("FilterInfo size:%{public}zu, filterInfo:%{public}s", filterInfoStr.size(), filterInfoStr.c_str());
1957    if (filterInfoStr.empty()) {
1958        FI_HILOGD("FilterInfo is empty");
1959        return false;
1960    }
1961    JsonParser filterInfoParser;
1962    filterInfoParser.json = cJSON_Parse(filterInfoStr.c_str());
1963    if (!cJSON_IsObject(filterInfoParser.json)) {
1964        FI_HILOGE("FilterInfo is not json object");
1965        return false;
1966    }
1967    cJSON *dipScale = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "dip_scale");
1968    if (cJSON_IsNumber(dipScale)) {
1969        filterInfo.dipScale = AdjustDoubleValue(dipScale->valuedouble);
1970    }
1971    cJSON *scale = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "scale");
1972    if (cJSON_IsNumber(scale)) {
1973        filterInfo.scale = AdjustDoubleValue(scale->valuedouble);
1974    }
1975    ParserCornerRadiusInfo(filterInfoParser.json, g_drawingInfo.filterInfo);
1976    cJSON *dragType = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "drag_type");
1977    if (cJSON_IsString(dragType)) {
1978        filterInfo.dragType = dragType->valuestring;
1979    }
1980    cJSON *shadowEnable = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "shadow_enable");
1981    if (cJSON_IsBool(shadowEnable)) {
1982        filterInfo.shadowEnable = cJSON_IsTrue(shadowEnable);
1983    }
1984    if (filterInfo.shadowEnable) {
1985        ParserDragShadowInfo(filterInfoParser.json, filterInfo);
1986        if (filterInfo.dragType == "text") {
1987            ParserTextDragShadowInfo(filterInfoParser.json, filterInfo);
1988        }
1989        PrintDragShadowInfo();
1990    }
1991    ParserBlurInfo(filterInfoParser.json, g_drawingInfo.filterInfo);
1992    cJSON *dragNodeGrayscale = cJSON_GetObjectItemCaseSensitive(filterInfoParser.json, "drag_node_gray_scale");
1993    if (cJSON_IsNumber(dragNodeGrayscale)) {
1994        filterInfo.dragNodeGrayscale = static_cast<float>(dragNodeGrayscale->valuedouble);
1995    }
1996    return true;
1997}
1998
1999void DragDrawing::ParserCornerRadiusInfo(const cJSON *cornerRadiusInfoStr, FilterInfo &filterInfo)
2000{
2001    CHKPV(cornerRadiusInfoStr);
2002    cJSON *cornerRadius1 = cJSON_GetObjectItemCaseSensitive(cornerRadiusInfoStr, "drag_corner_radius1");
2003    if (cJSON_IsNumber(cornerRadius1)) {
2004        filterInfo.cornerRadius1 = static_cast<float>(cornerRadius1->valuedouble);
2005    }
2006    cJSON *cornerRadius2 = cJSON_GetObjectItemCaseSensitive(cornerRadiusInfoStr, "drag_corner_radius2");
2007    if (cJSON_IsNumber(cornerRadius2)) {
2008        filterInfo.cornerRadius2 = static_cast<float>(cornerRadius2->valuedouble);
2009    }
2010    cJSON *cornerRadius3 = cJSON_GetObjectItemCaseSensitive(cornerRadiusInfoStr, "drag_corner_radius3");
2011    if (cJSON_IsNumber(cornerRadius3)) {
2012        filterInfo.cornerRadius3 = static_cast<float>(cornerRadius3->valuedouble);
2013    }
2014    cJSON *cornerRadius4 = cJSON_GetObjectItemCaseSensitive(cornerRadiusInfoStr, "drag_corner_radius4");
2015    if (cJSON_IsNumber(cornerRadius4)) {
2016        filterInfo.cornerRadius4 = static_cast<float>(cornerRadius4->valuedouble);
2017    }
2018}
2019
2020void DragDrawing::ParserBlurInfo(const cJSON *BlurInfoInfoStr, FilterInfo &filterInfo)
2021{
2022    CHKPV(BlurInfoInfoStr);
2023    cJSON *opacity = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "dip_opacity");
2024    if (cJSON_IsNumber(opacity)) {
2025        if ((opacity->valuedouble) > MAX_OPACITY || (opacity->valuedouble) <= MIN_OPACITY) {
2026            FI_HILOGE("Parser opacity limits abnormal, opacity:%{public}f", opacity->valuedouble);
2027        } else {
2028            filterInfo.opacity = static_cast<float>(opacity->valuedouble);
2029        }
2030    }
2031    float tempCoef1 = 0.0f;
2032    cJSON *coef1 = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_coef1");
2033    if (cJSON_IsNumber(coef1)) {
2034        tempCoef1 = static_cast<float>(coef1->valuedouble);
2035    }
2036    float tempCoef2 = 0.0f;
2037    cJSON *coef2 = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_coef2");
2038    if (cJSON_IsNumber(coef2)) {
2039        tempCoef2 = static_cast<float>(coef2->valuedouble);
2040    }
2041    filterInfo.coef = { tempCoef1, tempCoef2 };
2042    cJSON *blurRadius = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_radius");
2043    if (cJSON_IsNumber(blurRadius)) {
2044        filterInfo.blurRadius = AdjustDoubleValue(blurRadius->valuedouble);
2045    }
2046    cJSON *blurStaturation = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_staturation");
2047    if (cJSON_IsNumber(blurStaturation)) {
2048        filterInfo.blurStaturation = static_cast<float>(blurStaturation->valuedouble);
2049    }
2050    cJSON *blurBrightness = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_brightness");
2051    if (cJSON_IsNumber(blurBrightness)) {
2052        filterInfo.blurBrightness = static_cast<float>(blurBrightness->valuedouble);
2053    }
2054    cJSON *blurColor = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_color");
2055    if (cJSON_IsNumber(blurColor)) {
2056        filterInfo.blurColor = static_cast<uint32_t>(blurColor->valueint);
2057    }
2058    cJSON *blurStyle = cJSON_GetObjectItemCaseSensitive(BlurInfoInfoStr, "blur_style");
2059    if (cJSON_IsNumber(blurStyle)) {
2060        filterInfo.blurStyle = blurStyle->valueint;
2061    }
2062    return;
2063}
2064
2065bool DragDrawing::ParserExtraInfo(const std::string &extraInfoStr, ExtraInfo &extraInfo)
2066{
2067    FI_HILOGD("ExtraInfo size:%{public}zu, extraInfo:%{public}s",
2068        extraInfoStr.size(), extraInfoStr.c_str());
2069    if (extraInfoStr.empty()) {
2070        FI_HILOGD("ExtraInfo is empty");
2071        return false;
2072    }
2073    JsonParser extraInfoParser;
2074    extraInfoParser.json = cJSON_Parse(extraInfoStr.c_str());
2075    if (!cJSON_IsObject(extraInfoParser.json)) {
2076        FI_HILOGE("ExtraInfo is not json object");
2077        return false;
2078    }
2079    cJSON *componentType = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "drag_data_type");
2080    if (cJSON_IsString(componentType)) {
2081        extraInfo.componentType = componentType->valuestring;
2082    }
2083    cJSON *blurStyle = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "drag_blur_style");
2084    if (cJSON_IsNumber(blurStyle)) {
2085        extraInfo.blurStyle = blurStyle->valueint;
2086    }
2087    cJSON *cornerRadius = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "drag_corner_radius");
2088    if (cJSON_IsNumber(cornerRadius)) {
2089        extraInfo.cornerRadius = static_cast<float>(cornerRadius->valuedouble);
2090    }
2091    cJSON *allowDistributed = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "drag_allow_distributed");
2092    if (cJSON_IsBool(allowDistributed)) {
2093        extraInfo.allowDistributed = cJSON_IsTrue(allowDistributed) ? true : false;
2094    }
2095    float tempCoef1 = 0.0f;
2096    cJSON *coef1 = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "blur_coef1");
2097    if (cJSON_IsNumber(coef1)) {
2098        tempCoef1 = static_cast<float>(coef1->valuedouble);
2099    }
2100    float tempCoef2 = 0.0f;
2101    cJSON *coef2 = cJSON_GetObjectItemCaseSensitive(extraInfoParser.json, "blur_coef2");
2102    if (cJSON_IsNumber(coef2)) {
2103        tempCoef2 = static_cast<float>(coef2->valuedouble);
2104    }
2105    extraInfo.coef = { tempCoef1, tempCoef2 };
2106    return true;
2107}
2108
2109bool DragDrawing::GetAllowDragState()
2110{
2111    return g_drawingInfo.extraInfo.allowDistributed;
2112}
2113
2114void DragDrawing::SetScreenId(uint64_t screenId)
2115{
2116    FI_HILOGD("enter");
2117    screenId_ = screenId;
2118}
2119
2120int32_t DragDrawing::RotateDragWindow(Rosen::Rotation rotation,
2121    const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool isAnimated)
2122{
2123    if (needRotatePixelMapXY_) {
2124        CHKPR(g_drawingInfo.pixelMap, RET_ERR);
2125        g_drawingInfo.pixelMapX = -(HALF_RATIO * g_drawingInfo.pixelMap->GetWidth());
2126        g_drawingInfo.pixelMapY = -(EIGHT_SIZE * GetScaling());
2127    }
2128    float rotateAngle = (rotation == Rosen::Rotation::ROTATION_0) ? ROTATION_0 :
2129        ROTATION_360 - (ROTATION_90 * static_cast<int32_t>(rotation));
2130    FI_HILOGI("rotateAngle:%{public}f, isAnimated:%{public}d", rotateAngle, isAnimated);
2131    return DoRotateDragWindow(rotateAngle, rsTransaction, isAnimated);
2132}
2133
2134void DragDrawing::RotateCanvasNode(float pivotX, float pivotY, float rotation)
2135{
2136    FI_HILOGD("enter");
2137    CHKPV(g_drawingInfo.parentNode);
2138    g_drawingInfo.parentNode->SetPivot(pivotX, pivotY);
2139    g_drawingInfo.parentNode->SetRotation(rotation);
2140    if (!g_drawingInfo.multiSelectedNodes.empty()) {
2141        size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2142        for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
2143            std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
2144            CHKPV(multiSelectedNode);
2145            float degrees = DEFAULT_ANGLE;
2146            if (i == FIRST_PIXELMAP_INDEX) {
2147                degrees = rotation + POSITIVE_ANGLE;
2148            } else if (i == SECOND_PIXELMAP_INDEX) {
2149                degrees = rotation + NEGATIVE_ANGLE;
2150            }
2151            multiSelectedNode->SetPivot(HALF_PIVOT, HALF_PIVOT);
2152            multiSelectedNode->SetRotation(degrees);
2153        }
2154    }
2155    if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
2156        if (!CheckNodesValid()) {
2157            FI_HILOGE("Check nodes valid failed");
2158            return;
2159        }
2160        std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
2161        CHKPV(mouseIconNode);
2162        mouseIconNode->SetPivot(DEFAULT_PIVOT, DEFAULT_PIVOT);
2163        mouseIconNode->SetRotation(rotation);
2164    }
2165    float positionX = g_drawingInfo.currentPositionX;
2166    float positionY = g_drawingInfo.currentPositionY;
2167    AdjustRotateDisplayXY(positionX, positionY);
2168    DrawRotateDisplayXY(positionX, positionY);
2169    FI_HILOGD("leave");
2170}
2171
2172void DragDrawing::SetRotation(Rosen::Rotation rotation)
2173{
2174    rotation_ = rotation;
2175}
2176
2177void DragDrawing::ProcessFilter()
2178{
2179    FI_HILOGD("enter");
2180    if (g_drawingInfo.nodes.size() <= BACKGROUND_FILTER_INDEX) {
2181        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2182        return;
2183    }
2184    std::shared_ptr<Rosen::RSCanvasNode> filterNode = g_drawingInfo.nodes[BACKGROUND_FILTER_INDEX];
2185    CHKPV(filterNode);
2186    CHKPV(g_drawingInfo.pixelMap);
2187    FilterInfo filterInfo = g_drawingInfo.filterInfo;
2188    ExtraInfo extraInfo = g_drawingInfo.extraInfo;
2189    if (filterInfo.blurStyle != -1) {
2190        SetCustomDragBlur(filterInfo, filterNode);
2191    } else if (extraInfo.componentType == BIG_FOLDER_LABEL) {
2192        SetComponentDragBlur(filterInfo, extraInfo, filterNode);
2193    }
2194    FI_HILOGD("Add filter successfully");
2195    FI_HILOGD("leave");
2196}
2197
2198void DragDrawing::SetCustomDragBlur(const FilterInfo &filterInfo, std::shared_ptr<Rosen::RSCanvasNode> filterNode)
2199{
2200    CHKPV(filterNode);
2201    CHKPV(g_drawingInfo.pixelMap);
2202    Rosen::BLUR_COLOR_MODE mode = (Rosen::BLUR_COLOR_MODE)filterInfo.blurStyle;
2203    std::shared_ptr<Rosen::RSFilter> backFilter = Rosen::RSFilter::CreateMaterialFilter(
2204        RadiusVp2Sigma(filterInfo.blurRadius, filterInfo.dipScale),
2205        filterInfo.blurStaturation, filterInfo.blurBrightness, filterInfo.blurColor, mode);
2206    if (backFilter == nullptr) {
2207        FI_HILOGE("Create backgroundFilter failed");
2208        return;
2209    }
2210    filterNode->SetBackgroundFilter(backFilter);
2211    filterNode->SetGreyCoef(filterInfo.coef);
2212    filterNode->SetAlpha(filterInfo.opacity);
2213    int32_t adjustSize = TWELVE_SIZE * GetScaling();
2214    filterNode->SetBounds(DEFAULT_POSITION_X, adjustSize, g_drawingInfo.pixelMap->GetWidth(),
2215        g_drawingInfo.pixelMap->GetHeight());
2216    filterNode->SetFrame(DEFAULT_POSITION_X, adjustSize, g_drawingInfo.pixelMap->GetWidth(),
2217        g_drawingInfo.pixelMap->GetHeight());
2218    if ((filterInfo.blurRadius < 0) || (filterInfo.dipScale < 0) ||
2219        (fabs(filterInfo.dipScale) < EPSILON) || ((std::numeric_limits<float>::max()
2220        / filterInfo.dipScale) < filterInfo.blurRadius)) {
2221        FI_HILOGE("Invalid parameters, cornerRadius:%{public}f, dipScale:%{public}f",
2222            filterInfo.blurRadius, filterInfo.dipScale);
2223        return;
2224    }
2225    Rosen::Vector4f cornerRadiusVector = { filterInfo.cornerRadius1, filterInfo.cornerRadius2,
2226        filterInfo.cornerRadius3, filterInfo.cornerRadius4 };
2227    filterNode->SetCornerRadius(cornerRadiusVector * filterInfo.dipScale);
2228    FI_HILOGD("Set custom drag blur successfully");
2229}
2230
2231void DragDrawing::SetComponentDragBlur(const FilterInfo &filterInfo, const ExtraInfo &extraInfo,
2232    std::shared_ptr<Rosen::RSCanvasNode> filterNode)
2233{
2234    CHKPV(filterNode);
2235    CHKPV(g_drawingInfo.pixelMap);
2236    std::shared_ptr<Rosen::RSFilter> backFilter = Rosen::RSFilter::CreateMaterialFilter(
2237        RadiusVp2Sigma(RADIUS_VP, filterInfo.dipScale),
2238        DEFAULT_SATURATION, DEFAULT_BRIGHTNESS, DEFAULT_COLOR_VALUE);
2239    if (backFilter == nullptr) {
2240        FI_HILOGE("Create backgroundFilter failed");
2241        return;
2242    }
2243    filterNode->SetBackgroundFilter(backFilter);
2244    filterNode->SetGreyCoef(extraInfo.coef);
2245    filterNode->SetAlpha(filterInfo.opacity);
2246    int32_t adjustSize = TWELVE_SIZE * GetScaling();
2247    filterNode->SetBounds(DEFAULT_POSITION_X, adjustSize, g_drawingInfo.pixelMap->GetWidth(),
2248        g_drawingInfo.pixelMap->GetHeight());
2249    filterNode->SetFrame(DEFAULT_POSITION_X, adjustSize, g_drawingInfo.pixelMap->GetWidth(),
2250        g_drawingInfo.pixelMap->GetHeight());
2251    if ((extraInfo.cornerRadius < 0) || (filterInfo.dipScale < 0) ||
2252        (fabs(filterInfo.dipScale) < EPSILON) || ((std::numeric_limits<float>::max()
2253        / filterInfo.dipScale) < extraInfo.cornerRadius)) {
2254        FI_HILOGE("Invalid parameters, cornerRadius:%{public}f, dipScale:%{public}f",
2255            extraInfo.cornerRadius, filterInfo.dipScale);
2256        return;
2257    }
2258    filterNode->SetCornerRadius(extraInfo.cornerRadius * filterInfo.dipScale);
2259    FI_HILOGD("Set component drag blur successfully");
2260    return;
2261}
2262
2263int32_t DragDrawing::SetNodesLocation(int32_t positionX, int32_t positionY)
2264{
2265    FI_HILOGD("enter");
2266    Rosen::RSAnimationTimingProtocol protocol;
2267    int32_t adjustSize = TWELVE_SIZE * GetScaling();
2268    CHKPR(g_drawingInfo.parentNode, RET_ERR);
2269    CHKPR(g_drawingInfo.pixelMap, RET_ERR);
2270    Rosen::RSNode::Animate(protocol, SPRING, [&]() {
2271        g_drawingInfo.parentNode->SetBounds(positionX, positionY, g_drawingInfo.pixelMap->GetWidth(),
2272            g_drawingInfo.pixelMap->GetHeight() + adjustSize);
2273        g_drawingInfo.parentNode->SetFrame(positionX, positionY, g_drawingInfo.pixelMap->GetWidth(),
2274            g_drawingInfo.pixelMap->GetHeight() + adjustSize);
2275    }, []() { FI_HILOGD("SetNodesLocation end"); });
2276#ifdef IOS_PLATFORM
2277    g_drawingInfo.startNum = actionTime_; // IOS animation starts time
2278#else
2279    g_drawingInfo.startNum = START_TIME;
2280#endif // IOS_PLATFORM
2281    g_drawingInfo.needDestroyDragWindow = false;
2282    StartVsync();
2283    FI_HILOGD("leave");
2284    return RET_OK;
2285}
2286
2287
2288int32_t DragDrawing::EnterTextEditorArea(bool enable)
2289{
2290    FI_HILOGD("enter");
2291    if (enable) {
2292        DRAG_DATA_MGR.SetInitialPixelMapLocation({ g_drawingInfo.pixelMapX, g_drawingInfo.pixelMapY });
2293        needRotatePixelMapXY_ = true;
2294        RotatePixelMapXY();
2295    } else {
2296        needRotatePixelMapXY_ = false;
2297        auto initialPixelMapLocation = DRAG_DATA_MGR.GetInitialPixelMapLocation();
2298        g_drawingInfo.pixelMapX = initialPixelMapLocation.first;
2299        g_drawingInfo.pixelMapY = initialPixelMapLocation.second;
2300    }
2301    DRAG_DATA_MGR.SetPixelMapLocation({ g_drawingInfo.pixelMapX, g_drawingInfo.pixelMapY });
2302    float displayX = g_drawingInfo.currentPositionX;
2303    float displayY = g_drawingInfo.currentPositionY;
2304    AdjustRotateDisplayXY(displayX, displayY);
2305    int32_t positionX = displayX + g_drawingInfo.pixelMapX;
2306    int32_t positionY = displayY + g_drawingInfo.pixelMapY - TWELVE_SIZE * GetScaling();
2307    if (RunAnimation([this, positionX, positionY] {
2308        return this->SetNodesLocation(positionX, positionY);
2309    }) != RET_OK) {
2310        FI_HILOGE("RunAnimation to SetNodesLocation failed");
2311        return RET_ERR;
2312    }
2313    DRAG_DATA_MGR.SetTextEditorAreaFlag(enable);
2314    FI_HILOGI("EnterTextEditorArea %{public}s successfully", (enable ? "true" : "false"));
2315    return RET_OK;
2316}
2317
2318float DragDrawing::RadiusVp2Sigma(float radiusVp, float dipScale)
2319{
2320    float radiusPx = radiusVp * dipScale;
2321    return radiusPx > 0.0f ? BLUR_SIGMA_SCALE * radiusPx + 0.5f : 0.0f;
2322}
2323
2324int32_t DragDrawing::UpdatePreviewStyle(const PreviewStyle &previewStyle)
2325{
2326    FI_HILOGD("enter");
2327    if (g_drawingInfo.nodes.size() <= PIXEL_MAP_INDEX) {
2328        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2329        return RET_ERR;
2330    } else if (ModifyPreviewStyle(g_drawingInfo.nodes[PIXEL_MAP_INDEX], previewStyle) != RET_OK) {
2331        FI_HILOGE("ModifyPreviewStyle failed");
2332        return RET_ERR;
2333    }
2334    if (ModifyMultiPreviewStyle(std::vector<PreviewStyle>(g_drawingInfo.multiSelectedNodes.size(), previewStyle)) !=
2335        RET_OK) {
2336        FI_HILOGE("ModifyPreviewStyle failed");
2337        return RET_ERR;
2338    }
2339    Rosen::RSTransaction::FlushImplicitTransaction();
2340    FI_HILOGD("leave");
2341    return RET_OK;
2342}
2343
2344int32_t DragDrawing::UpdatePreviewStyleWithAnimation(const PreviewStyle &previewStyle,
2345    const PreviewAnimation &animation)
2346{
2347    FI_HILOGD("enter");
2348    std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
2349    CHKPR(pixelMapNode, RET_ERR);
2350    PreviewStyle originStyle;
2351    originStyle.types = previewStyle.types;
2352    if (auto color = pixelMapNode->GetShowingProperties().GetForegroundColor(); color.has_value()) {
2353        originStyle.foregroundColor = color->AsArgbInt();
2354        originStyle.radius = previewStyle.radius;
2355    }
2356    size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2357    std::vector<PreviewStyle> multiOriginStyles;
2358    for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
2359        if (auto color = g_drawingInfo.multiSelectedNodes[i]->GetShowingProperties().GetForegroundColor();
2360            color.has_value()) {
2361            PreviewStyle currentStyle;
2362            currentStyle.types = { PreviewType::FOREGROUND_COLOR, PreviewType::RADIUS };
2363            currentStyle.foregroundColor = color->AsArgbInt();
2364            currentStyle.radius = previewStyle.radius;
2365            multiOriginStyles.push_back(currentStyle);
2366        }
2367    }
2368    if (ModifyPreviewStyle(pixelMapNode, originStyle) != RET_OK) {
2369        FI_HILOGE("ModifyPreviewStyle failed");
2370        return RET_ERR;
2371    }
2372    if (ModifyMultiPreviewStyle(multiOriginStyles) != RET_OK) {
2373        FI_HILOGE("ModifyMultiPreviewStyle failed");
2374        return RET_ERR;
2375    }
2376    Rosen::RSAnimationTimingProtocol protocol;
2377    protocol.SetDuration(animation.duration);
2378    auto curve = AnimationCurve::CreateCurve(animation.curveName, animation.curve);
2379    Rosen::RSNode::Animate(protocol, curve, [&]() {
2380        if (ModifyPreviewStyle(pixelMapNode, previewStyle) != RET_OK) {
2381            FI_HILOGE("ModifyPreviewStyle failed");
2382        }
2383        if (ModifyMultiPreviewStyle(std::vector<PreviewStyle>(multiSelectedNodesSize, previewStyle)) != RET_OK) {
2384            FI_HILOGE("ModifyMultiPreviewStyle failed");
2385        }
2386    }, []() { FI_HILOGD("UpdatePreviewStyleWithAnimation end"); });
2387    FI_HILOGD("leave");
2388    return RET_OK;
2389}
2390
2391void DragDrawing::UpdateMousePosition(float mousePositionX, float mousePositionY)
2392{
2393    if (!CheckNodesValid()) {
2394        FI_HILOGE("Check nodes valid failed");
2395        return;
2396    }
2397    if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
2398        FI_HILOGE("The index out of bounds, node size:%{public}zu", g_drawingInfo.nodes.size());
2399        return;
2400    }
2401    std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
2402    CHKPV(mouseIconNode);
2403#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2404    if (pointerStyle_.id == MOUSE_DRAG_CURSOR_CIRCLE_STYLE || pointerStyle_.options == MAGIC_STYLE_OPT) {
2405        float positionX = mousePositionX - (static_cast<float>(g_drawingInfo.mouseWidth) / CURSOR_CIRCLE_MIDDLE);
2406        float positionY = mousePositionY - (static_cast<float>(g_drawingInfo.mouseHeight) / CURSOR_CIRCLE_MIDDLE);
2407        mouseIconNode->SetBounds(positionX, positionY, g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2408        mouseIconNode->SetFrame(positionX, positionY, g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2409    } else {
2410        mouseIconNode->SetBounds(mousePositionX, mousePositionY,
2411            g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2412        mouseIconNode->SetFrame(mousePositionX, mousePositionY,
2413            g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2414    }
2415#endif // OHOS_BUILD_ENABLE_ARKUI_X
2416}
2417
2418int32_t DragDrawing::RotateDragWindowAsync(Rosen::Rotation rotation)
2419{
2420    isRunningRotateAnimation_ = true;
2421    int32_t repeatTime = 1;
2422#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2423    CHKPR(context_, RET_ERR);
2424    timerId_ = context_->GetTimerManager().AddTimer(ASYNC_ROTATE_TIME, repeatTime, [this]() {
2425        RotateDragWindow(rotation_, nullptr, true);
2426        isRunningRotateAnimation_ = false;
2427    });
2428#endif // OHOS_BUILD_ENABLE_ARKUI_X
2429    if (timerId_ < 0) {
2430        FI_HILOGE("Add timer failed, timerId_:%{public}d", timerId_);
2431        isRunningRotateAnimation_ = false;
2432        return RET_ERR;
2433    }
2434    return RET_OK;
2435}
2436
2437int32_t DragDrawing::RotateDragWindowSync(const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
2438{
2439    FI_HILOGD("enter");
2440    isRunningRotateAnimation_ = true;
2441    RotateDragWindow(rotation_, rsTransaction, true);
2442    isRunningRotateAnimation_ = false;
2443#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2444    if ((context_ != nullptr) && (timerId_ >= 0)) {
2445        context_->GetTimerManager().RemoveTimer(timerId_);
2446        timerId_ = -1;
2447    }
2448#endif // OHOS_BUILD_ENABLE_ARKUI_X
2449    return RET_OK;
2450}
2451
2452void DragDrawing::DoDrawMouse(int32_t mousePositionX, int32_t mousePositionY)
2453{
2454    if (!CheckNodesValid()) {
2455        FI_HILOGE("Check nodes valid failed");
2456        return;
2457    }
2458    if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
2459        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2460        return;
2461    }
2462#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2463    std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
2464    CHKPV(mouseIconNode);
2465    if (pointerStyle_.id == MOUSE_DRAG_CURSOR_CIRCLE_STYLE || pointerStyle_.options == MAGIC_STYLE_OPT) {
2466        int32_t positionX = mousePositionX - (g_drawingInfo.mouseWidth / CURSOR_CIRCLE_MIDDLE);
2467        int32_t positionY = mousePositionY - (g_drawingInfo.mouseHeight / CURSOR_CIRCLE_MIDDLE);
2468        mouseIconNode->SetBounds(positionX, positionY, g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2469        mouseIconNode->SetFrame(positionX, positionY, g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2470    } else {
2471        mouseIconNode->SetBounds(mousePositionX, mousePositionY,
2472            g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2473        mouseIconNode->SetFrame(mousePositionX, mousePositionY,
2474            g_drawingInfo.mouseWidth, g_drawingInfo.mouseHeight);
2475    }
2476#endif // OHOS_BUILD_ENABLE_ARKUI_X
2477}
2478
2479int32_t DragDrawing::UpdateDefaultDragStyle(DragCursorStyle style)
2480{
2481    if (!CheckNodesValid()) {
2482        FI_HILOGE("Check nodes valid failed");
2483        return RET_ERR;
2484    }
2485    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
2486        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2487        return RET_ERR;
2488    }
2489    if (!g_drawingInfo.isCurrentDefaultStyle) {
2490        std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
2491        CHKPR(dragStyleNode, RET_ERR);
2492        CHKPR(g_drawingInfo.parentNode, RET_ERR);
2493        g_drawingInfo.parentNode->RemoveChild(dragStyleNode);
2494        CHKPR(rsUiDirector_, RET_ERR);
2495        rsUiDirector_->SendMessages();
2496    }
2497    g_drawingInfo.currentStyle = style;
2498    bool isPreviousDefaultStyle = g_drawingInfo.isCurrentDefaultStyle;
2499    g_drawingInfo.isPreviousDefaultStyle = isPreviousDefaultStyle;
2500    g_drawingInfo.isCurrentDefaultStyle = true;
2501    return RET_OK;
2502}
2503
2504int32_t DragDrawing::UpdateValidDragStyle(DragCursorStyle style)
2505{
2506    g_drawingInfo.currentStyle = style;
2507    if (g_drawingInfo.isCurrentDefaultStyle) {
2508        if (!CheckNodesValid()) {
2509            FI_HILOGE("Check nodes valid failed");
2510            return RET_ERR;
2511        }
2512        if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
2513            FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
2514            return RET_ERR;
2515        }
2516        std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
2517        CHKPR(dragStyleNode, RET_ERR);
2518        CHKPR(g_drawingInfo.parentNode, RET_ERR);
2519        g_drawingInfo.parentNode->AddChild(dragStyleNode);
2520    }
2521    std::string filePath;
2522    if (GetFilePath(filePath) != RET_OK) {
2523        FI_HILOGD("Get file path failed");
2524        return RET_ERR;
2525    }
2526    if (!IsValidSvgFile(filePath)) {
2527        FI_HILOGE("Svg file is invalid");
2528        return RET_ERR;
2529    }
2530    std::shared_ptr<Media::PixelMap> pixelMap = DecodeSvgToPixelMap(filePath);
2531    CHKPR(pixelMap, RET_ERR);
2532    bool isPreviousDefaultStyle = g_drawingInfo.isCurrentDefaultStyle;
2533    g_drawingInfo.isPreviousDefaultStyle = isPreviousDefaultStyle;
2534    g_drawingInfo.isCurrentDefaultStyle = false;
2535    g_drawingInfo.stylePixelMap = pixelMap;
2536    if (!CheckNodesValid()) {
2537        FI_HILOGE("Check nodes valid failed");
2538        return RET_ERR;
2539    }
2540    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
2541    CHKPR(dragStyleNode, RET_ERR);
2542    OnDragStyle(dragStyleNode, pixelMap);
2543    CHKPR(rsUiDirector_, RET_ERR);
2544    rsUiDirector_->SendMessages();
2545#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2546#ifdef MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
2547    DragDFX::WriteUpdateDragStyle(style, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
2548#endif // MSDP_HIVIEWDFX_HISYSEVENT_ENABLE
2549#endif // OHOS_BUILD_ENABLE_ARKUI_X
2550    return RET_OK;
2551}
2552
2553int32_t DragDrawing::ModifyPreviewStyle(std::shared_ptr<Rosen::RSCanvasNode> node, const PreviewStyle &previewStyle)
2554{
2555    FI_HILOGD("enter");
2556    CHKPR(node, RET_ERR);
2557    if (float radius = 0.0F; ParserRadius(radius)) {
2558        node->SetCornerRadius(radius);
2559        FI_HILOGD("SetCornerRadius by radius:%{public}f", radius);
2560    }
2561    for (const auto &type : previewStyle.types) {
2562        switch (type) {
2563            case PreviewType::FOREGROUND_COLOR: {
2564                node->SetForegroundColor(previewStyle.foregroundColor);
2565                break;
2566            }
2567            case PreviewType::OPACITY: {
2568                node->SetAlpha(previewStyle.opacity / static_cast<float>(HEX_FF));
2569                break;
2570            }
2571            case PreviewType::RADIUS: {
2572                node->SetCornerRadius(previewStyle.radius);
2573                break;
2574            }
2575            case PreviewType::SCALE: {
2576                node->SetScale(previewStyle.scale);
2577                break;
2578            }
2579            default: {
2580                FI_HILOGE("Unsupported type");
2581                break;
2582            }
2583        }
2584    }
2585    FI_HILOGD("leave");
2586    return RET_OK;
2587}
2588
2589int32_t DragDrawing::ModifyMultiPreviewStyle(const std::vector<PreviewStyle> &previewStyles)
2590{
2591    size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2592    if (previewStyles.size() != multiSelectedNodesSize) {
2593        FI_HILOGE("Size of previewStyles:%{public}zu does not match multiSelectedNodesSize:%{public}zu",
2594            previewStyles.size(), multiSelectedNodesSize);
2595        return RET_ERR;
2596    }
2597    for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
2598        if (ModifyPreviewStyle(g_drawingInfo.multiSelectedNodes[i], previewStyles[i]) != RET_OK) {
2599            FI_HILOGW("ModifyPreviewStyle No.%{public}zu failed", i);
2600        }
2601    }
2602    return RET_OK;
2603}
2604
2605void DragDrawing::MultiSelectedAnimation(int32_t positionX, int32_t positionY, int32_t adjustSize,
2606    bool isMultiSelectedAnimation)
2607{
2608    size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
2609    size_t multiSelectedPixelMapsSize = g_drawingInfo.multiSelectedPixelMaps.size();
2610    for (size_t i = 0; (i < multiSelectedNodesSize) && (i < multiSelectedPixelMapsSize); ++i) {
2611        std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
2612        std::shared_ptr<Media::PixelMap> multiSelectedPixelMap = g_drawingInfo.multiSelectedPixelMaps[i];
2613        CHKPV(g_drawingInfo.pixelMap);
2614        CHKPV(multiSelectedNode);
2615        CHKPV(multiSelectedPixelMap);
2616        int32_t multiSelectedPositionX = positionX + (g_drawingInfo.pixelMap->GetWidth() / TWICE_SIZE) -
2617            (multiSelectedPixelMap->GetWidth() / TWICE_SIZE);
2618        int32_t multiSelectedPositionY = positionY + (g_drawingInfo.pixelMap->GetHeight() / TWICE_SIZE) -
2619            ((multiSelectedPixelMap->GetHeight() / TWICE_SIZE) - adjustSize);
2620        if (isMultiSelectedAnimation) {
2621            Rosen::RSAnimationTimingProtocol protocol;
2622            if (i == FIRST_PIXELMAP_INDEX) {
2623                protocol.SetDuration(SHORT_DURATION);
2624            } else {
2625                protocol.SetDuration(LONG_DURATION);
2626            }
2627            Rosen::RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
2628                multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
2629                    multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2630                multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
2631                    multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2632            }, []() { FI_HILOGD("MultiSelectedAnimation end"); });
2633        } else {
2634            multiSelectedNode->SetBounds(multiSelectedPositionX, multiSelectedPositionY,
2635                multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2636            multiSelectedNode->SetFrame(multiSelectedPositionX, multiSelectedPositionY,
2637                multiSelectedPixelMap->GetWidth(), multiSelectedPixelMap->GetHeight());
2638        }
2639    }
2640}
2641
2642void DragDrawing::InitMultiSelectedNodes()
2643{
2644    FI_HILOGD("enter");
2645    size_t multiSelectedPixelMapsSize = g_drawingInfo.multiSelectedPixelMaps.size();
2646    for (size_t i = 0; i < multiSelectedPixelMapsSize; ++i) {
2647        std::shared_ptr<Media::PixelMap> multiSelectedPixelMap = g_drawingInfo.multiSelectedPixelMaps[i];
2648        std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = Rosen::RSCanvasNode::Create();
2649        multiSelectedNode->SetBgImageWidth(multiSelectedPixelMap->GetWidth());
2650        multiSelectedNode->SetBgImageHeight(multiSelectedPixelMap->GetHeight());
2651        multiSelectedNode->SetBgImagePositionX(0);
2652        multiSelectedNode->SetBgImagePositionY(0);
2653        multiSelectedNode->SetForegroundColor(TRANSPARENT_COLOR_ARGB);
2654        auto rosenImage = std::make_shared<Rosen::RSImage>();
2655        rosenImage->SetPixelMap(multiSelectedPixelMap);
2656        rosenImage->SetImageRepeat(0);
2657        multiSelectedNode->SetBgImage(rosenImage);
2658        float alpha = DEFAULT_ALPHA;
2659        float degrees = DEFAULT_ANGLE;
2660        if (i == FIRST_PIXELMAP_INDEX) {
2661            alpha = FIRST_PIXELMAP_ALPHA;
2662            degrees = POSITIVE_ANGLE;
2663        } else if (i == SECOND_PIXELMAP_INDEX) {
2664            alpha = SECOND_PIXELMAP_ALPHA;
2665            degrees = NEGATIVE_ANGLE;
2666        }
2667        multiSelectedNode->SetRotation(degrees);
2668        multiSelectedNode->SetCornerRadius(g_drawingInfo.filterInfo.cornerRadius1 * g_drawingInfo.filterInfo.dipScale *
2669            g_drawingInfo.filterInfo.scale);
2670        multiSelectedNode->SetAlpha(alpha);
2671        g_drawingInfo.multiSelectedNodes.emplace_back(multiSelectedNode);
2672    }
2673    FI_HILOGD("leave");
2674}
2675
2676void DragDrawing::ClearMultiSelectedData()
2677{
2678    FI_HILOGD("enter");
2679    if (!g_drawingInfo.multiSelectedNodes.empty()) {
2680        g_drawingInfo.multiSelectedNodes.clear();
2681        g_drawingInfo.multiSelectedNodes.shrink_to_fit();
2682    }
2683    if (!g_drawingInfo.multiSelectedPixelMaps.empty()) {
2684        g_drawingInfo.multiSelectedPixelMaps.clear();
2685        g_drawingInfo.multiSelectedPixelMaps.shrink_to_fit();
2686    }
2687    FI_HILOGD("leave");
2688}
2689
2690void DragDrawing::RotateDisplayXY(int32_t &displayX, int32_t &displayY)
2691{
2692#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2693    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
2694    if (display == nullptr) {
2695        FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
2696        display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
2697        CHKPV(display);
2698    }
2699    int32_t width = display->GetWidth();
2700    int32_t height = display->GetHeight();
2701#else
2702    CHKPV(window_);
2703    int32_t width = window_->GetRect().width_;
2704    int32_t height = window_->GetRect().height_;
2705#endif // OHOS_BUILD_ENABLE_ARKUI_X
2706    switch (rotation_) {
2707        case Rosen::Rotation::ROTATION_0: {
2708            break;
2709        }
2710        case Rosen::Rotation::ROTATION_90: {
2711            int32_t temp = displayY;
2712            displayY = width - displayX;
2713            displayX = temp;
2714            break;
2715        }
2716        case Rosen::Rotation::ROTATION_180: {
2717            displayX = width - displayX;
2718            displayY = height - displayY;
2719            break;
2720        }
2721        case Rosen::Rotation::ROTATION_270: {
2722            int32_t temp = displayX;
2723            displayX = height - displayY;
2724            displayY = temp;
2725            break;
2726        }
2727        default: {
2728            FI_HILOGW("Unknown parameter, rotation:%{public}d", static_cast<int32_t>(rotation_));
2729            break;
2730        }
2731    }
2732}
2733
2734void DragDrawing::RotatePosition(float &displayX, float &displayY)
2735{
2736#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2737    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
2738    if (display == nullptr) {
2739        FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
2740        display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
2741        CHKPV(display);
2742    }
2743    int32_t width = display->GetWidth();
2744    int32_t height = display->GetHeight();
2745#else
2746    CHKPV(window_);
2747    int32_t width = window_->GetRect().width_;
2748    int32_t height = window_->GetRect().height_;
2749#endif // OHOS_BUILD_ENABLE_ARKUI_X
2750    switch (rotation_) {
2751        case Rosen::Rotation::ROTATION_0: {
2752            break;
2753        }
2754        case Rosen::Rotation::ROTATION_90: {
2755            int32_t temp = displayY;
2756            displayY = width - displayX;
2757            displayX = temp;
2758            break;
2759        }
2760        case Rosen::Rotation::ROTATION_180: {
2761            displayX = width - displayX;
2762            displayY = height - displayY;
2763            break;
2764        }
2765        case Rosen::Rotation::ROTATION_270: {
2766            int32_t temp = displayX;
2767            displayX = height - displayY;
2768            displayY = temp;
2769            break;
2770        }
2771        default: {
2772            FI_HILOGE("Invalid parameter, rotation:%{public}d", static_cast<int32_t>(rotation_));
2773            break;
2774        }
2775    }
2776}
2777
2778void DragDrawing::RotatePixelMapXY()
2779{
2780    FI_HILOGI("rotation:%{public}d", static_cast<int32_t>(rotation_));
2781    CHKPV(g_drawingInfo.pixelMap);
2782    switch (rotation_) {
2783        case Rosen::Rotation::ROTATION_0:
2784        case Rosen::Rotation::ROTATION_180: {
2785            g_drawingInfo.pixelMapX = -(HALF_RATIO * g_drawingInfo.pixelMap->GetWidth());
2786            g_drawingInfo.pixelMapY = -(EIGHT_SIZE * GetScaling());
2787            break;
2788        }
2789        case Rosen::Rotation::ROTATION_90:
2790        case Rosen::Rotation::ROTATION_270: {
2791            g_drawingInfo.pixelMapX = -(HALF_RATIO * g_drawingInfo.pixelMap->GetHeight());
2792            g_drawingInfo.pixelMapY = -(EIGHT_SIZE * GetScaling());
2793            break;
2794        }
2795        default: {
2796            FI_HILOGE("Invalid parameter, rotation:%{public}d", static_cast<int32_t>(rotation_));
2797            break;
2798        }
2799    }
2800}
2801
2802void DragDrawing::ResetAnimationParameter()
2803{
2804    FI_HILOGI("enter");
2805    hasRunningScaleAnimation_ = false;
2806    CHKPV(handler_);
2807#ifndef IOS_PLATFORM
2808    handler_->RemoveAllEvents();
2809    handler_->RemoveAllFileDescriptorListeners();
2810#endif // IOS_PLATFORM
2811    handler_ = nullptr;
2812    receiver_ = nullptr;
2813#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2814    ResetSuperHubHandler();
2815#endif // OHOS_BUILD_ENABLE_ARKUI_X
2816    FI_HILOGI("leave");
2817}
2818
2819void DragDrawing::ResetAnimationFlag(bool isForce)
2820{
2821    FI_HILOGI("enter");
2822#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2823    if (!isForce && (g_drawingInfo.context != nullptr) && (g_drawingInfo.timerId >= 0)) {
2824        g_drawingInfo.context->GetTimerManager().RemoveTimer(g_drawingInfo.timerId);
2825        g_drawingInfo.timerId = -1;
2826    }
2827#endif // OHOS_BUILD_ENABLE_ARKUI_X
2828    if (drawDynamicEffectModifier_ != nullptr) {
2829        CHKPV(g_drawingInfo.rootNode);
2830        g_drawingInfo.rootNode->RemoveModifier(drawDynamicEffectModifier_);
2831        drawDynamicEffectModifier_ = nullptr;
2832    }
2833    DestroyDragWindow();
2834    g_drawingInfo.isRunning = false;
2835    g_drawingInfo.timerId = -1;
2836    ResetAnimationParameter();
2837    FI_HILOGI("leave");
2838}
2839
2840void DragDrawing::DoEndAnimation()
2841{
2842    FI_HILOGI("enter");
2843#ifdef IOS_PLATFORM
2844    g_drawingInfo.startNum = actionTime_;
2845#else
2846    g_drawingInfo.startNum = START_TIME;
2847#endif // IOS_PLATFORM
2848    g_drawingInfo.needDestroyDragWindow = true;
2849#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2850    if (g_drawingInfo.context != nullptr) {
2851        int32_t repeatCount = 1;
2852        g_drawingInfo.timerId = g_drawingInfo.context->GetTimerManager().AddTimer(TIMEOUT_MS, repeatCount, [this]() {
2853            FI_HILOGW("Timeout, automatically reset animation flag");
2854            ResetAnimationFlag(true);
2855        });
2856    }
2857#endif // OHOS_BUILD_ENABLE_ARKUI_X
2858    StartVsync();
2859    FI_HILOGI("leave");
2860}
2861
2862void DragDrawing::ResetParameter()
2863{
2864    FI_HILOGI("enter");
2865    g_drawingInfo.startNum = START_TIME;
2866    g_drawingInfo.needDestroyDragWindow = false;
2867    needRotatePixelMapXY_ = false;
2868    hasRunningStopAnimation_ = false;
2869    pointerStyle_ = {};
2870    g_drawingInfo.currentPositionX = -1.0f;
2871    g_drawingInfo.currentPositionY = -1.0f;
2872    g_drawingInfo.sourceType = -1;
2873    g_drawingInfo.currentDragNum = -1;
2874    g_drawingInfo.pixelMapX = -1;
2875    g_drawingInfo.pixelMapY = -1;
2876    g_drawingInfo.displayX = -1;
2877    g_drawingInfo.displayY = -1;
2878    g_drawingInfo.mouseWidth = 0;
2879    g_drawingInfo.mouseHeight = 0;
2880    g_drawingInfo.rootNodeWidth = -1;
2881    g_drawingInfo.rootNodeHeight = -1;
2882    g_drawingInfo.pixelMap = nullptr;
2883    g_drawingInfo.stylePixelMap = nullptr;
2884    g_drawingInfo.isPreviousDefaultStyle = false;
2885    g_drawingInfo.isCurrentDefaultStyle = false;
2886    g_drawingInfo.currentStyle = DragCursorStyle::DEFAULT;
2887    g_drawingInfo.filterInfo = {};
2888    g_drawingInfo.extraInfo = {};
2889#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2890    dragSmoothProcessor_.ResetParameters();
2891    vSyncStation_.StopVSyncRequest();
2892    frameCallback_ = nullptr;
2893#endif // OHOS_BUILD_ENABLE_ARKUI_X
2894    FI_HILOGI("leave");
2895}
2896
2897int32_t DragDrawing::DoRotateDragWindow(float rotation,
2898    const std::shared_ptr<Rosen::RSTransaction>& rsTransaction, bool isAnimated)
2899{
2900    FI_HILOGD("rotation:%{public}f, isAnimated:%{public}d", rotation, isAnimated);
2901    CHKPR(g_drawingInfo.pixelMap, RET_ERR);
2902    if ((g_drawingInfo.pixelMap->GetWidth() <= 0) || (g_drawingInfo.pixelMap->GetHeight() <= 0)) {
2903        FI_HILOGE("Invalid parameter pixelmap");
2904        return RET_ERR;
2905    }
2906    float adjustSize = TWELVE_SIZE * GetScaling();
2907    float pivotX = HALF_PIVOT;
2908    float pivotY = 0.0f;
2909    if (fabsf(adjustSize + g_drawingInfo.pixelMap->GetHeight()) < EPSILON) {
2910        pivotY = HALF_PIVOT;
2911    } else {
2912        pivotY = ((g_drawingInfo.pixelMap->GetHeight() * 1.0 / TWICE_SIZE) + adjustSize) /
2913            (adjustSize + g_drawingInfo.pixelMap->GetHeight());
2914    }
2915    if (!isAnimated) {
2916        DragWindowRotateInfo_.rotation = rotation;
2917        DragWindowRotateInfo_.pivotX = pivotX;
2918        DragWindowRotateInfo_.pivotY = pivotY;
2919        RotateCanvasNode(pivotX, pivotY, rotation);
2920        Rosen::RSTransaction::FlushImplicitTransaction();
2921        return RET_OK;
2922    }
2923    return DoRotateDragWindowAnimation(rotation, pivotX, pivotY, rsTransaction);
2924}
2925
2926template <typename T>
2927void DragDrawing::AdjustRotateDisplayXY(T &displayX, T &displayY)
2928{
2929    FI_HILOGD("rotation:%{public}d", static_cast<int32_t>(rotation_));
2930    CHKPV(g_drawingInfo.pixelMap);
2931    switch (rotation_) {
2932        case Rosen::Rotation::ROTATION_0: {
2933            break;
2934        }
2935        case Rosen::Rotation::ROTATION_90: {
2936            displayX -= (g_drawingInfo.pixelMap->GetWidth() - g_drawingInfo.pixelMap->GetHeight()) / TWICE_SIZE +
2937                g_drawingInfo.pixelMapX - g_drawingInfo.pixelMapY;
2938            displayY -= (g_drawingInfo.pixelMap->GetWidth() - g_drawingInfo.pixelMap->GetHeight()) / TWICE_SIZE +
2939                g_drawingInfo.pixelMapX + g_drawingInfo.pixelMap->GetHeight() + g_drawingInfo.pixelMapY;
2940            break;
2941        }
2942        case Rosen::Rotation::ROTATION_180: {
2943            displayX -= g_drawingInfo.pixelMap->GetWidth() + (g_drawingInfo.pixelMapX * TWICE_SIZE);
2944            displayY -= g_drawingInfo.pixelMap->GetHeight() + (g_drawingInfo.pixelMapY * TWICE_SIZE);
2945            break;
2946        }
2947        case Rosen::Rotation::ROTATION_270: {
2948            displayX -= (g_drawingInfo.pixelMap->GetWidth() - g_drawingInfo.pixelMap->GetHeight()) / TWICE_SIZE +
2949                g_drawingInfo.pixelMapX + g_drawingInfo.pixelMap->GetHeight() + g_drawingInfo.pixelMapY;
2950            displayY += (g_drawingInfo.pixelMap->GetWidth() - g_drawingInfo.pixelMap->GetHeight()) / TWICE_SIZE +
2951                g_drawingInfo.pixelMapX - g_drawingInfo.pixelMapY;
2952            break;
2953        }
2954        default: {
2955            FI_HILOGE("Invalid parameter, rotation:%{public}d", static_cast<int32_t>(rotation_));
2956            break;
2957        }
2958    }
2959}
2960
2961void DragDrawing::DrawRotateDisplayXY(float positionX, float positionY)
2962{
2963    FI_HILOGD("enter");
2964    float adjustSize = TWELVE_SIZE * GetScaling();
2965    float parentPositionX = positionX + g_drawingInfo.pixelMapX;
2966    float parentPositionY = positionY + g_drawingInfo.pixelMapY - adjustSize;
2967    auto parentNode = g_drawingInfo.parentNode;
2968    auto pixelMap  = g_drawingInfo.pixelMap;
2969    CHKPV(parentNode);
2970    CHKPV(pixelMap);
2971    parentNode->SetBounds(parentPositionX, parentPositionY, pixelMap->GetWidth(),
2972        pixelMap->GetHeight() + adjustSize);
2973    parentNode->SetFrame(parentPositionX, parentPositionY, pixelMap->GetWidth(),
2974        pixelMap->GetHeight() + adjustSize);
2975    if (!g_drawingInfo.multiSelectedNodes.empty() && !g_drawingInfo.multiSelectedPixelMaps.empty()) {
2976        DoMultiSelectedAnimation(parentPositionX, parentPositionY, adjustSize, false);
2977    }
2978    FI_HILOGD("leave");
2979}
2980
2981void DragDrawing::ScreenRotateAdjustDisplayXY(
2982    Rosen::Rotation rotation, Rosen::Rotation lastRotation, float &displayX, float &displayY)
2983{
2984    FI_HILOGI("enter");
2985#ifndef OHOS_BUILD_ENABLE_ARKUI_X
2986    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
2987    if (display == nullptr) {
2988        FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
2989        display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
2990        CHKPV(display);
2991    }
2992    int32_t width = display->GetWidth();
2993    int32_t height = display->GetHeight();
2994#else
2995    CHKPV(window_);
2996    int32_t width = window_->GetRect().width_;
2997    int32_t height = window_->GetRect().height_;
2998#endif // OHOS_BUILD_ENABLE_ARKUI_X
2999    if ((static_cast<int32_t>(lastRotation) + NUM_ONE) % NUM_FOUR == static_cast<int32_t>(rotation)) {
3000        int32_t temp = displayX;
3001        displayX = width - displayY;
3002        displayY = temp;
3003    } else if ((static_cast<int32_t>(lastRotation) + NUM_TWO) % NUM_FOUR == static_cast<int32_t>(rotation)) {
3004        displayX = width - displayX;
3005        displayY = height - displayY;
3006    } else {
3007        int32_t temp = displayY;
3008        displayY = height - displayX;
3009        displayX = temp;
3010    }
3011    FI_HILOGI("leave");
3012}
3013
3014void DragDrawing::ScreenRotate(Rosen::Rotation rotation, Rosen::Rotation lastRotation)
3015{
3016    FI_HILOGI("enter, rotation:%{public}d, lastRotation:%{public}d", static_cast<int32_t>(rotation),
3017        static_cast<int32_t>(lastRotation));
3018    ScreenRotateAdjustDisplayXY(rotation, lastRotation, g_drawingInfo.x, g_drawingInfo.y);
3019    DrawRotateDisplayXY(g_drawingInfo.x, g_drawingInfo.y);
3020
3021    if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
3022        ScreenRotateAdjustDisplayXY(
3023            rotation, lastRotation, g_drawingInfo.currentPositionX, g_drawingInfo.currentPositionY);
3024        UpdateMousePosition(g_drawingInfo.currentPositionX, g_drawingInfo.currentPositionY);
3025    }
3026    Rosen::RSTransaction::FlushImplicitTransaction();
3027    FI_HILOGI("leave");
3028}
3029
3030int32_t DragDrawing::DoRotateDragWindowAnimation(float rotation, float pivotX, float pivotY,
3031    const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
3032{
3033    FI_HILOGD("enter");
3034    if (rsTransaction != nullptr) {
3035        Rosen::RSTransaction::FlushImplicitTransaction();
3036        rsTransaction->Begin();
3037    }
3038    if ((rotation == ROTATION_0) && (DragWindowRotateInfo_.rotation == ROTATION_270)) {
3039        RotateCanvasNode(DragWindowRotateInfo_.pivotX, DragWindowRotateInfo_.pivotY, -ROTATION_90);
3040    } else if ((rotation == ROTATION_270) && (DragWindowRotateInfo_.rotation == ROTATION_0)) {
3041        RotateCanvasNode(DragWindowRotateInfo_.pivotX, DragWindowRotateInfo_.pivotY, ROTATION_360);
3042    }
3043
3044    Rosen::RSAnimationTimingProtocol protocol;
3045    protocol.SetDuration(ANIMATION_DURATION);
3046    Rosen::RSNode::Animate(protocol, SPRING, [&]() {
3047        RotateCanvasNode(pivotX, pivotY, rotation);
3048        DragWindowRotateInfo_.rotation = rotation;
3049        DragWindowRotateInfo_.pivotX = pivotX;
3050        DragWindowRotateInfo_.pivotY = pivotY;
3051        return RET_OK;
3052    }, []() { FI_HILOGD("DoRotateDragWindowAnimation end"); });
3053    if (rsTransaction != nullptr) {
3054        rsTransaction->Commit();
3055    } else {
3056        Rosen::RSTransaction::FlushImplicitTransaction();
3057    }
3058    FI_HILOGD("leave");
3059    return RET_OK;
3060}
3061
3062bool DragDrawing::ParserRadius(float &radius)
3063{
3064    FilterInfo filterInfo = g_drawingInfo.filterInfo;
3065    ExtraInfo extraInfo = g_drawingInfo.extraInfo;
3066    if ((extraInfo.cornerRadius < 0) || (filterInfo.dipScale < 0) ||
3067        (fabs(filterInfo.dipScale) < EPSILON) || ((std::numeric_limits<float>::max()
3068        / filterInfo.dipScale) < extraInfo.cornerRadius)) {
3069        FI_HILOGE("Invalid parameters, cornerRadius:%{public}f, dipScale:%{public}f",
3070            extraInfo.cornerRadius, filterInfo.dipScale);
3071        return false;
3072    }
3073    radius = extraInfo.cornerRadius * filterInfo.dipScale;
3074    return true;
3075}
3076
3077DragDrawing::~DragDrawing()
3078{
3079#ifndef OHOS_BUILD_ENABLE_ARKUI_X
3080    if (dragExtHandler_ != nullptr) {
3081        dlclose(dragExtHandler_);
3082        dragExtHandler_ = nullptr;
3083    }
3084#endif // OHOS_BUILD_ENABLE_ARKUI_X
3085}
3086
3087void DrawSVGModifier::Draw(Rosen::RSDrawingContext& context) const
3088{
3089    FI_HILOGD("enter");
3090    CHKPV(stylePixelMap_);
3091    CHKPV(g_drawingInfo.pixelMap);
3092    float scalingValue = GetScaling();
3093    if (SCALE_THRESHOLD_EIGHT < scalingValue || fabsf(SCALE_THRESHOLD_EIGHT - scalingValue) < EPSILON) {
3094        FI_HILOGE("Invalid scalingValue:%{public}f", scalingValue);
3095        return;
3096    }
3097    int32_t adjustSize = EIGHT_SIZE * scalingValue;
3098    int32_t svgTouchPositionX = g_drawingInfo.pixelMap->GetWidth() + adjustSize - stylePixelMap_->GetWidth();
3099    if (!CheckNodesValid()) {
3100        FI_HILOGE("Check nodes valid failed");
3101        return;
3102    }
3103    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
3104    CHKPV(dragStyleNode);
3105    adjustSize = (TWELVE_SIZE - EIGHT_SIZE) * scalingValue;
3106    dragStyleNode->SetBounds(svgTouchPositionX, adjustSize, stylePixelMap_->GetWidth() + adjustSize,
3107        stylePixelMap_->GetHeight());
3108    dragStyleNode->SetFrame(svgTouchPositionX, adjustSize, stylePixelMap_->GetWidth() + adjustSize,
3109        stylePixelMap_->GetHeight());
3110    dragStyleNode->SetBgImageWidth(stylePixelMap_->GetWidth());
3111    dragStyleNode->SetBgImageHeight(stylePixelMap_->GetHeight());
3112    dragStyleNode->SetBgImagePositionX(0);
3113    dragStyleNode->SetBgImagePositionY(0);
3114    auto rosenImage = std::make_shared<Rosen::RSImage>();
3115    rosenImage->SetPixelMap(stylePixelMap_);
3116    rosenImage->SetImageRepeat(0);
3117    dragStyleNode->SetBgImage(rosenImage);
3118    Rosen::RSTransaction::FlushImplicitTransaction();
3119    FI_HILOGD("leave");
3120}
3121
3122Rosen::SHADOW_COLOR_STRATEGY DrawPixelMapModifier::ConvertShadowColorStrategy(int32_t shadowColorStrategy) const
3123{
3124    if (shadowColorStrategy == static_cast<int32_t>(Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE)) {
3125        return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE ;
3126    } else if (shadowColorStrategy == static_cast<int32_t>(Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_AVERAGE)) {
3127        return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_AVERAGE ;
3128    } else if (shadowColorStrategy == static_cast<int32_t>(Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_MAIN)) {
3129        return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_MAIN ;
3130    } else {
3131        return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE;
3132    }
3133}
3134
3135void DrawPixelMapModifier::SetTextDragShadow(std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode) const
3136{
3137    if (!g_drawingInfo.filterInfo.path.empty()) {
3138        FI_HILOGD("path:%{private}s", g_drawingInfo.filterInfo.path.c_str());
3139        pixelMapNode->SetShadowPath(Rosen::RSPath::CreateRSPath(g_drawingInfo.filterInfo.path));
3140    } else {
3141        FI_HILOGW("path is empty");
3142    }
3143}
3144
3145void DrawPixelMapModifier::SetDragShadow(std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode) const
3146{
3147    if ((g_drawingInfo.filterInfo.dragType == "text") && (g_drawingInfo.filterInfo.path.empty())) {
3148        FI_HILOGI("path is empty");
3149        return;
3150    }
3151    pixelMapNode->SetShadowOffset(g_drawingInfo.filterInfo.offsetX, g_drawingInfo.filterInfo.offsetY);
3152    pixelMapNode->SetShadowColor(g_drawingInfo.filterInfo.argb);
3153    pixelMapNode->SetShadowMask(g_drawingInfo.filterInfo.shadowMask);
3154    pixelMapNode->SetShadowIsFilled(g_drawingInfo.filterInfo.shadowIsFilled);
3155    pixelMapNode->SetShadowColorStrategy(ConvertShadowColorStrategy(g_drawingInfo.filterInfo.shadowColorStrategy));
3156    if (g_drawingInfo.filterInfo.isHardwareAcceleration) {
3157        pixelMapNode->SetShadowElevation(g_drawingInfo.filterInfo.elevation);
3158    } else {
3159        pixelMapNode->SetShadowRadius(g_drawingInfo.filterInfo.shadowCorner);
3160    }
3161    if (g_drawingInfo.filterInfo.dragType == "text") {
3162        SetTextDragShadow(pixelMapNode);
3163    }
3164}
3165
3166void DrawPixelMapModifier::Draw(Rosen::RSDrawingContext &context) const
3167{
3168    FI_HILOGD("enter");
3169    CHKPV(g_drawingInfo.pixelMap);
3170    int32_t pixelMapWidth = g_drawingInfo.pixelMap->GetWidth();
3171    int32_t pixelMapHeight = g_drawingInfo.pixelMap->GetHeight();
3172    if (!CheckNodesValid()) {
3173        FI_HILOGE("Check nodes valid failed");
3174        return;
3175    }
3176    std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
3177    CHKPV(pixelMapNode);
3178    if (g_drawingInfo.filterInfo.shadowEnable) {
3179        SetDragShadow(pixelMapNode);
3180    }
3181    int32_t adjustSize = TWELVE_SIZE * GetScaling();
3182    pixelMapNode->SetBounds(DEFAULT_POSITION_X, adjustSize, pixelMapWidth, pixelMapHeight);
3183    pixelMapNode->SetFrame(DEFAULT_POSITION_X, adjustSize, pixelMapWidth, pixelMapHeight);
3184    pixelMapNode->SetBgImageWidth(pixelMapWidth);
3185    pixelMapNode->SetBgImageHeight(pixelMapHeight);
3186    pixelMapNode->SetBgImagePositionX(0);
3187    pixelMapNode->SetBgImagePositionY(0);
3188    Rosen::Drawing::AdaptiveImageInfo rsImageInfo = { 1, 0, {}, 1, 0, pixelMapWidth, pixelMapHeight };
3189    auto cvs = pixelMapNode->BeginRecording(pixelMapWidth, pixelMapHeight);
3190    CHKPV(cvs);
3191    Rosen::Drawing::Brush brush;
3192    cvs->AttachBrush(brush);
3193    FilterInfo filterInfo = g_drawingInfo.filterInfo;
3194    if (g_drawingInfo.filterInfo.shadowEnable && !filterInfo.path.empty() &&
3195        g_drawingInfo.filterInfo.dragType == "text") {
3196        auto rsPath = Rosen::RSPath::CreateRSPath(filterInfo.path);
3197        cvs->Save();
3198        cvs->ClipPath(rsPath->GetDrawingPath(), Rosen::Drawing::ClipOp::INTERSECT, true);
3199        cvs->DrawPixelMapWithParm(g_drawingInfo.pixelMap, rsImageInfo, Rosen::Drawing::SamplingOptions());
3200        cvs->Restore();
3201    } else {
3202        cvs->DrawPixelMapWithParm(g_drawingInfo.pixelMap, rsImageInfo, Rosen::Drawing::SamplingOptions());
3203    }
3204    cvs->DetachBrush();
3205    pixelMapNode->SetClipToBounds(true);
3206    pixelMapNode->FinishRecording();
3207    Rosen::RSTransaction::FlushImplicitTransaction();
3208    FI_HILOGD("leave");
3209}
3210
3211void DrawMouseIconModifier::Draw(Rosen::RSDrawingContext &context) const
3212{
3213    FI_HILOGD("enter");
3214#ifndef OHOS_BUILD_ENABLE_ARKUI_X
3215    std::shared_ptr<Media::PixelMap> pixelMap = std::make_shared<Media::PixelMap>();
3216    int32_t ret = RET_ERR;
3217#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
3218    ret = MMI::InputManager::GetInstance()->GetPointerSnapshot(&pixelMap);
3219#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
3220    if (ret != RET_OK) {
3221        FI_HILOGE("Get pointer snapshot failed, ret:%{public}d", ret);
3222        pixelMap = DrawFromSVG();
3223    }
3224    CHKPV(pixelMap);
3225    OnDraw(pixelMap);
3226#endif // OHOS_BUILD_ENABLE_ARKUI_X
3227    FI_HILOGD("leave");
3228}
3229
3230std::shared_ptr<Media::PixelMap> DrawMouseIconModifier::DrawFromSVG() const
3231{
3232    std::string imagePath;
3233    if (pointerStyle_.id == MOUSE_DRAG_CURSOR_CIRCLE_STYLE) {
3234        imagePath = MOUSE_DRAG_CURSOR_CIRCLE_PATH;
3235    } else {
3236        imagePath = MOUSE_DRAG_DEFAULT_PATH;
3237    }
3238    int32_t pointerSize = pointerStyle_.size;
3239    int32_t pointerColor = pointerStyle_.color;
3240    int32_t cursorPixel = DEVICE_INDEPENDENT_PIXEL;
3241#ifndef OHOS_BUILD_ENABLE_ARKUI_X
3242    if (pointerStyle_.options == MAGIC_STYLE_OPT) {
3243        imagePath = MOUSE_DRAG_MAGIC_DEFAULT_PATH;
3244        int32_t ret = MMI::InputManager::GetInstance()->GetPointerSize(pointerSize);
3245        if (ret != RET_OK) {
3246            FI_HILOGW("Get pointer size failed, ret:%{public}d", ret);
3247        }
3248        ret = MMI::InputManager::GetInstance()->GetPointerColor(pointerColor);
3249        if (ret != RET_OK) {
3250            FI_HILOGW("Get pointer color failed, ret:%{public}d", ret);
3251        }
3252        cursorPixel = MAGIC_INDEPENDENT_PIXEL;
3253    }
3254#endif // OHOS_BUILD_ENABLE_ARKUI_X
3255    Media::SourceOptions opts;
3256    opts.formatHint = "image/svg+xml";
3257    uint32_t errCode = 0;
3258    auto imageSource = Media::ImageSource::CreateImageSource(imagePath, opts, errCode);
3259    if (imageSource == nullptr) {
3260        FI_HILOGW("imageSource is null");
3261        return nullptr;
3262    }
3263    if (pointerSize < DEFAULT_MOUSE_SIZE) {
3264        FI_HILOGD("Invalid pointerSize:%{public}d", pointerSize);
3265        pointerSize = DEFAULT_MOUSE_SIZE;
3266    }
3267    Media::DecodeOptions decodeOpts;
3268    decodeOpts.desiredSize = {
3269        .width = pow(INCREASE_RATIO, pointerSize - 1) * cursorPixel * GetScaling(),
3270        .height = pow(INCREASE_RATIO, pointerSize - 1) * cursorPixel * GetScaling()
3271    };
3272    if (pointerColor != INVALID_COLOR_VALUE) {
3273        decodeOpts.SVGOpts.fillColor = {.isValidColor = true, .color = pointerColor};
3274    }
3275    return imageSource->CreatePixelMap(decodeOpts, errCode);
3276}
3277
3278void DrawMouseIconModifier::OnDraw(std::shared_ptr<Media::PixelMap> pixelMap) const
3279{
3280    FI_HILOGD("enter");
3281#ifndef OHOS_BUILD_ENABLE_ARKUI_X
3282    CHKPV(pixelMap);
3283    if (!CheckNodesValid()) {
3284        FI_HILOGE("Check nodes valid failed");
3285        return;
3286    }
3287    g_drawingInfo.mouseWidth = pixelMap->GetWidth();
3288    g_drawingInfo.mouseHeight = pixelMap->GetHeight();
3289    if (g_drawingInfo.nodes.size() <= MOUSE_ICON_INDEX) {
3290        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
3291        return;
3292    }
3293    std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
3294    CHKPV(mouseIconNode);
3295    mouseIconNode->SetBgImageWidth(pixelMap->GetWidth());
3296    mouseIconNode->SetBgImageHeight(pixelMap->GetHeight());
3297    mouseIconNode->SetBgImagePositionX(0);
3298    mouseIconNode->SetBgImagePositionY(0);
3299    auto rosenImage = std::make_shared<Rosen::RSImage>();
3300    rosenImage->SetPixelMap(pixelMap);
3301    rosenImage->SetImageRepeat(0);
3302    mouseIconNode->SetBgImage(rosenImage);
3303    Rosen::RSTransaction::FlushImplicitTransaction();
3304#endif // OHOS_BUILD_ENABLE_ARKUI_X
3305    FI_HILOGD("leave");
3306}
3307
3308void DrawDynamicEffectModifier::Draw(Rosen::RSDrawingContext &context) const
3309{
3310    FI_HILOGD("enter");
3311    CHKPV(alpha_);
3312    CHKPV(g_drawingInfo.parentNode);
3313    g_drawingInfo.parentNode->SetAlpha(alpha_->Get());
3314    CHKPV(scale_);
3315    g_drawingInfo.parentNode->SetScale(scale_->Get(), scale_->Get());
3316    Rosen::RSTransaction::FlushImplicitTransaction();
3317    FI_HILOGD("leave");
3318}
3319
3320void DrawDynamicEffectModifier::SetAlpha(float alpha)
3321{
3322    FI_HILOGD("enter");
3323    if (alpha_ == nullptr) {
3324        alpha_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(alpha);
3325        Rosen::RSModifier::AttachProperty(alpha_);
3326        return;
3327    }
3328    alpha_->Set(alpha);
3329    FI_HILOGD("leave");
3330}
3331
3332void DrawDynamicEffectModifier::SetScale(float scale)
3333{
3334    FI_HILOGD("enter");
3335    if (scale_ == nullptr) {
3336        scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3337        Rosen::RSModifier::AttachProperty(scale_);
3338        return;
3339    }
3340    scale_->Set(scale);
3341    FI_HILOGD("leave");
3342}
3343
3344void DrawStyleChangeModifier::Draw(Rosen::RSDrawingContext &context) const
3345{
3346    FI_HILOGD("enter");
3347    if (!CheckNodesValid()) {
3348        FI_HILOGE("Check nodes valid failed");
3349        return;
3350    }
3351    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
3352        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
3353        return;
3354    }
3355    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
3356    CHKPV(dragStyleNode);
3357    CHKPV(g_drawingInfo.pixelMap);
3358    float pixelMapWidth = g_drawingInfo.pixelMap->GetWidth();
3359    if (stylePixelMap_ == nullptr) {
3360        if (scale_ == nullptr) {
3361            return;
3362        }
3363        dragStyleNode->SetScale(scale_->Get());
3364        return;
3365    }
3366    float scalingValue = GetScaling();
3367    if ((1.0 * INT_MAX / EIGHT_SIZE) <= scalingValue) {
3368        return;
3369    }
3370    int32_t adjustSize = EIGHT_SIZE * scalingValue;
3371    int32_t svgTouchPositionX = pixelMapWidth + adjustSize - stylePixelMap_->GetWidth();
3372    dragStyleNode->SetBounds(svgTouchPositionX, (TWELVE_SIZE-EIGHT_SIZE)*scalingValue, stylePixelMap_->GetWidth(),
3373        stylePixelMap_->GetHeight());
3374    dragStyleNode->SetFrame(svgTouchPositionX, (TWELVE_SIZE-EIGHT_SIZE)*scalingValue, stylePixelMap_->GetWidth(),
3375        stylePixelMap_->GetHeight());
3376    dragStyleNode->SetBgImageWidth(stylePixelMap_->GetWidth());
3377    dragStyleNode->SetBgImageHeight(stylePixelMap_->GetHeight());
3378    dragStyleNode->SetBgImagePositionX(0);
3379    dragStyleNode->SetBgImagePositionY(0);
3380    auto rosenImage = std::make_shared<Rosen::RSImage>();
3381    rosenImage->SetPixelMap(stylePixelMap_);
3382    rosenImage->SetImageRepeat(0);
3383    dragStyleNode->SetBgImage(rosenImage);
3384    Rosen::RSTransaction::FlushImplicitTransaction();
3385    FI_HILOGD("leave");
3386}
3387
3388void DrawStyleChangeModifier::SetScale(float scale)
3389{
3390    FI_HILOGD("enter");
3391    if (scale_ == nullptr) {
3392        scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3393        Rosen::RSModifier::AttachProperty(scale_);
3394    } else {
3395        scale_->Set(scale);
3396    }
3397    FI_HILOGD("leave");
3398}
3399
3400void DrawStyleScaleModifier::Draw(Rosen::RSDrawingContext &context) const
3401{
3402    FI_HILOGD("enter");
3403    if (!CheckNodesValid()) {
3404        FI_HILOGE("Check nodes valid failed");
3405        return;
3406    }
3407    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
3408        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
3409        return;
3410    }
3411    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
3412    CHKPV(dragStyleNode);
3413    CHKPV(scale_);
3414    dragStyleNode->SetScale(scale_->Get());
3415    FI_HILOGD("leave");
3416}
3417
3418void DrawStyleScaleModifier::SetScale(float scale)
3419{
3420    FI_HILOGD("enter");
3421    if (scale_ == nullptr) {
3422        scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3423        Rosen::RSModifier::AttachProperty(scale_);
3424    } else {
3425        scale_->Set(scale);
3426    }
3427    FI_HILOGD("leave");
3428}
3429
3430void DrawDragStopModifier::Draw(Rosen::RSDrawingContext &context) const
3431{
3432    FI_HILOGD("enter");
3433    CHKPV(alpha_);
3434    CHKPV(scale_);
3435    if (!CheckNodesValid()) {
3436        FI_HILOGE("Check nodes valid failed");
3437        return;
3438    }
3439    CHKPV(g_drawingInfo.parentNode);
3440    g_drawingInfo.parentNode->SetAlpha(alpha_->Get());
3441    g_drawingInfo.parentNode->SetScale(scale_->Get(), scale_->Get());
3442    if (!g_drawingInfo.multiSelectedNodes.empty()) {
3443        size_t multiSelectedNodesSize = g_drawingInfo.multiSelectedNodes.size();
3444        for (size_t i = 0; i < multiSelectedNodesSize; ++i) {
3445            std::shared_ptr<Rosen::RSCanvasNode> multiSelectedNode = g_drawingInfo.multiSelectedNodes[i];
3446            CHKPV(multiSelectedNode);
3447            multiSelectedNode->SetAlpha(alpha_->Get());
3448            multiSelectedNode->SetScale(scale_->Get(), scale_->Get());
3449        }
3450    }
3451    if (g_drawingInfo.nodes.size() <= DRAG_STYLE_INDEX) {
3452        FI_HILOGE("The index is out of bounds, node size is %{public}zu", g_drawingInfo.nodes.size());
3453        return;
3454    }
3455    std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
3456    CHKPV(dragStyleNode);
3457    dragStyleNode->SetScale(styleScale_->Get());
3458    dragStyleNode->SetAlpha(styleAlpha_->Get());
3459    FI_HILOGD("leave");
3460}
3461
3462void DrawDragStopModifier::SetAlpha(float alpha)
3463{
3464    FI_HILOGD("enter");
3465    if (alpha_ == nullptr) {
3466        alpha_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(alpha);
3467        Rosen::RSModifier::AttachProperty(alpha_);
3468    } else {
3469        alpha_->Set(alpha);
3470    }
3471    FI_HILOGD("leave");
3472}
3473
3474void DrawDragStopModifier::SetScale(float scale)
3475{
3476    FI_HILOGD("enter");
3477    if (scale_ == nullptr) {
3478        scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3479        Rosen::RSModifier::AttachProperty(scale_);
3480    } else {
3481        scale_->Set(scale);
3482    }
3483    FI_HILOGD("leave");
3484}
3485
3486void DrawDragStopModifier::SetStyleScale(float scale)
3487{
3488    FI_HILOGD("enter");
3489    if (styleScale_ == nullptr) {
3490        styleScale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
3491        Rosen::RSModifier::AttachProperty(styleScale_);
3492    } else {
3493        styleScale_->Set(scale);
3494    }
3495    FI_HILOGD("leave");
3496}
3497
3498void DrawDragStopModifier::SetStyleAlpha(float alpha)
3499{
3500    FI_HILOGD("enter");
3501    if (styleAlpha_ == nullptr) {
3502        styleAlpha_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(alpha);
3503        Rosen::RSModifier::AttachProperty(styleAlpha_);
3504    } else {
3505        styleAlpha_->Set(alpha);
3506    }
3507    FI_HILOGD("leave");
3508}
3509
3510float DragDrawing::CalculateWidthScale()
3511{
3512#ifndef OHOS_BUILD_ENABLE_ARKUI_X
3513    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
3514    if (display == nullptr) {
3515        FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
3516        display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
3517        if (display == nullptr) {
3518            FI_HILOGE("Get display info failed, display is nullptr");
3519            return DEFAULT_SCALING;
3520        }
3521    }
3522    auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
3523    if (defaultDisplay == nullptr) {
3524        FI_HILOGE("defaultDisplay is nullptr");
3525        return DEFAULT_SCALING;
3526    }
3527    int32_t width = display->GetWidth();
3528    float density = defaultDisplay->GetVirtualPixelRatio();
3529#else
3530    if (window_ == nullptr) {
3531        FI_HILOGE("window_ is nullptr");
3532        return DEFAULT_SCALING;
3533    }
3534    int32_t width = window_->GetRect().width_;
3535    float density = window_->GetDensity();
3536#endif // OHOS_BUILD_ENABLE_ARKUI_X
3537    FI_HILOGD("density:%{public}f, width:%{public}d", density, width);
3538    if (width < MAX_SCREEN_WIDTH_SM * density) {
3539        currentScreenSize_ = ScreenSizeType::XS;
3540    } else if (width < MAX_SCREEN_WIDTH_MD * density) {
3541        currentScreenSize_ = ScreenSizeType::SM;
3542    } else if (width < MAX_SCREEN_WIDTH_LG * density) {
3543        currentScreenSize_ = ScreenSizeType::MD;
3544    } else if (width < MAX_SCREEN_WIDTH_XL * density) {
3545        currentScreenSize_ = ScreenSizeType::LG;
3546    } else {
3547        currentScreenSize_ = ScreenSizeType::XL;
3548    }
3549    float widthScale = GetMaxWidthScale(width);
3550    return widthScale;
3551}
3552
3553float DragDrawing::GetMaxWidthScale(int32_t width)
3554{
3555    float scale = 1.0;
3556    float widthScale = 1.0;
3557    if (g_drawingInfo.pixelMap == nullptr) {
3558        FI_HILOGE("pixelMap is nullptr");
3559        return DEFAULT_SCALING;
3560    }
3561    int32_t pixelMapWidth = g_drawingInfo.pixelMap->GetWidth();
3562    if (pixelMapWidth == 0) {
3563        FI_HILOGW("pixelMapWidth is 0");
3564        return DEFAULT_SCALING;
3565    }
3566    switch (currentScreenSize_) {
3567        case ScreenSizeType::XS: {
3568            return widthScale;
3569        }
3570        case ScreenSizeType::SM: {
3571            scale = width * SCALE_SM;
3572            if (pixelMapWidth > scale) {
3573                widthScale = scale / pixelMapWidth;
3574                return widthScale;
3575            }
3576            return widthScale;
3577        }
3578        case ScreenSizeType::MD: {
3579            scale = width * SCALE_MD;
3580            if (pixelMapWidth > scale) {
3581                widthScale = scale / pixelMapWidth;
3582                return widthScale;
3583            }
3584            return widthScale;
3585        }
3586        case ScreenSizeType::LG: {
3587            scale = width * SCALE_LG;
3588            if (pixelMapWidth > scale) {
3589                widthScale = scale / pixelMapWidth;
3590                return widthScale;
3591            }
3592            return widthScale;
3593        }
3594        default: {
3595            FI_HILOGI("Screen Size Type is XL");
3596            break;
3597        }
3598    }
3599    return widthScale;
3600}
3601
3602void DragDrawing::UpdateDragWindowDisplay(int32_t displayId)
3603{
3604#ifndef OHOS_BUILD_ENABLE_ARKUI_X
3605    CHKPV(g_drawingInfo.surfaceNode);
3606    CHKPV(g_drawingInfo.rootNode);
3607    sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId);
3608    if (display == nullptr) {
3609        FI_HILOGD("Get display info failed, display:%{public}d", displayId);
3610        display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
3611        if (display == nullptr) {
3612            FI_HILOGE("Get display info failed, display is nullptr");
3613        }
3614        return;
3615    }
3616    int32_t surfaceNodeSize = std::max(display->GetWidth(), display->GetHeight());
3617    g_drawingInfo.surfaceNode->SetBounds(0, 0, surfaceNodeSize, surfaceNodeSize);
3618    g_drawingInfo.rootNode->SetBounds(0, 0, surfaceNodeSize, surfaceNodeSize);
3619    g_drawingInfo.rootNode->SetFrame(0, 0, surfaceNodeSize, surfaceNodeSize);
3620    g_drawingInfo.surfaceNode->DetachToDisplay(screenId_);
3621    g_drawingInfo.surfaceNode->AttachToDisplay(displayId);
3622    Rosen::RSTransaction::FlushImplicitTransaction();
3623#endif // OHOS_BUILD_ENABLE_ARKUI_X
3624}
3625
3626#ifdef OHOS_BUILD_ENABLE_ARKUI_X
3627void DragDrawing::SetDragWindow(std::shared_ptr<OHOS::Rosen::Window> window)
3628{
3629    CALL_INFO_TRACE;
3630    window_ = window;
3631}
3632
3633void DragDrawing::AddDragDestroy(std::function<void()> cb)
3634{
3635    CALL_INFO_TRACE;
3636    callback_ = cb;
3637}
3638
3639void DragDrawing::SetSVGFilePath(const std::string &filePath)
3640{
3641    CALL_INFO_TRACE;
3642    svgFilePath_ = filePath;
3643}
3644#endif
3645
3646void DragDrawing::LoadDragDropLib()
3647{
3648    FI_HILOGI("Begin to open drag drop extension library");
3649    if (dragExtHandler_ == nullptr) {
3650        dragExtHandler_ = dlopen(DRAG_DROP_EXTENSION_SO_PATH.c_str(), RTLD_LAZY);
3651    }
3652    CHKPL(dragExtHandler_);
3653    FI_HILOGI("End to open drag drop extension library");
3654}
3655} // namespace DeviceStatus
3656} // namespace Msdp
3657} // namespace OHOS
3658