1/*
2 * Copyright (c) 2021-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 "pointer_drawing_manager.h"
17
18#include <parameters.h>
19
20#include "image/bitmap.h"
21#include "image_source.h"
22#include "image_type.h"
23#include "image_utils.h"
24#include "table_dump.h"
25#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
26#include "magic_pointer_drawing_manager.h"
27#include "magic_pointer_velocity_tracker.h"
28#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
29
30#include "define_multimodal.h"
31#include "i_multimodal_input_connect.h"
32#include "input_device_manager.h"
33#include "i_input_windows_manager.h"
34#include "ipc_skeleton.h"
35#include "mmi_log.h"
36#include "i_preference_manager.h"
37#include "parameters.h"
38#include "pipeline/rs_recording_canvas.h"
39#include "preferences.h"
40#include "preferences_errno.h"
41#include "preferences_helper.h"
42#include "render/rs_pixel_map_util.h"
43#include "scene_board_judgement.h"
44#include "setting_datashare.h"
45#include "util.h"
46#include "dfx_hisysevent.h"
47#include "timer_manager.h"
48
49#undef MMI_LOG_DOMAIN
50#define MMI_LOG_DOMAIN MMI_LOG_CURSOR
51#undef MMI_LOG_TAG
52#define MMI_LOG_TAG "PointerDrawingManager"
53#define FOCUS_COORDINATES(FOCUS_COORDINATES_, CHANGE) float FOCUS_COORDINATES_##CHANGE
54#define CALCULATE_CANVAS_SIZE(CALCULATE_CANVAS_SIZE_, CHANGE) float CALCULATE_CANVAS_SIZE_##CHANGE
55
56namespace OHOS {
57namespace MMI {
58namespace {
59const std::string FOLD_SCREEN_FLAG = system::GetParameter("const.window.foldscreen.type", "");
60const std::string IMAGE_POINTER_DEFAULT_PATH = "/system/etc/multimodalinput/mouse_icon/";
61const std::string DefaultIconPath = IMAGE_POINTER_DEFAULT_PATH + "Default.svg";
62const std::string CursorIconPath = IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png";
63const std::string POINTER_COLOR { "pointerColor" };
64const std::string POINTER_SIZE { "pointerSize" };
65const std::string MAGIC_POINTER_COLOR { "magicPointerColor" };
66const std::string MAGIC_POINTER_SIZE { "magicPointerSize"};
67const std::string POINTER_CURSOR_RENDER_RECEIVER_NAME { "PointerCursorReceiver" };
68const std::string DEVICE_TYPE_HARDEN { "HAD" };
69const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
70const std::string FOLDABLE_DEVICE_POLICY = system::GetParameter("const.window.foldabledevice.rotate_policy", "");
71constexpr int32_t WINDOW_ROTATE { 0 };
72constexpr char ROTATE_WINDOW_ROTATE { '0' };
73constexpr int32_t FOLDABLE_DEVICE { 2 };
74constexpr int32_t BASELINE_DENSITY { 160 };
75constexpr int32_t CALCULATE_MIDDLE { 2 };
76[[ maybe_unused ]] constexpr int32_t MAGIC_INDEPENDENT_PIXELS { 30 };
77constexpr int32_t DEVICE_INDEPENDENT_PIXELS { 40 };
78constexpr int32_t POINTER_WINDOW_INIT_SIZE { 64 };
79constexpr int32_t DEFAULT_POINTER_SIZE { 1 };
80constexpr int32_t MIN_POINTER_SIZE { 1 };
81constexpr int32_t MAX_POINTER_SIZE { 7 };
82constexpr int32_t DEFAULT_VALUE { -1 };
83constexpr int32_t ANIMATION_DURATION { 500 };
84constexpr int32_t DEFAULT_POINTER_STYLE { 0 };
85constexpr int32_t CURSOR_CIRCLE_STYLE { 41 };
86constexpr int32_t MOUSE_ICON_BAIS { 5 };
87constexpr int32_t VISIBLE_LIST_MAX_SIZE { 100 };
88[[ maybe_unused ]] constexpr int32_t WAIT_TIME_FOR_MAGIC_CURSOR { 6000 };
89constexpr float ROTATION_ANGLE { 360.f };
90constexpr float LOADING_CENTER_RATIO { 0.5f };
91constexpr float RUNNING_X_RATIO { 0.3f };
92constexpr float RUNNING_Y_RATIO { 0.675f };
93constexpr float INCREASE_RATIO { 1.22f };
94constexpr float ROTATION_ANGLE90 { 90.f };
95constexpr int32_t MIN_POINTER_COLOR { 0x000000 };
96constexpr int32_t MAX_POINTER_COLOR { 0x00ffffff };
97constexpr int32_t MIN_CURSOR_SIZE { 64 };
98constexpr uint32_t RGB_CHANNEL_BITS_LENGTH { 24 };
99constexpr float MAX_ALPHA_VALUE { 255.f };
100constexpr int32_t MOUSE_STYLE_OPT { 0 };
101constexpr int32_t MAGIC_STYLE_OPT { 1 };
102constexpr size_t RETRY_TIMES { 3 };
103const std::string MOUSE_FILE_NAME { "mouse_settings.xml" };
104bool g_isRsRemoteDied { false };
105bool g_isHdiRemoteDied { false };
106bool g_isReStartVsync { false };
107constexpr uint64_t FOLD_SCREEN_ID_FULL { 0 };
108constexpr uint64_t FOLD_SCREEN_ID_MAIN { 5 };
109constexpr float IMAGE_PIXEL { 0.0f };
110constexpr float CALCULATE_IMAGE_MIDDLE { 2.0f };
111constexpr int32_t QUEUE_SIZE { 5 };
112constexpr int32_t DYNAMIC_ROTATION_ANGLE { 12 };
113constexpr float CALCULATE_MOUSE_ICON_BAIS { 5.0f };
114constexpr int32_t SYNC_FENCE_WAIT_TIME { 3000 };
115float g_hardwareCanvasSize = { 512.0f };
116float g_focalPoint = { 256.0f };
117} // namespace
118} // namespace MMI
119} // namespace OHOS
120
121namespace OHOS {
122namespace MMI {
123
124static bool IsSingleDisplayFoldDevice()
125{
126    return (!FOLD_SCREEN_FLAG.empty() && FOLD_SCREEN_FLAG[0] == '1');
127}
128
129void RsRemoteDiedCallback()
130{
131    CALL_INFO_TRACE;
132    g_isRsRemoteDied = true;
133    g_isHdiRemoteDied = true;
134    g_isReStartVsync = true;
135#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
136    MAGIC_CURSOR->RsRemoteDiedCallbackForMagicCursor();
137#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
138    IPointerDrawingManager::GetInstance()->DestroyPointerWindow();
139}
140
141void PointerDrawingManager::InitPointerCallback()
142{
143    MMI_HILOGI("Init RS Callback start");
144    g_isRsRemoteDied = false;
145    Rosen::OnRemoteDiedCallback callback = RsRemoteDiedCallback;
146    Rosen::RSInterfaces::GetInstance().SetOnRemoteDiedCallback(callback);
147#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
148    if (HasMagicCursor() && surfaceNode_ != nullptr) {
149        surfaceNode_ = nullptr;
150        MAGIC_CURSOR->RsRemoteInitCallbackForMagicCursor();
151    }
152#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
153}
154
155void PointerDrawingManager::DestroyPointerWindow()
156{
157    CALL_INFO_TRACE;
158    CHKPV(delegateProxy_);
159    delegateProxy_->OnPostSyncTask([this] {
160        if (surfaceNode_ != nullptr) {
161            MMI_HILOGI("Pointer window destroy start");
162            g_isRsRemoteDied = false;
163            surfaceNode_->DetachToDisplay(screenId_);
164            surfaceNode_ = nullptr;
165            Rosen::RSTransaction::FlushImplicitTransaction();
166            MMI_HILOGI("Pointer window destroy success");
167        }
168        return RET_OK;
169    });
170}
171
172static inline bool IsNum(const std::string &str)
173{
174    std::istringstream sin(str);
175    double num;
176    return (sin >> num) && sin.eof();
177}
178
179static float GetCanvasSize()
180{
181    auto ret = system::GetParameter("rosen.multimodalinput.pc.setcanvassize", "512.0");
182    if (IsNum(ret)) {
183        return g_hardwareCanvasSize;
184    }
185    return std::atoi(ret.c_str());
186}
187
188static float GetFocusCoordinates()
189{
190    auto ret = system::GetParameter("rosen.multimodalinput.pc.setfocuscoordinates", "256.0");
191    if (IsNum(ret)) {
192        return g_focalPoint;
193    }
194    return std::atoi(ret.c_str());
195}
196
197PointerDrawingManager::PointerDrawingManager()
198{
199#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
200    MMI_HILOGI("magiccurosr InitStyle");
201    hasMagicCursor_.name = "isMagicCursor";
202    MAGIC_CURSOR->InitStyle();
203#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
204    InitStyle();
205#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
206    hardwareCursorPointerManager_ = std::make_shared<HardwareCursorPointerManager>();
207    g_hardwareCanvasSize = GetCanvasSize();
208    g_focalPoint = GetFocusCoordinates();
209#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
210}
211
212PointerDrawingManager::~PointerDrawingManager()
213{
214#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
215    if (runner_ != nullptr) {
216        runner_->Stop();
217    }
218    if ((renderThread_ != nullptr) && renderThread_->joinable()) {
219        renderThread_->join();
220    }
221#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
222}
223
224PointerStyle PointerDrawingManager::GetLastMouseStyle()
225{
226    CALL_DEBUG_ENTER;
227    return lastMouseStyle_;
228}
229
230float PointerDrawingManager::CalculateHardwareXOffset(ICON_TYPE iconType)
231{
232    int32_t width = imageWidth_;
233    int32_t userIconHotSpotX = 0;
234#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
235    if (hardwareCursorPointerManager_->IsSupported() &&
236        currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
237        width = cursorWidth_;
238        userIconHotSpotX = userIconHotSpotX_;
239    }
240#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
241    switch (iconType) {
242        case ANGLE_E:
243            return g_focalPoint;
244        case ANGLE_S:
245            return (g_focalPoint - (width / CALCULATE_IMAGE_MIDDLE));
246        case ANGLE_W:
247            return (g_focalPoint - width);
248        case ANGLE_N:
249            return (g_focalPoint - (width / CALCULATE_IMAGE_MIDDLE));
250        case ANGLE_SE:
251            return (g_focalPoint - width);
252        case ANGLE_NE:
253            return (g_focalPoint - width);
254        case ANGLE_SW:
255            return g_focalPoint;
256        case ANGLE_NW:
257            return g_focalPoint - userIconHotSpotX;
258        case ANGLE_CENTER:
259            return (g_focalPoint - (width / CALCULATE_IMAGE_MIDDLE));
260        case ANGLE_NW_RIGHT:
261            return g_focalPoint - CALCULATE_MOUSE_ICON_BAIS;
262        default:
263            MMI_HILOGW("No need calculate physicalX offset, iconType:%{public}d", iconType);
264            return g_focalPoint;
265    }
266}
267
268float PointerDrawingManager::CalculateHardwareYOffset(ICON_TYPE iconType)
269{
270    int32_t height = imageHeight_;
271    int32_t userIconHotSpotY = 0;
272#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
273    if (hardwareCursorPointerManager_->IsSupported() &&
274        currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
275        height = cursorHeight_;
276        userIconHotSpotY = userIconHotSpotY_;
277    }
278#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
279    switch (iconType) {
280        case ANGLE_E:
281            return (g_focalPoint - (height / CALCULATE_IMAGE_MIDDLE));
282        case ANGLE_S:
283            return g_focalPoint;
284        case ANGLE_W:
285            return (g_focalPoint - height);
286        case ANGLE_N:
287            return (g_focalPoint - height);
288        case ANGLE_SE:
289            return (g_focalPoint - height);
290        case ANGLE_NE:
291            return g_focalPoint;
292        case ANGLE_SW:
293            return (g_focalPoint - height);
294        case ANGLE_NW:
295            return g_focalPoint - userIconHotSpotY;
296        case ANGLE_CENTER:
297            return (g_focalPoint - (height / CALCULATE_IMAGE_MIDDLE));
298        case ANGLE_NW_RIGHT:
299            return g_focalPoint;
300        default:
301            MMI_HILOGW("No need calculate physicalY offset, iconType:%{public}d", iconType);
302            return g_focalPoint;
303    }
304}
305
306#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
307bool PointerDrawingManager::SetDynamicHardWareCursorLocation
308    (int32_t physicalX, int32_t physicalY, MOUSE_ICON mouseStyle)
309{
310    CHKPF(hardwareCursorPointerManager_);
311    CHKPF(surfaceNode_);
312    if (g_isHdiRemoteDied) {
313        hardwareCursorPointerManager_->SetHdiServiceState(false);
314    }
315    ICON_TYPE iconType = ICON_TYPE::ANGLE_NW;
316    if (mouseStyle == MOUSE_ICON::LOADING) {
317        iconType = ICON_TYPE::ANGLE_CENTER;
318    } else {
319        iconType = ICON_TYPE::ANGLE_NW;
320    }
321    if (hardwareCursorPointerManager_->IsSupported()) {
322    surfaceNode_->SetBounds((physicalX - CalculateHardwareXOffset(iconType)), (physicalY -
323        CalculateHardwareYOffset(iconType)), g_hardwareCanvasSize, g_hardwareCanvasSize);
324    }
325    Rosen::RSTransaction::FlushImplicitTransaction();
326    return true;
327}
328
329void PointerDrawingManager::PostTaskRSLocation(int32_t physicalX, int32_t physicalY,
330    std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode)
331{
332    hardwareCanvasSize_ = g_hardwareCanvasSize;
333    PostTask([this, physicalX, physicalY, surfaceNode]() -> void {
334        CHKPV(surfaceNode);
335        surfaceNode->SetBounds(physicalX, physicalY, hardwareCanvasSize_, hardwareCanvasSize_);
336        Rosen::RSTransaction::FlushImplicitTransaction();
337    });
338}
339#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
340
341bool PointerDrawingManager::SetTraditionsHardWareCursorLocation(int32_t displayId, int32_t physicalX,
342    int32_t physicalY, ICON_TYPE iconType)
343{
344    bool magicCursorSetBounds = false;
345    if (UpdateSurfaceNodeBounds(physicalX, physicalY) == RET_OK) {
346        magicCursorSetBounds = true;
347        Rosen::RSTransaction::FlushImplicitTransaction();
348    }
349#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
350    CHKPF(hardwareCursorPointerManager_);
351    CHKPF(surfaceNode_);
352    if (g_isHdiRemoteDied) {
353        hardwareCursorPointerManager_->SetHdiServiceState(false);
354    }
355    if (hardwareCursorPointerManager_->IsSupported() && (hasLoadingPointerStyle_ || hasHardwareCursorAnimate_)) {
356        if (hardwareCursorPointerManager_->SetPosition((physicalX -
357            CalculateHardwareXOffset(iconType)), (physicalY -
358            CalculateHardwareYOffset(iconType))) != RET_OK) {
359            MMI_HILOGE("Set hardware cursor position fail");
360            return false;
361        }
362        return true;
363    }
364    if (!magicCursorSetBounds) {
365        if (hardwareCursorPointerManager_->IsSupported()) {
366            // Change the coordinates issued by RS to asynchronous,
367            // without blocking the issuance of HardwareCursor coordinates.
368            PostTaskRSLocation((physicalX - CalculateHardwareXOffset(iconType)), (physicalY -
369                CalculateHardwareYOffset(iconType)), surfaceNode_);
370        } else {
371            surfaceNode_->SetBounds(physicalX, physicalY, surfaceNode_->GetStagingProperties().GetBounds().z_,
372                surfaceNode_->GetStagingProperties().GetBounds().w_);
373            Rosen::RSTransaction::FlushImplicitTransaction();
374        }
375    }
376#else
377    if (!magicCursorSetBounds) {
378        surfaceNode_->SetBounds(physicalX, physicalY,
379            surfaceNode_->GetStagingProperties().GetBounds().z_, surfaceNode_->GetStagingProperties().GetBounds().w_);
380        Rosen::RSTransaction::FlushImplicitTransaction();
381    }
382#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
383#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
384    CHKPF(hardwareCursorPointerManager_);
385    hardwareCursorPointerManager_->SetTargetDevice(displayId);
386    if (hardwareCursorPointerManager_->IsSupported()) {
387        if (hardwareCursorPointerManager_->SetPosition((physicalX - CalculateHardwareXOffset(
388            iconType)), (physicalY - CalculateHardwareYOffset(iconType))) != RET_OK) {
389            MMI_HILOGE("Set hardware cursor position error");
390        }
391    }
392#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
393    return true;
394}
395
396void PointerDrawingManager::ForceClearPointerVisiableStatus()
397{
398    MMI_HILOGI("force clear all pointer visiable status");
399    pidInfos_.clear();
400    UpdatePointerVisible();
401}
402
403void PointerDrawingManager::SetSurfaceNodeVisible(bool visible)
404{
405#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
406    CHKPV(hardwareCursorPointerManager_);
407    CHKPV(surfaceNode_);
408    if (!hardwareCursorPointerManager_->IsSupported()) {
409        surfaceNode_->SetVisible(visible);
410    }
411#else
412    surfaceNode_->SetVisible(visible);
413#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
414}
415
416int32_t PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
417    PointerStyle pointerStyle, Direction direction)
418{
419    CHKPR(surfaceNode_, RET_ERR);
420    MMI_HILOGD("Pointer window move success, pointerStyle id: %{public}d", pointerStyle.id);
421    displayId_ = displayId;
422#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
423    bool cursorEnlarged = MAGIC_POINTER_VELOCITY_TRACKER->GetCursorEnlargedStatus();
424    if (cursorEnlarged) {
425        MAGIC_POINTER_VELOCITY_TRACKER->SetLastPointerStyle(pointerStyle);
426        MAGIC_POINTER_VELOCITY_TRACKER->SetDirection(direction);
427        if (pointerStyle.id != MOUSE_ICON::DEFAULT && pointerStyle.id != MOUSE_ICON::CROSS) {
428            pointerStyle.id = MOUSE_ICON::DEFAULT;
429        }
430    }
431#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
432#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
433    UpdateBindDisplayId(displayId);
434#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
435    if (lastMouseStyle_ == pointerStyle && !mouseIconUpdate_ && lastDirection_ == direction) {
436        if (!SetTraditionsHardWareCursorLocation(displayId, physicalX, physicalY,
437            ICON_TYPE(mouseIcons_[MOUSE_ICON(pointerStyle.id)].alignmentWay))) {
438            return RET_ERR;
439        }
440        MMI_HILOGD("The lastpointerStyle is equal with pointerStyle, id:%{public}d, size:%{public}d",
441            pointerStyle.id, pointerStyle.size);
442        return RET_OK;
443    }
444    if (lastDirection_ != direction) {
445        RotateDegree(direction);
446        lastDirection_ = direction;
447    }
448    lastMouseStyle_ = pointerStyle;
449    SetSurfaceNodeVisible(false);
450    if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
451        mouseIconUpdate_ = false;
452        MMI_HILOGE("Init layer failed");
453        return RET_ERR;
454    }
455    SetSurfaceNodeVisible(true);
456    if (!SetTraditionsHardWareCursorLocation(displayId, physicalX, physicalY,
457        ICON_TYPE(mouseIcons_[MOUSE_ICON(lastMouseStyle_.id)].alignmentWay))) {
458        MMI_HILOGE("Set traditions hardware cursor location error");
459        return RET_ERR;
460    }
461    UpdatePointerVisible();
462    mouseIconUpdate_ = false;
463    MMI_HILOGD("Leave, display:%{public}d, physicalX:%{public}d, physicalY:%{public}d",
464        displayId, physicalX, physicalY);
465    return RET_OK;
466}
467
468int32_t PointerDrawingManager::UpdateSurfaceNodeBounds(int32_t physicalX, int32_t physicalY)
469{
470#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
471    if (HasMagicCursor()) {
472        if (currentMouseStyle_.id == DEVELOPER_DEFINED_ICON) {
473            surfaceNode_->SetBounds(physicalX, physicalY,
474                canvasWidth_, canvasHeight_);
475        } else {
476            surfaceNode_->SetBounds(physicalX, physicalY,
477                imageWidth_, imageHeight_);
478        }
479        return RET_OK;
480    }
481#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
482    return RET_ERR;
483}
484
485void PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY)
486{
487    CALL_DEBUG_ENTER;
488    if (surfaceNode_ != nullptr) {
489        if (!SetTraditionsHardWareCursorLocation(displayId, physicalX, physicalY,
490            ICON_TYPE(mouseIcons_[MOUSE_ICON(lastMouseStyle_.id)].alignmentWay))) {
491            return;
492        }
493        MMI_HILOGD("Move pointer, physicalX:%d, physicalY:%d", physicalX, physicalY);
494    }
495}
496
497void PointerDrawingManager::SetHardwareCursorPosition(int32_t displayId, int32_t physicalX, int32_t physicalY,
498    PointerStyle pointerStyle)
499{
500#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
501    CHKPV(hardwareCursorPointerManager_);
502    if (g_isHdiRemoteDied) {
503        hardwareCursorPointerManager_->SetHdiServiceState(false);
504    }
505    hardwareCursorPointerManager_->SetTargetDevice(displayId);
506    if (hardwareCursorPointerManager_->IsSupported() && lastMouseStyle_.id != MOUSE_ICON::LOADING &&
507            lastMouseStyle_.id != MOUSE_ICON::RUNNING) {
508        if (hardwareCursorPointerManager_->SetPosition((physicalX - CalculateHardwareXOffset(ICON_TYPE(
509            mouseIcons_[MOUSE_ICON(pointerStyle.id)].alignmentWay))), (physicalY - CalculateHardwareYOffset(
510                ICON_TYPE(mouseIcons_[MOUSE_ICON(pointerStyle.id)].alignmentWay)))) != RET_OK) {
511            MMI_HILOGE("Set hardware cursor position error");
512        }
513    }
514#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
515}
516
517void PointerDrawingManager::DrawPointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
518    const PointerStyle pointerStyle, Direction direction)
519{
520    CALL_DEBUG_ENTER;
521    MMI_HILOGD("Display:%{public}d, physicalX:%{public}d, physicalY:%{public}d, pointerStyle:%{public}d",
522        displayId, physicalX, physicalY, pointerStyle.id);
523    FixCursorPosition(physicalX, physicalY);
524    lastPhysicalX_ = physicalX;
525    lastPhysicalY_ = physicalY;
526    currentMouseStyle_ = pointerStyle;
527    currentDirection_ = direction;
528    if (pointerStyle.id == MOUSE_ICON::DEFAULT && mouseIcons_[MOUSE_ICON(pointerStyle.id)].iconPath == CursorIconPath) {
529        AdjustMouseFocus(direction, ICON_TYPE(mouseIcons_[MOUSE_ICON(MOUSE_ICON::CURSOR_CIRCLE)].alignmentWay),
530            physicalX, physicalY);
531    } else {
532        AdjustMouseFocus(direction, ICON_TYPE(mouseIcons_[MOUSE_ICON(pointerStyle.id)].alignmentWay),
533            physicalX, physicalY);
534    }
535    // Log printing only occurs when the mouse style changes
536    if (currentMouseStyle_.id != lastMouseStyle_.id) {
537        MMI_HILOGD("MagicCursor AdjustMouseFocus:%{public}d",
538            ICON_TYPE(mouseIcons_[MOUSE_ICON(pointerStyle.id)].alignmentWay));
539    }
540    if (DrawMovePointer(displayId, physicalX, physicalY, pointerStyle, direction) == RET_OK) {
541        return;
542    }
543#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
544    if (HasMagicCursor() && currentMouseStyle_.id != DEVELOPER_DEFINED_ICON) {
545        MMI_HILOGD("magicCursor DrawPointer enter CreatePointerWindow");
546        MAGIC_CURSOR->CreatePointerWindow(displayId, physicalX, physicalY, direction, surfaceNode_);
547    } else {
548        CreatePointerWindow(displayId, physicalX, physicalY, direction);
549    }
550#else
551    CreatePointerWindow(displayId, physicalX, physicalY, direction);
552#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
553    CHKPV(surfaceNode_);
554    UpdateMouseStyle();
555    if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
556        MMI_HILOGE("Init layer failed");
557        return;
558    }
559    UpdatePointerVisible();
560    SetHardwareCursorPosition(displayId, physicalX, physicalY, lastMouseStyle_);
561    MMI_HILOGI("Leave, display:%{public}d, physicalX:%d, physicalY:%d", displayId, physicalX, physicalY);
562}
563
564void PointerDrawingManager::UpdateMouseStyle()
565{
566    CALL_DEBUG_ENTER;
567    PointerStyle curPointerStyle;
568    GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
569    if (curPointerStyle.id == CURSOR_CIRCLE_STYLE) {
570        lastMouseStyle_.id = curPointerStyle.id;
571        int ret = SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
572        if (ret != RET_OK) {
573            MMI_HILOGE("Set pointer style failed");
574        }
575        return;
576    }
577}
578
579int32_t PointerDrawingManager::SwitchPointerStyle()
580{
581    CALL_DEBUG_ENTER;
582    int32_t size = GetPointerSize();
583    if (size < MIN_POINTER_SIZE) {
584        size = MIN_POINTER_SIZE;
585    } else if (size > MAX_POINTER_SIZE) {
586        size = MAX_POINTER_SIZE;
587    }
588    imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
589    imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
590    canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
591    canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
592#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
593    MAGIC_CURSOR->SetPointerSize(imageWidth_, imageHeight_);
594#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
595    Direction direction = DIRECTION0;
596    int32_t physicalX = lastPhysicalX_;
597    int32_t physicalY = lastPhysicalY_;
598    AdjustMouseFocus(
599        direction, ICON_TYPE(GetIconStyle(MOUSE_ICON(lastMouseStyle_.id)).alignmentWay), physicalX, physicalY);
600#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
601    if (HasMagicCursor()) {
602        MAGIC_CURSOR->EnableCursorInversion();
603        MAGIC_CURSOR->CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction, surfaceNode_);
604    } else {
605        MAGIC_CURSOR->DisableCursorInversion();
606        CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
607    }
608#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
609    int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
610    if (ret != RET_OK) {
611        MMI_HILOGE("Init layer failed");
612        return ret;
613    }
614    UpdatePointerVisible();
615    SetHardwareCursorPosition(displayInfo_.id, physicalX, physicalY, lastMouseStyle_);
616    return RET_OK;
617}
618
619void PointerDrawingManager::CreateMagicCursorChangeObserver()
620{
621    // Listening enabling cursor deformation and color inversion
622    SettingObserver::UpdateFunc func = [](const std::string& key) {
623        bool statusValue = false;
624        auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue);
625        if (ret != RET_OK) {
626            MMI_HILOGE("Get value from setting date fail");
627            return;
628        }
629#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
630        MAGIC_CURSOR->UpdateMagicCursorChangeState(statusValue);
631#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
632    };
633    std::string dynamicallyKey = "smartChange";
634    sptr<SettingObserver> magicCursorChangeObserver = SettingDataShare::GetInstance(
635        MULTIMODAL_INPUT_SERVICE_ID).CreateObserver(dynamicallyKey, func);
636    ErrCode ret =
637        SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(magicCursorChangeObserver);
638    if (ret != ERR_OK) {
639#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
640        DfxHisysevent::ReportMagicCursorFault(dynamicallyKey, "Register setting observer failed");
641#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
642        MMI_HILOGE("Register magic cursor change observer failed, ret:%{public}d", ret);
643        magicCursorChangeObserver = nullptr;
644    }
645}
646
647void PointerDrawingManager::UpdateStyleOptions()
648{
649    CALL_DEBUG_ENTER;
650    PointerStyle curPointerStyle;
651    WIN_MGR->GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
652    curPointerStyle.options = HasMagicCursor() ? MAGIC_STYLE_OPT : MOUSE_STYLE_OPT;
653    int ret = WIN_MGR->SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
654    if (ret != RET_OK) {
655        MMI_HILOGE("Set pointer style failed");
656    }
657}
658
659void PointerDrawingManager::InitPointerObserver()
660{
661    CALL_INFO_TRACE;
662    if (hasInitObserver_) {
663        MMI_HILOGI("Settingdata observer has init");
664        return;
665    }
666#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
667    int32_t ret = CreatePointerSwitchObserver(hasMagicCursor_);
668    if (ret == RET_OK) {
669        hasInitObserver_ = true;
670        MMI_HILOGD("Create pointer switch observer success");
671    }
672#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
673}
674
675int32_t PointerDrawingManager::CreatePointerSwitchObserver(isMagicCursor& item)
676{
677    CALL_DEBUG_ENTER;
678    SettingObserver::UpdateFunc updateFunc = [this, &item](const std::string& key) {
679        bool statusValue = false;
680#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
681        statusValue = true;
682#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
683        auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue);
684        if (ret != RET_OK) {
685            MMI_HILOGE("Get value from setting date fail");
686            return;
687        }
688        bool tmp = item.isShow;
689        item.isShow = statusValue;
690        this->UpdateStyleOptions();
691        if (item.isShow != tmp) {
692#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
693            MAGIC_CURSOR->InitRenderThread([]() { IPointerDrawingManager::GetInstance()->SwitchPointerStyle(); });
694#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
695            CHKPV(surfaceNode_);
696#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
697            MMI_HILOGD("Switch pointer style");
698            int64_t nodeId = surfaceNode_->GetId();
699            if (nodeId != MAGIC_CURSOR->GetSurfaceNodeId(nodeId)) {
700                surfaceNode_->DetachToDisplay(screenId_);
701                Rosen::RSTransaction::FlushImplicitTransaction();
702            }
703            MAGIC_CURSOR->DetachDisplayNode();
704            this->SwitchPointerStyle();
705#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
706        }
707    };
708    sptr<SettingObserver> statusObserver =
709        SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).CreateObserver(item.name, updateFunc);
710    ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
711    if (ret != ERR_OK) {
712#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
713        DfxHisysevent::ReportMagicCursorFault(item.name, "Register setting observer failed");
714#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
715        MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
716        statusObserver = nullptr;
717        return RET_ERR;
718    }
719    CreateMagicCursorChangeObserver();
720    return RET_OK;
721}
722
723bool PointerDrawingManager::HasMagicCursor()
724{
725#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
726    if (!MAGIC_CURSOR->isExistDefaultStyle) {
727        MMI_HILOGE("MagicCursor default icon file is not exist");
728        return false;
729    }
730#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
731    return hasMagicCursor_.isShow;
732}
733
734void PointerDrawingManager::CreateDynamicCanvas()
735{
736    CALL_DEBUG_ENTER;
737    OHOS::Rosen::Drawing::BitmapFormat format { OHOS::Rosen::Drawing::COLORTYPE_RGBA_8888,
738        OHOS::Rosen::Drawing::ALPHATYPE_OPAQUE };
739    if (dynamicBitmap_ == nullptr) {
740        dynamicBitmap_ = std::make_shared<OHOS::Rosen::Drawing::Bitmap>();
741    }
742    g_hardwareCanvasSize = GetCanvasSize();
743    dynamicBitmap_->Build(g_hardwareCanvasSize, g_hardwareCanvasSize, format);
744    if (dynamicCanvas_ == nullptr) {
745        dynamicCanvas_ = std::make_shared<OHOS::Rosen::Drawing::Canvas>();
746    }
747    dynamicCanvas_->Bind(*dynamicBitmap_);
748}
749
750int32_t PointerDrawingManager::ParsingDynamicImage(MOUSE_ICON mouseStyle)
751{
752    CALL_DEBUG_ENTER;
753    std::shared_ptr<OHOS::Media::PixelMap> pixelmap = nullptr;
754    if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
755        MMI_HILOGD("Set mouseicon by userIcon_");
756        image_ = ExtractDrawingImage(userIcon_);
757    } else {
758        if (mouseStyle == MOUSE_ICON::RUNNING) {
759            pixelmap = DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_LEFT].iconPath);
760        } else {
761            pixelmap = DecodeImageToPixelMap(mouseIcons_[mouseStyle].iconPath);
762        }
763        CHKPR(pixelmap, RET_ERR);
764        if (mouseStyle == MOUSE_ICON::RUNNING_RIGHT) {
765            runningRightImage_ = ExtractDrawingImage(pixelmap);
766            CHKPR(runningRightImage_, RET_ERR);
767            return RET_OK;
768        }
769        image_ = ExtractDrawingImage(pixelmap);
770        CHKPR(image_, RET_ERR);
771    }
772    return RET_OK;
773}
774
775#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
776void PointerDrawingManager::DrawTraditionsCursor(MOUSE_ICON mouseStyle)
777{
778    PostTask([this, mouseStyle]() -> void {
779        this->DrawCursor(mouseStyle);
780    });
781}
782
783int32_t PointerDrawingManager::InitVsync(MOUSE_ICON mouseStyle)
784{
785    if (ParsingDynamicImage(mouseStyle) != RET_OK) {
786        MMI_HILOGE("Parsing mouseStyle fail");
787        return RET_ERR;
788    }
789    if (ParsingDynamicImage(MOUSE_ICON::RUNNING_RIGHT) != RET_OK) {
790        MMI_HILOGE("Parsing mouse icon fail");
791        return RET_ERR;
792    }
793    if (mouseStyle == MOUSE_ICON::LOADING) {
794        hasLoadingPointerStyle_ = true;
795    } else if (mouseStyle == MOUSE_ICON::RUNNING) {
796        hasHardwareCursorAnimate_ = true;
797    }
798    CreateDynamicCanvas();
799    if (g_isReStartVsync) {
800        isRenderRuning_.store(true);
801        auto rsClient = std::static_pointer_cast<Rosen::RSRenderServiceClient>(
802            Rosen::RSIRenderClient::CreateRenderServiceClient());
803        CHKPR(rsClient, RET_ERR);
804        receiver_ = rsClient->CreateVSyncReceiver(POINTER_CURSOR_RENDER_RECEIVER_NAME, handler_);
805        if (receiver_ == nullptr || receiver_->Init() != VSYNC_ERROR_OK) {
806            MMI_HILOGE("Receiver init failed");
807            return RET_ERR;
808        }
809        g_isReStartVsync = false;
810    }
811    return RequestNextVSync();
812}
813
814bool PointerDrawingManager::RetryGetSurfaceBuffer(sptr<OHOS::SurfaceBuffer> buffer, sptr<OHOS::Surface> layer)
815{
816    bool ret = true;
817    if (hardwareCursorPointerManager_->IsSupported()) {
818        for (size_t i = 0; i < RETRY_TIMES; i++) {
819            buffer = GetSurfaceBuffer(layer);
820            if (buffer != nullptr && buffer->GetVirAddr() != nullptr) {
821                ret = false;
822                break;
823            }
824        }
825    }
826    return ret;
827}
828#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
829
830int32_t PointerDrawingManager::InitLayer(const MOUSE_ICON mouseStyle)
831{
832#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
833    if (HasMagicCursor() && mouseStyle != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
834        MMI_HILOGD("magiccursor enter MAGIC_CURSOR->Initlayer");
835        return MAGIC_CURSOR->InitLayer(mouseStyle);
836    }
837#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
838#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
839    CHKPR(hardwareCursorPointerManager_, RET_ERR);
840    hasLoadingPointerStyle_ = false;
841    hasHardwareCursorAnimate_ = false;
842    if (hardwareCursorPointerManager_->IsSupported()) {
843        if ((mouseStyle == MOUSE_ICON::LOADING) || (mouseStyle == MOUSE_ICON::RUNNING)) {
844            return InitVsync(mouseStyle);
845        } else {
846            GetCanvasSize();
847            GetFocusCoordinates();
848            hardwareCanvasSize_ = g_hardwareCanvasSize;
849            // Change the drawing to asynchronous, and when obtaining the surfaceBuffer fails,
850            // repeatedly obtain the surfaceBuffer.
851            DrawTraditionsCursor(mouseStyle);
852            return RET_OK;
853        }
854    }
855#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
856    return DrawCursor(mouseStyle);
857}
858
859int32_t PointerDrawingManager::DrawCursor(const MOUSE_ICON mouseStyle)
860{
861    CALL_DEBUG_ENTER;
862    CHKPR(surfaceNode_, RET_ERR);
863    DrawLoadingPointerStyle(mouseStyle);
864    DrawRunningPointerAnimate(mouseStyle);
865    sptr<OHOS::Surface> layer = GetLayer();
866    if (layer == nullptr) {
867        MMI_HILOGE("Init layer is failed, Layer is nullptr");
868        surfaceNode_->DetachToDisplay(screenId_);
869        surfaceNode_ = nullptr;
870        Rosen::RSTransaction::FlushImplicitTransaction();
871        MMI_HILOGE("Pointer window destroy success");
872        return RET_ERR;
873    }
874    if (!isInit_) {
875        layer->SetQueueSize(QUEUE_SIZE);
876        isInit_ = true;
877    }
878    sptr<OHOS::SurfaceBuffer> buffer = GetSurfaceBuffer(layer);
879    if (buffer == nullptr || buffer->GetVirAddr() == nullptr) {
880#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
881        if (RetryGetSurfaceBuffer(buffer, layer)) {
882            return RET_OK;
883        }
884#else
885        surfaceNode_->DetachToDisplay(screenId_);
886        surfaceNode_ = nullptr;
887        Rosen::RSTransaction::FlushImplicitTransaction();
888        MMI_HILOGE("Pointer window destroy success");
889        return RET_ERR;
890#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
891    }
892
893    auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
894    DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), mouseStyle);
895    OHOS::BufferFlushConfig flushConfig = {
896        .damage = {
897            .w = buffer->GetWidth(),
898            .h = buffer->GetHeight(),
899        },
900    };
901    OHOS::SurfaceError ret = layer->FlushBuffer(buffer, -1, flushConfig);
902    if (ret != OHOS::SURFACE_ERROR_OK) {
903        MMI_HILOGE("Init layer failed, FlushBuffer return ret:%{public}s", SurfaceErrorStr(ret).c_str());
904        return RET_ERR;
905    }
906    MMI_HILOGD("Init layer success");
907    return RET_OK;
908}
909
910void PointerDrawingManager::DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)
911{
912    CALL_DEBUG_ENTER;
913    CHKPV(surfaceNode_);
914#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
915    CHKPV(hardwareCursorPointerManager_);
916    if (hardwareCursorPointerManager_->IsSupported()) {
917        return;
918    }
919#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
920    Rosen::RSAnimationTimingProtocol protocol;
921    if (mouseStyle != MOUSE_ICON::LOADING &&
922        (mouseStyle != MOUSE_ICON::DEFAULT ||
923            mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"))) {
924        protocol.SetDuration(0);
925        Rosen::RSNode::Animate(
926            protocol,
927            Rosen::RSAnimationTimingCurve::LINEAR,
928            [this]() {
929                if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
930                    RotateDegree(DIRECTION0);
931                    return;
932                }
933                RotateDegree(currentDirection_);
934            });
935        MMI_HILOGE("current pointer is not loading");
936        Rosen::RSTransaction::FlushImplicitTransaction();
937        return;
938    }
939    float ratio = imageWidth_ * 1.0 / canvasWidth_;
940    surfaceNode_->SetPivot({LOADING_CENTER_RATIO * ratio, LOADING_CENTER_RATIO * ratio});
941    protocol.SetDuration(ANIMATION_DURATION);
942    protocol.SetRepeatCount(DEFAULT_VALUE);
943
944    // create property animation
945    Rosen::RSNode::Animate(
946        protocol,
947        Rosen::RSAnimationTimingCurve::LINEAR,
948        [this]() { surfaceNode_->SetRotation(ROTATION_ANGLE); });
949
950    Rosen::RSTransaction::FlushImplicitTransaction();
951}
952
953std::shared_ptr<Rosen::Drawing::ColorSpace> PointerDrawingManager::ConvertToColorSpace(
954    Media::ColorSpace colorSpace)
955{
956    switch (colorSpace) {
957        case Media::ColorSpace::DISPLAY_P3:
958            return Rosen::Drawing::ColorSpace::CreateRGB(
959                Rosen::Drawing::CMSTransferFuncType::SRGB, Rosen::Drawing::CMSMatrixType::DCIP3);
960        case Media::ColorSpace::LINEAR_SRGB:
961            return Rosen::Drawing::ColorSpace::CreateSRGBLinear();
962        case Media::ColorSpace::SRGB:
963            return Rosen::Drawing::ColorSpace::CreateSRGB();
964        default:
965            return Rosen::Drawing::ColorSpace::CreateSRGB();
966    }
967}
968
969Rosen::Drawing::ColorType PointerDrawingManager::PixelFormatToColorType(Media::PixelFormat pixelFormat)
970{
971    switch (pixelFormat) {
972        case Media::PixelFormat::RGB_565:
973            return Rosen::Drawing::ColorType::COLORTYPE_RGB_565;
974        case Media::PixelFormat::RGBA_8888:
975            return Rosen::Drawing::ColorType::COLORTYPE_RGBA_8888;
976        case Media::PixelFormat::BGRA_8888:
977            return Rosen::Drawing::ColorType::COLORTYPE_BGRA_8888;
978        case Media::PixelFormat::ALPHA_8:
979            return Rosen::Drawing::ColorType::COLORTYPE_ALPHA_8;
980        case Media::PixelFormat::RGBA_F16:
981            return Rosen::Drawing::ColorType::COLORTYPE_RGBA_F16;
982        case Media::PixelFormat::UNKNOWN:
983        case Media::PixelFormat::ARGB_8888:
984        case Media::PixelFormat::RGB_888:
985        case Media::PixelFormat::NV21:
986        case Media::PixelFormat::NV12:
987        case Media::PixelFormat::CMYK:
988        default:
989            return Rosen::Drawing::ColorType::COLORTYPE_UNKNOWN;
990    }
991}
992
993Rosen::Drawing::AlphaType PointerDrawingManager::AlphaTypeToAlphaType(Media::AlphaType alphaType)
994{
995    switch (alphaType) {
996        case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
997            return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
998        case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
999            return Rosen::Drawing::AlphaType::ALPHATYPE_OPAQUE;
1000        case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
1001            return Rosen::Drawing::AlphaType::ALPHATYPE_PREMUL;
1002        case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
1003            return Rosen::Drawing::AlphaType::ALPHATYPE_UNPREMUL;
1004        default:
1005            return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
1006    }
1007}
1008
1009static void PixelMapReleaseProc(const void* /* pixels */, void* context)
1010{
1011    PixelMapReleaseContext* ctx = static_cast<PixelMapReleaseContext*>(context);
1012    if (ctx != nullptr) {
1013        delete ctx;
1014    }
1015}
1016
1017std::shared_ptr<Rosen::Drawing::Image> PointerDrawingManager::ExtractDrawingImage(
1018    std::shared_ptr<Media::PixelMap> pixelMap)
1019{
1020    CHKPP(pixelMap);
1021    Media::ImageInfo imageInfo;
1022    pixelMap->GetImageInfo(imageInfo);
1023    Rosen::Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
1024        PixelFormatToColorType(imageInfo.pixelFormat),
1025        AlphaTypeToAlphaType(imageInfo.alphaType),
1026        ConvertToColorSpace(imageInfo.colorSpace) };
1027    Rosen::Drawing::Pixmap imagePixmap(drawingImageInfo,
1028        reinterpret_cast<const void*>(pixelMap->GetPixels()), pixelMap->GetRowBytes());
1029    PixelMapReleaseContext* releaseContext = new (std::nothrow) PixelMapReleaseContext(pixelMap);
1030    CHKPP(releaseContext);
1031    auto image = Rosen::Drawing::Image::MakeFromRaster(imagePixmap, PixelMapReleaseProc, releaseContext);
1032    if (image == nullptr) {
1033        MMI_HILOGE("ExtractDrawingImage image fail");
1034        delete releaseContext;
1035    }
1036    return image;
1037}
1038
1039#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1040void PointerDrawingManager::PostTask(Rosen::RSTaskMessage::RSTask task)
1041{
1042    CHKPV(hardwareCursorPointerManager_);
1043    if (g_isHdiRemoteDied) {
1044        hardwareCursorPointerManager_->SetHdiServiceState(false);
1045    }
1046    if (handler_ != nullptr) {
1047        handler_->PostTask(task);
1048    }
1049}
1050
1051void PointerDrawingManager::DoHardwareCursorDraw()
1052{
1053    CHKPV(hardwareCursorPointerManager_);
1054    CHKPV(dynamicCanvas_);
1055    CHKPV(dynamicBitmap_);
1056    dynamicCanvas_->Save();
1057    dynamicCanvas_->Clear(OHOS::Rosen::Drawing::Color::COLOR_TRANSPARENT);
1058    FOCUS_COORDINATES(FOCUS_COORDINATES_, CHANGE) = GetFocusCoordinates();
1059    CALCULATE_CANVAS_SIZE(CALCULATE_CANVAS_SIZE_, CHANGE) = GetCanvasSize();
1060    if (hardwareCursorPointerManager_->IsSupported() && hasLoadingPointerStyle_) {
1061        dynamicCanvas_->Rotate(DYNAMIC_ROTATION_ANGLE * currentFrame_, FOCUS_COORDINATES_CHANGE,
1062            FOCUS_COORDINATES_CHANGE);
1063        currentFrame_++;
1064        if (currentFrame_ == frameCount_) {
1065            currentFrame_ = 0;
1066        }
1067    }
1068    DrawDynamicImage(*dynamicCanvas_, MOUSE_ICON(lastMouseStyle_.id));
1069    if (hardwareCursorPointerManager_->IsSupported() && hasHardwareCursorAnimate_) {
1070        dynamicCanvas_->Rotate(DYNAMIC_ROTATION_ANGLE * currentFrame_, (FOCUS_COORDINATES_CHANGE +
1071            (imageWidth_ * RUNNING_X_RATIO)), (FOCUS_COORDINATES_CHANGE + (imageHeight_ * RUNNING_Y_RATIO)));
1072        DrawDynamicImage(*dynamicCanvas_, MOUSE_ICON::RUNNING_RIGHT);
1073        currentFrame_++;
1074        if (currentFrame_ == frameCount_) {
1075            currentFrame_ = 0;
1076        }
1077    }
1078    dynamicCanvas_->Restore();
1079    static constexpr uint32_t stride = 4;
1080    uint32_t addrSize = buffer_->GetWidth() * buffer_->GetHeight() * stride;
1081    CHKPV(addr_);
1082    errno_t ret = memcpy_s(*addr_, addrSize, dynamicBitmap_->GetPixels(), addrSize);
1083    if (ret != EOK) {
1084        MMI_HILOGE("Memcpy data is error, ret:%{public}d", ret);
1085    }
1086}
1087
1088int32_t PointerDrawingManager::FlushBuffer()
1089{
1090    CHKPR(buffer_, RET_ERR);
1091    CHKPR(layer_, RET_ERR);
1092    OHOS::BufferFlushConfig flushConfig = {
1093        .damage = {
1094            .w = buffer_->GetWidth(),
1095            .h = buffer_->GetHeight(),
1096        },
1097    };
1098    OHOS::SurfaceError ret = layer_->FlushBuffer(buffer_, DEFAULT_VALUE, flushConfig);
1099    if (ret != OHOS::SURFACE_ERROR_OK) {
1100        MMI_HILOGE("Init layer failed, FlushBuffer return ret:%{public}s", SurfaceErrorStr(ret).c_str());
1101    }
1102    return ret;
1103}
1104
1105int32_t PointerDrawingManager::GetSurfaceInformation()
1106{
1107    CHKPR(surfaceNode_, RET_ERR);
1108    if (currentMouseStyle_.id != MOUSE_ICON::RUNNING && currentMouseStyle_.id != MOUSE_ICON::LOADING) {
1109        MMI_HILOGE("Current mouse style is not equal to last mouse style");
1110        return RET_ERR;
1111    }
1112    layer_ = GetLayer();
1113    CHKPR(layer_, RET_ERR);
1114    buffer_ = GetSurfaceBuffer(layer_);
1115    if (buffer_ == nullptr || buffer_->GetVirAddr() == nullptr) {
1116        MMI_HILOGE("Init layer is failed, buffer or virAddr is nullptr");
1117        return RET_ERR;
1118    }
1119    addr_ = std::make_shared<uint8_t *>(static_cast<uint8_t *>(buffer_->GetVirAddr()));
1120    CHKPR(addr_, RET_ERR);
1121    return RET_OK;
1122}
1123
1124void PointerDrawingManager::OnVsync(uint64_t timestamp)
1125{
1126    if (currentMouseStyle_.id != MOUSE_ICON::RUNNING && currentMouseStyle_.id != MOUSE_ICON::LOADING) {
1127        MMI_HILOGE("Current mouse style is not equal to last mouse style");
1128        return;
1129    }
1130    PostTask([this]() -> void {
1131        if (currentMouseStyle_.id != MOUSE_ICON::RUNNING && currentMouseStyle_.id != MOUSE_ICON::LOADING) {
1132            MMI_HILOGE("Current post task mouse style is not equal to last mouse style");
1133            return;
1134        }
1135        if (GetSurfaceInformation() != RET_OK) {
1136            MMI_HILOGE("OnVsync Get surface information fail");
1137            return;
1138        }
1139        DoHardwareCursorDraw();
1140        FlushBuffer();
1141        UpdatePointerVisible();
1142        mouseIconUpdate_ = false;
1143        if (!SetDynamicHardWareCursorLocation(lastPhysicalX_, lastPhysicalY_, MOUSE_ICON(lastMouseStyle_.id))) {
1144            MMI_HILOGE("OnVsync set dynamic hardware cursor location error");
1145            return;
1146        }
1147    });
1148    RequestNextVSync();
1149}
1150
1151int32_t PointerDrawingManager::RequestNextVSync()
1152{
1153    if (handler_ != nullptr) {
1154        Rosen::VSyncReceiver::FrameCallback fcb = {
1155            .userData_ = this,
1156            .callback_ = [this] (uint64_t timestamp, void*) {
1157                return this->OnVsync(timestamp);
1158            },
1159        };
1160        if (receiver_ != nullptr) {
1161            receiver_->RequestNextVSync(fcb);
1162            return RET_OK;
1163        }
1164    }
1165    return RET_ERR;
1166}
1167
1168void PointerDrawingManager::RenderThreadLoop()
1169{
1170    isRenderRuning_.store(true);
1171    runner_ = AppExecFwk::EventRunner::Create(false);
1172    CHKPV(runner_);
1173    handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
1174    CHKPV(handler_);
1175    auto rsClient = std::static_pointer_cast<Rosen::RSRenderServiceClient>(
1176        Rosen::RSIRenderClient::CreateRenderServiceClient());
1177    CHKPV(rsClient);
1178    receiver_ = rsClient->CreateVSyncReceiver(POINTER_CURSOR_RENDER_RECEIVER_NAME, handler_);
1179    if (receiver_ == nullptr || receiver_->Init() != VSYNC_ERROR_OK) {
1180        MMI_HILOGE("Receiver init failed");
1181        return;
1182    }
1183    if (runner_ != nullptr) {
1184        MMI_HILOGI("Runner is run");
1185        runner_->Run();
1186    }
1187}
1188#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1189
1190void PointerDrawingManager::DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)
1191{
1192    CALL_DEBUG_ENTER;
1193#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1194    CHKPV(hardwareCursorPointerManager_);
1195    if (hardwareCursorPointerManager_->IsSupported()) {
1196        return;
1197    }
1198#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1199    CHKPV(surfaceNode_);
1200    CHKPV(canvasNode_);
1201    if (mouseStyle != MOUSE_ICON::RUNNING && (mouseStyle != MOUSE_ICON::DEFAULT ||
1202            mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"))) {
1203        if (canvasNode_ != nullptr) {
1204            Rosen::RSAnimationTimingProtocol protocol;
1205            protocol.SetDuration(0);
1206            Rosen::RSNode::Animate(
1207                protocol,
1208                Rosen::RSAnimationTimingCurve::LINEAR,
1209                [this]() { canvasNode_->SetRotation(0); });
1210            Rosen::RSTransaction::FlushImplicitTransaction();
1211            canvasNode_->SetVisible(false);
1212        }
1213        MMI_HILOGE("current pointer is not running");
1214        return;
1215    }
1216    canvasNode_->SetVisible(true);
1217    float ratio = imageWidth_ * 1.0 / canvasWidth_;
1218    canvasNode_->SetPivot({RUNNING_X_RATIO * ratio, RUNNING_Y_RATIO * ratio});
1219    std::shared_ptr<OHOS::Media::PixelMap> pixelmap =
1220        DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_RIGHT].iconPath);
1221    CHKPV(pixelmap);
1222    MMI_HILOGD("Set mouseicon to OHOS system");
1223
1224#ifndef USE_ROSEN_DRAWING
1225    auto canvas = static_cast<Rosen::RSRecordingCanvas *>(canvasNode_->BeginRecording(imageWidth_, imageHeight_));
1226    canvas->DrawPixelMap(pixelmap, 0, 0, SkSamplingOptions(), nullptr);
1227#else
1228    Rosen::Drawing::Brush brush;
1229    Rosen::Drawing::Rect src = Rosen::Drawing::Rect(0, 0, pixelmap->GetWidth(), pixelmap->GetHeight());
1230    Rosen::Drawing::Rect dst = Rosen::Drawing::Rect(src);
1231    auto canvas =
1232        static_cast<Rosen::ExtendRecordingCanvas *>(canvasNode_->BeginRecording(imageWidth_, imageHeight_));
1233    canvas->AttachBrush(brush);
1234    canvas->DrawPixelMapRect(pixelmap, src, dst, Rosen::Drawing::SamplingOptions());
1235    canvas->DetachBrush();
1236#endif // USE_ROSEN_DRAWING
1237
1238    canvasNode_->FinishRecording();
1239
1240    Rosen::RSAnimationTimingProtocol protocol;
1241    protocol.SetDuration(ANIMATION_DURATION);
1242    protocol.SetRepeatCount(DEFAULT_VALUE);
1243
1244    // create property animation
1245    Rosen::RSNode::Animate(
1246        protocol,
1247        Rosen::RSAnimationTimingCurve::LINEAR,
1248        [this]() { canvasNode_->SetRotation(ROTATION_ANGLE); });
1249
1250    Rosen::RSTransaction::FlushImplicitTransaction();
1251}
1252
1253void PointerDrawingManager::AdjustMouseFocus(Direction direction, ICON_TYPE iconType,
1254    int32_t &physicalX, int32_t &physicalY)
1255{
1256    CALL_DEBUG_ENTER;
1257    switch (direction) {
1258        case DIRECTION0: {
1259            AdjustMouseFocusByDirection0(iconType, physicalX, physicalY);
1260            break;
1261        }
1262        case DIRECTION90: {
1263            AdjustMouseFocusByDirection90(iconType, physicalX, physicalY);
1264            break;
1265        }
1266        case DIRECTION180: {
1267            AdjustMouseFocusByDirection180(iconType, physicalX, physicalY);
1268            break;
1269        }
1270        case DIRECTION270: {
1271            AdjustMouseFocusByDirection270(iconType, physicalX, physicalY);
1272            break;
1273        }
1274        default: {
1275            MMI_HILOGW("direction is invalid,direction:%{public}d", direction);
1276            break;
1277        }
1278    }
1279}
1280
1281void PointerDrawingManager::AdjustMouseFocusByDirection0(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
1282{
1283    CALL_DEBUG_ENTER;
1284    int32_t height = imageHeight_;
1285    int32_t width = imageWidth_;
1286#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1287    CHKPV(hardwareCursorPointerManager_);
1288    if (hardwareCursorPointerManager_->IsSupported() &&
1289        currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1290        height = cursorHeight_;
1291        width = cursorWidth_;
1292    }
1293#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1294    switch (iconType) {
1295        case ANGLE_SW: {
1296            physicalY -= height;
1297            break;
1298        }
1299        case ANGLE_CENTER: {
1300            physicalX -= width / CALCULATE_MIDDLE;
1301            physicalY -= height / CALCULATE_MIDDLE;
1302            break;
1303        }
1304        case ANGLE_NW_RIGHT: {
1305            physicalX -= MOUSE_ICON_BAIS;
1306            [[fallthrough]];
1307        }
1308        case ANGLE_NW: {
1309            if (userIcon_ != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1310                physicalX -= userIconHotSpotX_;
1311                physicalY -= userIconHotSpotY_;
1312            }
1313            break;
1314        }
1315        default: {
1316            MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
1317            break;
1318        }
1319    }
1320}
1321
1322void PointerDrawingManager::AdjustMouseFocusByDirection90(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
1323{
1324    CALL_DEBUG_ENTER;
1325    int32_t height = imageHeight_;
1326    int32_t width = imageWidth_;
1327#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1328    CHKPV(hardwareCursorPointerManager_);
1329    if (hardwareCursorPointerManager_->IsSupported() &&
1330        currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1331        height = cursorHeight_;
1332        width = cursorWidth_;
1333    }
1334#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1335    switch (iconType) {
1336        case ANGLE_SW: {
1337            physicalY += height;
1338            break;
1339        }
1340        case ANGLE_CENTER: {
1341            physicalX -= width / CALCULATE_MIDDLE;
1342            physicalY += height / CALCULATE_MIDDLE;
1343            break;
1344        }
1345        case ANGLE_NW_RIGHT: {
1346            physicalX -= MOUSE_ICON_BAIS;
1347            [[fallthrough]];
1348        }
1349        case ANGLE_NW: {
1350            if (userIcon_ != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1351                physicalX -= userIconHotSpotX_;
1352                physicalY += userIconHotSpotY_;
1353            }
1354            break;
1355        }
1356        default: {
1357            MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
1358            break;
1359        }
1360    }
1361}
1362
1363void PointerDrawingManager::AdjustMouseFocusByDirection180(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
1364{
1365    CALL_DEBUG_ENTER;
1366    int32_t height = imageHeight_;
1367    int32_t width = imageWidth_;
1368#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1369    CHKPV(hardwareCursorPointerManager_);
1370    if (hardwareCursorPointerManager_->IsSupported() &&
1371        currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1372        height = cursorHeight_;
1373        width = cursorWidth_;
1374    }
1375#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1376    switch (iconType) {
1377        case ANGLE_SW: {
1378            physicalY += height;
1379            break;
1380        }
1381        case ANGLE_CENTER: {
1382            physicalX += width / CALCULATE_MIDDLE;
1383            physicalY += height / CALCULATE_MIDDLE;
1384            break;
1385        }
1386        case ANGLE_NW_RIGHT: {
1387            physicalX += MOUSE_ICON_BAIS;
1388            [[fallthrough]];
1389        }
1390        case ANGLE_NW: {
1391            if (userIcon_ != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1392                physicalX += userIconHotSpotX_;
1393                physicalY += userIconHotSpotY_;
1394            }
1395            break;
1396        }
1397        default: {
1398            MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
1399            break;
1400        }
1401    }
1402}
1403
1404void PointerDrawingManager::AdjustMouseFocusByDirection270(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
1405{
1406    CALL_DEBUG_ENTER;
1407    int32_t height = imageHeight_;
1408    int32_t width = imageWidth_;
1409#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1410    CHKPV(hardwareCursorPointerManager_);
1411    if (hardwareCursorPointerManager_->IsSupported() &&
1412        currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1413        height = cursorHeight_;
1414        width = cursorWidth_;
1415    }
1416#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1417    switch (iconType) {
1418        case ANGLE_SW: {
1419            physicalY -= height;
1420            break;
1421        }
1422        case ANGLE_CENTER: {
1423            physicalX += width / CALCULATE_MIDDLE;
1424            physicalY -= height / CALCULATE_MIDDLE;
1425            break;
1426        }
1427        case ANGLE_NW_RIGHT: {
1428            physicalX += MOUSE_ICON_BAIS;
1429            [[fallthrough]];
1430        }
1431        case ANGLE_NW: {
1432            if (userIcon_ != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1433                physicalX += userIconHotSpotX_;
1434                physicalY -= userIconHotSpotY_;
1435            }
1436            break;
1437        }
1438        default: {
1439            MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
1440            break;
1441        }
1442    }
1443}
1444
1445void PointerDrawingManager::SetMouseDisplayState(bool state)
1446{
1447    CALL_DEBUG_ENTER;
1448    if (mouseDisplayState_ != state) {
1449        mouseDisplayState_ = state;
1450        if (mouseDisplayState_) {
1451            InitLayer(MOUSE_ICON(lastMouseStyle_.id));
1452        }
1453        MMI_HILOGI("state:%{public}s", state ? "true" : "false");
1454        UpdatePointerVisible();
1455    }
1456}
1457
1458bool PointerDrawingManager::GetMouseDisplayState() const
1459{
1460    return mouseDisplayState_;
1461}
1462
1463bool PointerDrawingManager::IsWindowRotation()
1464{
1465    MMI_HILOGD("ROTATE_POLICY: %{public}d, FOLDABLE_DEVICE_POLICY:%{public}s",
1466        ROTATE_POLICY, FOLDABLE_DEVICE_POLICY.c_str());
1467    return (ROTATE_POLICY == WINDOW_ROTATE ||
1468        (ROTATE_POLICY == FOLDABLE_DEVICE &&
1469        ((displayInfo_.displayMode == DisplayMode::MAIN &&
1470        FOLDABLE_DEVICE_POLICY[0] == ROTATE_WINDOW_ROTATE) ||
1471        (displayInfo_.displayMode == DisplayMode::FULL &&
1472        FOLDABLE_DEVICE_POLICY[FOLDABLE_DEVICE] == ROTATE_WINDOW_ROTATE))));
1473}
1474
1475void PointerDrawingManager::FixCursorPosition(int32_t &physicalX, int32_t &physicalY)
1476{
1477    if (physicalX < 0) {
1478        physicalX = 0;
1479    }
1480
1481    if (physicalY < 0) {
1482        physicalY = 0;
1483    }
1484    const int32_t cursorUnit = 16;
1485    if (IsWindowRotation()) {
1486        if (displayInfo_.direction == DIRECTION0 || displayInfo_.direction == DIRECTION180) {
1487            if (physicalX > (displayInfo_.width - imageWidth_ / cursorUnit)) {
1488                physicalX = displayInfo_.width - imageWidth_ / cursorUnit;
1489            }
1490            if (physicalY > (displayInfo_.height - imageHeight_ / cursorUnit)) {
1491                physicalY = displayInfo_.height - imageHeight_ / cursorUnit;
1492            }
1493        } else {
1494            if (physicalX > (displayInfo_.height - imageHeight_ / cursorUnit)) {
1495                physicalX = displayInfo_.height - imageHeight_ / cursorUnit;
1496            }
1497            if (physicalY > (displayInfo_.width - imageWidth_ / cursorUnit)) {
1498                physicalY = displayInfo_.width - imageWidth_ / cursorUnit;
1499            }
1500        }
1501    } else {
1502        if (physicalX > (displayInfo_.width - imageWidth_ / cursorUnit)) {
1503            physicalX = displayInfo_.width - imageWidth_ / cursorUnit;
1504        }
1505        if (physicalY > (displayInfo_.height - imageHeight_ / cursorUnit)) {
1506            physicalY = displayInfo_.height - imageHeight_ / cursorUnit;
1507        }
1508    }
1509}
1510
1511void PointerDrawingManager::AttachToDisplay()
1512{
1513    CALL_DEBUG_ENTER;
1514    CHKPV(surfaceNode_);
1515    if (IsSingleDisplayFoldDevice() && (WIN_MGR->GetDisplayMode() == DisplayMode::MAIN)
1516        && (screenId_ == FOLD_SCREEN_ID_FULL)) {
1517        screenId_ = FOLD_SCREEN_ID_MAIN;
1518    }
1519    MMI_HILOGI("screenId_: %{public}" PRIu64"", screenId_);
1520    surfaceNode_->AttachToDisplay(screenId_);
1521}
1522
1523void PointerDrawingManager::CreateCanvasNode()
1524{
1525#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1526    CHKPV(hardwareCursorPointerManager_);
1527    CHKPV(surfaceNode_);
1528    if (!hardwareCursorPointerManager_->IsSupported()) {
1529        canvasNode_ = Rosen::RSCanvasNode::Create();
1530        CHKPV(canvasNode_);
1531        canvasNode_->SetBounds(0, 0, canvasWidth_, canvasHeight_);
1532        canvasNode_->SetFrame(0, 0, canvasWidth_, canvasHeight_);
1533#ifndef USE_ROSEN_DRAWING
1534        canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
1535#else
1536        canvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1537#endif // USE_ROSEN_DRAWING
1538        canvasNode_->SetCornerRadius(1);
1539        canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
1540        canvasNode_->SetRotation(0);
1541        surfaceNode_->AddChild(canvasNode_, DEFAULT_VALUE);
1542    }
1543#else
1544    canvasNode_ = Rosen::RSCanvasNode::Create();
1545    CHKPV(canvasNode_);
1546    canvasNode_->SetBounds(0, 0, canvasWidth_, canvasHeight_);
1547    canvasNode_->SetFrame(0, 0, canvasWidth_, canvasHeight_);
1548#ifndef USE_ROSEN_DRAWING
1549    canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
1550#else
1551    canvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1552#endif // USE_ROSEN_DRAWING
1553    canvasNode_->SetCornerRadius(1);
1554    canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
1555    canvasNode_->SetRotation(0);
1556    surfaceNode_->AddChild(canvasNode_, DEFAULT_VALUE);
1557#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1558}
1559
1560void PointerDrawingManager::CreatePointerWindow(int32_t displayId, int32_t physicalX, int32_t physicalY,
1561    Direction direction)
1562{
1563    CALL_DEBUG_ENTER;
1564    CALL_INFO_TRACE;
1565    Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
1566    surfaceNodeConfig.SurfaceNodeName = "pointer window";
1567    Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
1568    surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
1569    CHKPV(surfaceNode_);
1570    surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
1571#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1572    CHKPV(hardwareCursorPointerManager_);
1573    hardwareCursorPointerManager_->SetTargetDevice(displayId);
1574    if (g_isHdiRemoteDied) {
1575        hardwareCursorPointerManager_->SetHdiServiceState(false);
1576    }
1577    if (hardwareCursorPointerManager_->IsSupported()) {
1578        surfaceNode_->SetFrameGravity(Rosen::Gravity::TOP_LEFT);
1579        g_isHdiRemoteDied = false;
1580        CALCULATE_CANVAS_SIZE(CALCULATE_CANVAS_SIZE_, CHANGE) = GetCanvasSize();
1581        surfaceNode_->SetBounds(
1582            (physicalX - CalculateHardwareXOffset(ICON_TYPE(mouseIcons_[MOUSE_ICON(
1583                lastMouseStyle_.id)].alignmentWay))),
1584            (physicalY - CalculateHardwareYOffset(ICON_TYPE(mouseIcons_[MOUSE_ICON(
1585                lastMouseStyle_.id)].alignmentWay))),
1586            CALCULATE_CANVAS_SIZE_CHANGE,
1587            CALCULATE_CANVAS_SIZE_CHANGE);
1588    } else {
1589        surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
1590        surfaceNode_->SetBounds(physicalX, physicalY, canvasWidth_, canvasHeight_);
1591    }
1592#else
1593    surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
1594    surfaceNode_->SetBounds(physicalX, physicalY, canvasWidth_, canvasHeight_);
1595#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1596#ifndef USE_ROSEN_DRAWING
1597    surfaceNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
1598#else
1599    surfaceNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1600#endif
1601
1602    screenId_ = static_cast<uint64_t>(displayId);
1603    std::cout << "ScreenId: " << screenId_ << std::endl;
1604    AttachToDisplay();
1605    lastDisplayId_ = displayId;
1606    RotateDegree(direction);
1607    lastDirection_ = direction;
1608    CreateCanvasNode();
1609    Rosen::RSTransaction::FlushImplicitTransaction();
1610}
1611
1612sptr<OHOS::Surface> PointerDrawingManager::GetLayer()
1613{
1614    CALL_DEBUG_ENTER;
1615    CHKPP(surfaceNode_);
1616    return surfaceNode_->GetSurface();
1617}
1618
1619sptr<OHOS::SurfaceBuffer> PointerDrawingManager::GetSurfaceBuffer(sptr<OHOS::Surface> layer) const
1620{
1621    CALL_DEBUG_ENTER;
1622    sptr<OHOS::SurfaceBuffer> buffer;
1623    int32_t releaseFence = -1;
1624    int32_t width = 0;
1625    int32_t height = 0;
1626#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1627    CHKPP(hardwareCursorPointerManager_);
1628    if (g_isHdiRemoteDied) {
1629        hardwareCursorPointerManager_->SetHdiServiceState(false);
1630    }
1631    if (hardwareCursorPointerManager_->IsSupported()) {
1632        CALCULATE_CANVAS_SIZE(CALCULATE_CANVAS_SIZE_, CHANGE) = GetCanvasSize();
1633        auto canvasSize = static_cast<int32_t>(CALCULATE_CANVAS_SIZE_CHANGE);
1634        width = canvasSize;
1635        height = canvasSize;
1636    } else {
1637        width = canvasWidth_;
1638        height = canvasHeight_;
1639    }
1640#else
1641    width = canvasWidth_;
1642    height = canvasHeight_;
1643#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1644    OHOS::BufferRequestConfig config = {
1645        .width = width,
1646        .height = height,
1647        .strideAlignment = 0x8,
1648        .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
1649        .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
1650        .timeout = 150,
1651    };
1652
1653    OHOS::SurfaceError ret = layer->RequestBuffer(buffer, releaseFence, config);
1654    if (ret != OHOS::SURFACE_ERROR_OK) {
1655        MMI_HILOGE("Request buffer ret:%{public}s", SurfaceErrorStr(ret).c_str());
1656        return nullptr;
1657    }
1658#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1659    if (hardwareCursorPointerManager_->IsSupported()) {
1660        sptr<OHOS::SyncFence> tempFence = new OHOS::SyncFence(releaseFence);
1661        if (tempFence != nullptr && (tempFence->Wait(SYNC_FENCE_WAIT_TIME) < 0)) {
1662            MMI_HILOGE("Failed to create surface, this buffer is not available");
1663        }
1664    }
1665#else
1666    close(releaseFence);
1667#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1668    return buffer;
1669}
1670
1671void PointerDrawingManager::DrawDynamicImage(OHOS::Rosen::Drawing::Canvas &canvas, MOUSE_ICON mouseStyle)
1672{
1673    CALL_DEBUG_ENTER;
1674    OHOS::Rosen::Drawing::Pen pen;
1675    pen.SetAntiAlias(true);
1676    pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1677    OHOS::Rosen::Drawing::scalar penWidth = 1;
1678    pen.SetWidth(penWidth);
1679    canvas.AttachPen(pen);
1680    CHKPV(image_);
1681    OHOS::Rosen::Drawing::Brush brush;
1682    brush.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1683    canvas.DrawBackground(brush);
1684    ICON_TYPE iconType = ICON_TYPE::ANGLE_NW;
1685    if (mouseStyle == MOUSE_ICON::LOADING) {
1686        iconType = ICON_TYPE::ANGLE_CENTER;
1687    } else {
1688        iconType = ICON_TYPE::ANGLE_NW;
1689    }
1690    float physicalXOffset = CalculateHardwareXOffset(iconType);
1691    float physicalYOffset = CalculateHardwareYOffset(iconType);
1692    if (mouseStyle == MOUSE_ICON::RUNNING_RIGHT) {
1693        CHKPV(runningRightImage_);
1694        canvas.DrawImage(*runningRightImage_, physicalXOffset, physicalYOffset, Rosen::Drawing::SamplingOptions());
1695    } else {
1696        canvas.DrawImage(*image_, physicalXOffset, physicalYOffset, Rosen::Drawing::SamplingOptions());
1697    }
1698}
1699
1700void PointerDrawingManager::DrawImage(OHOS::Rosen::Drawing::Canvas &canvas, MOUSE_ICON mouseStyle)
1701{
1702    MMI_HILOGI("Draw mouse icon of style(%{public}d)", static_cast<int32_t>(mouseStyle));
1703    OHOS::Rosen::Drawing::Pen pen;
1704    pen.SetAntiAlias(true);
1705    pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1706    OHOS::Rosen::Drawing::scalar penWidth = 1;
1707    pen.SetWidth(penWidth);
1708    canvas.AttachPen(pen);
1709    std::shared_ptr<Rosen::Drawing::Image> image = nullptr;
1710    std::shared_ptr<OHOS::Media::PixelMap> pixelmap = nullptr;
1711    if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1712        MMI_HILOGD("Set mouseicon by userIcon_");
1713        image = ExtractDrawingImage(userIcon_);
1714#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1715        SetPixelMap(userIcon_);
1716#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1717    } else {
1718        if (mouseStyle == MOUSE_ICON::RUNNING) {
1719            pixelmap = DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_LEFT].iconPath);
1720        } else {
1721            pixelmap = DecodeImageToPixelMap(mouseIcons_[mouseStyle].iconPath);
1722        }
1723        CHKPV(pixelmap);
1724        image = ExtractDrawingImage(pixelmap);
1725#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1726        if ((mouseStyle == MOUSE_ICON::DEFAULT) || (mouseStyle == MOUSE_ICON::CURSOR_CIRCLE)) {
1727            SetPixelMap(pixelmap);
1728        }
1729#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1730    }
1731    CHKPV(image);
1732    OHOS::Rosen::Drawing::Brush brush;
1733    brush.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1734    canvas.DrawBackground(brush);
1735#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1736    CHKPV(hardwareCursorPointerManager_);
1737    if (hardwareCursorPointerManager_->IsSupported()) {
1738        float physicalXOffset = CalculateHardwareXOffset(ICON_TYPE(mouseIcons_[MOUSE_ICON(
1739            mouseStyle)].alignmentWay));
1740        float physicalYOffset = CalculateHardwareYOffset(ICON_TYPE(mouseIcons_[MOUSE_ICON(
1741            mouseStyle)].alignmentWay));
1742        canvas.DrawImage(*image, physicalXOffset, physicalYOffset, Rosen::Drawing::SamplingOptions());
1743    } else {
1744        canvas.DrawImage(*image, IMAGE_PIXEL, IMAGE_PIXEL, Rosen::Drawing::SamplingOptions());
1745    }
1746#else
1747    canvas.DrawImage(*image, IMAGE_PIXEL, IMAGE_PIXEL, Rosen::Drawing::SamplingOptions());
1748#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1749    MMI_HILOGD("Canvas draw image, success");
1750}
1751
1752#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1753void PointerDrawingManager::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
1754{
1755    MMI_HILOGI("Set pointer snapshot");
1756    pixelMap_ = pixelMap;
1757}
1758
1759int32_t PointerDrawingManager::GetPointerSnapshot(void *pixelMapPtr)
1760{
1761    CALL_DEBUG_ENTER;
1762    std::shared_ptr<Media::PixelMap> *newPixelMapPtr = static_cast<std::shared_ptr<Media::PixelMap> *>(pixelMapPtr);
1763    MMI_HILOGI("Get pointer snapshot");
1764    *newPixelMapPtr = pixelMap_;
1765    if (HasMagicCursor()) {
1766        MMI_HILOGE("magic pixelmap");
1767        *newPixelMapPtr = MAGIC_CURSOR->GetPixelMap();
1768    }
1769    CHKPR(*newPixelMapPtr, ERROR_NULL_POINTER);
1770    return RET_OK;
1771}
1772#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1773
1774void PointerDrawingManager::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, const MOUSE_ICON mouseStyle)
1775{
1776    CALL_DEBUG_ENTER;
1777    currentFrame_ = 0;
1778    OHOS::Rosen::Drawing::Bitmap bitmap;
1779    OHOS::Rosen::Drawing::BitmapFormat format { OHOS::Rosen::Drawing::COLORTYPE_RGBA_8888,
1780        OHOS::Rosen::Drawing::ALPHATYPE_OPAQUE };
1781    bitmap.Build(width, height, format);
1782    OHOS::Rosen::Drawing::Canvas canvas;
1783    canvas.Bind(bitmap);
1784    canvas.Clear(OHOS::Rosen::Drawing::Color::COLOR_TRANSPARENT);
1785    DrawImage(canvas, mouseStyle);
1786    static constexpr uint32_t stride = 4;
1787    uint32_t addrSize = width * height * stride;
1788    errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize);
1789    if (ret != EOK) {
1790        MMI_HILOGE("Memcpy data is error, ret:%{public}d", ret);
1791        return;
1792    }
1793}
1794
1795void PointerDrawingManager::DrawPixelmap(OHOS::Rosen::Drawing::Canvas &canvas, const MOUSE_ICON mouseStyle)
1796{
1797    CALL_DEBUG_ENTER;
1798    OHOS::Rosen::Drawing::Pen pen;
1799    pen.SetAntiAlias(true);
1800    pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1801    OHOS::Rosen::Drawing::scalar penWidth = 1;
1802    pen.SetWidth(penWidth);
1803    canvas.AttachPen(pen);
1804    if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1805        MMI_HILOGD("Set mouseicon by userIcon_");
1806        OHOS::Rosen::RSPixelMapUtil::DrawPixelMap(canvas, *userIcon_, 0, 0);
1807    } else {
1808        std::shared_ptr<OHOS::Media::PixelMap> pixelmap;
1809        if (mouseStyle == MOUSE_ICON::RUNNING) {
1810            pixelmap = DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_LEFT].iconPath);
1811        } else {
1812            pixelmap = DecodeImageToPixelMap(mouseIcons_[mouseStyle].iconPath);
1813        }
1814        CHKPV(pixelmap);
1815        MMI_HILOGD("Set mouseicon to OHOS system");
1816        OHOS::Rosen::RSPixelMapUtil::DrawPixelMap(canvas, *pixelmap, 0, 0);
1817    }
1818}
1819
1820int32_t PointerDrawingManager::SetCustomCursor(void* pixelMap, int32_t pid, int32_t windowId, int32_t focusX,
1821    int32_t focusY)
1822{
1823    CALL_DEBUG_ENTER;
1824    CHKPR(pixelMap, RET_ERR);
1825    if (pid == -1) {
1826        MMI_HILOGE("The pid is invalid");
1827        return RET_ERR;
1828    }
1829    if (windowId < 0) {
1830        MMI_HILOGE("The windowId is invalid, windowId:%{public}d", windowId);
1831        return RET_ERR;
1832    }
1833    if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1834        MMI_HILOGE("The windowId not in right pid");
1835        return RET_ERR;
1836    }
1837    int32_t ret = UpdateCursorProperty(pixelMap, focusX, focusY);
1838    if (ret != RET_OK) {
1839        MMI_HILOGE("UpdateCursorProperty is failed");
1840        return ret;
1841    }
1842    mouseIconUpdate_ = true;
1843    PointerStyle style;
1844    style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
1845    lastMouseStyle_ = style;
1846
1847    ret = SetPointerStyle(pid, windowId, style);
1848    if (ret == RET_ERR) {
1849        MMI_HILOGE("SetPointerStyle is failed");
1850    }
1851    MMI_HILOGD("style.id:%{public}d, userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
1852        style.id, userIconHotSpotX_, userIconHotSpotY_);
1853    return ret;
1854}
1855
1856int32_t PointerDrawingManager::UpdateCursorProperty(void* pixelMap, const int32_t &focusX, const int32_t &focusY)
1857{
1858    CHKPR(pixelMap, RET_ERR);
1859    Media::PixelMap* newPixelMap = static_cast<Media::PixelMap*>(pixelMap);
1860    CHKPR(newPixelMap, RET_ERR);
1861    Media::ImageInfo imageInfo;
1862    newPixelMap->GetImageInfo(imageInfo);
1863    int32_t cursorSize = GetPointerSize();
1864    cursorWidth_ =
1865        pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1866    cursorHeight_ =
1867        pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1868    cursorWidth_ = cursorWidth_ < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorWidth_;
1869    cursorHeight_ = cursorHeight_ < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorHeight_;
1870    float xAxis = (float)cursorWidth_ / (float)imageInfo.size.width;
1871    float yAxis = (float)cursorHeight_ / (float)imageInfo.size.height;
1872    newPixelMap->scale(xAxis, yAxis, Media::AntiAliasingOption::LOW);
1873    userIcon_.reset(newPixelMap);
1874    userIconHotSpotX_ = static_cast<int32_t>((float)focusX * xAxis);
1875    userIconHotSpotY_ = static_cast<int32_t>((float)focusY * yAxis);
1876    MMI_HILOGI("cursorWidth:%{public}d, cursorHeight:%{public}d, imageWidth:%{public}d, imageHeight:%{public}d,"
1877        "focusX:%{public}d, focuxY:%{public}d, xAxis:%{public}f, yAxis:%{public}f, userIconHotSpotX_:%{public}d,"
1878        "userIconHotSpotY_:%{public}d", cursorWidth_, cursorHeight_, imageInfo.size.width, imageInfo.size.height,
1879        focusX, focusY, xAxis, yAxis, userIconHotSpotX_, userIconHotSpotY_);
1880    return RET_OK;
1881}
1882
1883int32_t PointerDrawingManager::SetMouseIcon(int32_t pid, int32_t windowId, void* pixelMap)
1884    __attribute__((no_sanitize("cfi")))
1885{
1886    CALL_DEBUG_ENTER;
1887    if (pid == -1) {
1888        MMI_HILOGE("pid is invalid return -1");
1889        return RET_ERR;
1890    }
1891    CHKPR(pixelMap, RET_ERR);
1892    if (windowId < 0) {
1893        MMI_HILOGE("Get invalid windowId, %{public}d", windowId);
1894        return RET_ERR;
1895    }
1896    if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1897        MMI_HILOGE("windowId not in right pid");
1898        return RET_ERR;
1899    }
1900    OHOS::Media::PixelMap* pixelMapPtr = static_cast<OHOS::Media::PixelMap*>(pixelMap);
1901    userIcon_.reset(pixelMapPtr);
1902    mouseIconUpdate_ = true;
1903    PointerStyle style;
1904    style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
1905    int32_t ret = SetPointerStyle(pid, windowId, style);
1906    if (ret == RET_ERR) {
1907        MMI_HILOGE("SetPointerStyle return RET_ERR here");
1908    }
1909    return ret;
1910}
1911
1912int32_t PointerDrawingManager::SetMouseHotSpot(int32_t pid, int32_t windowId, int32_t hotSpotX, int32_t hotSpotY)
1913{
1914    CALL_DEBUG_ENTER;
1915    if (pid == -1) {
1916        MMI_HILOGE("pid is invalid return -1");
1917        return RET_ERR;
1918    }
1919    if (windowId < 0) {
1920        MMI_HILOGE("invalid windowId, %{public}d", windowId);
1921        return RET_ERR;
1922    }
1923    if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1924        MMI_HILOGE("windowId not in right pid");
1925        return RET_ERR;
1926    }
1927    if (hotSpotX < 0 || hotSpotY < 0 || userIcon_ == nullptr) {
1928        MMI_HILOGE("invalid value");
1929        return RET_ERR;
1930    }
1931    PointerStyle pointerStyle;
1932    WIN_MGR->GetPointerStyle(pid, windowId, pointerStyle);
1933    if (pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1934        MMI_HILOGE("Get pointer style failed, pid %{publid}d, pointerStyle %{public}d", pid, pointerStyle.id);
1935        return RET_ERR;
1936    }
1937    userIconHotSpotX_ = hotSpotX;
1938    userIconHotSpotY_ = hotSpotY;
1939    return RET_OK;
1940}
1941
1942std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::DecodeImageToPixelMap(const std::string &imagePath)
1943{
1944    CALL_DEBUG_ENTER;
1945    OHOS::Media::SourceOptions opts;
1946    uint32_t ret = 0;
1947    auto imageSource = OHOS::Media::ImageSource::CreateImageSource(imagePath, opts, ret);
1948    CHKPP(imageSource);
1949    std::set<std::string> formats;
1950    ret = imageSource->GetSupportedFormats(formats);
1951    MMI_HILOGD("Get supported format ret:%{public}u", ret);
1952
1953    OHOS::Media::DecodeOptions decodeOpts;
1954    decodeOpts.desiredSize = {
1955        .width = imageWidth_,
1956        .height = imageHeight_
1957    };
1958    int32_t pointerColor = GetPointerColor();
1959    if (tempPointerColor_ != DEFAULT_VALUE) {
1960        decodeOpts.SVGOpts.fillColor = {.isValidColor = true, .color = pointerColor};
1961        if (pointerColor == MAX_POINTER_COLOR) {
1962            decodeOpts.SVGOpts.strokeColor = {.isValidColor = true, .color = MIN_POINTER_COLOR};
1963        } else {
1964            decodeOpts.SVGOpts.strokeColor = {.isValidColor = true, .color = MAX_POINTER_COLOR};
1965        }
1966    }
1967
1968    std::shared_ptr<OHOS::Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, ret);
1969    CHKPL(pixelMap);
1970    return pixelMap;
1971}
1972
1973void PointerDrawingManager::GetPreferenceKey(std::string &name)
1974{
1975#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1976    if (HasMagicCursor()) {
1977        if (name == POINTER_COLOR) {
1978            name = MAGIC_POINTER_COLOR;
1979        } else if (name == POINTER_SIZE) {
1980            name = MAGIC_POINTER_SIZE;
1981        }
1982    }
1983#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1984}
1985
1986int32_t PointerDrawingManager::SetPointerColor(int32_t color)
1987{
1988    CALL_DEBUG_ENTER;
1989    if (surfaceNode_ != nullptr) {
1990        float alphaRatio = (static_cast<uint32_t>(color) >> RGB_CHANNEL_BITS_LENGTH) / MAX_ALPHA_VALUE;
1991        if (alphaRatio > 1) {
1992            MMI_HILOGW("Invalid alphaRatio:%{public}f", alphaRatio);
1993        } else {
1994            surfaceNode_->SetAlpha(1 - alphaRatio);
1995        }
1996    }
1997    MMI_HILOGI("PointerColor:%{public}x", color);
1998    // ARGB从表面看比RGB多了个A,也是一种色彩模式,是在RGB的基础上添加了Alpha(透明度)通道。
1999    // 透明度也是以0到255表示的,所以也是总共有256级,透明是0,不透明是255。
2000    // 这个color每8位代表一个通道值,分别是alpha和rgb,总共32位。
2001    color = static_cast<int32_t>(static_cast<uint32_t>(color) & static_cast<uint32_t>(MAX_POINTER_COLOR));
2002    std::string name = POINTER_COLOR;
2003    GetPreferenceKey(name);
2004    int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, color);
2005    if (ret != RET_OK) {
2006        MMI_HILOGE("Set pointer color failed, color:%{public}d", color);
2007        return ret;
2008    }
2009    MMI_HILOGD("Set pointer color successfully, color:%{public}d", color);
2010#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2011    if (HasMagicCursor()) {
2012        ret = MAGIC_CURSOR->SetPointerColor(color);
2013    } else {
2014        ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
2015    }
2016#else
2017    ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
2018#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2019    if (ret != RET_OK) {
2020        MMI_HILOGE("Init layer failed");
2021        return RET_ERR;
2022    }
2023    UpdatePointerVisible();
2024    SetHardwareCursorPosition(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, lastMouseStyle_);
2025    return RET_OK;
2026}
2027
2028int32_t PointerDrawingManager::GetPointerColor()
2029{
2030    CALL_DEBUG_ENTER;
2031    std::string name = POINTER_COLOR;
2032    GetPreferenceKey(name);
2033    int32_t pointerColor = PREFERENCES_MGR->GetIntValue(name, DEFAULT_VALUE);
2034    tempPointerColor_ = pointerColor;
2035    if (pointerColor == DEFAULT_VALUE) {
2036        pointerColor = MIN_POINTER_COLOR;
2037    }
2038    MMI_HILOGD("Get pointer color successfully, pointerColor:%{public}d", pointerColor);
2039    return pointerColor;
2040}
2041
2042void PointerDrawingManager::UpdateDisplayInfo(const DisplayInfo &displayInfo)
2043{
2044    CALL_DEBUG_ENTER;
2045#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2046    CHKPV(hardwareCursorPointerManager_);
2047    hardwareCursorPointerManager_->SetTargetDevice(displayInfo.id);
2048#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2049    hasDisplay_ = true;
2050    displayInfo_ = displayInfo;
2051    int32_t size = GetPointerSize();
2052    imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * GetIndependentPixels() / BASELINE_DENSITY;
2053    imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * GetIndependentPixels() / BASELINE_DENSITY;
2054    canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
2055    canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
2056#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2057    MAGIC_CURSOR->SetDisplayInfo(displayInfo);
2058#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2059}
2060
2061int32_t PointerDrawingManager::GetIndependentPixels()
2062{
2063    CALL_DEBUG_ENTER;
2064#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2065    if (HasMagicCursor()) {
2066        return MAGIC_INDEPENDENT_PIXELS;
2067    } else {
2068        return DEVICE_INDEPENDENT_PIXELS;
2069    }
2070#else
2071    return DEVICE_INDEPENDENT_PIXELS;
2072#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2073}
2074
2075int32_t PointerDrawingManager::SetPointerSize(int32_t size)
2076{
2077    CALL_DEBUG_ENTER;
2078    if (size < MIN_POINTER_SIZE) {
2079        size = MIN_POINTER_SIZE;
2080    } else if (size > MAX_POINTER_SIZE) {
2081        size = MAX_POINTER_SIZE;
2082    }
2083    std::string name = POINTER_SIZE;
2084    GetPreferenceKey(name);
2085    int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, size);
2086    if (ret != RET_OK) {
2087        MMI_HILOGE("Set pointer size failed, code:%{public}d", ret);
2088        return ret;
2089    }
2090
2091    CHKPR(surfaceNode_, RET_OK);
2092    imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
2093    imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
2094    canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
2095    canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
2096    int32_t physicalX = lastPhysicalX_;
2097    int32_t physicalY = lastPhysicalY_;
2098#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2099    MAGIC_CURSOR->SetPointerSize(imageWidth_, imageHeight_);
2100#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2101    Direction direction = DIRECTION0;
2102    if (IsWindowRotation()) {
2103        direction = displayInfo_.direction;
2104    }
2105    auto& iconPath = GetMouseIconPath();
2106    AdjustMouseFocus(direction, ICON_TYPE(iconPath.at(MOUSE_ICON(lastMouseStyle_.id)).alignmentWay),
2107        physicalX, physicalY);
2108#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2109    if (HasMagicCursor()) {
2110        MAGIC_CURSOR->CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction, surfaceNode_);
2111    } else {
2112        CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
2113    }
2114#else
2115    CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
2116#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2117    if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
2118        MMI_HILOGE("Init layer failed");
2119        return RET_ERR;
2120    }
2121    UpdatePointerVisible();
2122    SetHardwareCursorPosition(displayInfo_.id, physicalX, physicalY, lastMouseStyle_);
2123    return RET_OK;
2124}
2125
2126int32_t PointerDrawingManager::GetPointerSize()
2127{
2128    CALL_DEBUG_ENTER;
2129    std::string name = POINTER_SIZE;
2130    GetPreferenceKey(name);
2131    int32_t pointerSize = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_SIZE);
2132    MMI_HILOGD("Get pointer size successfully, pointerSize:%{public}d", pointerSize);
2133    return pointerSize;
2134}
2135
2136void PointerDrawingManager::OnDisplayInfo(const DisplayGroupInfo &displayGroupInfo)
2137{
2138    CALL_DEBUG_ENTER;
2139    for (const auto& item : displayGroupInfo.displaysInfo) {
2140        if (item.id == displayInfo_.id) {
2141            UpdateDisplayInfo(item);
2142            DrawManager();
2143            return;
2144        }
2145    }
2146    UpdateDisplayInfo(displayGroupInfo.displaysInfo[0]);
2147    lastPhysicalX_ = displayGroupInfo.displaysInfo[0].width / CALCULATE_MIDDLE;
2148    lastPhysicalY_ = displayGroupInfo.displaysInfo[0].height / CALCULATE_MIDDLE;
2149    MouseEventHdr->OnDisplayLost(displayInfo_.id);
2150    if (surfaceNode_ != nullptr) {
2151        surfaceNode_->DetachToDisplay(screenId_);
2152#ifndef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2153        surfaceNode_ = nullptr;
2154#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2155        Rosen::RSTransaction::FlushImplicitTransaction();
2156        MMI_HILOGD("Pointer window destroy success");
2157    }
2158    MMI_HILOGD("displayId_:%{public}d, displayWidth_:%{public}d, displayHeight_:%{public}d",
2159        displayInfo_.id, displayInfo_.width, displayInfo_.height);
2160}
2161
2162void PointerDrawingManager::OnWindowInfo(const WinInfo &info)
2163{
2164    CALL_DEBUG_ENTER;
2165    if (pid_ != info.windowPid) {
2166        windowId_ = info.windowId;
2167        pid_ = info.windowPid;
2168        UpdatePointerVisible();
2169    }
2170}
2171
2172void PointerDrawingManager::UpdatePointerDevice(bool hasPointerDevice, bool isPointerVisible,
2173    bool isHotPlug)
2174{
2175    CALL_DEBUG_ENTER;
2176    MMI_HILOGD("hasPointerDevice:%{public}s, isPointerVisible:%{public}s",
2177        hasPointerDevice ? "true" : "false", isPointerVisible? "true" : "false");
2178    hasPointerDevice_ = hasPointerDevice;
2179    if (hasPointerDevice_) {
2180        bool pointerVisible = isPointerVisible;
2181        if (!isHotPlug) {
2182            pointerVisible = (pointerVisible && IsPointerVisible());
2183        }
2184        SetPointerVisible(getpid(), pointerVisible, 0, false);
2185    } else {
2186        DeletePointerVisible(getpid());
2187    }
2188    DrawManager();
2189    if (!hasPointerDevice_ && surfaceNode_ != nullptr) {
2190        MMI_HILOGD("Pointer window destroy start");
2191        surfaceNode_->DetachToDisplay(screenId_);
2192        surfaceNode_ = nullptr;
2193        Rosen::RSTransaction::FlushImplicitTransaction();
2194        MMI_HILOGD("Pointer window destroy success");
2195    }
2196}
2197
2198void PointerDrawingManager::DrawManager()
2199{
2200    CALL_DEBUG_ENTER;
2201#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2202    if (HasMagicCursor() && lastDrawPointerStyle_.id != currentMouseStyle_.id
2203        && (lastDrawPointerStyle_.id == DEVELOPER_DEFINED_ICON
2204        || currentMouseStyle_.id == DEVELOPER_DEFINED_ICON)) {
2205        if (surfaceNode_ != nullptr) {
2206            surfaceNode_->DetachToDisplay(screenId_);
2207            surfaceNode_ = nullptr;
2208            Rosen::RSTransaction::FlushImplicitTransaction();
2209        }
2210    }
2211#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2212    if (hasDisplay_ && hasPointerDevice_ && surfaceNode_ == nullptr) {
2213        MMI_HILOGD("Draw pointer begin");
2214        PointerStyle pointerStyle;
2215        WIN_MGR->GetPointerStyle(pid_, windowId_, pointerStyle);
2216        MMI_HILOGD("Get pid %{publid}d with pointerStyle %{public}d", pid_, pointerStyle.id);
2217        Direction direction = DIRECTION0;
2218        if (IsWindowRotation()) {
2219            direction = displayInfo_.direction;
2220        }
2221        lastDrawPointerStyle_ = pointerStyle;
2222        if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
2223            DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
2224                pointerStyle, direction);
2225            MMI_HILOGD("Draw manager, mouseStyle:%{public}d, last physical is initial value", pointerStyle.id);
2226            return;
2227        }
2228        DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
2229        MMI_HILOGD("Draw manager, mouseStyle:%{public}d", pointerStyle.id);
2230        return;
2231    }
2232}
2233
2234bool PointerDrawingManager::Init()
2235{
2236    CALL_DEBUG_ENTER;
2237    INPUT_DEV_MGR->Attach(shared_from_this());
2238    pidInfos_.clear();
2239    hapPidInfos_.clear();
2240    return true;
2241}
2242
2243std::shared_ptr<IPointerDrawingManager> IPointerDrawingManager::GetInstance()
2244{
2245    if (iPointDrawMgr_ == nullptr) {
2246        iPointDrawMgr_ = std::make_shared<PointerDrawingManager>();
2247    }
2248    return iPointDrawMgr_;
2249}
2250
2251void PointerDrawingManager::UpdatePointerVisible()
2252{
2253    CALL_DEBUG_ENTER;
2254    CHKPV(surfaceNode_);
2255    if (IsPointerVisible() && mouseDisplayState_) {
2256        surfaceNode_->SetVisible(true);
2257        MMI_HILOGI("Pointer window show success, mouseDisplayState_:%{public}s",
2258            mouseDisplayState_ ? "true" : "false");
2259    } else {
2260        surfaceNode_->SetVisible(false);
2261        MMI_HILOGI("Pointer window hide success, mouseDisplayState_:%{public}s",
2262            mouseDisplayState_ ? "true" : "false");
2263    }
2264    Rosen::RSTransaction::FlushImplicitTransaction();
2265}
2266
2267bool PointerDrawingManager::IsPointerVisible()
2268{
2269    CALL_DEBUG_ENTER;
2270    if (!pidInfos_.empty()) {
2271        auto info = pidInfos_.back();
2272        if (!info.visible) {
2273            MMI_HILOGI("High priority visible property:%{public}zu.%{public}d-visible:%{public}s",
2274                pidInfos_.size(), info.pid, info.visible?"true":"false");
2275            return info.visible;
2276        }
2277    }
2278    if (!hapPidInfos_.empty()) {
2279        for (auto& item : hapPidInfos_) {
2280            if (item.pid == pid_) {
2281                MMI_HILOGI("Visible pid:%{public}d-visible:%{public}s",
2282                    item.pid, item.visible ? "true" : "false");
2283                return item.visible;
2284            }
2285        }
2286        if (!(INPUT_DEV_MGR->HasPointerDevice() || WIN_MGR->IsMouseSimulate()) || pid_ == 0) {
2287            auto info = hapPidInfos_.back();
2288            MMI_HILOGI("Only hap visible pid:%{public}d-visible:%{public}s",
2289                info.pid, info.visible ? "true" : "false");
2290            return info.visible;
2291        }
2292    }
2293    if (pidInfos_.empty()) {
2294        MMI_HILOGD("Visible property is true");
2295        return true;
2296    }
2297    auto info = pidInfos_.back();
2298    MMI_HILOGI("Visible property:%{public}zu.%{public}d-visible:%{public}s",
2299        pidInfos_.size(), info.pid, info.visible ? "true" : "false");
2300    return info.visible;
2301}
2302
2303void PointerDrawingManager::DeletePointerVisible(int32_t pid)
2304{
2305    CALL_DEBUG_ENTER;
2306    MMI_HILOGI("g_isRsRemoteDied:%{public}d", g_isRsRemoteDied ? 1 : 0);
2307    if (g_isRsRemoteDied && surfaceNode_ != nullptr) {
2308        g_isRsRemoteDied = false;
2309        surfaceNode_->DetachToDisplay(screenId_);
2310        surfaceNode_ = nullptr;
2311        Rosen::RSTransaction::FlushImplicitTransaction();
2312    }
2313    if (pidInfos_.empty()) {
2314        return;
2315    }
2316    auto it = pidInfos_.begin();
2317    for (; it != pidInfos_.end(); ++it) {
2318        if (it->pid == pid) {
2319            pidInfos_.erase(it);
2320            break;
2321        }
2322    }
2323    if (it != pidInfos_.end()) {
2324        if (IsPointerVisible()) {
2325            InitLayer(MOUSE_ICON(lastMouseStyle_.id));
2326        }
2327        UpdatePointerVisible();
2328    }
2329}
2330
2331bool PointerDrawingManager::GetPointerVisible(int32_t pid)
2332{
2333    bool ret = true;
2334    int32_t count = 0;
2335    for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
2336        if (it->pid == pid) {
2337            count++;
2338            ret = it->visible;
2339            break;
2340        }
2341    }
2342    if (count == 0 && !hapPidInfos_.empty()) {
2343        for (auto& item : hapPidInfos_) {
2344            if (item.pid == pid_) {
2345                MMI_HILOGI("Visible pid:%{public}d-visible:%{public}s",
2346                    item.pid, item.visible ? "true" : "false");
2347                count++;
2348                ret = item.visible;
2349                break;
2350            }
2351        }
2352    }
2353    return ret;
2354}
2355
2356void PointerDrawingManager::OnSessionLost(int32_t pid)
2357{
2358    for (auto it = hapPidInfos_.begin(); it != hapPidInfos_.end(); ++it) {
2359        if (it->pid == pid) {
2360            hapPidInfos_.erase(it);
2361            break;
2362        }
2363    }
2364}
2365
2366int32_t PointerDrawingManager::SetPointerVisible(int32_t pid, bool visible, int32_t priority, bool isHap)
2367{
2368    MMI_HILOGI("pid:%{public}d,visible:%{public}s,priority:%{public}d,isHap:%{public}s", pid,
2369        visible ? "true" : "false", priority, isHap ? "true" : "false");
2370    if (isHap) {
2371        for (auto it = hapPidInfos_.begin(); it != hapPidInfos_.end(); ++it) {
2372            if (it->pid == pid) {
2373                hapPidInfos_.erase(it);
2374                break;
2375            }
2376        }
2377        PidInfo info = { .pid = pid, .visible = visible };
2378        hapPidInfos_.push_back(info);
2379        if (hapPidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
2380            hapPidInfos_.pop_front();
2381        }
2382        UpdatePointerVisible();
2383        return RET_OK;
2384    }
2385    if (WIN_MGR->GetExtraData().appended && visible && priority == 0) {
2386        MMI_HILOGE("current is drag state, can not set pointer visible");
2387        return RET_ERR;
2388    }
2389    for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
2390        if (it->pid == pid) {
2391            pidInfos_.erase(it);
2392            break;
2393        }
2394    }
2395    PidInfo info = { .pid = pid, .visible = visible };
2396    pidInfos_.push_back(info);
2397    if (pidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
2398        pidInfos_.pop_front();
2399    }
2400    UpdatePointerVisible();
2401    return RET_OK;
2402}
2403
2404void PointerDrawingManager::SetPointerLocation(int32_t x, int32_t y)
2405{
2406    CALL_DEBUG_ENTER;
2407    FixCursorPosition(x, y);
2408    lastPhysicalX_ = x;
2409    lastPhysicalY_ = y;
2410    MMI_HILOGD("Pointer window move, x:%{public}d, y:%{public}d", lastPhysicalX_, lastPhysicalY_);
2411    CHKPV(surfaceNode_);
2412#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2413    CHKPV(hardwareCursorPointerManager_);
2414    if (g_isHdiRemoteDied) {
2415        hardwareCursorPointerManager_->SetHdiServiceState(false);
2416    }
2417    if (hardwareCursorPointerManager_->IsSupported()) {
2418        if (!SetTraditionsHardWareCursorLocation(displayId_, x, y,
2419            ICON_TYPE(mouseIcons_[MOUSE_ICON(lastMouseStyle_.id)].alignmentWay))) {
2420            MMI_HILOGE("Set hardware cursor position fail");
2421            return;
2422        }
2423    }
2424#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2425    MMI_HILOGD("Pointer window move success");
2426}
2427
2428int32_t PointerDrawingManager::UpdateDefaultPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle,
2429    bool isUiExtension)
2430{
2431    if (windowId != GLOBAL_WINDOW_ID) {
2432        MMI_HILOGD("No need to change the default icon style");
2433        return RET_OK;
2434    }
2435    PointerStyle style;
2436    WIN_MGR->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style, isUiExtension);
2437    if (pointerStyle.id != style.id) {
2438        auto iconPath = GetMouseIconPath();
2439        auto it = iconPath.find(MOUSE_ICON(MOUSE_ICON::DEFAULT));
2440        if (it == iconPath.end()) {
2441            MMI_HILOGE("Cannot find the default style");
2442            return RET_ERR;
2443        }
2444        std::string newIconPath;
2445        if (pointerStyle.id == MOUSE_ICON::DEFAULT) {
2446            newIconPath = DefaultIconPath;
2447        } else {
2448            newIconPath = iconPath.at(MOUSE_ICON(pointerStyle.id)).iconPath;
2449        }
2450        MMI_HILOGD("Default path has changed from %{public}s to %{public}s",
2451            it->second.iconPath.c_str(), newIconPath.c_str());
2452        UpdateIconPath(MOUSE_ICON(MOUSE_ICON::DEFAULT), newIconPath);
2453    }
2454    lastMouseStyle_ = style;
2455    return RET_OK;
2456}
2457
2458const std::map<MOUSE_ICON, IconStyle>& PointerDrawingManager::GetMouseIconPath()
2459{
2460    CALL_DEBUG_ENTER;
2461#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2462    if (HasMagicCursor()) {
2463        MMI_HILOGD("Magiccurosr get magic mouse map");
2464        return MAGIC_CURSOR->magicMouseIcons_;
2465    } else {
2466        MMI_HILOGD("Magiccurosr get mouse icon, HasMagicCursor is false");
2467        return mouseIcons_;
2468    }
2469#else
2470    return mouseIcons_;
2471#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2472}
2473
2474IconStyle PointerDrawingManager::GetIconStyle(const MOUSE_ICON mouseStyle)
2475{
2476    std::map<MOUSE_ICON, IconStyle> mouseIcons = GetMouseIcons();
2477    auto iter = mouseIcons.find(mouseStyle);
2478    if (iter == mouseIcons.end()) {
2479        MMI_HILOGE("Cannot find the mouseStyle:%{public}d", static_cast<int32_t>(mouseStyle));
2480        return IconStyle();
2481    }
2482    return iter->second;
2483}
2484
2485std::map<MOUSE_ICON, IconStyle>& PointerDrawingManager::GetMouseIcons()
2486{
2487#ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2488    if (HasMagicCursor()) {
2489        MMI_HILOGD("Magiccurosr get magic mouse map");
2490        return MAGIC_CURSOR->magicMouseIcons_;
2491    } else {
2492        MMI_HILOGD("Magiccurosr get mouse icon, HasMagicCursor is false");
2493        return mouseIcons_;
2494    }
2495#else
2496    return mouseIcons_;
2497#endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2498}
2499
2500void PointerDrawingManager::UpdateIconPath(const MOUSE_ICON mouseStyle, std::string iconPath)
2501{
2502    auto iter = mouseIcons_.find(mouseStyle);
2503    if (iter == mouseIcons_.end()) {
2504        MMI_HILOGE("Cannot find the mouseStyle:%{public}d", static_cast<int32_t>(mouseStyle));
2505        return;
2506    }
2507    iter->second.iconPath = iconPath;
2508}
2509
2510int32_t PointerDrawingManager::SetPointerStylePreference(PointerStyle pointerStyle)
2511{
2512    CALL_DEBUG_ENTER;
2513    std::string name = "pointerStyle";
2514    int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, pointerStyle.id);
2515    if (ret == RET_OK) {
2516        MMI_HILOGE("Set pointer style successfully, style:%{public}d", pointerStyle.id);
2517    }
2518    return RET_OK;
2519}
2520
2521bool PointerDrawingManager::CheckPointerStyleParam(int32_t windowId, PointerStyle pointerStyle)
2522{
2523    CALL_DEBUG_ENTER;
2524    if (windowId < -1) {
2525        return false;
2526    }
2527    if ((pointerStyle.id < MOUSE_ICON::DEFAULT && pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) ||
2528        pointerStyle.id > MOUSE_ICON::RUNNING_RIGHT) {
2529        return false;
2530    }
2531    return true;
2532}
2533
2534int32_t PointerDrawingManager::SetPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle,
2535    bool isUiExtension)
2536{
2537    CALL_DEBUG_ENTER;
2538    if (!CheckPointerStyleParam(windowId, pointerStyle)) {
2539        MMI_HILOGE("PointerStyle param is invalid");
2540        return RET_ERR;
2541    }
2542    if (windowId == GLOBAL_WINDOW_ID) {
2543        int32_t ret = SetPointerStylePreference(pointerStyle);
2544        if (ret != RET_OK) {
2545            MMI_HILOGE("Set style preference is failed, ret:%{public}d", ret);
2546            return RET_ERR;
2547        }
2548    }
2549    auto& iconPath = GetMouseIconPath();
2550    if (iconPath.find(MOUSE_ICON(pointerStyle.id)) == iconPath.end()) {
2551        MMI_HILOGE("The param pointerStyle is invalid");
2552        return RET_ERR;
2553    }
2554    if (UpdateDefaultPointerStyle(pid, windowId, pointerStyle) != RET_OK) {
2555        MMI_HILOGE("Update default pointer iconPath failed");
2556        return RET_ERR;
2557    }
2558    if (WIN_MGR->SetPointerStyle(pid, windowId, pointerStyle, isUiExtension) != RET_OK) {
2559        MMI_HILOGE("Set pointer style failed");
2560        return RET_ERR;
2561    }
2562    if (!INPUT_DEV_MGR->HasPointerDevice() && !WIN_MGR->IsMouseSimulate()) {
2563        MMI_HILOGD("The pointer device is not exist");
2564        return RET_OK;
2565    }
2566    if (!WIN_MGR->IsNeedRefreshLayer(windowId)) {
2567        MMI_HILOGD("Not need refresh layer, window type:%{public}d, pointer style:%{public}d",
2568            windowId, pointerStyle.id);
2569        return RET_OK;
2570    }
2571    if (windowId != GLOBAL_WINDOW_ID && (pointerStyle.id == MOUSE_ICON::DEFAULT &&
2572        iconPath.at(MOUSE_ICON(pointerStyle.id)).iconPath != DefaultIconPath)) {
2573        PointerStyle style;
2574        WIN_MGR->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style);
2575        pointerStyle = style;
2576    }
2577    if (windowId == windowId_ || windowId == GLOBAL_WINDOW_ID) {
2578        // Draw mouse style only when the current window is the top-level window
2579        if (!WIN_MGR->SelectPointerChangeArea(windowId, lastPhysicalX_ + displayInfo_.x,
2580            lastPhysicalY_ + displayInfo_.y)) {
2581            DrawPointerStyle(pointerStyle);
2582        } else {
2583            MMI_HILOGW("skip the pointerstyle");
2584        }
2585    } else {
2586        MMI_HILOGW("set windowid:%{public}d, top windowid:%{public}d, dont draw pointer", windowId, windowId_);
2587    }
2588    MMI_HILOGI("Window id:%{public}d set pointer style:%{public}d success", windowId, pointerStyle.id);
2589    return RET_OK;
2590}
2591
2592int32_t PointerDrawingManager::GetPointerStyle(int32_t pid, int32_t windowId, PointerStyle &pointerStyle,
2593    bool isUiExtension)
2594{
2595    CALL_DEBUG_ENTER;
2596    if (windowId == GLOBAL_WINDOW_ID) {
2597        std::string name = POINTER_COLOR;
2598        pointerStyle.color = PREFERENCES_MGR->GetIntValue(name, DEFAULT_VALUE);
2599        name = POINTER_SIZE;
2600        pointerStyle.size = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_SIZE);
2601        name = "pointerStyle";
2602        int32_t style = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_STYLE);
2603        MMI_HILOGD("Get pointer style successfully, pointerStyle:%{public}d", style);
2604        if (style == CURSOR_CIRCLE_STYLE) {
2605            pointerStyle.id = style;
2606            return RET_OK;
2607        }
2608    }
2609    WIN_MGR->GetPointerStyle(pid, windowId, pointerStyle, isUiExtension);
2610    MMI_HILOGD("Window id:%{public}d get pointer style:%{public}d success", windowId, pointerStyle.id);
2611    return RET_OK;
2612}
2613
2614int32_t PointerDrawingManager::ClearWindowPointerStyle(int32_t pid, int32_t windowId)
2615{
2616    CALL_DEBUG_ENTER;
2617    return WIN_MGR->ClearWindowPointerStyle(pid, windowId);
2618}
2619
2620void PointerDrawingManager::DrawPointerStyle(const PointerStyle& pointerStyle)
2621{
2622    CALL_DEBUG_ENTER;
2623    bool simulate = WIN_MGR->IsMouseSimulate();
2624    if (hasDisplay_ && (hasPointerDevice_ || simulate)) {
2625        if (surfaceNode_ != nullptr) {
2626            AttachToDisplay();
2627            Rosen::RSTransaction::FlushImplicitTransaction();
2628        }
2629        Direction direction = DIRECTION0;
2630        if (IsWindowRotation()) {
2631            direction = displayInfo_.direction;
2632        }
2633        if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
2634            DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
2635                pointerStyle, direction);
2636            MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
2637            return;
2638        }
2639
2640        DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
2641        MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
2642    }
2643}
2644
2645void PointerDrawingManager::CheckMouseIconPath()
2646{
2647    for (auto iter = mouseIcons_.begin(); iter != mouseIcons_.end();) {
2648        if ((ReadCursorStyleFile(iter->second.iconPath)) != RET_OK) {
2649            iter = mouseIcons_.erase(iter);
2650            continue;
2651        }
2652        ++iter;
2653    }
2654}
2655
2656int32_t PointerDrawingManager::EnableHardwareCursorStats(int32_t pid, bool enable)
2657{
2658    CALL_DEBUG_ENTER;
2659#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2660    CHKPR(hardwareCursorPointerManager_, ERROR_NULL_POINTER);
2661    if (g_isHdiRemoteDied) {
2662        hardwareCursorPointerManager_->SetHdiServiceState(false);
2663    }
2664    if (hardwareCursorPointerManager_->IsSupported()) {
2665        if ((hardwareCursorPointerManager_->EnableStats(enable)) != RET_OK) {
2666            MMI_HILOGE("Enable stats failed");
2667            return RET_ERR;
2668        }
2669    }
2670#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2671    MMI_HILOGI("EnableHardwareCursorStats, enable:%{private}d", enable);
2672    return RET_OK;
2673}
2674
2675int32_t PointerDrawingManager::GetHardwareCursorStats(int32_t pid, uint32_t &frameCount, uint32_t &vsyncCount)
2676{
2677    CALL_DEBUG_ENTER;
2678#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2679    CHKPR(hardwareCursorPointerManager_, ERROR_NULL_POINTER);
2680    if (g_isHdiRemoteDied) {
2681        hardwareCursorPointerManager_->SetHdiServiceState(false);
2682    }
2683    if (hardwareCursorPointerManager_->IsSupported()) {
2684        if ((hardwareCursorPointerManager_->GetCursorStats(frameCount, vsyncCount)) != RET_OK) {
2685            MMI_HILOGE("Query stats failed");
2686            return RET_ERR;
2687        }
2688    }
2689#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2690    MMI_HILOGI("GetHardwareCursorStats, frameCount:%{private}d, vsyncCount:%{private}d", frameCount, vsyncCount);
2691    return RET_OK;
2692}
2693
2694void PointerDrawingManager::InitStyle()
2695{
2696    CALL_DEBUG_ENTER;
2697    mouseIcons_ = {
2698        {DEFAULT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
2699        {EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "East.svg"}},
2700        {WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West.svg"}},
2701        {SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South.svg"}},
2702        {NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North.svg"}},
2703        {WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West_East.svg"}},
2704        {NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_South.svg"}},
2705        {NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East.svg"}},
2706        {NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West.svg"}},
2707        {SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_East.svg"}},
2708        {SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_West.svg"}},
2709        {NORTH_EAST_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East_South_West.svg"}},
2710        {NORTH_WEST_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West_South_East.svg"}},
2711        {CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cross.svg"}},
2712        {CURSOR_COPY, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Copy.svg"}},
2713        {CURSOR_FORBID, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Forbid.svg"}},
2714        {COLOR_SUCKER, {ANGLE_SW, IMAGE_POINTER_DEFAULT_PATH + "Colorsucker.svg"}},
2715        {HAND_GRABBING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Grabbing.svg"}},
2716        {HAND_OPEN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Open.svg"}},
2717        {HAND_POINTING, {ANGLE_NW_RIGHT, IMAGE_POINTER_DEFAULT_PATH + "Hand_Pointing.svg"}},
2718        {HELP, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Help.svg"}},
2719        {CURSOR_MOVE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Move.svg"}},
2720        {RESIZE_LEFT_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Left_Right.svg"}},
2721        {RESIZE_UP_DOWN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Up_Down.svg"}},
2722        {SCREENSHOT_CHOOSE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cross.svg"}},
2723        {SCREENSHOT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cursor.png"}},
2724        {TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Text_Cursor.svg"}},
2725        {ZOOM_IN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_In.svg"}},
2726        {ZOOM_OUT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_Out.svg"}},
2727        {MIDDLE_BTN_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_East.svg"}},
2728        {MIDDLE_BTN_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_West.svg"}},
2729        {MIDDLE_BTN_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South.svg"}},
2730        {MIDDLE_BTN_NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North.svg"}},
2731        {MIDDLE_BTN_NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_South.svg"}},
2732        {MIDDLE_BTN_NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_East.svg"}},
2733        {MIDDLE_BTN_NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_West.svg"}},
2734        {MIDDLE_BTN_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_East.svg"}},
2735        {MIDDLE_BTN_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_West.svg"}},
2736        {MIDDLE_BTN_NORTH_SOUTH_WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH +
2737            "MID_Btn_North_South_West_East.svg"}},
2738        {HORIZONTAL_TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Horizontal_Text_Cursor.svg"}},
2739        {CURSOR_CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Cross.svg"}},
2740        {CURSOR_CIRCLE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png"}},
2741        {LOADING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"}},
2742        {RUNNING, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
2743        {RUNNING_LEFT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
2744        {RUNNING_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading_Right.svg"}},
2745        {DEVELOPER_DEFINED_ICON, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
2746    };
2747    CheckMouseIconPath();
2748#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2749    std::string productType = OHOS::system::GetParameter("const.build.product", "HYM");
2750    if (productType == DEVICE_TYPE_HARDEN) {
2751        renderThread_ = std::make_unique<std::thread>([this] { this->RenderThreadLoop(); });
2752    }
2753#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2754}
2755
2756void PointerDrawingManager::RotateDegree(Direction direction)
2757{
2758    CHKPV(surfaceNode_);
2759    surfaceNode_->SetPivot(0, 0);
2760    float degree = (static_cast<int>(DIRECTION0) - static_cast<int>(direction)) * ROTATION_ANGLE90;
2761    surfaceNode_->SetRotation(degree);
2762}
2763
2764int32_t PointerDrawingManager::SkipPointerLayer(bool isSkip)
2765{
2766    CALL_INFO_TRACE;
2767    if (surfaceNode_ != nullptr) {
2768        surfaceNode_->SetSkipLayer(isSkip);
2769    }
2770    return RET_OK;
2771}
2772
2773void PointerDrawingManager::Dump(int32_t fd, const std::vector<std::string> &args)
2774{
2775    CALL_DEBUG_ENTER;
2776    std::ostringstream oss;
2777    oss << std::endl;
2778
2779    std::vector<std::string> displayTitles = {"ID", "X", "Y", "Width", "Height", "DPI", "Name", "Uniq",
2780                                              "Direction", "Display Direction", "Display Mode"};
2781    DisplayInfo &di = displayInfo_;
2782    std::vector<std::vector<std::string>> displayInfo = {
2783        {std::to_string(di.id), std::to_string(di.x), std::to_string(di.y), std::to_string(di.width),
2784         std::to_string(di.height), std::to_string(di.dpi), di.name, di.uniq,
2785         std::to_string(static_cast<int32_t>(di.direction)), std::to_string(static_cast<int32_t>(di.displayDirection)),
2786         std::to_string(static_cast<int32_t>(di.displayMode))}};
2787
2788    DumpFullTable(oss, "Display Info", displayTitles, displayInfo);
2789    oss << std::endl;
2790
2791    std::vector<std::string> titles1 = {"hasDisplay", "hasPointerDevice", "lastPhysicalX", "lastPhysicalY",
2792                                        "pid", "windowId", "imageWidth", "imageHeight", "canvasWidth", "canvasHeight"};
2793    std::vector<std::vector<std::string>> data1 = {
2794        {std::to_string(hasDisplay_), std::to_string(hasPointerDevice_), std::to_string(lastPhysicalX_),
2795         std::to_string(lastPhysicalY_), std::to_string(pid_), std::to_string(windowId_),
2796         std::to_string(imageWidth_), std::to_string(imageHeight_), std::to_string(canvasWidth_),
2797         std::to_string(canvasHeight_)}};
2798
2799    DumpFullTable(oss, "Cursor Info", titles1, data1);
2800    oss << std::endl;
2801
2802    std::vector<std::string> titles2 = {"mouseDisplayState", "mouseIconUpdate", "screenId", "userIconHotSpotX",
2803                                        "userIconHotSpotY", "tempPointerColor", "lastDirection", "currentDirection"};
2804    std::vector<std::vector<std::string>> data2 = {
2805        {std::to_string(mouseDisplayState_), std::to_string(mouseIconUpdate_), std::to_string(screenId_),
2806         std::to_string(userIconHotSpotX_), std::to_string(userIconHotSpotY_), std::to_string(tempPointerColor_),
2807         std::to_string(lastDirection_), std::to_string(currentDirection_)}};
2808
2809    DumpFullTable(oss, "Cursor Info", titles2, data2);
2810    oss << std::endl;
2811
2812    std::vector<std::string> styleTitles = {"name", "Size", "Color", "ID"};
2813    std::vector<std::vector<std::string>> styleData = {
2814        {"lastMouseStyle", std::to_string(lastMouseStyle_.size), std::to_string(lastMouseStyle_.color),
2815         std::to_string(lastMouseStyle_.id)},
2816        {"currentMouseStyle", std::to_string(currentMouseStyle_.size), std::to_string(currentMouseStyle_.color),
2817         std::to_string(currentMouseStyle_.id)}};
2818
2819    DumpFullTable(oss, "Cursor Style Info", styleTitles, styleData);
2820    oss << std::endl;
2821
2822    std::vector<std::string> pidTitles = {"pid", "visible"};
2823    std::vector<std::vector<std::string>> pidInfos;
2824    for (const auto &pidInfo : pidInfos_) {
2825        pidInfos.push_back({std::to_string(pidInfo.pid), pidInfo.visible ? "true" : "false"});
2826    }
2827    DumpFullTable(oss, "Visible Info", pidTitles, pidInfos);
2828    oss << std::endl;
2829
2830    std::string dumpInfo = oss.str();
2831    dprintf(fd, dumpInfo.c_str());
2832}
2833
2834#ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2835void PointerDrawingManager::UpdateBindDisplayId(int32_t displayId)
2836{
2837    if (lastDisplayId_ != displayId) {
2838        MMI_HILOGI("Mouse traversal occurs, lastDisplayId_:%{public}d, displayId:%{public}d",
2839            lastDisplayId_, displayId);
2840        CHKPV(surfaceNode_);
2841        surfaceNode_->DetachToDisplay(screenId_);
2842        screenId_ = static_cast<uint64_t>(displayId);
2843        MMI_HILOGI("screenId_: %{public}" PRIu64, screenId_);
2844        AttachToDisplay();
2845        CHKPV(hardwareCursorPointerManager_);
2846        if (!hardwareCursorPointerManager_->IsSupported()) {
2847            DrawCursor(MOUSE_ICON(lastMouseStyle_.id));
2848        }
2849        lastDisplayId_ = displayId;
2850    }
2851}
2852#endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2853
2854void PointerDrawingManager::DrawScreenCenterPointer(const PointerStyle& pointerStyle)
2855{
2856    CALL_DEBUG_ENTER;
2857    if (hasDisplay_ && hasPointerDevice_) {
2858        if (surfaceNode_ != nullptr) {
2859            AttachToDisplay();
2860            Rosen::RSTransaction::FlushImplicitTransaction();
2861        }
2862        Direction direction = DIRECTION0;
2863        if (displayInfo_.displayDirection == DIRECTION0) {
2864            direction = displayInfo_.direction;
2865        }
2866        DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
2867            pointerStyle, direction);
2868    }
2869}
2870} // namespace MMI
2871} // namespace OHOS
2872