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