• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <string>
22 
23 #include <dlfcn.h>
24 
25 #include "display_manager.h"
26 #include "include/core/SkTextBlob.h"
27 #include "image_source.h"
28 #include "image_type.h"
29 #include "image_utils.h"
30 #include "libxml/tree.h"
31 #include "libxml/parser.h"
32 #include "parameters.h"
33 #include "pointer_event.h"
34 #include "string_ex.h"
35 #include "transaction/rs_interfaces.h"
36 #include "ui/rs_surface_extractor.h"
37 #include "ui/rs_surface_node.h"
38 #include "ui/rs_ui_director.h"
39 
40 #include "devicestatus_define.h"
41 #include "drag_data_manager.h"
42 #include "util.h"
43 
44 namespace OHOS {
45 namespace Msdp {
46 namespace DeviceStatus {
47 namespace {
48 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "DragDrawing" };
49 constexpr int32_t BASELINE_DENSITY { 160 };
50 constexpr int32_t DEVICE_INDEPENDENT_PIXEL { 40 };
51 constexpr int32_t DRAG_NUM_ONE { 1 };
52 constexpr int32_t STRING_PX_LENGTH { 2 };
53 constexpr int32_t EIGHT_SIZE { 8 };
54 constexpr int32_t TWELVE_SIZE { 12 };
55 constexpr int32_t IMAGE_WIDTH { 400 };
56 constexpr int32_t IMAGE_HEIGHT { 500 };
57 constexpr int64_t START_TIME { 181154000809 };
58 constexpr int64_t INTERVAL_TIME { 16666667 };
59 constexpr int32_t FRAMERATE { 30 };
60 constexpr int32_t SVG_WIDTH { 40 };
61 constexpr int32_t SVG_HEIGHT { 40 };
62 constexpr int32_t SIXTEEN { 16 };
63 constexpr int32_t SUCCESS_ANIMATION_DURATION { 300 };
64 constexpr int32_t VIEW_BOX_POS { 2 };
65 constexpr int32_t PIXEL_MAP_INDEX { 0 };
66 constexpr int32_t DRAG_STYLE_INDEX { 1 };
67 constexpr int32_t MOUSE_ICON_INDEX { 2 };
68 constexpr size_t TOUCH_NODE_MIN_COUNT { 2 };
69 constexpr size_t MOUSE_NODE_MIN_COUNT { 3 };
70 constexpr double ONETHOUSAND { 1000.0 };
71 constexpr float DEFAULT_SCALING { 1.0f };
72 constexpr float BEGIN_ALPHA { 1.0f };
73 constexpr float END_ALPHA { 0.0f };
74 constexpr float BEGIN_SCALE { 1.0f };
75 constexpr float END_SCALE_FAIL { 1.2f };
76 constexpr float END_SCALE_SUCCESS { 0.1f };
77 constexpr float PIVOT_X { 0.5f };
78 constexpr float PIVOT_Y { 0.5f };
79 constexpr float SVG_ORIGINAL_SIZE { 40.0f };;
80 const std::string DEVICE_TYPE_DEFAULT { "default" };
81 const std::string DEVICE_TYPE_PHONE { "phone" };
82 const std::string THREAD_NAME { "AnimationEventRunner" };
83 const std::string COPY_DRAG_PATH { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
84 const std::string COPY_ONE_DRAG_PATH { "/system/etc/device_status/drag_icon/Copy_One_Drag.svg" };
85 const std::string DEFAULT_DRAG_PATH { "/system/etc/device_status/drag_icon/Default_Drag.svg" };
86 const std::string FORBID_DRAG_PATH { "/system/etc/device_status/drag_icon/Forbid_Drag.svg" };
87 const std::string FORBID_ONE_DRAG_PATH { "/system/etc/device_status/drag_icon/Forbid_One_Drag.svg" };
88 const std::string MOUSE_DRAG_PATH { "/system/etc/device_status/drag_icon/Mouse_Drag.svg" };
89 const std::string MOVE_DRAG_PATH { "/system/etc/device_status/drag_icon/Move_Drag.svg" };
90 #ifdef __aarch64__
91 const std::string DRAG_ANIMATION_EXTENSION_SO_PATH { "/system/lib64/drag_drop_ext/libdrag_drop_ext.z.so" };
92 #else
93 const std::string DRAG_ANIMATION_EXTENSION_SO_PATH { "/system/lib/drag_drop_ext/libdrag_drop_ext.z.so" };
94 #endif
95 struct DrawingInfo g_drawingInfo;
96 
CheckNodesValid()97 bool CheckNodesValid()
98 {
99     CALL_DEBUG_ENTER;
100     if ((g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
101         (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT)) {
102         FI_HILOGE("Nodes size invalid when mouse type, node size:%{public}zu", g_drawingInfo.nodes.size());
103         return false;
104     }
105     if ((g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) &&
106         (g_drawingInfo.nodes.size() < TOUCH_NODE_MIN_COUNT)) {
107         FI_HILOGE("Nodes size invalid when touchscreen type, node size:%{public}zu", g_drawingInfo.nodes.size());
108         return false;
109     }
110     return true;
111 }
112 
GetScaling()113 float GetScaling()
114 {
115     CALL_DEBUG_ENTER;
116     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(g_drawingInfo.displayId);
117     if (display == nullptr) {
118         FI_HILOGD("Get display info failed, display:%{public}d", g_drawingInfo.displayId);
119         display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
120         if (display == nullptr) {
121             FI_HILOGE("Get display info failed, display is nullptr");
122             return DEFAULT_SCALING;
123         }
124     }
125 
126     int32_t deviceDpi = display->GetDpi();
127     FI_HILOGD("displayId:%{public}d, deviceDpi:%{public}d", g_drawingInfo.displayId, deviceDpi);
128     if (deviceDpi < -std::numeric_limits<float>::epsilon()) {
129         FI_HILOGE("Invalid deviceDpi:%{public}d", deviceDpi);
130         return DEFAULT_SCALING;
131     }
132     return (1.0 * deviceDpi * DEVICE_INDEPENDENT_PIXEL / BASELINE_DENSITY) / SVG_ORIGINAL_SIZE;
133 }
134 } // namespace
135 
Init(const DragData & dragData)136 int32_t DragDrawing::Init(const DragData &dragData)
137 {
138     CALL_DEBUG_ENTER;
139     if (g_drawingInfo.isRunning) {
140         FI_HILOGE("Drag drawing is running, can not init again");
141         return INIT_CANCEL;
142     }
143     CHKPR(dragData.shadowInfo.pixelMap, INIT_FAIL);
144     if ((dragData.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
145         (dragData.sourceType != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN)) {
146         FI_HILOGE("Invalid sourceType:%{public}d", dragData.sourceType);
147         return INIT_FAIL;
148     }
149     if (dragData.dragNum < 0) {
150         FI_HILOGE("Invalid dragNum:%{public}d", dragData.dragNum);
151         return INIT_FAIL;
152     }
153     InitDrawingInfo(dragData);
154     CreateWindow(dragData.displayX, dragData.displayY);
155     CHKPR(g_drawingInfo.surfaceNode, INIT_FAIL);
156     if (InitLayer() != RET_OK) {
157         FI_HILOGE("Init layer failed");
158         return INIT_FAIL;
159     }
160     DragAnimationData dragAnimationData;
161     if (InitDragAnimationData(dragAnimationData) != RET_OK) {
162         FI_HILOGE("Init drag animation data failed");
163         return INIT_FAIL;
164     }
165     if (!CheckNodesValid()) {
166         FI_HILOGE("Check nodes valid failed");
167         return INIT_FAIL;
168     }
169     std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
170     CHKPR(shadowNode, INIT_FAIL);
171     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
172     CHKPR(dragStyleNode, INIT_FAIL);
173     dragExtHandle_ = dlopen(DRAG_ANIMATION_EXTENSION_SO_PATH.c_str(), RTLD_LAZY);
174     if (dragExtHandle_ == nullptr) {
175         FI_HILOGE("Failed to open drag extension library");
176     }
177     OnStartDrag(dragAnimationData, shadowNode, dragStyleNode);
178     CHKPR(rsUiDirector_, INIT_FAIL);
179     if (g_drawingInfo.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
180         rsUiDirector_->SendMessages();
181         return INIT_SUCCESS;
182     }
183     if (DrawMouseIcon() != RET_OK) {
184         FI_HILOGE("Draw mouse icon failed");
185         return INIT_FAIL;
186     }
187     rsUiDirector_->SendMessages();
188     return INIT_SUCCESS;
189 }
190 
Draw(int32_t displayId,int32_t displayX,int32_t displayY)191 void DragDrawing::Draw(int32_t displayId, int32_t displayX, int32_t displayY)
192 {
193     CALL_DEBUG_ENTER;
194     if (displayId < 0) {
195         FI_HILOGE("Invalid displayId:%{public}d", displayId);
196         return;
197     }
198     g_drawingInfo.displayId = displayId;
199     g_drawingInfo.displayX = displayX;
200     g_drawingInfo.displayY = displayY;
201     if (displayX < 0) {
202         g_drawingInfo.displayX = 0;
203     }
204     if (displayY < 0) {
205         g_drawingInfo.displayY = 0;
206     }
207     int32_t adjustSize = TWELVE_SIZE * GetScaling();
208     int32_t positionY = g_drawingInfo.displayY + g_drawingInfo.pixelMapY - adjustSize;
209     int32_t positionX = g_drawingInfo.displayX + g_drawingInfo.pixelMapX;
210     if (g_drawingInfo.surfaceNode != nullptr) {
211         g_drawingInfo.surfaceNode->SetBounds(positionX, positionY,
212             g_drawingInfo.surfaceNode->GetStagingProperties().GetBounds().z_,
213             g_drawingInfo.surfaceNode->GetStagingProperties().GetBounds().w_);
214         Rosen::RSTransaction::FlushImplicitTransaction();
215         return;
216     }
217     CreateWindow(positionX, positionY);
218     CHKPV(g_drawingInfo.surfaceNode);
219 }
220 
UpdateDragStyle(DragCursorStyle style)221 int32_t DragDrawing::UpdateDragStyle(DragCursorStyle style)
222 {
223     CALL_DEBUG_ENTER;
224     if ((style < DragCursorStyle::DEFAULT) || (style > DragCursorStyle::MOVE)) {
225         FI_HILOGE("Invalid style:%{public}d", style);
226         return RET_ERR;
227     }
228     if (g_drawingInfo.currentStyle == style) {
229         FI_HILOGD("Not need update drag style");
230         return RET_OK;
231     }
232     g_drawingInfo.currentStyle = style;
233     std::string filePath;
234     if (GetFilePath(filePath) != RET_OK) {
235         FI_HILOGD("Get file path failed");
236         return RET_ERR;
237     }
238     if (!IsValidSvgFile(filePath)) {
239         FI_HILOGE("Svg file is invalid");
240         return RET_ERR;
241     }
242     std::shared_ptr<Media::PixelMap> pixelMap = DecodeSvgToPixelMap(filePath);
243     CHKPR(pixelMap, RET_ERR);
244     bool isPreviousDefaultStyle = g_drawingInfo.isCurrentDefaultStyle;
245     g_drawingInfo.isPreviousDefaultStyle = isPreviousDefaultStyle;
246     g_drawingInfo.isCurrentDefaultStyle = (filePath == DEFAULT_DRAG_PATH);
247     g_drawingInfo.stylePixelMap = pixelMap;
248     if (!CheckNodesValid()) {
249         FI_HILOGE("Check nodes valid failed");
250         return RET_ERR;
251     }
252     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
253     CHKPR(dragStyleNode, RET_ERR);
254     OnDragStyle(dragStyleNode, pixelMap);
255     CHKPR(rsUiDirector_, RET_ERR);
256     rsUiDirector_->SendMessages();
257     return RET_OK;
258 }
259 
UpdateShadowPic(const ShadowInfo & shadowInfo)260 int32_t DragDrawing::UpdateShadowPic(const ShadowInfo &shadowInfo)
261 {
262     CALL_DEBUG_ENTER;
263     CHKPR(shadowInfo.pixelMap, RET_ERR);
264     Draw(g_drawingInfo.displayId, g_drawingInfo.displayX + shadowInfo.x - g_drawingInfo.pixelMapX,
265         g_drawingInfo.displayY + shadowInfo.y - g_drawingInfo.pixelMapY);
266     g_drawingInfo.pixelMap = shadowInfo.pixelMap;
267     if (!CheckNodesValid()) {
268         FI_HILOGE("Check nodes valid failed");
269         return RET_ERR;
270     }
271     std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
272     CHKPR(shadowNode, RET_ERR);
273     DrawShadow(shadowNode);
274     float scalingValue = GetScaling();
275     if ((1.0 * INT32_MAX / (SVG_WIDTH + TWELVE_SIZE)) <= scalingValue) {
276         FI_HILOGE("Invalid scalingValue:%{public}f", scalingValue);
277         return RET_ERR;
278     }
279     int32_t adjustSize = (SVG_WIDTH + TWELVE_SIZE) * scalingValue;
280     g_drawingInfo.rootNodeWidth = g_drawingInfo.pixelMap->GetWidth() + adjustSize;
281     g_drawingInfo.rootNodeHeight = g_drawingInfo.pixelMap->GetHeight() + adjustSize;
282     CHKPR(g_drawingInfo.rootNode, RET_ERR);
283     g_drawingInfo.rootNode->SetBounds(0, 0, g_drawingInfo.rootNodeWidth, g_drawingInfo.rootNodeHeight);
284     g_drawingInfo.rootNode->SetFrame(0, 0, g_drawingInfo.rootNodeWidth, g_drawingInfo.rootNodeHeight);
285     CHKPR(g_drawingInfo.surfaceNode, RET_ERR);
286     g_drawingInfo.surfaceNode->SetBoundsWidth(g_drawingInfo.rootNodeWidth);
287     g_drawingInfo.surfaceNode->SetBoundsHeight(g_drawingInfo.rootNodeHeight);
288     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
289         g_drawingInfo.pixelMapX = shadowInfo.x;
290         g_drawingInfo.pixelMapY = shadowInfo.y;
291         DrawMouseIcon();
292     }
293     Rosen::RSTransaction::FlushImplicitTransaction();
294     CHKPR(rsUiDirector_, RET_ERR);
295     rsUiDirector_->SendMessages();
296     return RET_OK;
297 }
298 
OnDragSuccess()299 void DragDrawing::OnDragSuccess()
300 {
301     CALL_DEBUG_ENTER;
302     if (!CheckNodesValid()) {
303         FI_HILOGE("Check nodes valid failed");
304         return;
305     }
306     std::shared_ptr<Rosen::RSCanvasNode> shadowNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
307     CHKPV(shadowNode);
308     std::shared_ptr<Rosen::RSCanvasNode> styleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
309     CHKPV(styleNode);
310     OnStopDragSuccess(shadowNode, styleNode);
311 }
312 
OnDragFail()313 void DragDrawing::OnDragFail()
314 {
315     CALL_DEBUG_ENTER;
316     std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode = g_drawingInfo.surfaceNode;
317     CHKPV(surfaceNode);
318     std::shared_ptr<Rosen::RSNode> rootNode = g_drawingInfo.rootNode;
319     CHKPV(rootNode);
320     OnStopDragFail(surfaceNode, rootNode);
321 }
322 
EraseMouseIcon()323 void DragDrawing::EraseMouseIcon()
324 {
325     CALL_DEBUG_ENTER;
326     if (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT) {
327         FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
328         return;
329     }
330     std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
331     CHKPV(mouseIconNode);
332     if (drawMouseIconModifier_ != nullptr) {
333         mouseIconNode->RemoveModifier(drawMouseIconModifier_);
334         drawMouseIconModifier_ = nullptr;
335     }
336     CHKPV(g_drawingInfo.rootNode);
337     g_drawingInfo.rootNode->RemoveChild(mouseIconNode);
338     CHKPV(rsUiDirector_);
339     rsUiDirector_->SendMessages();
340 }
341 
DestroyDragWindow()342 void DragDrawing::DestroyDragWindow()
343 {
344     CALL_DEBUG_ENTER;
345     startNum_ = START_TIME;
346     g_drawingInfo.sourceType = -1;
347     g_drawingInfo.currentDragNum = -1;
348     g_drawingInfo.pixelMapX = -1;
349     g_drawingInfo.pixelMapY = -1;
350     g_drawingInfo.displayX = -1;
351     g_drawingInfo.displayY = -1;
352     g_drawingInfo.rootNodeWidth = -1;
353     g_drawingInfo.rootNodeHeight = -1;
354     g_drawingInfo.pixelMap = nullptr;
355     g_drawingInfo.stylePixelMap = nullptr;
356     g_drawingInfo.isPreviousDefaultStyle = false;
357     g_drawingInfo.isCurrentDefaultStyle = false;
358     g_drawingInfo.currentStyle = DragCursorStyle::DEFAULT;
359     RemoveModifier();
360     if (!g_drawingInfo.nodes.empty()) {
361         g_drawingInfo.nodes.clear();
362         g_drawingInfo.nodes.shrink_to_fit();
363     }
364     if (g_drawingInfo.rootNode != nullptr) {
365         g_drawingInfo.rootNode->ClearChildren();
366         g_drawingInfo.rootNode.reset();
367         g_drawingInfo.rootNode = nullptr;
368     }
369     if (g_drawingInfo.surfaceNode != nullptr) {
370         g_drawingInfo.surfaceNode->DetachToDisplay(g_drawingInfo.displayId);
371         g_drawingInfo.surfaceNode = nullptr;
372         g_drawingInfo.displayId = -1;
373         Rosen::RSTransaction::FlushImplicitTransaction();
374     }
375     CHKPV(rsUiDirector_);
376     rsUiDirector_->SetRoot(-1);
377     rsUiDirector_->SendMessages();
378 }
379 
UpdateDrawingState()380 void DragDrawing::UpdateDrawingState()
381 {
382     CALL_DEBUG_ENTER;
383     g_drawingInfo.isRunning = false;
384 }
385 
UpdateDragWindowState(bool visible)386 void DragDrawing::UpdateDragWindowState(bool visible)
387 {
388     CALL_DEBUG_ENTER;
389     CHKPV(g_drawingInfo.surfaceNode);
390     if (visible) {
391         g_drawingInfo.surfaceNode->SetVisible(true);
392         FI_HILOGD("Drag surfaceNode show success");
393     } else {
394         g_drawingInfo.surfaceNode->SetVisible(false);
395         FI_HILOGD("Drag surfaceNode hide success");
396     }
397     Rosen::RSTransaction::FlushImplicitTransaction();
398 }
399 
OnStartDrag(const DragAnimationData & dragAnimationData,std::shared_ptr<Rosen::RSCanvasNode> shadowNode,std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)400 void DragDrawing::OnStartDrag(const DragAnimationData &dragAnimationData,
401     std::shared_ptr<Rosen::RSCanvasNode> shadowNode, std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
402 {
403     CALL_DEBUG_ENTER;
404     CHKPV(shadowNode);
405     CHKPV(dragStyleNode);
406     if (DrawShadow(shadowNode) != RET_OK) {
407         FI_HILOGE("Draw shadow failed");
408         return;
409     }
410     if (InitDrawStyle(dragStyleNode) != RET_OK) {
411         FI_HILOGE("Init draw style failed");
412         return;
413     }
414     if (dragExtHandle_ == nullptr) {
415         FI_HILOGE("Failed to open drag extension library");
416         return;
417     }
418     auto animationExtFunc = reinterpret_cast<DragExtFunc>(dlsym(dragExtHandle_, "OnStartDragExt"));
419     if (animationExtFunc == nullptr) {
420         FI_HILOGE("Failed to get drag extension func");
421         dlclose(dragExtHandle_);
422         dragExtHandle_ = nullptr;
423         return;
424     }
425     if (handler_ == nullptr) {
426         auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
427         CHKPV(runner);
428         handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
429     }
430     if (!handler_->PostTask(std::bind(animationExtFunc, this, &g_drawingInfo))) {
431         FI_HILOGE("Send animationExtFunc failed");
432     }
433 }
434 
OnDragStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,std::shared_ptr<Media::PixelMap> stylePixelMap)435 void DragDrawing::OnDragStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,
436     std::shared_ptr<Media::PixelMap> stylePixelMap)
437 {
438     CALL_DEBUG_ENTER;
439     CHKPV(dragStyleNode);
440     CHKPV(stylePixelMap);
441     if (dragExtHandle_ == nullptr) {
442         FI_HILOGE("Failed to open drag extension library");
443         DrawStyle(dragStyleNode, stylePixelMap);
444         return;
445     }
446     auto animationExtFunc = reinterpret_cast<DragExtFunc>(dlsym(dragExtHandle_, "OnDragStyleExt"));
447     if (animationExtFunc == nullptr) {
448         FI_HILOGE("Failed to get drag extension func");
449         DrawStyle(dragStyleNode, stylePixelMap);
450         dlclose(dragExtHandle_);
451         dragExtHandle_ = nullptr;
452         return;
453     }
454     if (handler_ == nullptr) {
455         auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
456         CHKPV(runner);
457         handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
458     }
459     if (drawSVGModifier_ != nullptr) {
460         dragStyleNode->RemoveModifier(drawSVGModifier_);
461         drawSVGModifier_ = nullptr;
462     }
463     if (!handler_->PostTask(std::bind(animationExtFunc, this, &g_drawingInfo))) {
464         FI_HILOGE("Send animationExtFunc failed");
465         DrawStyle(dragStyleNode, stylePixelMap);
466     }
467 }
468 
OnStopDragSuccess(std::shared_ptr<Rosen::RSCanvasNode> shadowNode,std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)469 void DragDrawing::OnStopDragSuccess(std::shared_ptr<Rosen::RSCanvasNode> shadowNode,
470     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
471 {
472     CALL_DEBUG_ENTER;
473     if (dragExtHandle_ == nullptr) {
474         FI_HILOGE("Failed to open drag extension library");
475         RunAnimation(END_ALPHA, END_SCALE_SUCCESS);
476         return;
477     }
478     auto animationExtFunc = reinterpret_cast<DragExtFunc>(dlsym(dragExtHandle_, "OnStopDragSuccessExt"));
479     if (animationExtFunc == nullptr) {
480         FI_HILOGE("Failed to get drag extension func");
481         RunAnimation(END_ALPHA, END_SCALE_SUCCESS);
482         dlclose(dragExtHandle_);
483         dragExtHandle_ = nullptr;
484         return;
485     }
486     if (handler_ == nullptr) {
487         auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
488         CHKPV(runner);
489         handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
490     }
491     if (!handler_->PostTask(std::bind(animationExtFunc, this, &g_drawingInfo))) {
492         FI_HILOGE("Send animationExtFunc failed");
493         RunAnimation(END_ALPHA, END_SCALE_SUCCESS);
494     } else {
495         StartVsync();
496     }
497 }
498 
OnStopDragFail(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,std::shared_ptr<Rosen::RSNode> rootNode)499 void DragDrawing::OnStopDragFail(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,
500     std::shared_ptr<Rosen::RSNode> rootNode)
501 {
502     CALL_DEBUG_ENTER;
503     if (dragExtHandle_ == nullptr) {
504         FI_HILOGE("Failed to open drag extension library");
505         RunAnimation(END_ALPHA, END_SCALE_FAIL);
506         return;
507     }
508     auto animationExtFunc = reinterpret_cast<DragExtFunc>(dlsym(dragExtHandle_, "OnStopDragFailExt"));
509     if (animationExtFunc == nullptr) {
510         FI_HILOGE("Failed to get drag extension func");
511         RunAnimation(END_ALPHA, END_SCALE_FAIL);
512         dlclose(dragExtHandle_);
513         dragExtHandle_ = nullptr;
514         return;
515     }
516     if (handler_ == nullptr) {
517         auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
518         CHKPV(runner);
519         handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
520     }
521     if (!handler_->PostTask(std::bind(animationExtFunc, this, &g_drawingInfo))) {
522         FI_HILOGE("Send animationExtFunc failed");
523         RunAnimation(END_ALPHA, END_SCALE_FAIL);
524     } else {
525         StartVsync();
526     }
527 }
528 
OnStopAnimation()529 void DragDrawing::OnStopAnimation()
530 {
531     CALL_DEBUG_ENTER;
532 }
533 
RunAnimation(float endAlpha,float endScale)534 void DragDrawing::RunAnimation(float endAlpha, float endScale)
535 {
536     CALL_DEBUG_ENTER;
537     if (handler_ == nullptr) {
538         auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
539         CHKPV(runner);
540         handler_ = std::make_shared<AppExecFwk::EventHandler>(std::move(runner));
541     }
542     if (!handler_->PostTask(std::bind(&DragDrawing::InitVSync, this, endAlpha, endScale))) {
543         FI_HILOGE("Send vsync event failed");
544     }
545 }
546 
InitDrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)547 int32_t DragDrawing::InitDrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode)
548 {
549     CALL_DEBUG_ENTER;
550     CHKPR(dragStyleNode, RET_ERR);
551     std::string filePath;
552     if (GetFilePath(filePath) != RET_OK) {
553         FI_HILOGD("Get file path failed");
554         return RET_ERR;
555     }
556     if (!IsValidSvgFile(filePath)) {
557         FI_HILOGE("Svg file is invalid");
558         return RET_ERR;
559     }
560     g_drawingInfo.isCurrentDefaultStyle = (filePath == DEFAULT_DRAG_PATH);
561     std::shared_ptr<Media::PixelMap> pixelMap = DecodeSvgToPixelMap(filePath);
562     CHKPR(pixelMap, RET_ERR);
563     int32_t ret = DrawStyle(dragStyleNode, pixelMap);
564     if (ret != RET_OK) {
565         FI_HILOGE("Drag style failed");
566     }
567     return ret;
568 }
569 
DrawShadow(std::shared_ptr<Rosen::RSCanvasNode> shadowNode)570 int32_t DragDrawing::DrawShadow(std::shared_ptr<Rosen::RSCanvasNode> shadowNode)
571 {
572     CALL_DEBUG_ENTER;
573     CHKPR(shadowNode, RET_ERR);
574     if (drawPixelMapModifier_ != nullptr) {
575         shadowNode->RemoveModifier(drawPixelMapModifier_);
576         drawPixelMapModifier_ = nullptr;
577     }
578     drawPixelMapModifier_ = std::make_shared<DrawPixelMapModifier>();
579     shadowNode->AddModifier(drawPixelMapModifier_);
580     return RET_OK;
581 }
582 
DrawMouseIcon()583 int32_t DragDrawing::DrawMouseIcon()
584 {
585     CALL_DEBUG_ENTER;
586     if (g_drawingInfo.nodes.size() < MOUSE_NODE_MIN_COUNT) {
587         FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
588         return RET_ERR;
589     }
590     std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
591     CHKPR(mouseIconNode, RET_ERR);
592     if (drawMouseIconModifier_ != nullptr) {
593         mouseIconNode->RemoveModifier(drawMouseIconModifier_);
594         drawMouseIconModifier_ = nullptr;
595     }
596     drawMouseIconModifier_ = std::make_shared<DrawMouseIconModifier>();
597     mouseIconNode->AddModifier(drawMouseIconModifier_);
598     return RET_OK;
599 }
600 
DrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,std::shared_ptr<Media::PixelMap> stylePixelMap)601 int32_t DragDrawing::DrawStyle(std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode,
602     std::shared_ptr<Media::PixelMap> stylePixelMap)
603 {
604     CALL_DEBUG_ENTER;
605     CHKPR(dragStyleNode, RET_ERR);
606     CHKPR(stylePixelMap, RET_ERR);
607     if (drawSVGModifier_ != nullptr) {
608         dragStyleNode->RemoveModifier(drawSVGModifier_);
609         drawSVGModifier_ = nullptr;
610     }
611     drawSVGModifier_ = std::make_shared<DrawSVGModifier>(stylePixelMap);
612     dragStyleNode->AddModifier(drawSVGModifier_);
613     return RET_OK;
614 }
615 
InitVSync(float endAlpha,float endScale)616 int32_t DragDrawing::InitVSync(float endAlpha, float endScale)
617 {
618     CALL_DEBUG_ENTER;
619     startNum_ = START_TIME;
620     CHKPR(g_drawingInfo.rootNode, RET_ERR);
621     if (drawDynamicEffectModifier_ != nullptr) {
622         g_drawingInfo.rootNode->RemoveModifier(drawDynamicEffectModifier_);
623         drawDynamicEffectModifier_ = nullptr;
624     }
625     drawDynamicEffectModifier_ = std::make_shared<DrawDynamicEffectModifier>();
626     g_drawingInfo.rootNode->AddModifier(drawDynamicEffectModifier_);
627     drawDynamicEffectModifier_->SetAlpha(BEGIN_ALPHA);
628     drawDynamicEffectModifier_->SetScale(BEGIN_SCALE);
629 
630     Rosen::RSAnimationTimingProtocol protocol;
631     protocol.SetDuration(SUCCESS_ANIMATION_DURATION);
632     Rosen::RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
633         drawDynamicEffectModifier_->SetAlpha(endAlpha);
634         drawDynamicEffectModifier_->SetScale(endScale);
635     });
636     return StartVsync();
637 }
638 
StartVsync()639 int32_t DragDrawing::StartVsync()
640 {
641     CHKPR(g_drawingInfo.surfaceNode, RET_ERR);
642     g_drawingInfo.surfaceNode->SetPivot(PIVOT_X, PIVOT_Y);
643     Rosen::RSTransaction::FlushImplicitTransaction();
644     if (receiver_ == nullptr) {
645         CHKPR(handler_, RET_ERR);
646         receiver_ = Rosen::RSInterfaces::GetInstance().CreateVSyncReceiver("DragDrawing", handler_);
647         CHKPR(receiver_, RET_ERR);
648     }
649     int32_t ret = receiver_->Init();
650     if (ret != RET_OK) {
651         FI_HILOGE("Receiver init failed");
652         return RET_ERR;
653     }
654     Rosen::VSyncReceiver::FrameCallback fcb = {
655         .userData_ = this,
656         .callback_ = std::bind(&DragDrawing::OnVsync, this)
657     };
658     int32_t changeFreq = static_cast<int32_t>((ONETHOUSAND / FRAMERATE) / SIXTEEN);
659     ret = receiver_->SetVSyncRate(fcb, changeFreq);
660     if (ret != RET_OK) {
661         FI_HILOGE("Set vsync rate failed");
662     }
663     return ret;
664 }
665 
OnVsync()666 void DragDrawing::OnVsync()
667 {
668     CALL_DEBUG_ENTER;
669     CHKPV(rsUiDirector_);
670     bool hasRunningAnimation = rsUiDirector_->RunningCustomAnimation(startNum_);
671     if (!hasRunningAnimation) {
672         FI_HILOGD("Stop runner, hasRunningAnimation:%{public}d", hasRunningAnimation);
673         CHKPV(handler_);
674         handler_->RemoveAllEvents();
675         handler_->RemoveAllFileDescriptorListeners();
676         handler_ = nullptr;
677         g_drawingInfo.isRunning = false;
678         receiver_ = nullptr;
679         CHKPV(g_drawingInfo.rootNode);
680         if (drawDynamicEffectModifier_ != nullptr) {
681             g_drawingInfo.rootNode->RemoveModifier(drawDynamicEffectModifier_);
682             drawDynamicEffectModifier_ = nullptr;
683         }
684         DestroyDragWindow();
685         return;
686     }
687     rsUiDirector_->SendMessages();
688     startNum_ += INTERVAL_TIME;
689 }
690 
InitDrawingInfo(const DragData & dragData)691 void DragDrawing::InitDrawingInfo(const DragData &dragData)
692 {
693     CALL_DEBUG_ENTER;
694     g_drawingInfo.isRunning = true;
695     g_drawingInfo.currentDragNum = dragData.dragNum;
696     g_drawingInfo.sourceType = dragData.sourceType;
697     g_drawingInfo.displayId = dragData.displayId;
698     g_drawingInfo.displayX = dragData.displayX;
699     g_drawingInfo.displayY = dragData.displayY;
700     g_drawingInfo.pixelMap = dragData.shadowInfo.pixelMap;
701     g_drawingInfo.pixelMapX = dragData.shadowInfo.x;
702     g_drawingInfo.pixelMapY = dragData.shadowInfo.y;
703 }
704 
InitDragAnimationData(DragAnimationData & dragAnimationData)705 int32_t DragDrawing::InitDragAnimationData(DragAnimationData &dragAnimationData)
706 {
707     CALL_DEBUG_ENTER;
708     CHKPR(g_drawingInfo.pixelMap, RET_ERR);
709     dragAnimationData.pixelMap = g_drawingInfo.pixelMap;
710     dragAnimationData.displayX = g_drawingInfo.displayX;
711     dragAnimationData.displayY = g_drawingInfo.displayY;
712     dragAnimationData.offsetX = g_drawingInfo.pixelMapX;
713     dragAnimationData.offsetY = g_drawingInfo.pixelMapY;
714     return RET_OK;
715 }
716 
InitLayer()717 int32_t DragDrawing::InitLayer()
718 {
719     CALL_DEBUG_ENTER;
720     if (g_drawingInfo.surfaceNode == nullptr) {
721         FI_HILOGE("Init layer failed, surfaceNode is nullptr");
722         return RET_ERR;
723     }
724     auto surface = g_drawingInfo.surfaceNode->GetSurface();
725     if (surface == nullptr) {
726         g_drawingInfo.surfaceNode->DetachToDisplay(g_drawingInfo.displayId);
727         g_drawingInfo.surfaceNode = nullptr;
728         FI_HILOGE("Init layer failed, surface is nullptr");
729         Rosen::RSTransaction::FlushImplicitTransaction();
730         return RET_ERR;
731     }
732     if (g_drawingInfo.isInitUiDirector) {
733         g_drawingInfo.isInitUiDirector = false;
734         rsUiDirector_ = Rosen::RSUIDirector::Create();
735         CHKPR(rsUiDirector_, RET_ERR);
736         rsUiDirector_->Init();
737     }
738     rsUiDirector_->SetRSSurfaceNode(g_drawingInfo.surfaceNode);
739     InitCanvas(IMAGE_WIDTH, IMAGE_HEIGHT);
740     Rosen::RSTransaction::FlushImplicitTransaction();
741     return RET_OK;
742 }
743 
InitCanvas(int32_t width,int32_t height)744 void DragDrawing::InitCanvas(int32_t width, int32_t height)
745 {
746     CALL_DEBUG_ENTER;
747     if (g_drawingInfo.rootNode == nullptr) {
748         g_drawingInfo.rootNode = Rosen::RSRootNode::Create();
749         CHKPV(g_drawingInfo.rootNode);
750     }
751     int32_t adjustSize = TWELVE_SIZE * GetScaling();
752     g_drawingInfo.rootNode->SetBounds(g_drawingInfo.displayX, g_drawingInfo.displayY - adjustSize, width, height);
753     g_drawingInfo.rootNode->SetFrame(g_drawingInfo.displayX, g_drawingInfo.displayY - adjustSize, width, height);
754     g_drawingInfo.rootNode->SetBackgroundColor(SK_ColorTRANSPARENT);
755 
756     std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = Rosen::RSCanvasNode::Create();
757     CHKPV(pixelMapNode);
758     CHKPV(g_drawingInfo.pixelMap);
759     pixelMapNode->SetBounds(0, adjustSize, g_drawingInfo.pixelMap->GetWidth(), g_drawingInfo.pixelMap->GetHeight());
760     pixelMapNode->SetFrame(0, adjustSize, g_drawingInfo.pixelMap->GetWidth(), g_drawingInfo.pixelMap->GetHeight());
761     g_drawingInfo.nodes.emplace_back(pixelMapNode);
762     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = Rosen::RSCanvasNode::Create();
763     CHKPV(dragStyleNode);
764     dragStyleNode->SetBounds(0, 0, SVG_HEIGHT, SVG_HEIGHT);
765     dragStyleNode->SetFrame(0, 0, SVG_HEIGHT, SVG_HEIGHT);
766     g_drawingInfo.nodes.emplace_back(dragStyleNode);
767 
768     CHKPV(rsUiDirector_);
769     if (g_drawingInfo.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
770         std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = Rosen::RSCanvasNode::Create();
771         CHKPV(mouseIconNode);
772         mouseIconNode->SetBounds(-g_drawingInfo.pixelMapX, -g_drawingInfo.pixelMapY,
773             SVG_HEIGHT, SVG_HEIGHT);
774         mouseIconNode->SetFrame(-g_drawingInfo.pixelMapX, -g_drawingInfo.pixelMapY,
775             SVG_HEIGHT, SVG_HEIGHT);
776         g_drawingInfo.nodes.emplace_back(mouseIconNode);
777         g_drawingInfo.rootNode->AddChild(pixelMapNode);
778         g_drawingInfo.rootNode->AddChild(dragStyleNode);
779         g_drawingInfo.rootNode->AddChild(mouseIconNode);
780         rsUiDirector_->SetRoot(g_drawingInfo.rootNode->GetId());
781         return;
782     }
783     g_drawingInfo.rootNode->AddChild(pixelMapNode);
784     g_drawingInfo.rootNode->AddChild(dragStyleNode);
785     rsUiDirector_->SetRoot(g_drawingInfo.rootNode->GetId());
786 }
787 
CreateWindow(int32_t displayX,int32_t displayY)788 void DragDrawing::CreateWindow(int32_t displayX, int32_t displayY)
789 {
790     CALL_DEBUG_ENTER;
791     Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
792     surfaceNodeConfig.SurfaceNodeName = "drag window";
793     Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
794     g_drawingInfo.surfaceNode = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
795     CHKPV(g_drawingInfo.surfaceNode);
796     g_drawingInfo.surfaceNode->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
797     g_drawingInfo.surfaceNode->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
798     g_drawingInfo.surfaceNode->SetBounds(displayX, displayY, IMAGE_WIDTH, IMAGE_HEIGHT);
799     g_drawingInfo.surfaceNode->SetBackgroundColor(SK_ColorTRANSPARENT);
800     g_drawingInfo.surfaceNode->AttachToDisplay(g_drawingInfo.displayId);
801     g_drawingInfo.surfaceNode->SetVisible(false);
802     Rosen::RSTransaction::FlushImplicitTransaction();
803 }
804 
RemoveModifier()805 void DragDrawing::RemoveModifier()
806 {
807     CALL_DEBUG_ENTER;
808     if ((g_drawingInfo.nodes.size() < TOUCH_NODE_MIN_COUNT)) {
809         FI_HILOGE("Nodes size invalid, node size:%{public}zu", g_drawingInfo.nodes.size());
810         return;
811     }
812 
813     std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
814     CHKPV(pixelMapNode);
815     if (drawPixelMapModifier_ != nullptr) {
816         pixelMapNode->RemoveModifier(drawPixelMapModifier_);
817         drawPixelMapModifier_ = nullptr;
818     }
819     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
820     CHKPV(dragStyleNode);
821     if (drawSVGModifier_ != nullptr) {
822         dragStyleNode->RemoveModifier(drawSVGModifier_);
823         drawSVGModifier_ = nullptr;
824     }
825 }
826 
UpdateSvgNodeInfo(xmlNodePtr curNode,int32_t extendSvgWidth)827 int32_t DragDrawing::UpdateSvgNodeInfo(xmlNodePtr curNode, int32_t extendSvgWidth)
828 {
829     CALL_DEBUG_ENTER;
830     if (xmlStrcmp(curNode->name, BAD_CAST "svg")) {
831         FI_HILOGE("Svg format invalid");
832         return RET_ERR;
833     }
834     std::ostringstream oStrStream;
835     oStrStream << xmlGetProp(curNode, BAD_CAST "width");
836     std::string srcSvgWidth = oStrStream.str();
837     if (srcSvgWidth.length() < STRING_PX_LENGTH) {
838         FI_HILOGE("Svg width invalid, srcSvgWidth:%{public}s", srcSvgWidth.c_str());
839         return RET_ERR;
840     }
841     srcSvgWidth = srcSvgWidth.substr(0, srcSvgWidth.length() - STRING_PX_LENGTH);
842     if (!IsNum(srcSvgWidth)) {
843         FI_HILOGE("srcSvgWidth is not digital, srcSvgWidth:%{public}s", srcSvgWidth.c_str());
844         return RET_ERR;
845     }
846     int32_t number = std::stoi(srcSvgWidth) + extendSvgWidth;
847     std::string tgtSvgWidth  = std::to_string(number);
848     tgtSvgWidth.append("px");
849     xmlSetProp(curNode, BAD_CAST "width", BAD_CAST tgtSvgWidth.c_str());
850     oStrStream.str("");
851     oStrStream << xmlGetProp(curNode, BAD_CAST "viewBox");
852     std::string srcViewBox = oStrStream.str();
853     std::istringstream iStrStream(srcViewBox);
854     std::string tmpString;
855     std::string tgtViewBox;
856     int32_t i = 0;
857     while (iStrStream >> tmpString) {
858         if (i == VIEW_BOX_POS) {
859             if (!IsNum(tmpString)) {
860                 FI_HILOGE("tmpString is not digital, tmpString:%{public}s", tmpString.c_str());
861                 return RET_ERR;
862             }
863             number = std::stoi(tmpString) + extendSvgWidth;
864             tmpString = std::to_string(number);
865         }
866         tgtViewBox.append(tmpString);
867         tgtViewBox += " ";
868         ++i;
869     }
870 
871     xmlSetProp(curNode, BAD_CAST "viewBox", BAD_CAST tgtViewBox.c_str());
872     return RET_OK;
873 }
874 
GetRectNode(xmlNodePtr curNode)875 xmlNodePtr DragDrawing::GetRectNode(xmlNodePtr curNode)
876 {
877     CALL_DEBUG_ENTER;
878     curNode = curNode->xmlChildrenNode;
879     while (curNode != nullptr) {
880         if (!xmlStrcmp(curNode->name, BAD_CAST "g")) {
881             while (!xmlStrcmp(curNode->name, BAD_CAST "g")) {
882                 curNode = curNode->xmlChildrenNode;
883             }
884             break;
885         }
886         curNode = curNode->next;
887     }
888     return curNode;
889 }
890 
UpdateRectNode(int32_t extendSvgWidth,xmlNodePtr curNode)891 xmlNodePtr DragDrawing::UpdateRectNode(int32_t extendSvgWidth, xmlNodePtr curNode)
892 {
893     CALL_DEBUG_ENTER;
894     while (curNode != nullptr) {
895         if (!xmlStrcmp(curNode->name, BAD_CAST "rect")) {
896             std::ostringstream oStrStream;
897             oStrStream << xmlGetProp(curNode, BAD_CAST "width");
898             std::string srcRectWidth = oStrStream.str();
899             if (!IsNum(srcRectWidth)) {
900                 FI_HILOGE("srcRectWidth is not digital, srcRectWidth:%{public}s", srcRectWidth.c_str());
901                 return nullptr;
902             }
903             int32_t number = std::stoi(srcRectWidth) + extendSvgWidth;
904             xmlSetProp(curNode, BAD_CAST "width", BAD_CAST std::to_string(number).c_str());
905         }
906         if (!xmlStrcmp(curNode->name, BAD_CAST "text")) {
907             return curNode->xmlChildrenNode;
908         }
909         curNode = curNode->next;
910     }
911     FI_HILOGE("Empty node of XML");
912     return nullptr;
913 }
914 
UpdateTspanNode(xmlNodePtr curNode)915 void DragDrawing::UpdateTspanNode(xmlNodePtr curNode)
916 {
917     CALL_DEBUG_ENTER;
918     while (curNode != nullptr) {
919         if (!xmlStrcmp(curNode->name, BAD_CAST "tspan")) {
920             xmlNodeSetContent(curNode, BAD_CAST std::to_string(g_drawingInfo.currentDragNum).c_str());
921         }
922         curNode = curNode->next;
923     }
924 }
925 
ParseAndAdjustSvgInfo(xmlNodePtr curNode)926 int32_t DragDrawing::ParseAndAdjustSvgInfo(xmlNodePtr curNode)
927 {
928     CALL_DEBUG_ENTER;
929     CHKPR(curNode, RET_ERR);
930     std::string strStyle = std::to_string(g_drawingInfo.currentDragNum);
931     if (strStyle.empty()) {
932         FI_HILOGE("strStyle size:%{public}zu invalid", strStyle.size());
933         return RET_ERR;
934     }
935     int32_t extendSvgWidth = (static_cast<int32_t>(strStyle.size()) - 1) * EIGHT_SIZE;
936     xmlKeepBlanksDefault(0);
937     int32_t ret = UpdateSvgNodeInfo(curNode, extendSvgWidth);
938     if (ret != RET_OK) {
939         FI_HILOGE("Update svg node info failed, ret:%{public}d", ret);
940         return RET_ERR;
941     }
942     curNode = GetRectNode(curNode);
943     CHKPR(curNode, RET_ERR);
944     curNode = UpdateRectNode(extendSvgWidth, curNode);
945     CHKPR(curNode, RET_ERR);
946     UpdateTspanNode(curNode);
947     return RET_OK;
948 }
949 
DecodeSvgToPixelMap(const std::string & filePath)950 std::shared_ptr<Media::PixelMap> DragDrawing::DecodeSvgToPixelMap(
951     const std::string &filePath)
952 {
953     CALL_DEBUG_ENTER;
954     xmlDocPtr xmlDoc = xmlReadFile(filePath.c_str(), 0, XML_PARSE_NOBLANKS);
955     if (NeedAdjustSvgInfo()) {
956         xmlNodePtr node = xmlDocGetRootElement(xmlDoc);
957         CHKPP(node);
958         int32_t ret = ParseAndAdjustSvgInfo(node);
959         if (ret != RET_OK) {
960             FI_HILOGE("Parse and adjust svg info failed, ret:%{public}d", ret);
961             return nullptr;
962         }
963     }
964     xmlChar *xmlbuff = nullptr;
965     int32_t buffersize = 0;
966     xmlDocDumpFormatMemory(xmlDoc, &xmlbuff, &buffersize, 1);
967     std::ostringstream oStrStream;
968     oStrStream << xmlbuff;
969     std::string content = oStrStream.str();
970     xmlFree(xmlbuff);
971     xmlFreeDoc(xmlDoc);
972     Media::SourceOptions opts;
973     opts.formatHint = "image/svg+xml";
974     uint32_t errCode = 0;
975     auto imageSource = Media::ImageSource::CreateImageSource(reinterpret_cast<const uint8_t*>(content.c_str()),
976         content.size(), opts, errCode);
977     CHKPP(imageSource);
978     Media::DecodeOptions decodeOpts;
979     SetDecodeOptions(decodeOpts);
980     std::shared_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
981     return pixelMap;
982 }
983 
NeedAdjustSvgInfo()984 bool DragDrawing::NeedAdjustSvgInfo()
985 {
986     CALL_DEBUG_ENTER;
987     if (g_drawingInfo.currentStyle == DragCursorStyle::DEFAULT) {
988         return false;
989     }
990     if ((g_drawingInfo.currentStyle == DragCursorStyle::COPY) &&
991         (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
992         return false;
993     }
994     std::string deviceType = system::GetDeviceType();
995     if ((g_drawingInfo.currentStyle == DragCursorStyle::MOVE) &&
996         ((deviceType.compare(0, DEVICE_TYPE_DEFAULT.size(), DEVICE_TYPE_DEFAULT) == 0) ||
997         (deviceType.compare(0, DEVICE_TYPE_PHONE.size(), DEVICE_TYPE_PHONE) == 0)) &&
998         (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
999         return false;
1000     }
1001     if ((g_drawingInfo.currentStyle == DragCursorStyle::FORBIDDEN) &&
1002         (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1003         return false;
1004     }
1005     return true;
1006 }
1007 
GetFilePath(std::string & filePath)1008 int32_t DragDrawing::GetFilePath(std::string &filePath)
1009 {
1010     CALL_DEBUG_ENTER;
1011     switch (g_drawingInfo.currentStyle) {
1012         case DragCursorStyle::COPY: {
1013             if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
1014                 filePath = COPY_ONE_DRAG_PATH;
1015             } else {
1016                 filePath = COPY_DRAG_PATH;
1017             }
1018             break;
1019         }
1020         case DragCursorStyle::MOVE: {
1021             std::string deviceType = system::GetDeviceType();
1022             if (((deviceType.compare(0, DEVICE_TYPE_DEFAULT.size(), DEVICE_TYPE_DEFAULT) == 0) ||
1023                 (deviceType.compare(0, DEVICE_TYPE_PHONE.size(), DEVICE_TYPE_PHONE) == 0)) &&
1024                 (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1025                 FI_HILOGD("Device type is phone, not need draw svg style, deviceType:%{public}s", deviceType.c_str());
1026                 filePath = DEFAULT_DRAG_PATH;
1027             } else {
1028                 filePath = MOVE_DRAG_PATH;
1029             }
1030             break;
1031         }
1032         case DragCursorStyle::FORBIDDEN: {
1033             if (g_drawingInfo.currentDragNum == DRAG_NUM_ONE) {
1034                 filePath = FORBID_ONE_DRAG_PATH;
1035             } else {
1036                 filePath = FORBID_DRAG_PATH;
1037             }
1038             break;
1039         }
1040         case DragCursorStyle::DEFAULT:
1041         default: {
1042             FI_HILOGW("Not need draw svg style, DragCursorStyle:%{public}d", g_drawingInfo.currentStyle);
1043             filePath = DEFAULT_DRAG_PATH;
1044             break;
1045         }
1046     }
1047     return RET_OK;
1048 }
1049 
SetDecodeOptions(Media::DecodeOptions & decodeOpts)1050 void DragDrawing::SetDecodeOptions(Media::DecodeOptions &decodeOpts)
1051 {
1052     CALL_DEBUG_ENTER;
1053     std::string strStyle = std::to_string(g_drawingInfo.currentDragNum);
1054     if (strStyle.empty()) {
1055         FI_HILOGE("strStyle size:%{public}zu invalid", strStyle.size());
1056         return;
1057     }
1058     int32_t extendSvgWidth = (static_cast<int32_t>(strStyle.size()) - 1) * EIGHT_SIZE;
1059     std::string deviceType = system::GetDeviceType();
1060     if ((g_drawingInfo.currentStyle == DragCursorStyle::COPY) && (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1061         decodeOpts.desiredSize = {
1062             .width = DEVICE_INDEPENDENT_PIXEL * GetScaling(),
1063             .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1064         };
1065     } else if (((deviceType.compare(0, DEVICE_TYPE_DEFAULT.size(), DEVICE_TYPE_DEFAULT) == 0) ||
1066         (deviceType.compare(0, DEVICE_TYPE_PHONE.size(), DEVICE_TYPE_PHONE) == 0)) &&
1067         (g_drawingInfo.currentStyle == DragCursorStyle::MOVE) && (g_drawingInfo.currentDragNum == DRAG_NUM_ONE)) {
1068         decodeOpts.desiredSize = {
1069             .width = DEVICE_INDEPENDENT_PIXEL * GetScaling(),
1070             .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1071         };
1072     } else {
1073         decodeOpts.desiredSize = {
1074             .width = (DEVICE_INDEPENDENT_PIXEL + extendSvgWidth) * GetScaling(),
1075             .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1076         };
1077     }
1078 }
1079 
~DragDrawing()1080 DragDrawing::~DragDrawing()
1081 {
1082     if (dragExtHandle_ != nullptr) {
1083         dlclose(dragExtHandle_);
1084         dragExtHandle_ = nullptr;
1085     }
1086 }
1087 
Draw(Rosen::RSDrawingContext & context) const1088 void DrawSVGModifier::Draw(Rosen::RSDrawingContext& context) const
1089 {
1090     CALL_DEBUG_ENTER;
1091     CHKPV(stylePixelMap_);
1092     CHKPV(g_drawingInfo.pixelMap);
1093     float scalingValue = GetScaling();
1094     if ((1.0 * INT_MAX / (SVG_WIDTH + EIGHT_SIZE)) <= scalingValue) {
1095         FI_HILOGE("Invalid scalingValue:%{public}f", scalingValue);
1096         return;
1097     }
1098     int32_t adjustSize = EIGHT_SIZE * scalingValue;
1099     int32_t svgTouchPositionX = 0;
1100     if ((g_drawingInfo.pixelMap->GetWidth() + adjustSize) > stylePixelMap_->GetWidth()) {
1101         svgTouchPositionX = g_drawingInfo.pixelMap->GetWidth() + adjustSize - stylePixelMap_->GetWidth();
1102     }
1103     if (!CheckNodesValid()) {
1104         FI_HILOGE("Check nodes valid failed");
1105         return;
1106     }
1107     std::shared_ptr<Rosen::RSCanvasNode> dragStyleNode = g_drawingInfo.nodes[DRAG_STYLE_INDEX];
1108     CHKPV(dragStyleNode);
1109     dragStyleNode->SetBounds(svgTouchPositionX, (TWELVE_SIZE - EIGHT_SIZE) * scalingValue, stylePixelMap_->GetWidth(),
1110         stylePixelMap_->GetHeight());
1111     dragStyleNode->SetFrame(svgTouchPositionX, (TWELVE_SIZE - EIGHT_SIZE) * scalingValue, stylePixelMap_->GetWidth(),
1112         stylePixelMap_->GetHeight());
1113     dragStyleNode->SetBgImageWidth(stylePixelMap_->GetWidth());
1114     dragStyleNode->SetBgImageHeight(stylePixelMap_->GetHeight());
1115     dragStyleNode->SetBgImagePositionX(0);
1116     dragStyleNode->SetBgImagePositionY(0);
1117     auto rosenImage = std::make_shared<Rosen::RSImage>();
1118     rosenImage->SetPixelMap(stylePixelMap_);
1119     rosenImage->SetImageRepeat(0);
1120     dragStyleNode->SetBgImage(rosenImage);
1121     adjustSize = (SVG_WIDTH + TWELVE_SIZE) * scalingValue;
1122     g_drawingInfo.rootNodeWidth = g_drawingInfo.pixelMap->GetWidth() + adjustSize;
1123     g_drawingInfo.rootNodeHeight = g_drawingInfo.pixelMap->GetHeight() + adjustSize;
1124     CHKPV(g_drawingInfo.rootNode);
1125     g_drawingInfo.rootNode->SetBounds(0, 0, g_drawingInfo.rootNodeWidth, g_drawingInfo.rootNodeHeight);
1126     g_drawingInfo.rootNode->SetFrame(0, 0, g_drawingInfo.rootNodeWidth, g_drawingInfo.rootNodeHeight);
1127     CHKPV(g_drawingInfo.surfaceNode);
1128     g_drawingInfo.surfaceNode->SetBoundsWidth(g_drawingInfo.rootNodeWidth);
1129     g_drawingInfo.surfaceNode->SetBoundsHeight(g_drawingInfo.rootNodeHeight);
1130     Rosen::RSTransaction::FlushImplicitTransaction();
1131 }
1132 
Draw(Rosen::RSDrawingContext & context) const1133 void DrawPixelMapModifier::Draw(Rosen::RSDrawingContext &context) const
1134 {
1135     CALL_DEBUG_ENTER;
1136     CHKPV(g_drawingInfo.pixelMap);
1137     auto rosenImage = std::make_shared<Rosen::RSImage>();
1138     rosenImage->SetPixelMap(g_drawingInfo.pixelMap);
1139     rosenImage->SetImageRepeat(0);
1140     int32_t pixelMapWidth = g_drawingInfo.pixelMap->GetWidth();
1141     int32_t pixelMapHeight = g_drawingInfo.pixelMap->GetHeight();
1142     if (!CheckNodesValid()) {
1143         FI_HILOGE("Check nodes valid failed");
1144         return;
1145     }
1146     std::shared_ptr<Rosen::RSCanvasNode> pixelMapNode = g_drawingInfo.nodes[PIXEL_MAP_INDEX];
1147     CHKPV(pixelMapNode);
1148     pixelMapNode->SetBoundsWidth(pixelMapWidth);
1149     pixelMapNode->SetBoundsHeight(pixelMapHeight);
1150     pixelMapNode->SetBgImageWidth(pixelMapWidth);
1151     pixelMapNode->SetBgImageHeight(pixelMapHeight);
1152     pixelMapNode->SetBgImagePositionX(0);
1153     pixelMapNode->SetBgImagePositionY(0);
1154     pixelMapNode->SetBgImage(rosenImage);
1155     Rosen::RSTransaction::FlushImplicitTransaction();
1156 }
1157 
Draw(Rosen::RSDrawingContext & context) const1158 void DrawMouseIconModifier::Draw(Rosen::RSDrawingContext &context) const
1159 {
1160     CALL_DEBUG_ENTER;
1161     std::string imagePath = MOUSE_DRAG_PATH;
1162     Media::SourceOptions opts;
1163     opts.formatHint = "image/svg+xml";
1164     uint32_t errCode = 0;
1165     auto imageSource = Media::ImageSource::CreateImageSource(imagePath, opts, errCode);
1166     CHKPV(imageSource);
1167     Media::DecodeOptions decodeOpts;
1168     decodeOpts.desiredSize = {
1169         .width = DEVICE_INDEPENDENT_PIXEL * GetScaling(),
1170         .height = DEVICE_INDEPENDENT_PIXEL * GetScaling()
1171     };
1172     std::shared_ptr<Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
1173     CHKPV(pixelMap);
1174     if (!CheckNodesValid()) {
1175         FI_HILOGE("Check nodes valid failed");
1176         return;
1177     }
1178     std::shared_ptr<Rosen::RSCanvasNode> mouseIconNode = g_drawingInfo.nodes[MOUSE_ICON_INDEX];
1179     CHKPV(mouseIconNode);
1180     int32_t adjustSize = TWELVE_SIZE * GetScaling();
1181     mouseIconNode->SetBounds(-g_drawingInfo.pixelMapX, -g_drawingInfo.pixelMapY + adjustSize,
1182         pixelMap->GetWidth(), pixelMap->GetHeight());
1183     mouseIconNode->SetFrame(-g_drawingInfo.pixelMapX, -g_drawingInfo.pixelMapY + adjustSize,
1184         pixelMap->GetWidth(), pixelMap->GetHeight());
1185     mouseIconNode->SetBgImageWidth(decodeOpts.desiredSize.width);
1186     mouseIconNode->SetBgImageHeight(decodeOpts.desiredSize.height);
1187     mouseIconNode->SetBgImagePositionX(0);
1188     mouseIconNode->SetBgImagePositionY(0);
1189     auto rosenImage = std::make_shared<Rosen::RSImage>();
1190     rosenImage->SetPixelMap(pixelMap);
1191     rosenImage->SetImageRepeat(0);
1192     mouseIconNode->SetBgImage(rosenImage);
1193     Rosen::RSTransaction::FlushImplicitTransaction();
1194 }
1195 
Draw(Rosen::RSDrawingContext & context) const1196 void DrawDynamicEffectModifier::Draw(Rosen::RSDrawingContext &context) const
1197 {
1198     CALL_DEBUG_ENTER;
1199     CHKPV(alpha_);
1200     CHKPV(g_drawingInfo.rootNode);
1201     g_drawingInfo.rootNode->SetAlpha(alpha_->Get());
1202     CHKPV(scale_);
1203     CHKPV(g_drawingInfo.surfaceNode);
1204     g_drawingInfo.surfaceNode->SetScale(scale_->Get(), scale_->Get());
1205     Rosen::RSTransaction::FlushImplicitTransaction();
1206 }
1207 
SetAlpha(float alpha)1208 void DrawDynamicEffectModifier::SetAlpha(float alpha)
1209 {
1210     CALL_DEBUG_ENTER;
1211     if (alpha_ == nullptr) {
1212         alpha_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(alpha);
1213         Rosen::RSModifier::AttachProperty(alpha_);
1214         return;
1215     }
1216     alpha_->Set(alpha);
1217 }
1218 
SetScale(float scale)1219 void DrawDynamicEffectModifier::SetScale(float scale)
1220 {
1221     CALL_DEBUG_ENTER;
1222     if (scale_ == nullptr) {
1223         scale_ = std::make_shared<Rosen::RSAnimatableProperty<float>>(scale);
1224         Rosen::RSModifier::AttachProperty(scale_);
1225         return;
1226     }
1227     scale_->Set(scale);
1228 }
1229 } // namespace DeviceStatus
1230 } // namespace Msdp
1231 } // namespace OHOS