• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <regex>
20 #include <utility>
21 
22 #include "image/bitmap.h"
23 #include "image_source.h"
24 #include "image_type.h"
25 #include "image_utils.h"
26 #include "table_dump.h"
27 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
28 #include "magic_pointer_drawing_manager.h"
29 #include "magic_pointer_velocity_tracker.h"
30 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
31 
32 #include "bytrace_adapter.h"
33 #include "define_multimodal.h"
34 #include "i_multimodal_input_connect.h"
35 #include "input_device_manager.h"
36 #include "i_input_windows_manager.h"
37 #include "ipc_skeleton.h"
38 #include "mmi_log.h"
39 #include "i_preference_manager.h"
40 #include "parameters.h"
41 #include "pipeline/rs_recording_canvas.h"
42 #include "preferences.h"
43 #include "preferences_errno.h"
44 #include "preferences_helper.h"
45 #include "render/rs_pixel_map_util.h"
46 #include "scene_board_judgement.h"
47 #include "setting_datashare.h"
48 #include "util.h"
49 #include "dfx_hisysevent.h"
50 #include "timer_manager.h"
51 #include "surface.h"
52 #include "common_event_data.h"
53 #include "common_event_manager.h"
54 #include "common_event_support.h"
55 
56 #undef MMI_LOG_DOMAIN
57 #define MMI_LOG_DOMAIN MMI_LOG_CURSOR
58 #undef MMI_LOG_TAG
59 #define MMI_LOG_TAG "PointerDrawingManager"
60 #define FOCUS_COORDINATES(FOCUS_COORDINATES_, CHANGE) float FOCUS_COORDINATES_##CHANGE
61 #define CALCULATE_CANVAS_SIZE(CALCULATE_CANVAS_SIZE_, CHANGE) float CALCULATE_CANVAS_SIZE_##CHANGE
62 
63 namespace OHOS {
64 namespace MMI {
65 namespace {
66 const std::string FOLD_SCREEN_FLAG = system::GetParameter("const.window.foldscreen.type", "");
67 const std::string IMAGE_POINTER_DEFAULT_PATH = "/system/etc/multimodalinput/mouse_icon/";
68 const std::string DefaultIconPath = IMAGE_POINTER_DEFAULT_PATH + "Default.svg";
69 const std::string CursorIconPath = IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png";
70 const std::string CustomCursorIconPath = IMAGE_POINTER_DEFAULT_PATH + "Custom_Cursor_Circle.svg";
71 const std::string LoadingIconPath = IMAGE_POINTER_DEFAULT_PATH + "Loading.svg";
72 const std::string LoadingRightIconPath = IMAGE_POINTER_DEFAULT_PATH + "Loading_Right.svg";
73 const char* POINTER_COLOR { "pointerColor" };
74 const char* POINTER_SIZE { "pointerSize" };
75 const char* MAGIC_POINTER_COLOR { "magicPointerColor" };
76 const char* MAGIC_POINTER_SIZE { "magicPointerSize"};
77 const char* POINTER_CURSOR_RENDER_RECEIVER_NAME { "PointerCursorReceiver" };
78 const std::vector<std::string> DEVICE_TYPES = {};
79 constexpr int32_t BASELINE_DENSITY { 160 };
80 constexpr int32_t CALCULATE_MIDDLE { 2 };
81 [[ maybe_unused ]] constexpr int32_t MAGIC_INDEPENDENT_PIXELS { 30 };
82 constexpr int32_t DEVICE_INDEPENDENT_PIXELS { 40 };
83 constexpr int32_t POINTER_WINDOW_INIT_SIZE { 64 };
84 constexpr int32_t DEFAULT_POINTER_SIZE { 1 };
85 constexpr int32_t MIN_POINTER_SIZE { 1 };
86 constexpr int32_t MAX_POINTER_SIZE { 7 };
87 constexpr int32_t DEFAULT_VALUE { -1 };
88 constexpr int32_t ANIMATION_DURATION { 500 };
89 constexpr int32_t DEFAULT_POINTER_STYLE { 0 };
90 constexpr int32_t CURSOR_CIRCLE_STYLE { 41 };
91 constexpr int32_t AECH_DEVELOPER_DEFINED_STYLE { 47 };
92 constexpr float MOUSE_ICON_BIAS_RATIO { 5 / 33.0f };
93 constexpr int32_t VISIBLE_LIST_MAX_SIZE { 100 };
94 [[ maybe_unused ]] constexpr int32_t WAIT_TIME_FOR_MAGIC_CURSOR { 6000 };
95 constexpr float ROTATION_ANGLE { 360.f };
96 constexpr float LOADING_CENTER_RATIO { 0.5f };
97 constexpr float RUNNING_X_RATIO { 0.3f };
98 constexpr float RUNNING_Y_RATIO { 0.675f };
99 constexpr float INCREASE_RATIO { 1.22f };
100 constexpr float ROTATION_ANGLE90 { 90.f };
101 constexpr int32_t MIN_POINTER_COLOR { 0x000000 };
102 constexpr int32_t MAX_POINTER_COLOR { 0x00ffffff };
103 constexpr int32_t MIN_CURSOR_SIZE { 64 };
104 constexpr uint32_t RGB_CHANNEL_BITS_LENGTH { 24 };
105 constexpr float MAX_ALPHA_VALUE { 255.f };
106 constexpr int32_t MOUSE_STYLE_OPT { 0 };
107 constexpr int32_t MAGIC_STYLE_OPT { 1 };
108 constexpr size_t RETRY_TIMES { 3 };
109 const std::string MOUSE_FILE_NAME { "mouse_settings.xml" };
110 bool g_isRsRemoteDied { false };
111 bool g_isHdiRemoteDied { false };
112 bool g_isReStartVsync { false };
113 constexpr uint64_t FOLD_SCREEN_ID_FULL { 0 };
114 constexpr uint64_t FOLD_SCREEN_ID_MAIN { 5 };
115 constexpr float IMAGE_PIXEL { 0.0f };
116 constexpr float CALCULATE_IMAGE_MIDDLE { 2.0f };
117 constexpr int32_t QUEUE_SIZE { 5 };
118 constexpr int32_t DYNAMIC_ROTATION_ANGLE { 12 };
119 constexpr float CALCULATE_MOUSE_ICON_BAIS { 5.0f };
120 constexpr int32_t SYNC_FENCE_WAIT_TIME { 3000 };
121 float g_hardwareCanvasSize = { 512.0f };
122 float g_focalPoint = { 256.0f };
123 constexpr int32_t REPEAT_COOLING_TIME { 1000 };
124 constexpr int32_t REPEAT_ONCE { 1 };
125 constexpr int32_t ANGLE_90 { 90 };
126 constexpr int32_t ANGLE_360 { 360 };
127 constexpr int32_t MAX_CUSTOM_CURSOR_SIZE { 256 };
128 constexpr float MAX_CUSTOM_CURSOR_DIMENSION { 256.0f };
129 constexpr int32_t CURSOR_STRIDE { 4 };
130 std::atomic<bool> g_isRsRestart { false };
131 } // namespace
132 } // namespace MMI
133 } // namespace OHOS
134 
135 namespace OHOS {
136 namespace MMI {
137 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
138 class DisplyStatusReceiver : public EventFwk::CommonEventSubscriber {
139 public:
DisplyStatusReceiver(const OHOS::EventFwk::CommonEventSubscribeInfo & subscribeInfo)140     explicit DisplyStatusReceiver(const OHOS::EventFwk::CommonEventSubscribeInfo& subscribeInfo)
141         : OHOS::EventFwk::CommonEventSubscriber(subscribeInfo)
142     {
143         MMI_HILOGI("DisplyStatusReceiver register");
144     }
145 
146     virtual ~DisplyStatusReceiver() = default;
147 
OnReceiveEvent(const EventFwk::CommonEventData & eventData)148     void OnReceiveEvent(const EventFwk::CommonEventData &eventData)
149     {
150         std::string action = eventData.GetWant().GetAction();
151         if (action.empty()) {
152             MMI_HILOGE("action is empty");
153             return;
154         }
155         MMI_HILOGI("Received screen status:%{public}s", action.c_str());
156         PointerStyle curPointerStyle = IPointerDrawingManager::GetInstance()->GetLastMouseStyle();
157         curPointerStyle.id = MOUSE_ICON::TRANSPARENT_ICON;
158         if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
159         } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
160             CursorPosition cursorPos = WIN_MGR->ResetCursorPos();
161             IPointerDrawingManager::GetInstance()->DrawScreenCenterPointer(curPointerStyle);
162         }
163     }
164 };
165 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
166 
IsSingleDisplayFoldDevice()167 static bool IsSingleDisplayFoldDevice()
168 {
169     return (!FOLD_SCREEN_FLAG.empty() && (FOLD_SCREEN_FLAG[0] == '1' || FOLD_SCREEN_FLAG[0] == '4'));
170 }
171 
RsRemoteDiedCallback()172 void RsRemoteDiedCallback()
173 {
174     CALL_INFO_TRACE;
175     g_isRsRemoteDied = true;
176     g_isHdiRemoteDied = true;
177     g_isReStartVsync = true;
178     g_isRsRestart = false;
179 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
180     MAGIC_CURSOR->RsRemoteDiedCallbackForMagicCursor();
181 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
182     IPointerDrawingManager::GetInstance()->DestroyPointerWindow();
183 }
184 
InitPointerCallback()185 void PointerDrawingManager::InitPointerCallback()
186 {
187     MMI_HILOGI("Init RS Callback start");
188     g_isRsRemoteDied = false;
189     g_isRsRestart = false;
190     Rosen::OnRemoteDiedCallback callback = RsRemoteDiedCallback;
191     auto begin = std::chrono::high_resolution_clock::now();
192     Rosen::RSInterfaces::GetInstance().SetOnRemoteDiedCallback(callback);
193     auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
194         std::chrono::high_resolution_clock::now() - begin).count();
195 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
196     DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::SET_ON_REMOTE_DIED_CALLBACK, durationMS);
197 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
198 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
199     if (HasMagicCursor() && surfaceNode_ != nullptr) {
200         surfaceNode_ = nullptr;
201         MAGIC_CURSOR->RsRemoteInitCallbackForMagicCursor();
202     }
203 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
204 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
205     if (!initEventhandlerFlag_.load()) {
206         std::string productType = OHOS::system::GetParameter("const.build.product", "HYM");
207         if (std::find(DEVICE_TYPES.begin(), DEVICE_TYPES.end(), productType) != DEVICE_TYPES.end()) {
208             renderThread_ = std::make_unique<std::thread>([this] { this->RenderThreadLoop(); });
209             softCursorRenderThread_ =
210                 std::make_unique<std::thread>([this] { this->SoftCursorRenderThreadLoop(); });
211         }
212         initEventhandlerFlag_.store(true);
213     }
214 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
215 }
216 
DestroyPointerWindow()217 void PointerDrawingManager::DestroyPointerWindow()
218 {
219     CALL_INFO_TRACE;
220     CHKPV(delegateProxy_);
221     delegateProxy_->OnPostSyncTask([this] {
222         if (surfaceNode_ != nullptr) {
223             MMI_HILOGI("Pointer window destroy start");
224             g_isRsRemoteDied = false;
225             surfaceNode_->DetachToDisplay(screenId_);
226             surfaceNode_ = nullptr;
227             Rosen::RSTransaction::FlushImplicitTransaction();
228             MMI_HILOGI("Pointer window destroy success");
229         }
230         return RET_OK;
231     });
232 }
233 
IsNum(const std::string & str)234 static inline bool IsNum(const std::string &str)
235 {
236     std::istringstream sin(str);
237     double num;
238     return (sin >> num) && sin.eof();
239 }
240 
GetCanvasSize()241 static float GetCanvasSize()
242 {
243     auto ret = system::GetParameter("rosen.multimodalinput.pc.setcanvassize", "512.0");
244     if (IsNum(ret)) {
245         return g_hardwareCanvasSize;
246     }
247     return std::stoi(ret.c_str());
248 }
249 
GetFocusCoordinates()250 static float GetFocusCoordinates()
251 {
252     auto ret = system::GetParameter("rosen.multimodalinput.pc.setfocuscoordinates", "256.0");
253     if (IsNum(ret)) {
254         return g_focalPoint;
255     }
256     return std::stoi(ret.c_str());
257 }
258 
PointerDrawingManager()259 PointerDrawingManager::PointerDrawingManager()
260 {
261 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
262     MMI_HILOGI("The magiccurosr InitStyle");
263     hasMagicCursor_.name = "isMagicCursor";
264     MAGIC_CURSOR->InitStyle();
265 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
266     InitStyle();
267 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
268     hardwareCursorPointerManager_ = std::make_shared<HardwareCursorPointerManager>();
269     g_hardwareCanvasSize = GetCanvasSize();
270     g_focalPoint = GetFocusCoordinates();
271 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
272 }
273 
~PointerDrawingManager()274 PointerDrawingManager::~PointerDrawingManager()
275 {
276     MMI_HILOGI("~PointerDrawingManager enter");
277 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
278     if (runner_ != nullptr) {
279         runner_->Stop();
280     }
281     if ((renderThread_ != nullptr) && renderThread_->joinable()) {
282         renderThread_->join();
283     }
284 
285     if (softCursorRunner_ != nullptr) {
286         softCursorRunner_->Stop();
287     }
288     if ((softCursorRenderThread_ != nullptr) && softCursorRenderThread_->joinable()) {
289         softCursorRenderThread_->join();
290     }
291 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
292     MMI_HILOGI("~PointerDrawingManager complete");
293 }
294 
GetLastMouseStyle()295 PointerStyle PointerDrawingManager::GetLastMouseStyle()
296 {
297     CALL_DEBUG_ENTER;
298     return lastMouseStyle_;
299 }
300 
MouseIcon2IconType(MOUSE_ICON m)301 ICON_TYPE PointerDrawingManager::MouseIcon2IconType(MOUSE_ICON m)
302 {
303     return ICON_TYPE(mouseIcons_[m].alignmentWay);
304 }
305 
SetCursorLocation(int32_t displayId,int32_t physicalX,int32_t physicalY,ICON_TYPE iconType)306 bool PointerDrawingManager::SetCursorLocation(int32_t displayId, int32_t physicalX,
307     int32_t physicalY, ICON_TYPE iconType)
308 {
309     bool magicCursorSetBounds = false;
310     if (UpdateSurfaceNodeBounds(physicalX, physicalY) == RET_OK) {
311         magicCursorSetBounds = true;
312         Rosen::RSTransaction::FlushImplicitTransaction();
313     }
314 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
315     CHKPF(hardwareCursorPointerManager_);
316     CHKPF(surfaceNode_);
317     if (g_isHdiRemoteDied) {
318         hardwareCursorPointerManager_->SetHdiServiceState(false);
319     }
320     if (!magicCursorSetBounds) {
321         if (hardwareCursorPointerManager_->IsSupported()) {
322             if (lastMouseStyle_.id != MOUSE_ICON::LOADING &&
323                 lastMouseStyle_.id != MOUSE_ICON::RUNNING) {
324                 // Change the coordinates issued by RS to asynchronous,
325                 // without blocking the issuance of HardwareCursor coordinates.
326                 SoftwareCursorMoveAsync(physicalX, physicalY, iconType);
327             }
328         } else {
329             surfaceNode_->SetBounds(physicalX, physicalY, surfaceNode_->GetStagingProperties().GetBounds().z_,
330                 surfaceNode_->GetStagingProperties().GetBounds().w_);
331             Rosen::RSTransaction::FlushImplicitTransaction();
332         }
333     }
334     CHKPF(hardwareCursorPointerManager_);
335     if (hardwareCursorPointerManager_->IsSupported() &&
336         lastMouseStyle_.id != MOUSE_ICON::LOADING &&
337         lastMouseStyle_.id != MOUSE_ICON::RUNNING) {
338         HardwareCursorMove(physicalX, physicalY, iconType);
339     }
340 #else
341     if (!magicCursorSetBounds) {
342         surfaceNode_->SetBounds(physicalX, physicalY,
343             surfaceNode_->GetStagingProperties().GetBounds().z_, surfaceNode_->GetStagingProperties().GetBounds().w_);
344         Rosen::RSTransaction::FlushImplicitTransaction();
345     }
346 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
347     return true;
348 }
349 
ForceClearPointerVisiableStatus()350 void PointerDrawingManager::ForceClearPointerVisiableStatus()
351 {
352     MMI_HILOGI("Force clear all pointer visiable status");
353     pidInfos_.clear();
354     UpdatePointerVisible();
355 }
356 
UpdateMouseLayer(const PointerStyle & pointerStyle,int32_t displayId,int32_t physicalX,int32_t physicalY)357 int32_t PointerDrawingManager::UpdateMouseLayer(const PointerStyle& pointerStyle,
358     int32_t displayId, int32_t physicalX, int32_t physicalY)
359 {
360     if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
361         mouseIconUpdate_ = false;
362         MMI_HILOGE("Init layer failed");
363         return RET_ERR;
364     }
365     if (!SetCursorLocation(displayId, physicalX, physicalY, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)))) {
366         return RET_ERR;
367     }
368     return RET_OK;
369 }
370 
DrawMovePointer(int32_t displayId,int32_t physicalX,int32_t physicalY,PointerStyle pointerStyle,Direction direction)371 int32_t PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
372     PointerStyle pointerStyle, Direction direction)
373 {
374     CHKPR(surfaceNode_, RET_ERR);
375     MMI_HILOGD("Pointer window move success, pointerStyle id:%{public}d", pointerStyle.id);
376     displayId_ = displayId;
377 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
378     bool cursorEnlarged = MAGIC_POINTER_VELOCITY_TRACKER->GetCursorEnlargedStatus();
379     if (cursorEnlarged) {
380         MAGIC_POINTER_VELOCITY_TRACKER->SetLastPointerStyle(pointerStyle);
381         MAGIC_POINTER_VELOCITY_TRACKER->SetDirection(direction);
382         if (pointerStyle.id != MOUSE_ICON::DEFAULT && pointerStyle.id != MOUSE_ICON::CROSS) {
383             pointerStyle.id = MOUSE_ICON::DEFAULT;
384         }
385     }
386 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
387 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
388     UpdateBindDisplayId(displayId);
389 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
390     if (lastMouseStyle_ == pointerStyle && !mouseIconUpdate_ && lastDirection_ == direction) {
391         if (!SetCursorLocation(displayId, physicalX, physicalY, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)))) {
392             return RET_ERR;
393         }
394         MMI_HILOGD("The lastpointerStyle is equal with pointerStyle, id:%{public}d, size:%{public}d",
395             pointerStyle.id, pointerStyle.size);
396         return RET_OK;
397     }
398     if (lastDirection_ != direction) {
399         RotateDegree(direction);
400         lastDirection_ = direction;
401     }
402     lastMouseStyle_ = pointerStyle;
403 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
404     CHKPR(hardwareCursorPointerManager_, RET_ERR);
405     if (hardwareCursorPointerManager_->IsSupported()) {
406         UpdatePointerVisible();
407     } else {
408         int32_t UpdateLayerRes = UpdateMouseLayer(pointerStyle, displayId, physicalX, physicalY);
409         if (UpdateLayerRes != RET_OK) {
410             MMI_HILOGE("Update Mouse Layer failed.");
411         }
412         UpdatePointerVisible();
413     }
414 #else
415     int32_t UpdateLayerRes = UpdateMouseLayer(pointerStyle, displayId, physicalX, physicalY);
416     if (UpdateLayerRes != RET_OK) {
417         MMI_HILOGE("Update Mouse Layer failed.");
418     }
419     UpdatePointerVisible();
420 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
421     mouseIconUpdate_ = false;
422     MMI_HILOGD("Leave, display:%{public}d, physicalX:%{public}d, physicalY:%{public}d",
423         displayId, physicalX, physicalY);
424     return RET_OK;
425 }
426 
UpdateSurfaceNodeBounds(int32_t physicalX,int32_t physicalY)427 int32_t PointerDrawingManager::UpdateSurfaceNodeBounds(int32_t physicalX, int32_t physicalY)
428 {
429 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
430     if (HasMagicCursor()) {
431         if (currentMouseStyle_.id == DEVELOPER_DEFINED_ICON) {
432             surfaceNode_->SetBounds(physicalX, physicalY,
433                 canvasWidth_, canvasHeight_);
434         } else {
435             CHKPR(surfaceNode_, RET_ERR);
436             surfaceNode_->SetBounds(physicalX, physicalY,
437                 imageWidth_, imageHeight_);
438         }
439         return RET_OK;
440     }
441 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
442     return RET_ERR;
443 }
444 
DrawMovePointer(int32_t displayId,int32_t physicalX,int32_t physicalY)445 void PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY)
446 {
447     CALL_DEBUG_ENTER;
448     if (surfaceNode_ != nullptr) {
449         if (!SetCursorLocation(displayId, physicalX, physicalY, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)))) {
450             return;
451         }
452         MMI_HILOGD("Move pointer, physicalX:%d, physicalY:%d", physicalX, physicalY);
453     }
454 }
455 
SetHardwareCursorPosition(int32_t displayId,int32_t physicalX,int32_t physicalY,PointerStyle pointerStyle)456 void PointerDrawingManager::SetHardwareCursorPosition(int32_t displayId, int32_t physicalX, int32_t physicalY,
457     PointerStyle pointerStyle)
458 {
459 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
460     CHKPV(hardwareCursorPointerManager_);
461     if (g_isHdiRemoteDied) {
462         hardwareCursorPointerManager_->SetHdiServiceState(false);
463     }
464     if (hardwareCursorPointerManager_->IsSupported() && lastMouseStyle_.id != MOUSE_ICON::LOADING &&
465             lastMouseStyle_.id != MOUSE_ICON::RUNNING) {
466         auto align = MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id));
467         HardwareCursorMove(physicalX, physicalY, align);
468     }
469 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
470 }
471 
DrawPointer(int32_t displayId,int32_t physicalX,int32_t physicalY,const PointerStyle pointerStyle,Direction direction)472 void PointerDrawingManager::DrawPointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
473     const PointerStyle pointerStyle, Direction direction)
474 {
475     CALL_DEBUG_ENTER;
476     MMI_HILOGD("Display:%{public}d, physicalX:%{public}d, physicalY:%{public}d, pointerStyle:%{public}d",
477         displayId, physicalX, physicalY, pointerStyle.id);
478     FixCursorPosition(physicalX, physicalY);
479     lastPhysicalX_ = physicalX;
480     lastPhysicalY_ = physicalY;
481     currentMouseStyle_ = pointerStyle;
482     currentDirection_ = direction;
483     if (pointerStyle.id == MOUSE_ICON::DEFAULT && mouseIcons_[MOUSE_ICON(pointerStyle.id)].iconPath == CursorIconPath) {
484         AdjustMouseFocus(direction, ICON_TYPE(mouseIcons_[MOUSE_ICON(MOUSE_ICON::CURSOR_CIRCLE)].alignmentWay),
485             physicalX, physicalY);
486     } else if (pointerStyle.id == MOUSE_ICON::DEFAULT &&
487         mouseIcons_[MOUSE_ICON(pointerStyle.id)].iconPath == CustomCursorIconPath) {
488             AdjustMouseFocus(direction,
489                 ICON_TYPE(mouseIcons_[MOUSE_ICON(MOUSE_ICON::AECH_DEVELOPER_DEFINED_ICON)].alignmentWay),
490                     physicalX, physicalY);
491     } else {
492         AdjustMouseFocus(direction, ICON_TYPE(mouseIcons_[MOUSE_ICON(pointerStyle.id)].alignmentWay),
493             physicalX, physicalY);
494     }
495     // Log printing only occurs when the mouse style changes
496     if (currentMouseStyle_.id != lastMouseStyle_.id) {
497         MMI_HILOGD("MagicCursor AdjustMouseFocus:%{public}d",
498             ICON_TYPE(mouseIcons_[MOUSE_ICON(pointerStyle.id)].alignmentWay));
499     }
500     if (DrawMovePointer(displayId, physicalX, physicalY, pointerStyle, direction) == RET_OK) {
501         return;
502     }
503 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
504     if (HasMagicCursor() && currentMouseStyle_.id != DEVELOPER_DEFINED_ICON) {
505         MMI_HILOGD("magicCursor DrawPointer enter CreatePointerWindow");
506         MAGIC_CURSOR->CreatePointerWindow(displayId, physicalX, physicalY, direction, surfaceNode_);
507     } else {
508         CreatePointerWindow(displayId, physicalX, physicalY, direction);
509     }
510 #else
511     CreatePointerWindow(displayId, physicalX, physicalY, direction);
512 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
513     CHKPV(surfaceNode_);
514     UpdateMouseStyle();
515     if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
516         MMI_HILOGE("Init layer failed");
517         return;
518     }
519     UpdatePointerVisible();
520     SetHardwareCursorPosition(displayId, physicalX, physicalY, lastMouseStyle_);
521     MMI_HILOGI("Leave, display:%{public}d, physicalX:%d, physicalY:%d", displayId, physicalX, physicalY);
522 }
523 
UpdateMouseStyle()524 void PointerDrawingManager::UpdateMouseStyle()
525 {
526     CALL_DEBUG_ENTER;
527     PointerStyle curPointerStyle;
528     GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
529     if (curPointerStyle.id == CURSOR_CIRCLE_STYLE || curPointerStyle.id == AECH_DEVELOPER_DEFINED_STYLE) {
530         lastMouseStyle_.id = curPointerStyle.id;
531         int ret = SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
532         if (ret != RET_OK) {
533             MMI_HILOGE("Set pointer style failed");
534         }
535         return;
536     }
537 }
538 
SwitchPointerStyle()539 int32_t PointerDrawingManager::SwitchPointerStyle()
540 {
541     CALL_DEBUG_ENTER;
542     int32_t size = GetPointerSize();
543     if (size < MIN_POINTER_SIZE) {
544         size = MIN_POINTER_SIZE;
545     } else if (size > MAX_POINTER_SIZE) {
546         size = MAX_POINTER_SIZE;
547     }
548     imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
549     imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
550     canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
551     canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
552 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
553     MAGIC_CURSOR->SetPointerSize(imageWidth_, imageHeight_);
554 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
555     Direction direction = DIRECTION0;
556     int32_t physicalX = lastPhysicalX_;
557     int32_t physicalY = lastPhysicalY_;
558     AdjustMouseFocus(
559         direction, ICON_TYPE(GetIconStyle(MOUSE_ICON(lastMouseStyle_.id)).alignmentWay), physicalX, physicalY);
560 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
561     if (HasMagicCursor()) {
562         MAGIC_CURSOR->EnableCursorInversion();
563         MAGIC_CURSOR->CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction, surfaceNode_);
564     } else {
565         MAGIC_CURSOR->DisableCursorInversion();
566         CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
567     }
568 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
569     int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
570     if (ret != RET_OK) {
571         MMI_HILOGE("Init layer failed");
572         return ret;
573     }
574     UpdatePointerVisible();
575     SetHardwareCursorPosition(displayInfo_.id, physicalX, physicalY, lastMouseStyle_);
576     return RET_OK;
577 }
578 
CreateMagicCursorChangeObserver()579 void PointerDrawingManager::CreateMagicCursorChangeObserver()
580 {
581     // Listening enabling cursor deformation and color inversion
582     SettingObserver::UpdateFunc func = [](const std::string& key) {
583         bool statusValue = false;
584         auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue);
585         if (ret != RET_OK) {
586             MMI_HILOGE("Get value from setting date fail");
587             return;
588         }
589 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
590         MAGIC_CURSOR->UpdateMagicCursorChangeState(statusValue);
591 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
592     };
593     std::string dynamicallyKey = "smartChange";
594     sptr<SettingObserver> magicCursorChangeObserver = SettingDataShare::GetInstance(
595         MULTIMODAL_INPUT_SERVICE_ID).CreateObserver(dynamicallyKey, func);
596     ErrCode ret =
597         SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(magicCursorChangeObserver);
598     if (ret != ERR_OK) {
599 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
600         DfxHisysevent::ReportMagicCursorFault(dynamicallyKey, "Register setting observer failed");
601 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
602         MMI_HILOGE("Register magic cursor change observer failed, ret:%{public}d", ret);
603         magicCursorChangeObserver = nullptr;
604     }
605 }
606 
UpdateStyleOptions()607 void PointerDrawingManager::UpdateStyleOptions()
608 {
609     CALL_DEBUG_ENTER;
610     PointerStyle curPointerStyle;
611     WIN_MGR->GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
612     curPointerStyle.options = HasMagicCursor() ? MAGIC_STYLE_OPT : MOUSE_STYLE_OPT;
613     int ret = WIN_MGR->SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
614     if (ret != RET_OK) {
615         MMI_HILOGE("Set pointer style failed");
616     }
617 }
618 
InitPointerObserver()619 void PointerDrawingManager::InitPointerObserver()
620 {
621     CALL_INFO_TRACE;
622     if (hasInitObserver_) {
623         MMI_HILOGI("Settingdata observer has init");
624         return;
625     }
626 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
627     int32_t ret = CreatePointerSwitchObserver(hasMagicCursor_);
628     if (ret == RET_OK) {
629         hasInitObserver_ = true;
630         MMI_HILOGD("Create pointer switch observer success");
631     }
632 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
633 }
634 
CreatePointerSwitchObserver(isMagicCursor & item)635 int32_t PointerDrawingManager::CreatePointerSwitchObserver(isMagicCursor& item)
636 {
637     CALL_DEBUG_ENTER;
638     SettingObserver::UpdateFunc updateFunc = [this, &item](const std::string& key) {
639         bool statusValue = false;
640 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
641         statusValue = true;
642 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
643         auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue);
644         if (ret != RET_OK) {
645             MMI_HILOGE("Get value from setting date fail");
646             return;
647         }
648         bool tmp = item.isShow;
649         item.isShow = statusValue;
650         this->UpdateStyleOptions();
651         if (item.isShow != tmp) {
652 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
653             MAGIC_CURSOR->InitRenderThread([]() { IPointerDrawingManager::GetInstance()->SwitchPointerStyle(); });
654 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
655             CHKPV(surfaceNode_);
656 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
657             MMI_HILOGD("Switch pointer style");
658             int64_t nodeId = static_cast<int64_t>(this->surfaceNode_->GetId());
659             if (nodeId != MAGIC_CURSOR->GetSurfaceNodeId(nodeId)) {
660                 surfaceNode_->DetachToDisplay(screenId_);
661                 Rosen::RSTransaction::FlushImplicitTransaction();
662             }
663             MAGIC_CURSOR->DetachDisplayNode();
664             this->SwitchPointerStyle();
665 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
666         }
667     };
668     sptr<SettingObserver> statusObserver =
669         SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).CreateObserver(item.name, updateFunc);
670     ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
671     if (ret != ERR_OK) {
672 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
673         DfxHisysevent::ReportMagicCursorFault(item.name, "Register setting observer failed");
674 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
675         MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
676         statusObserver = nullptr;
677         return RET_ERR;
678     }
679     CreateMagicCursorChangeObserver();
680     return RET_OK;
681 }
682 
HasMagicCursor()683 bool PointerDrawingManager::HasMagicCursor()
684 {
685 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
686     if (!MAGIC_CURSOR->isExistDefaultStyle) {
687         MMI_HILOGE("MagicCursor default icon file is not exist");
688         return false;
689     }
690 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
691     return hasMagicCursor_.isShow;
692 }
693 
694 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
InitVsync(MOUSE_ICON mouseStyle)695 int32_t PointerDrawingManager::InitVsync(MOUSE_ICON mouseStyle)
696 {
697     if (g_isReStartVsync) {
698         isRenderRuning_.store(true);
699         auto rsClient = std::static_pointer_cast<Rosen::RSRenderServiceClient>(
700             Rosen::RSIRenderClient::CreateRenderServiceClient());
701         CHKPR(rsClient, RET_ERR);
702         receiver_ = rsClient->CreateVSyncReceiver(POINTER_CURSOR_RENDER_RECEIVER_NAME, handler_);
703         if (receiver_ == nullptr || receiver_->Init() != VSYNC_ERROR_OK) {
704             MMI_HILOGE("Receiver init failed");
705             return RET_ERR;
706         }
707         g_isReStartVsync = false;
708     }
709     return RequestNextVSync();
710 }
711 
RetryGetSurfaceBuffer(sptr<OHOS::Surface> layer)712 sptr<OHOS::SurfaceBuffer> PointerDrawingManager::RetryGetSurfaceBuffer(sptr<OHOS::Surface> layer)
713 {
714     sptr<OHOS::SurfaceBuffer> buffer;
715     if (hardwareCursorPointerManager_->IsSupported()) {
716         for (size_t i = 0; i < RETRY_TIMES; i++) {
717             buffer = GetSurfaceBuffer(layer);
718             if (buffer != nullptr && buffer->GetVirAddr() != nullptr) {
719                 return buffer;
720             }
721         }
722     }
723     return buffer;
724 }
725 
GetMainScreenDisplayInfo(const DisplayGroupInfo & displayGroupInfo,DisplayInfo & mainScreenDisplayInfo) const726 int32_t PointerDrawingManager::GetMainScreenDisplayInfo(const DisplayGroupInfo &displayGroupInfo,
727     DisplayInfo &mainScreenDisplayInfo) const
728 {
729     if (displayGroupInfo.displaysInfo.empty()) {
730         MMI_HILOGE("displayGroupInfo doesn't contain displayInfo");
731         return RET_ERR;
732     }
733     for (const DisplayInfo& display : displayGroupInfo.displaysInfo) {
734         if (display.screenCombination == OHOS::MMI::ScreenCombination::SCREEN_MAIN) {
735             mainScreenDisplayInfo = display;
736             return RET_OK;
737         }
738     }
739     mainScreenDisplayInfo = displayGroupInfo.displaysInfo[0];
740     return RET_OK;
741 }
742 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
743 
InitLayer(const MOUSE_ICON mouseStyle)744 int32_t PointerDrawingManager::InitLayer(const MOUSE_ICON mouseStyle)
745 {
746 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
747     if (HasMagicCursor() && mouseStyle != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
748         MMI_HILOGD("magiccursor enter MAGIC_CURSOR->Initlayer");
749         return MAGIC_CURSOR->InitLayer(mouseStyle);
750     }
751 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
752 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
753     CHKPR(hardwareCursorPointerManager_, RET_ERR);
754     if (hardwareCursorPointerManager_->IsSupported()) {
755         if ((mouseStyle == MOUSE_ICON::LOADING) || (mouseStyle == MOUSE_ICON::RUNNING)) {
756             return InitVsync(mouseStyle);
757         } else {
758             GetCanvasSize();
759             GetFocusCoordinates();
760             hardwareCanvasSize_ = g_hardwareCanvasSize;
761             // Change the drawing to asynchronous, and when obtaining the surfaceBuffer fails,
762             // repeatedly obtain the surfaceBuffer.
763             PostSoftCursorTask([this, mouseStyle]() {
764                 SoftwareCursorRender(mouseStyle);
765             });
766             HardwareCursorRender(mouseStyle);
767             return RET_OK;
768         }
769     }
770 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
771     return DrawCursor(mouseStyle);
772 }
773 
DrawCursor(const MOUSE_ICON mouseStyle)774 int32_t PointerDrawingManager::DrawCursor(const MOUSE_ICON mouseStyle)
775 {
776     CALL_DEBUG_ENTER;
777     CHKPR(surfaceNode_, RET_ERR);
778     DrawLoadingPointerStyle(mouseStyle);
779     DrawRunningPointerAnimate(mouseStyle);
780     sptr<OHOS::Surface> layer = GetLayer();
781     if (layer == nullptr) {
782         MMI_HILOGE("Init layer is failed, Layer is nullptr");
783         surfaceNode_->DetachToDisplay(screenId_);
784         surfaceNode_ = nullptr;
785         Rosen::RSTransaction::FlushImplicitTransaction();
786         MMI_HILOGE("Pointer window destroy success");
787         return RET_ERR;
788     }
789     sptr<OHOS::SurfaceBuffer> buffer = GetSurfaceBuffer(layer);
790     if (buffer == nullptr || buffer->GetVirAddr() == nullptr) {
791         surfaceNode_->DetachToDisplay(screenId_);
792         surfaceNode_ = nullptr;
793         Rosen::RSTransaction::FlushImplicitTransaction();
794         MMI_HILOGE("Pointer window destroy success");
795         return RET_ERR;
796     }
797 
798     CHKPR(buffer, RET_ERR);
799     auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
800     CHKPR(addr, RET_ERR);
801     DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), mouseStyle);
802     OHOS::BufferFlushConfig flushConfig = {
803         .damage = {
804             .w = buffer->GetWidth(),
805             .h = buffer->GetHeight(),
806         },
807     };
808     OHOS::SurfaceError ret = layer->FlushBuffer(buffer, DEFAULT_VALUE, flushConfig);
809     if (ret != OHOS::SURFACE_ERROR_OK) {
810         MMI_HILOGE("Init layer failed, FlushBuffer return ret:%{public}s", SurfaceErrorStr(ret).c_str());
811         layer->CancelBuffer(buffer);
812         return RET_ERR;
813     }
814     MMI_HILOGD("Init layer success");
815     return RET_OK;
816 }
817 
DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)818 void PointerDrawingManager::DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)
819 {
820     CALL_DEBUG_ENTER;
821     CHKPV(surfaceNode_);
822     Rosen::RSAnimationTimingProtocol protocol;
823     if (mouseStyle != MOUSE_ICON::LOADING &&
824         (mouseStyle != MOUSE_ICON::DEFAULT ||
825             mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"))) {
826         protocol.SetDuration(0);
827         Rosen::RSNode::Animate(
828             protocol,
829             Rosen::RSAnimationTimingCurve::LINEAR,
830             [this]() {
831                 if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
832                     RotateDegree(DIRECTION0);
833                     return;
834                 }
835                 RotateDegree(currentDirection_);
836             });
837         MMI_HILOGE("Current pointer is not loading");
838         Rosen::RSTransaction::FlushImplicitTransaction();
839         return;
840     }
841     float ratio = imageWidth_ * 1.0 / canvasWidth_;
842     surfaceNode_->SetPivot({LOADING_CENTER_RATIO * ratio, LOADING_CENTER_RATIO * ratio});
843     protocol.SetDuration(ANIMATION_DURATION);
844     protocol.SetRepeatCount(DEFAULT_VALUE);
845 
846     // create property animation
847     Rosen::RSNode::Animate(
848         protocol,
849         Rosen::RSAnimationTimingCurve::LINEAR,
850         [this]() { surfaceNode_->SetRotation(ROTATION_ANGLE); });
851 
852     Rosen::RSTransaction::FlushImplicitTransaction();
853 }
854 
ConvertToColorSpace(Media::ColorSpace colorSpace)855 std::shared_ptr<Rosen::Drawing::ColorSpace> PointerDrawingManager::ConvertToColorSpace(
856     Media::ColorSpace colorSpace)
857 {
858     switch (colorSpace) {
859         case Media::ColorSpace::DISPLAY_P3:
860             return Rosen::Drawing::ColorSpace::CreateRGB(
861                 Rosen::Drawing::CMSTransferFuncType::SRGB, Rosen::Drawing::CMSMatrixType::DCIP3);
862         case Media::ColorSpace::LINEAR_SRGB:
863             return Rosen::Drawing::ColorSpace::CreateSRGBLinear();
864         case Media::ColorSpace::SRGB:
865             return Rosen::Drawing::ColorSpace::CreateSRGB();
866         default:
867             return Rosen::Drawing::ColorSpace::CreateSRGB();
868     }
869 }
870 
PixelFormatToColorType(Media::PixelFormat pixelFormat)871 Rosen::Drawing::ColorType PointerDrawingManager::PixelFormatToColorType(Media::PixelFormat pixelFormat)
872 {
873     switch (pixelFormat) {
874         case Media::PixelFormat::RGB_565:
875             return Rosen::Drawing::ColorType::COLORTYPE_RGB_565;
876         case Media::PixelFormat::RGBA_8888:
877             return Rosen::Drawing::ColorType::COLORTYPE_RGBA_8888;
878         case Media::PixelFormat::BGRA_8888:
879             return Rosen::Drawing::ColorType::COLORTYPE_BGRA_8888;
880         case Media::PixelFormat::ALPHA_8:
881             return Rosen::Drawing::ColorType::COLORTYPE_ALPHA_8;
882         case Media::PixelFormat::RGBA_F16:
883             return Rosen::Drawing::ColorType::COLORTYPE_RGBA_F16;
884         case Media::PixelFormat::UNKNOWN:
885         case Media::PixelFormat::ARGB_8888:
886         case Media::PixelFormat::RGB_888:
887         case Media::PixelFormat::NV21:
888         case Media::PixelFormat::NV12:
889         case Media::PixelFormat::CMYK:
890         default:
891             return Rosen::Drawing::ColorType::COLORTYPE_UNKNOWN;
892     }
893 }
894 
AlphaTypeToAlphaType(Media::AlphaType alphaType)895 Rosen::Drawing::AlphaType PointerDrawingManager::AlphaTypeToAlphaType(Media::AlphaType alphaType)
896 {
897     switch (alphaType) {
898         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
899             return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
900         case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
901             return Rosen::Drawing::AlphaType::ALPHATYPE_OPAQUE;
902         case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
903             return Rosen::Drawing::AlphaType::ALPHATYPE_PREMUL;
904         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
905             return Rosen::Drawing::AlphaType::ALPHATYPE_UNPREMUL;
906         default:
907             return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
908     }
909 }
910 
PixelMapReleaseProc(const void *,void * context)911 static void PixelMapReleaseProc(const void* /* pixels */, void* context)
912 {
913     PixelMapReleaseContext* ctx = static_cast<PixelMapReleaseContext*>(context);
914     if (ctx != nullptr) {
915         delete ctx;
916     }
917 }
918 
ExtractDrawingImage(std::shared_ptr<Media::PixelMap> pixelMap)919 std::shared_ptr<Rosen::Drawing::Image> PointerDrawingManager::ExtractDrawingImage(
920     std::shared_ptr<Media::PixelMap> pixelMap)
921 {
922     CHKPP(pixelMap);
923     Media::ImageInfo imageInfo;
924     pixelMap->GetImageInfo(imageInfo);
925     Rosen::Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
926         PixelFormatToColorType(imageInfo.pixelFormat),
927         AlphaTypeToAlphaType(imageInfo.alphaType),
928         ConvertToColorSpace(imageInfo.colorSpace) };
929     Rosen::Drawing::Pixmap imagePixmap(drawingImageInfo,
930         reinterpret_cast<const void*>(pixelMap->GetPixels()), pixelMap->GetRowBytes());
931     PixelMapReleaseContext* releaseContext = new (std::nothrow) PixelMapReleaseContext(pixelMap);
932     CHKPP(releaseContext);
933     auto image = Rosen::Drawing::Image::MakeFromRaster(imagePixmap, PixelMapReleaseProc, releaseContext);
934     if (image == nullptr) {
935         MMI_HILOGE("ExtractDrawingImage image fail");
936         delete releaseContext;
937     }
938     return image;
939 }
940 
941 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
PostTask(std::function<void ()> task)942 void PointerDrawingManager::PostTask(std::function<void()> task)
943 {
944     CHKPV(hardwareCursorPointerManager_);
945     if (g_isHdiRemoteDied) {
946         hardwareCursorPointerManager_->SetHdiServiceState(false);
947     }
948     if (handler_ != nullptr) {
949         handler_->PostTask(task);
950     }
951 }
952 
PostSoftCursorTask(std::function<void ()> task)953 void PointerDrawingManager::PostSoftCursorTask(std::function<void()> task)
954 {
955     CHKPV(hardwareCursorPointerManager_);
956     if (g_isHdiRemoteDied) {
957         hardwareCursorPointerManager_->SetHdiServiceState(false);
958     }
959     if (softCursorHander_ != nullptr) {
960         softCursorHander_->PostTask(task);
961     }
962 }
963 
DrawDynamicHardwareCursor(std::shared_ptr<OHOS::Rosen::Drawing::Bitmap> bitmap,int32_t px,int32_t py,ICON_TYPE align)964 void PointerDrawingManager::DrawDynamicHardwareCursor(std::shared_ptr<OHOS::Rosen::Drawing::Bitmap> bitmap,
965     int32_t px, int32_t py, ICON_TYPE align)
966 {
967     auto sp = GetScreenPointer(screenId_);
968     CHKPV(sp);
969     auto buffer = sp->RequestBuffer();
970     CHKPV(buffer);
971     auto addr = static_cast<uint8_t*>(buffer->GetVirAddr());
972     CHKPV(addr);
973 
974     uint32_t addrSize = buffer->GetWidth() * buffer->GetHeight() * CURSOR_STRIDE;
975     auto ret = memcpy_s(addr, addrSize, bitmap->GetPixels(), addrSize);
976     if (ret != EOK) {
977         MMI_HILOGE("memcpy_s failed, ret:%{public}d", ret);
978         return;
979     }
980     for (auto &sp : GetMirrorScreenPointers()) {
981         auto buf = sp->RequestBuffer();
982         CHKPC(buf);
983         auto addr = static_cast<uint8_t*>(buf->GetVirAddr());
984         CHKPC(addr);
985         ret = memcpy_s(addr, addrSize, bitmap->GetPixels(), addrSize);
986         if (ret != EOK) {
987             MMI_HILOGE("memcpy_s failed, ret:%{public}d", ret);
988             return;
989         }
990     }
991 }
992 
DrawDynamicHardwareCursor(std::shared_ptr<ScreenPointer> sp,const RenderConfig & cfg)993 int32_t PointerDrawingManager::DrawDynamicHardwareCursor(std::shared_ptr<ScreenPointer> sp,
994     const RenderConfig &cfg)
995 {
996     CHKPR(sp, RET_ERR);
997     auto buffer = sp->RequestBuffer();
998     CHKPR(buffer, RET_ERR);
999     auto addr = static_cast<uint8_t*>(buffer->GetVirAddr());
1000     CHKPR(addr, RET_ERR);
1001     pointerRenderer_.DynamicRender(addr, buffer->GetWidth(), buffer->GetHeight(), cfg);
1002     MMI_HILOGD("DrawDynamicHardwareCursor on ScreenPointer success, screenId = %{public}u",
1003         sp->GetScreenId());
1004     return RET_OK;
1005 }
1006 
HardwareCursorDynamicRender(MOUSE_ICON mouseStyle)1007 void PointerDrawingManager::HardwareCursorDynamicRender(MOUSE_ICON mouseStyle)
1008 {
1009     std::unordered_map<uint32_t, std::shared_ptr<ScreenPointer>> screenPointers;
1010     {
1011         std::lock_guard<std::mutex> lock(mtx_);
1012         screenPointers = screenPointers_;
1013     }
1014     RenderConfig cfg {
1015         .style = mouseStyle,
1016         .align = MouseIcon2IconType(mouseStyle),
1017         .path = mouseIcons_[mouseStyle].iconPath,
1018         .color = GetPointerColor(),
1019         .size = GetPointerSize(),
1020         .direction = displayInfo_.direction,
1021         .isHard = true,
1022         .rotationAngle = currentFrame_ * DYNAMIC_ROTATION_ANGLE,
1023         .userIconPixelMap = DecodeImageToPixelMap(mouseStyle),
1024     };
1025     for (auto it : screenPointers) {
1026         cfg.dpi = it.second->GetRenderDPI();
1027         cfg.direction = it.second->IsMirror() ? DIRECTION0 : displayInfo_.direction;
1028         MMI_HILOGD("HardwareCursorRender, screen = %{public}u, dpi = %{public}f",
1029             it.first, cfg.dpi);
1030         if (it.second->IsMirror() || it.first == screenId_) {
1031             if (mouseStyle == MOUSE_ICON::LOADING) {
1032                 cfg.rotationFocusX = GetFocusCoordinates();
1033                 cfg.rotationFocusY = GetFocusCoordinates();
1034             } else {
1035                 cfg.rotationFocusX = GetFocusCoordinates() + cfg.GetImageSize() * RUNNING_X_RATIO;
1036                 cfg.rotationFocusY = GetFocusCoordinates() + cfg.GetImageSize() * RUNNING_Y_RATIO;
1037             }
1038             cfg.direction = it.second->IsMirror() ? DIRECTION0 : displayInfo_.direction;
1039             DrawDynamicHardwareCursor(it.second, cfg);
1040         } else {
1041             it.second->SetInvisible();
1042         }
1043     }
1044     MMI_HILOGD("HardwareCursorDynamicRender success");
1045 }
1046 
DrawDynamicSoftCursor(std::shared_ptr<Rosen::RSSurfaceNode> sn,const RenderConfig & cfg)1047 int32_t PointerDrawingManager::DrawDynamicSoftCursor(std::shared_ptr<Rosen::RSSurfaceNode> sn,
1048     const RenderConfig &cfg)
1049 {
1050     CHKPR(sn, RET_ERR);
1051     auto layer = sn->GetSurface();
1052     CHKPR(layer, RET_ERR);
1053     auto buffer = GetSurfaceBuffer(layer);
1054     CHKPR(buffer, RET_ERR);
1055     auto addr = static_cast<uint8_t*>(buffer->GetVirAddr());
1056     CHKPR(addr, RET_ERR);
1057     pointerRenderer_.DynamicRender(addr, buffer->GetWidth(), buffer->GetHeight(), cfg);
1058 
1059     OHOS::BufferFlushConfig flushConfig = {
1060         .damage = {
1061             .w = buffer->GetWidth(),
1062             .h = buffer->GetHeight(),
1063         }
1064     };
1065     OHOS::SurfaceError ret = layer->FlushBuffer(buffer, -1, flushConfig);
1066     if (ret != OHOS::SURFACE_ERROR_OK) {
1067         MMI_HILOGE("FlushBuffer failed, return: %{public}s", SurfaceErrorStr(ret).data());
1068         layer->CancelBuffer(buffer);
1069         return RET_ERR;
1070     }
1071     MMI_HILOGD("DrawDynamicSoftCursor on sn success");
1072     return RET_OK;
1073 }
1074 
SoftwareCursorDynamicRender(MOUSE_ICON mouseStyle)1075 void PointerDrawingManager::SoftwareCursorDynamicRender(MOUSE_ICON mouseStyle)
1076 {
1077     std::unordered_map<uint32_t, std::shared_ptr<ScreenPointer>> screenPointers;
1078     {
1079         std::lock_guard<std::mutex> lock(mtx_);
1080         screenPointers = screenPointers_;
1081     }
1082     for (auto it : screenPointers) {
1083         RenderConfig cfg {
1084             .style = mouseStyle,
1085             .align = MouseIcon2IconType(mouseStyle),
1086             .path = mouseIcons_[mouseStyle].iconPath,
1087             .color = GetPointerColor(),
1088             .size = GetPointerSize(),
1089             .direction = displayInfo_.direction,
1090             .isHard = false,
1091             .rotationAngle = currentFrame_ * DYNAMIC_ROTATION_ANGLE,
1092         };
1093         auto sn = it.second->GetSurfaceNode();
1094         cfg.dpi = it.second->GetRenderDPI();
1095         MMI_HILOGD("SoftwareCursorDynamicRender, screen = %{public}u, dpi = %{public}f",
1096             it.first, cfg.dpi);
1097         if (it.second->IsMirror() || it.first == screenId_) {
1098             if (mouseStyle == MOUSE_ICON::LOADING) {
1099                 cfg.rotationFocusX = GetFocusCoordinates();
1100                 cfg.rotationFocusY = GetFocusCoordinates();
1101             } else {
1102                 cfg.rotationFocusX = GetFocusCoordinates() + cfg.GetImageSize() * RUNNING_X_RATIO;
1103                 cfg.rotationFocusY = GetFocusCoordinates() + cfg.GetImageSize() * RUNNING_Y_RATIO;
1104             }
1105             DrawDynamicSoftCursor(sn, cfg);
1106         } else {
1107             cfg.style = MOUSE_ICON::TRANSPARENT_ICON;
1108             cfg.align = MouseIcon2IconType(cfg.style);
1109             cfg.path = mouseIcons_[cfg.style].iconPath;
1110             DrawDynamicSoftCursor(it.second->GetSurfaceNode(), cfg);
1111         }
1112     }
1113 }
1114 
OnVsync(uint64_t timestamp)1115 void PointerDrawingManager::OnVsync(uint64_t timestamp)
1116 {
1117     if (currentMouseStyle_.id != MOUSE_ICON::RUNNING && currentMouseStyle_.id != MOUSE_ICON::LOADING) {
1118         MMI_HILOGE("Current mouse style is not equal to last mouse style");
1119         return;
1120     }
1121     PostTask([this]() -> void {
1122         if (currentMouseStyle_.id != MOUSE_ICON::RUNNING && currentMouseStyle_.id != MOUSE_ICON::LOADING) {
1123             MMI_HILOGE("Current post task mouse style is not equal to last mouse style");
1124             return;
1125         }
1126 
1127         HardwareCursorDynamicRender(MOUSE_ICON(currentMouseStyle_.id));
1128         HardwareCursorMove(lastPhysicalX_, lastPhysicalY_, MouseIcon2IconType(MOUSE_ICON(currentMouseStyle_.id)));
1129         PostSoftCursorTask([this]() {
1130             SoftwareCursorDynamicRender(MOUSE_ICON(currentMouseStyle_.id));
1131             SoftwareCursorMove(lastPhysicalX_, lastPhysicalY_, MouseIcon2IconType(MOUSE_ICON(currentMouseStyle_.id)));
1132         });
1133         currentFrame_++;
1134         if (currentFrame_ == frameCount_) {
1135             currentFrame_ = 0;
1136         }
1137         mouseIconUpdate_ = false;
1138     });
1139     RequestNextVSync();
1140 }
1141 
RequestNextVSync()1142 int32_t PointerDrawingManager::RequestNextVSync()
1143 {
1144     if (handler_ != nullptr) {
1145         Rosen::VSyncReceiver::FrameCallback fcb = {
1146             .userData_ = this,
1147             .callback_ = [this] (uint64_t timestamp, void*) {
1148                 return this->OnVsync(timestamp);
1149             },
1150         };
1151         if (receiver_ != nullptr) {
1152             receiver_->RequestNextVSync(fcb);
1153             return RET_OK;
1154         }
1155     }
1156     return RET_ERR;
1157 }
1158 
RenderThreadLoop()1159 void PointerDrawingManager::RenderThreadLoop()
1160 {
1161     isRenderRuning_.store(true);
1162     runner_ = AppExecFwk::EventRunner::Create(false);
1163     CHKPV(runner_);
1164     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner_);
1165     CHKPV(handler_);
1166     auto rsClient = std::static_pointer_cast<Rosen::RSRenderServiceClient>(
1167         Rosen::RSIRenderClient::CreateRenderServiceClient());
1168     CHKPV(rsClient);
1169     receiver_ = rsClient->CreateVSyncReceiver(POINTER_CURSOR_RENDER_RECEIVER_NAME, handler_);
1170     if (receiver_ == nullptr || receiver_->Init() != VSYNC_ERROR_OK) {
1171         MMI_HILOGE("Receiver init failed");
1172         return;
1173     }
1174     if (runner_ != nullptr) {
1175         MMI_HILOGI("Runner is run");
1176         runner_->Run();
1177     }
1178 }
1179 
SoftCursorRenderThreadLoop()1180 void PointerDrawingManager::SoftCursorRenderThreadLoop()
1181 {
1182     softCursorRunner_ = AppExecFwk::EventRunner::Create(false);
1183     CHKPV(softCursorRunner_);
1184     softCursorHander_ = std::make_shared<AppExecFwk::EventHandler>(softCursorRunner_);
1185     CHKPV(softCursorHander_);
1186     if (softCursorRunner_ != nullptr) {
1187         MMI_HILOGI("Runner is run");
1188         softCursorRunner_->Run();
1189     }
1190 }
1191 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1192 
DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)1193 void PointerDrawingManager::DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)
1194 {
1195     CALL_DEBUG_ENTER;
1196     CHKPV(surfaceNode_);
1197     CHKPV(canvasNode_);
1198     if (mouseStyle != MOUSE_ICON::RUNNING && (mouseStyle != MOUSE_ICON::DEFAULT ||
1199             mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"))) {
1200         if (canvasNode_ != nullptr) {
1201             Rosen::RSAnimationTimingProtocol protocol;
1202             protocol.SetDuration(0);
1203             Rosen::RSNode::Animate(
1204                 protocol,
1205                 Rosen::RSAnimationTimingCurve::LINEAR,
1206                 [this]() { canvasNode_->SetRotation(0); });
1207             Rosen::RSTransaction::FlushImplicitTransaction();
1208             canvasNode_->SetVisible(false);
1209         }
1210         MMI_HILOGE("current pointer is not running");
1211         return;
1212     }
1213     canvasNode_->SetVisible(true);
1214     float ratio = imageWidth_ * 1.0 / canvasWidth_;
1215     canvasNode_->SetPivot({RUNNING_X_RATIO * ratio, RUNNING_Y_RATIO * ratio});
1216     std::shared_ptr<OHOS::Media::PixelMap> pixelmap =
1217         DecodeImageToPixelMap(MOUSE_ICON::RUNNING_RIGHT);
1218     CHKPV(pixelmap);
1219     MMI_HILOGD("Set mouseicon to OHOS system");
1220 
1221 #ifndef USE_ROSEN_DRAWING
1222     auto canvas = static_cast<Rosen::RSRecordingCanvas *>(canvasNode_->BeginRecording(imageWidth_, imageHeight_));
1223     canvas->DrawPixelMap(pixelmap, 0, 0, SkSamplingOptions(), nullptr);
1224 #else
1225     Rosen::Drawing::Brush brush;
1226     Rosen::Drawing::Rect src = Rosen::Drawing::Rect(0, 0, pixelmap->GetWidth(), pixelmap->GetHeight());
1227     Rosen::Drawing::Rect dst = Rosen::Drawing::Rect(src);
1228     auto canvas =
1229         static_cast<Rosen::ExtendRecordingCanvas *>(canvasNode_->BeginRecording(imageWidth_, imageHeight_));
1230     canvas->AttachBrush(brush);
1231     canvas->DrawPixelMapRect(pixelmap, src, dst, Rosen::Drawing::SamplingOptions());
1232     canvas->DetachBrush();
1233 #endif // USE_ROSEN_DRAWING
1234 
1235     canvasNode_->FinishRecording();
1236 
1237     Rosen::RSAnimationTimingProtocol protocol;
1238     protocol.SetDuration(ANIMATION_DURATION);
1239     protocol.SetRepeatCount(DEFAULT_VALUE);
1240 
1241     // create property animation
1242     Rosen::RSNode::Animate(
1243         protocol,
1244         Rosen::RSAnimationTimingCurve::LINEAR,
1245         [this]() { canvasNode_->SetRotation(ROTATION_ANGLE); });
1246 
1247     Rosen::RSTransaction::FlushImplicitTransaction();
1248 }
1249 
AdjustMouseFocus(Direction direction,ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)1250 void PointerDrawingManager::AdjustMouseFocus(Direction direction, ICON_TYPE iconType,
1251     int32_t &physicalX, int32_t &physicalY)
1252 {
1253     CALL_DEBUG_ENTER;
1254 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1255     CHKPV(hardwareCursorPointerManager_);
1256     if (hardwareCursorPointerManager_->IsSupported()) {
1257         return;
1258     }
1259 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1260     switch (direction) {
1261         case DIRECTION0: {
1262             AdjustMouseFocusByDirection0(iconType, physicalX, physicalY);
1263             break;
1264         }
1265         case DIRECTION90: {
1266             AdjustMouseFocusByDirection90(iconType, physicalX, physicalY);
1267             break;
1268         }
1269         case DIRECTION180: {
1270             AdjustMouseFocusByDirection180(iconType, physicalX, physicalY);
1271             break;
1272         }
1273         case DIRECTION270: {
1274             AdjustMouseFocusByDirection270(iconType, physicalX, physicalY);
1275             break;
1276         }
1277         default: {
1278             MMI_HILOGW("direction is invalid,direction:%{public}d", direction);
1279             break;
1280         }
1281     }
1282 }
1283 
AdjustMouseFocusByDirection0(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)1284 void PointerDrawingManager::AdjustMouseFocusByDirection0(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
1285 {
1286     CALL_DEBUG_ENTER;
1287     int32_t height = imageHeight_;
1288     int32_t width = imageWidth_;
1289 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1290     CHKPV(hardwareCursorPointerManager_);
1291     if (hardwareCursorPointerManager_->IsSupported() &&
1292         currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1293         height = cursorHeight_;
1294         width = cursorWidth_;
1295     }
1296 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1297     switch (iconType) {
1298         case ANGLE_SW: {
1299             physicalY -= height;
1300             break;
1301         }
1302         case ANGLE_CENTER: {
1303             physicalX -= width / CALCULATE_MIDDLE;
1304             physicalY -= height / CALCULATE_MIDDLE;
1305             break;
1306         }
1307         case ANGLE_NW_RIGHT: {
1308             physicalX -= width * MOUSE_ICON_BIAS_RATIO;
1309             [[fallthrough]];
1310         }
1311         case ANGLE_NW: {
1312             if (currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1313                 if (GetUserIconCopy() != nullptr) {
1314                     physicalX -= userIconHotSpotX_;
1315                     physicalY -= userIconHotSpotY_;
1316                 }
1317             }
1318             break;
1319         }
1320         default: {
1321             MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
1322             break;
1323         }
1324     }
1325 }
1326 
AdjustMouseFocusByDirection90(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)1327 void PointerDrawingManager::AdjustMouseFocusByDirection90(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
1328 {
1329     CALL_DEBUG_ENTER;
1330     int32_t height = imageHeight_;
1331     int32_t width = imageWidth_;
1332 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1333     CHKPV(hardwareCursorPointerManager_);
1334     if (hardwareCursorPointerManager_->IsSupported() &&
1335         currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1336         height = cursorHeight_;
1337         width = cursorWidth_;
1338     }
1339 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1340     switch (iconType) {
1341         case ANGLE_SW: {
1342             physicalY += height;
1343             break;
1344         }
1345         case ANGLE_CENTER: {
1346             physicalX -= width / CALCULATE_MIDDLE;
1347             physicalY += height / CALCULATE_MIDDLE;
1348             break;
1349         }
1350         case ANGLE_NW_RIGHT: {
1351             physicalX -= width * MOUSE_ICON_BIAS_RATIO;
1352             [[fallthrough]];
1353         }
1354         case ANGLE_NW: {
1355             if (currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1356                 if (GetUserIconCopy() != nullptr) {
1357                     physicalX -= userIconHotSpotX_;
1358                     physicalY += userIconHotSpotY_;
1359                 }
1360             }
1361             break;
1362         }
1363         default: {
1364             MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
1365             break;
1366         }
1367     }
1368 }
1369 
AdjustMouseFocusByDirection180(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)1370 void PointerDrawingManager::AdjustMouseFocusByDirection180(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
1371 {
1372     CALL_DEBUG_ENTER;
1373     int32_t height = imageHeight_;
1374     int32_t width = imageWidth_;
1375 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1376     CHKPV(hardwareCursorPointerManager_);
1377     if (hardwareCursorPointerManager_->IsSupported() &&
1378         currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1379         height = cursorHeight_;
1380         width = cursorWidth_;
1381     }
1382 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1383     switch (iconType) {
1384         case ANGLE_SW: {
1385             physicalY += height;
1386             break;
1387         }
1388         case ANGLE_CENTER: {
1389             physicalX += width / CALCULATE_MIDDLE;
1390             physicalY += height / CALCULATE_MIDDLE;
1391             break;
1392         }
1393         case ANGLE_NW_RIGHT: {
1394             physicalX += width * MOUSE_ICON_BIAS_RATIO;
1395             [[fallthrough]];
1396         }
1397         case ANGLE_NW: {
1398             if (currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1399                 if (GetUserIconCopy() != nullptr) {
1400                     physicalX += userIconHotSpotX_;
1401                     physicalY += userIconHotSpotY_;
1402                 }
1403             }
1404             break;
1405         }
1406         default: {
1407             MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
1408             break;
1409         }
1410     }
1411 }
1412 
AdjustMouseFocusByDirection270(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)1413 void PointerDrawingManager::AdjustMouseFocusByDirection270(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
1414 {
1415     CALL_DEBUG_ENTER;
1416     int32_t height = imageHeight_;
1417     int32_t width = imageWidth_;
1418 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1419     CHKPV(hardwareCursorPointerManager_);
1420     if (hardwareCursorPointerManager_->IsSupported() &&
1421         currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1422         height = cursorHeight_;
1423         width = cursorWidth_;
1424     }
1425 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1426     switch (iconType) {
1427         case ANGLE_SW: {
1428             physicalY -= height;
1429             break;
1430         }
1431         case ANGLE_CENTER: {
1432             physicalX += width / CALCULATE_MIDDLE;
1433             physicalY -= height / CALCULATE_MIDDLE;
1434             break;
1435         }
1436         case ANGLE_NW_RIGHT: {
1437             physicalX += width * MOUSE_ICON_BIAS_RATIO;
1438             [[fallthrough]];
1439         }
1440         case ANGLE_NW: {
1441             if (currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1442                 if (GetUserIconCopy() != nullptr) {
1443                     physicalX += userIconHotSpotX_;
1444                     physicalY -= userIconHotSpotY_;
1445                 }
1446             }
1447             break;
1448         }
1449         default: {
1450             MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
1451             break;
1452         }
1453     }
1454 }
1455 
SetMouseDisplayState(bool state)1456 void PointerDrawingManager::SetMouseDisplayState(bool state)
1457 {
1458     CALL_DEBUG_ENTER;
1459     if (mouseDisplayState_ != state) {
1460         mouseDisplayState_ = state;
1461         if (mouseDisplayState_) {
1462             InitLayer(MOUSE_ICON(lastMouseStyle_.id));
1463         }
1464         MMI_HILOGI("The state:%{public}s", state ? "true" : "false");
1465         UpdatePointerVisible();
1466     }
1467 }
1468 
GetMouseDisplayState() const1469 bool PointerDrawingManager::GetMouseDisplayState() const
1470 {
1471     return mouseDisplayState_;
1472 }
1473 
FixCursorPosition(int32_t & physicalX,int32_t & physicalY)1474 void PointerDrawingManager::FixCursorPosition(int32_t &physicalX, int32_t &physicalY)
1475 {
1476     if (physicalX < 0) {
1477         physicalX = 0;
1478     }
1479 
1480     if (physicalY < 0) {
1481         physicalY = 0;
1482     }
1483     const int32_t cursorUnit = 16;
1484     Direction direction = static_cast<Direction>((
1485         ((displayInfo_.direction - displayInfo_.displayDirection) * ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
1486 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1487     if (hardwareCursorPointerManager_->IsSupported()) {
1488         direction = displayInfo_.direction;
1489     }
1490 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1491     if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
1492         direction = displayInfo_.direction;
1493     }
1494     if (displayInfo_.direction == DIRECTION0) {
1495         if (physicalX > (displayInfo_.validWidth - imageWidth_ / cursorUnit)) {
1496             physicalX = displayInfo_.validWidth - imageWidth_ / cursorUnit;
1497         }
1498         if (physicalY > (displayInfo_.validHeight - imageHeight_ / cursorUnit)) {
1499             physicalY = displayInfo_.validHeight - imageHeight_ / cursorUnit;
1500         }
1501     } else if (displayInfo_.direction == DIRECTION90) {
1502         if (physicalX > (displayInfo_.validHeight - imageHeight_ / cursorUnit)) {
1503             physicalX = displayInfo_.validHeight - imageHeight_ / cursorUnit;
1504         }
1505         if (physicalY < imageWidth_ / cursorUnit) {
1506             physicalY = imageWidth_ / cursorUnit;
1507         }
1508     } else if (displayInfo_.direction == DIRECTION180) {
1509         if (physicalX < imageHeight_ / cursorUnit) {
1510             physicalX = imageHeight_ / cursorUnit;
1511         }
1512         if (physicalY < imageWidth_ / cursorUnit) {
1513             physicalY = imageWidth_ / cursorUnit;
1514         }
1515     } else if (displayInfo_.direction == DIRECTION270) {
1516         if (physicalX < imageHeight_ / cursorUnit) {
1517             physicalX = imageHeight_ / cursorUnit;
1518         }
1519         if (physicalY > (displayInfo_.validWidth - imageWidth_ / cursorUnit)) {
1520             physicalY = displayInfo_.validWidth - imageWidth_ / cursorUnit;
1521         }
1522     }
1523 }
1524 
AttachToDisplay()1525 void PointerDrawingManager::AttachToDisplay()
1526 {
1527     CALL_DEBUG_ENTER;
1528     CHKPV(surfaceNode_);
1529     if (IsSingleDisplayFoldDevice() && (WIN_MGR->GetDisplayMode() == DisplayMode::MAIN)
1530         && (screenId_ == FOLD_SCREEN_ID_FULL)) {
1531         screenId_ = FOLD_SCREEN_ID_MAIN;
1532     }
1533     MMI_HILOGI("The screenId_:%{public}" PRIu64"", screenId_);
1534 
1535 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1536     CHKPV(hardwareCursorPointerManager_);
1537     if (g_isHdiRemoteDied) {
1538         hardwareCursorPointerManager_->SetHdiServiceState(false);
1539     }
1540     if (hardwareCursorPointerManager_->IsSupported()) {
1541         auto sp = GetScreenPointer(screenId_);
1542         CHKPV(sp);
1543         surfaceNode_ = sp->GetSurfaceNode();
1544         if (originSetColor_ != -1 && surfaceNode_ != nullptr) {
1545             float alphaRatio = (static_cast<uint32_t>(originSetColor_) >> RGB_CHANNEL_BITS_LENGTH) / MAX_ALPHA_VALUE;
1546             if (alphaRatio > 1) {
1547                 MMI_HILOGW("Invalid alphaRatio:%{public}f", alphaRatio);
1548             } else {
1549                 surfaceNode_->SetAlpha(1 - alphaRatio);
1550             }
1551         }
1552     }
1553 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1554     surfaceNode_->AttachToDisplay(screenId_);
1555 }
1556 
CreateCanvasNode()1557 void PointerDrawingManager::CreateCanvasNode()
1558 {
1559 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1560     CHKPV(hardwareCursorPointerManager_);
1561     if (g_isHdiRemoteDied) {
1562         hardwareCursorPointerManager_->SetHdiServiceState(false);
1563     }
1564     if (hardwareCursorPointerManager_->IsSupported()) {
1565         return;
1566     }
1567 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1568     CHKPV(surfaceNode_);
1569     canvasNode_ = Rosen::RSCanvasNode::Create();
1570     CHKPV(canvasNode_);
1571     canvasNode_->SetBounds(0, 0, canvasWidth_, canvasHeight_);
1572     canvasNode_->SetFrame(0, 0, canvasWidth_, canvasHeight_);
1573 #ifndef USE_ROSEN_DRAWING
1574     canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
1575 #else
1576     canvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1577 #endif // USE_ROSEN_DRAWING
1578     canvasNode_->SetCornerRadius(1);
1579     canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
1580     canvasNode_->SetRotation(0);
1581     surfaceNode_->AddChild(canvasNode_, DEFAULT_VALUE);
1582 }
1583 
1584 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
CreatePointerWindowForScreenPointer(int32_t displayId,int32_t physicalX,int32_t physicalY)1585 int32_t PointerDrawingManager::CreatePointerWindowForScreenPointer(int32_t displayId,
1586     int32_t physicalX, int32_t physicalY)
1587 {
1588     CALL_DEBUG_ENTER;
1589     // suface node init
1590     std::shared_ptr<ScreenPointer> sp = nullptr;
1591     {
1592         if (screenPointers_.count(displayId)) {
1593             sp = screenPointers_[displayId];
1594             if (!g_isRsRestart) {
1595                 for (auto it : screenPointers_) {
1596                     CHKPR(it.second, RET_ERR);
1597                     it.second->Init();
1598                 }
1599                 if (displayId == displayInfo_.id) {
1600                     surfaceNode_ = sp->GetSurfaceNode();
1601                 }
1602                 Rosen::RSTransaction::FlushImplicitTransaction();
1603                 g_isRsRestart = true;
1604             }
1605         } else {
1606             g_isRsRestart = true;
1607             sp = std::make_shared<ScreenPointer>(hardwareCursorPointerManager_, handler_, displayInfo_);
1608             screenPointers_[displayInfo_.id] = sp;
1609             CHKPR(sp, RET_ERR);
1610             if (!sp->Init()) {
1611                 MMI_HILOGE("ScreenPointer %{public}d init failed", displayInfo_.id);
1612                 return RET_ERR;
1613             }
1614             if (displayId == displayInfo_.id) {
1615                 surfaceNode_ = sp->GetSurfaceNode();
1616             }
1617             MMI_HILOGI("ScreenPointer displayId %{public}d displayInfo_.id %{public}d", displayId, displayInfo_.id);
1618             Rosen::RSTransaction::FlushImplicitTransaction();
1619         }
1620     }
1621     CHKPR(sp, RET_ERR);
1622     surfaceNode_ = sp->GetSurfaceNode(); // use SurfaceNode from current display
1623     CHKPR(surfaceNode_, RET_ERR);
1624     sp->MoveSoft(physicalX, physicalY, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)));
1625     return RET_OK;
1626 }
1627 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1628 
CreatePointerWindowForNoScreenPointer(int32_t displayId,int32_t physicalX,int32_t physicalY)1629 int32_t PointerDrawingManager::CreatePointerWindowForNoScreenPointer(int32_t displayId,
1630     int32_t physicalX, int32_t physicalY)
1631 {
1632     CALL_DEBUG_ENTER;
1633     Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
1634     surfaceNodeConfig.SurfaceNodeName = "pointer window";
1635     Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
1636     surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
1637     CHKPR(surfaceNode_, RET_ERR);
1638     surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
1639     surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
1640     surfaceNode_->SetBounds(physicalX, physicalY, canvasWidth_, canvasHeight_);
1641 #ifndef USE_ROSEN_DRAWING
1642     surfaceNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
1643 #else
1644     surfaceNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1645 #endif
1646     return RET_OK;
1647 }
1648 
CreatePointerWindow(int32_t displayId,int32_t physicalX,int32_t physicalY,Direction direction)1649 void PointerDrawingManager::CreatePointerWindow(int32_t displayId, int32_t physicalX, int32_t physicalY,
1650     Direction direction)
1651 {
1652     CALL_DEBUG_ENTER;
1653     CALL_INFO_TRACE;
1654     BytraceAdapter::StartRsSurfaceNode(displayId);
1655 
1656 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1657     CHKPV(hardwareCursorPointerManager_);
1658     if (g_isHdiRemoteDied) {
1659         hardwareCursorPointerManager_->SetHdiServiceState(false);
1660     }
1661     if (hardwareCursorPointerManager_->IsSupported()) {
1662         g_isHdiRemoteDied = false;
1663         if (CreatePointerWindowForScreenPointer(displayId, physicalX, physicalY) != RET_OK) {
1664             return;
1665         }
1666     } else {
1667         if (CreatePointerWindowForNoScreenPointer(displayId, physicalX, physicalY) != RET_OK) {
1668             return;
1669         }
1670     }
1671 #else
1672     if (CreatePointerWindowForNoScreenPointer(displayId, physicalX, physicalY) != RET_OK) {
1673         return;
1674     }
1675 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1676 
1677     screenId_ = static_cast<uint64_t>(displayId);
1678     AttachToDisplay();
1679     lastDisplayId_ = displayId;
1680     RotateDegree(direction);
1681     lastDirection_ = direction;
1682     CreateCanvasNode();
1683     Rosen::RSTransaction::FlushImplicitTransaction();
1684     BytraceAdapter::StopRsSurfaceNode();
1685 }
1686 
GetLayer()1687 sptr<OHOS::Surface> PointerDrawingManager::GetLayer()
1688 {
1689     CALL_DEBUG_ENTER;
1690     CHKPP(surfaceNode_);
1691     return surfaceNode_->GetSurface();
1692 }
1693 
GetSurfaceBuffer(sptr<OHOS::Surface> layer)1694 sptr<OHOS::SurfaceBuffer> PointerDrawingManager::GetSurfaceBuffer(sptr<OHOS::Surface> layer)
1695 {
1696     CALL_DEBUG_ENTER;
1697     sptr<OHOS::SurfaceBuffer> buffer;
1698     int32_t releaseFence = -1;
1699     int32_t width = 0;
1700     int32_t height = 0;
1701 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1702     CHKPP(hardwareCursorPointerManager_);
1703     if (g_isHdiRemoteDied) {
1704         hardwareCursorPointerManager_->SetHdiServiceState(false);
1705     }
1706     if (hardwareCursorPointerManager_->IsSupported()) {
1707         CALCULATE_CANVAS_SIZE(CALCULATE_CANVAS_SIZE_, CHANGE) = GetCanvasSize();
1708         auto canvasSize = static_cast<int32_t>(CALCULATE_CANVAS_SIZE_CHANGE);
1709         width = canvasSize;
1710         height = canvasSize;
1711     } else {
1712         width = canvasWidth_;
1713         height = canvasHeight_;
1714     }
1715 #else
1716     width = canvasWidth_;
1717     height = canvasHeight_;
1718 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1719     OHOS::BufferRequestConfig config = {
1720         .width = width,
1721         .height = height,
1722         .strideAlignment = 0x8,
1723         .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
1724         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
1725         .timeout = 150,
1726     };
1727 
1728     OHOS::SurfaceError ret = layer->RequestBuffer(buffer, releaseFence, config);
1729     if (ret != OHOS::SURFACE_ERROR_OK) {
1730         MMI_HILOGE("Request buffer ret:%{public}s", SurfaceErrorStr(ret).c_str());
1731         return nullptr;
1732     }
1733     sptr<OHOS::SyncFence> tempFence = new OHOS::SyncFence(releaseFence);
1734     if (tempFence != nullptr && (tempFence->Wait(SYNC_FENCE_WAIT_TIME) < 0)) {
1735         MMI_HILOGE("Failed to create surface, this buffer is not available");
1736     }
1737     return buffer;
1738 }
1739 
DrawImage(OHOS::Rosen::Drawing::Canvas & canvas,MOUSE_ICON mouseStyle)1740 void PointerDrawingManager::DrawImage(OHOS::Rosen::Drawing::Canvas &canvas, MOUSE_ICON mouseStyle)
1741 {
1742     MMI_HILOGI("Draw mouse icon of style(%{public}d)", static_cast<int32_t>(mouseStyle));
1743     OHOS::Rosen::Drawing::Pen pen;
1744     pen.SetAntiAlias(true);
1745     pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1746     OHOS::Rosen::Drawing::scalar penWidth = 1;
1747     pen.SetWidth(penWidth);
1748     canvas.AttachPen(pen);
1749     std::shared_ptr<Rosen::Drawing::Image> image = nullptr;
1750     std::shared_ptr<OHOS::Media::PixelMap> pixelmap = nullptr;
1751     if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1752         MMI_HILOGD("Set mouseicon by userIcon_");
1753         auto userIconCopy = GetUserIconCopy();
1754         image = ExtractDrawingImage(userIconCopy);
1755 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1756         SetPixelMap(userIconCopy);
1757 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1758     } else {
1759         surfaceNode_->SetBounds(lastPhysicalX_, lastPhysicalY_, canvasWidth_, canvasHeight_);
1760         if (mouseStyle == MOUSE_ICON::RUNNING) {
1761             pixelmap = DecodeImageToPixelMap(MOUSE_ICON::RUNNING_LEFT);
1762         } else {
1763             pixelmap = DecodeImageToPixelMap(mouseStyle);
1764         }
1765         CHKPV(pixelmap);
1766         image = ExtractDrawingImage(pixelmap);
1767 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1768         if ((mouseStyle == MOUSE_ICON::DEFAULT) || (mouseStyle == MOUSE_ICON::CURSOR_CIRCLE) ||
1769              (mouseStyle == MOUSE_ICON::AECH_DEVELOPER_DEFINED_ICON)) {
1770             SetPixelMap(pixelmap);
1771         }
1772 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1773     }
1774     CHKPV(image);
1775     OHOS::Rosen::Drawing::Brush brush;
1776     brush.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1777     canvas.DrawBackground(brush);
1778     canvas.DrawImage(*image, IMAGE_PIXEL, IMAGE_PIXEL, Rosen::Drawing::SamplingOptions());
1779     MMI_HILOGD("Canvas draw image, success");
1780 }
1781 
1782 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)1783 void PointerDrawingManager::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
1784 {
1785     MMI_HILOGI("Set pointer snapshot");
1786     pixelMap_ = pixelMap;
1787 }
1788 
GetPointerSnapshot(void * pixelMapPtr)1789 int32_t PointerDrawingManager::GetPointerSnapshot(void *pixelMapPtr)
1790 {
1791     CALL_DEBUG_ENTER;
1792     std::shared_ptr<Media::PixelMap> *newPixelMapPtr = static_cast<std::shared_ptr<Media::PixelMap> *>(pixelMapPtr);
1793     MMI_HILOGI("Get pointer snapshot");
1794     *newPixelMapPtr = pixelMap_;
1795     if (HasMagicCursor()) {
1796         MMI_HILOGE("magic pixelmap");
1797         *newPixelMapPtr = MAGIC_CURSOR->GetPixelMap();
1798     }
1799     CHKPR(*newPixelMapPtr, ERROR_NULL_POINTER);
1800     return RET_OK;
1801 }
1802 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1803 
DoDraw(uint8_t * addr,uint32_t width,uint32_t height,const MOUSE_ICON mouseStyle)1804 void PointerDrawingManager::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, const MOUSE_ICON mouseStyle)
1805 {
1806     CALL_DEBUG_ENTER;
1807     CHKPV(addr);
1808 
1809     const uint32_t addrSize = width * height * CURSOR_STRIDE;
1810 
1811     currentFrame_ = 0;
1812     OHOS::Rosen::Drawing::Bitmap bitmap;
1813     OHOS::Rosen::Drawing::BitmapFormat format { OHOS::Rosen::Drawing::COLORTYPE_RGBA_8888,
1814         OHOS::Rosen::Drawing::ALPHATYPE_OPAQUE };
1815     bitmap.Build(width, height, format);
1816     OHOS::Rosen::Drawing::Canvas canvas;
1817     canvas.Bind(bitmap);
1818     canvas.Clear(OHOS::Rosen::Drawing::Color::COLOR_TRANSPARENT);
1819     DrawImage(canvas, mouseStyle);
1820     errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize);
1821     if (ret != EOK) {
1822         MMI_HILOGE("Memcpy data is error, ret:%{public}d", ret);
1823         return;
1824     }
1825 }
1826 
DrawPixelmap(OHOS::Rosen::Drawing::Canvas & canvas,const MOUSE_ICON mouseStyle)1827 void PointerDrawingManager::DrawPixelmap(OHOS::Rosen::Drawing::Canvas &canvas, const MOUSE_ICON mouseStyle)
1828 {
1829     CALL_DEBUG_ENTER;
1830     OHOS::Rosen::Drawing::Pen pen;
1831     pen.SetAntiAlias(true);
1832     pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1833     OHOS::Rosen::Drawing::scalar penWidth = 1;
1834     pen.SetWidth(penWidth);
1835     canvas.AttachPen(pen);
1836     if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1837         MMI_HILOGD("Set mouseicon by userIcon_");
1838         auto userIconCopy = GetUserIconCopy();
1839         CHKPV(userIconCopy);
1840         OHOS::Rosen::RSPixelMapUtil::DrawPixelMap(canvas, *userIconCopy, 0, 0);
1841     } else {
1842         std::shared_ptr<OHOS::Media::PixelMap> pixelmap;
1843         if (mouseStyle == MOUSE_ICON::RUNNING) {
1844             pixelmap = DecodeImageToPixelMap(MOUSE_ICON::RUNNING_LEFT);
1845         } else {
1846             pixelmap = DecodeImageToPixelMap(mouseStyle);
1847         }
1848         CHKPV(pixelmap);
1849         MMI_HILOGD("Set mouseicon to OHOS system");
1850         OHOS::Rosen::RSPixelMapUtil::DrawPixelMap(canvas, *pixelmap, 0, 0);
1851     }
1852 }
1853 
SetCustomCursor(void * pixelMap,int32_t pid,int32_t windowId,int32_t focusX,int32_t focusY)1854 int32_t PointerDrawingManager::SetCustomCursor(void* pixelMap, int32_t pid, int32_t windowId, int32_t focusX,
1855     int32_t focusY)
1856 {
1857     CALL_DEBUG_ENTER;
1858     followSystem_ = false;
1859 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1860     userIconFollowSystem_ = true;
1861 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1862     CHKPR(pixelMap, RET_ERR);
1863     if (pid == -1) {
1864         MMI_HILOGE("The pid is invalid");
1865         return RET_ERR;
1866     }
1867     if (windowId < 0) {
1868         int32_t ret = UpdateCursorProperty(pixelMap, focusX, focusY);
1869         if (ret != RET_OK) {
1870             MMI_HILOGE("UpdateCursorProperty is failed");
1871             return ret;
1872         }
1873         // Constructing a PointerStyle indicates that the SA is being passed in
1874         MMI_HILOGE("This indicates that the message transmitted is SA, windowId:%{public}d", windowId);
1875         mouseIconUpdate_ = true;
1876         PointerStyle style;
1877         style.id = MOUSE_ICON::AECH_DEVELOPER_DEFINED_ICON;
1878         lastMouseStyle_ = style;
1879         ret = SetPointerStyle(pid, windowId, style);
1880         if (ret != RET_OK) {
1881             MMI_HILOGE("SetPointerStyle is failed");
1882         }
1883         return ret;
1884     }
1885     if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1886         MMI_HILOGE("The windowId not in right pid");
1887         return RET_ERR;
1888     }
1889     int32_t ret = UpdateCursorProperty(pixelMap, focusX, focusY);
1890     if (ret != RET_OK) {
1891         MMI_HILOGE("UpdateCursorProperty is failed");
1892         return ret;
1893     }
1894     mouseIconUpdate_ = true;
1895     PointerStyle style;
1896     style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
1897     lastMouseStyle_ = style;
1898 
1899     ret = SetPointerStyle(pid, windowId, style);
1900     if (ret == RET_ERR) {
1901         MMI_HILOGE("SetPointerStyle is failed");
1902     }
1903     MMI_HILOGD("style.id:%{public}d, userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
1904         style.id, userIconHotSpotX_, userIconHotSpotY_);
1905     return ret;
1906 }
1907 
1908 
UpdateCursorProperty(void * pixelMap,const int32_t & focusX,const int32_t & focusY)1909 int32_t PointerDrawingManager::UpdateCursorProperty(void* pixelMap, const int32_t &focusX, const int32_t &focusY)
1910 {
1911     CHKPR(pixelMap, RET_ERR);
1912     Media::PixelMap* newPixelMap = static_cast<Media::PixelMap*>(pixelMap);
1913     CHKPR(newPixelMap, RET_ERR);
1914     Media::ImageInfo imageInfo;
1915     newPixelMap->GetImageInfo(imageInfo);
1916     int32_t cursorSize = GetPointerSize();
1917     cursorWidth_ =
1918         pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1919     cursorHeight_ =
1920         pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1921     cursorWidth_ = cursorWidth_ < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorWidth_;
1922     cursorHeight_ = cursorHeight_ < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorHeight_;
1923     float xAxis = (float)cursorWidth_ / (float)imageInfo.size.width;
1924     float yAxis = (float)cursorHeight_ / (float)imageInfo.size.height;
1925     newPixelMap->scale(xAxis, yAxis, Media::AntiAliasingOption::LOW);
1926     {
1927         std::lock_guard<std::mutex> guard(mtx_);
1928         userIcon_.reset(newPixelMap);
1929     }
1930     userIconHotSpotX_ = static_cast<int32_t>((float)focusX * xAxis);
1931     userIconHotSpotY_ = static_cast<int32_t>((float)focusY * yAxis);
1932     MMI_HILOGI("cursorWidth:%{public}d, cursorHeight:%{public}d, imageWidth:%{public}d, imageHeight:%{public}d,"
1933         "focusX:%{public}d, focuxY:%{public}d, xAxis:%{public}f, yAxis:%{public}f, userIconHotSpotX_:%{public}d,"
1934         "userIconHotSpotY_:%{public}d", cursorWidth_, cursorHeight_, imageInfo.size.width, imageInfo.size.height,
1935         focusX, focusY, xAxis, yAxis, userIconHotSpotX_, userIconHotSpotY_);
1936     return RET_OK;
1937 }
1938 
SetMouseIcon(int32_t pid,int32_t windowId,void * pixelMap)1939 int32_t PointerDrawingManager::SetMouseIcon(int32_t pid, int32_t windowId, void* pixelMap)
1940     __attribute__((no_sanitize("cfi")))
1941 {
1942     CALL_DEBUG_ENTER;
1943     if (pid == -1) {
1944         MMI_HILOGE("pid is invalid return -1");
1945         return RET_ERR;
1946     }
1947     CHKPR(pixelMap, RET_ERR);
1948     if (windowId < 0) {
1949         MMI_HILOGE("Get invalid windowId, %{public}d", windowId);
1950         return RET_ERR;
1951     }
1952     if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1953         MMI_HILOGE("windowId not in right pid");
1954         return RET_ERR;
1955     }
1956     OHOS::Media::PixelMap* pixelMapPtr = static_cast<OHOS::Media::PixelMap*>(pixelMap);
1957     {
1958         std::lock_guard<std::mutex> guard(mtx_);
1959         userIcon_.reset(pixelMapPtr);
1960     }
1961 
1962     mouseIconUpdate_ = true;
1963     PointerStyle style;
1964     style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
1965     int32_t ret = SetPointerStyle(pid, windowId, style);
1966     if (ret == RET_ERR) {
1967         MMI_HILOGE("SetPointerStyle return RET_ERR here");
1968     }
1969     return ret;
1970 }
1971 
SetMouseHotSpot(int32_t pid,int32_t windowId,int32_t hotSpotX,int32_t hotSpotY)1972 int32_t PointerDrawingManager::SetMouseHotSpot(int32_t pid, int32_t windowId, int32_t hotSpotX, int32_t hotSpotY)
1973 {
1974     CALL_DEBUG_ENTER;
1975     if (pid == -1) {
1976         MMI_HILOGE("Pid is invalid return -1");
1977         return RET_ERR;
1978     }
1979     if (windowId < 0) {
1980         MMI_HILOGE("Invalid windowId, %{public}d", windowId);
1981         return RET_ERR;
1982     }
1983     if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1984         MMI_HILOGE("WindowId not in right pid");
1985         return RET_ERR;
1986     }
1987     auto userIconCopy = GetUserIconCopy();
1988     if (hotSpotX < 0 || hotSpotY < 0 || userIconCopy == nullptr) {
1989         MMI_HILOGE("Invalid value");
1990         return RET_ERR;
1991     }
1992     PointerStyle pointerStyle;
1993     WIN_MGR->GetPointerStyle(pid, windowId, pointerStyle);
1994     if (pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1995         MMI_HILOGE("Get pointer style failed, pid %{public}d, pointerStyle %{public}d", pid, pointerStyle.id);
1996         return RET_ERR;
1997     }
1998     userIconHotSpotX_ = hotSpotX;
1999     userIconHotSpotY_ = hotSpotY;
2000     return RET_OK;
2001 }
2002 
ChangeSvgCursorColor(std::string & str,int32_t color)2003 static void ChangeSvgCursorColor(std::string& str, int32_t color)
2004 {
2005     std::string targetColor = IntToHexRGB(color);
2006     StringReplace(str, "#000000", targetColor);
2007     if (color == MAX_POINTER_COLOR) {
2008         // stroke=\"#FFFFFF" fill="#000000" stroke-linejoin="round" transform="xxx"
2009         std::regex re("(<path.*)(stroke=\"#[a-fA-F0-9]{6}\")(.*path>)");
2010         str = std::regex_replace(str, re, "$1stroke=\"#000000\"$3");
2011     }
2012 }
2013 
LoadCursorSvgWithColor(MOUSE_ICON type,int32_t color)2014 std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::LoadCursorSvgWithColor(MOUSE_ICON type, int32_t color)
2015 {
2016     CALL_DEBUG_ENTER;
2017     std::string svgContent;
2018     std::string imagePath = mouseIcons_[type].iconPath;
2019     if (!ReadFile(imagePath, svgContent)) {
2020         MMI_HILOGE("read file failed");
2021         return nullptr;
2022     }
2023     OHOS::Media::SourceOptions opts;
2024     uint32_t ret = 0;
2025     std::unique_ptr<std::istream> isp(std::make_unique<std::istringstream>(svgContent));
2026     auto imageSource = OHOS::Media::ImageSource::CreateImageSource(std::move(isp), opts, ret);
2027     if (!imageSource || ret != ERR_OK) {
2028         MMI_HILOGE("Get image source failed, ret:%{public}d", ret);
2029     }
2030     CHKPP(imageSource);
2031     OHOS::Media::DecodeOptions decodeOpts;
2032     decodeOpts.desiredSize = {
2033         .width = imageWidth_,
2034         .height = imageHeight_
2035     };
2036     int32_t pointerColor = GetPointerColor();
2037     if (tempPointerColor_ != DEFAULT_VALUE && type != AECH_DEVELOPER_DEFINED_STYLE) {
2038         decodeOpts.SVGOpts.fillColor = {.isValidColor = true, .color = pointerColor};
2039         if (color == MAX_POINTER_COLOR) {
2040             decodeOpts.SVGOpts.strokeColor = {.isValidColor = true, .color = MIN_POINTER_COLOR};
2041         } else {
2042             decodeOpts.SVGOpts.strokeColor = {.isValidColor = true, .color = MAX_POINTER_COLOR};
2043         }
2044     }
2045 
2046     std::shared_ptr<OHOS::Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, ret);
2047     CHKPL(pixelMap);
2048     return pixelMap;
2049 }
DecodeImageToPixelMap(MOUSE_ICON type)2050 std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::DecodeImageToPixelMap(MOUSE_ICON type)
2051 {
2052     CALL_DEBUG_ENTER;
2053     auto pointerColor = GetPointerColor();
2054     std::lock_guard<std::mutex> guard(mousePixelMapMutex_);
2055     auto pixelInfo = mousePixelMap_.find(type);
2056     // 目前只缓存了两个光标
2057     if (pixelInfo == mousePixelMap_.end()) {
2058         return LoadCursorSvgWithColor(type, pointerColor);
2059     }
2060     if (pixelInfo->second.imageWidth != imageWidth_ || pixelInfo->second.imageHeight != imageHeight_ ||
2061         pixelInfo->second.pointerColor != pointerColor) {
2062         ReloadPixelMaps(mousePixelMap_, pointerColor);
2063         return mousePixelMap_[type].pixelMap;
2064     } else {
2065         return pixelInfo->second.pixelMap;
2066     }
2067 }
2068 
GetPreferenceKey(std::string & name)2069 void PointerDrawingManager::GetPreferenceKey(std::string &name)
2070 {
2071 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2072     if (HasMagicCursor()) {
2073         if (name == POINTER_COLOR) {
2074             name = MAGIC_POINTER_COLOR;
2075         } else if (name == POINTER_SIZE) {
2076             name = MAGIC_POINTER_SIZE;
2077         }
2078     }
2079 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2080 }
2081 
ReloadPixelMaps(std::map<MOUSE_ICON,PixelMapInfo> & mousePixelMap,int32_t pointerColor)2082 int32_t PointerDrawingManager::ReloadPixelMaps(
2083     std::map<MOUSE_ICON, PixelMapInfo>& mousePixelMap, int32_t pointerColor)
2084 {
2085     for (auto iter = mousePixelMap.begin(); iter != mousePixelMap.end(); ++iter) {
2086         std::shared_ptr<OHOS::Media::PixelMap> pixelMap = LoadCursorSvgWithColor(iter->first, pointerColor);
2087         CHKPR(pixelMap, RET_ERR);
2088         iter->second.pixelMap = pixelMap;
2089         iter->second.imageWidth = imageWidth_;
2090         iter->second.imageHeight = imageHeight_;
2091         iter->second.pointerColor = pointerColor;
2092         int32_t width = pixelMap->GetWidth();
2093         int32_t height = pixelMap->GetHeight();
2094         MMI_HILOGI("Pixelmap width:%{public}d, height:%{public}d, %{public}d update success",
2095             width, height, iter->first);
2096     }
2097     return RET_OK;
2098 }
2099 
SetPointerColor(int32_t color)2100 int32_t PointerDrawingManager::SetPointerColor(int32_t color)
2101 {
2102     CALL_DEBUG_ENTER;
2103     MMI_HILOGI("PointerColor:%{public}x", color);
2104     originSetColor_ = color;
2105     // ARGB从表面看比RGB多了个A,也是一种色彩模式,是在RGB的基础上添加了Alpha(透明度)通道。
2106     // 透明度也是以0到255表示的,所以也是总共有256级,透明是0,不透明是255。
2107     // 这个color每8位代表一个通道值,分别是alpha和rgb,总共32位。
2108     color = static_cast<int32_t>(static_cast<uint32_t>(color) & static_cast<uint32_t>(MAX_POINTER_COLOR));
2109     std::string name = POINTER_COLOR;
2110     GetPreferenceKey(name);
2111     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, color);
2112     if (ret != RET_OK) {
2113         MMI_HILOGE("Set pointer color failed, color:%{public}d", color);
2114         return ret;
2115     }
2116     MMI_HILOGD("Set pointer color successfully, color:%{public}d", color);
2117     if (!WIN_MGR->GetExtraData().drawCursor) {
2118         if (surfaceNode_ != nullptr) {
2119             float alphaRatio = (static_cast<uint32_t>(color) >> RGB_CHANNEL_BITS_LENGTH) / MAX_ALPHA_VALUE;
2120             if (alphaRatio > 1) {
2121                 MMI_HILOGW("Invalid alphaRatio:%{public}f", alphaRatio);
2122             } else {
2123                 surfaceNode_->SetAlpha(1 - alphaRatio);
2124             }
2125         }
2126 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2127         if (HasMagicCursor()) {
2128             ret = MAGIC_CURSOR->SetPointerColor(color);
2129         } else {
2130             ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
2131         }
2132 #else
2133         ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
2134 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2135         if (ret != RET_OK) {
2136             MMI_HILOGE("Init layer failed");
2137             return RET_ERR;
2138         }
2139     }
2140     UpdatePointerVisible();
2141     SetHardwareCursorPosition(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, lastMouseStyle_);
2142     return RET_OK;
2143 }
2144 
GetPointerColor()2145 int32_t PointerDrawingManager::GetPointerColor()
2146 {
2147     CALL_DEBUG_ENTER;
2148     std::string name = POINTER_COLOR;
2149     GetPreferenceKey(name);
2150     int32_t pointerColor = PREFERENCES_MGR->GetIntValue(name, DEFAULT_VALUE);
2151     tempPointerColor_ = pointerColor;
2152     if (pointerColor == DEFAULT_VALUE) {
2153         pointerColor = MIN_POINTER_COLOR;
2154     }
2155     MMI_HILOGD("Get pointer color successfully, pointerColor:%{public}d", pointerColor);
2156     return pointerColor;
2157 }
2158 
UpdateDisplayInfo(const DisplayInfo & displayInfo)2159 void PointerDrawingManager::UpdateDisplayInfo(const DisplayInfo &displayInfo)
2160 {
2161     CALL_DEBUG_ENTER;
2162 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2163     CHKPV(hardwareCursorPointerManager_);
2164     if (g_isHdiRemoteDied) {
2165         hardwareCursorPointerManager_->SetHdiServiceState(false);
2166     }
2167     if (hardwareCursorPointerManager_->IsSupported()) {
2168         if (screenPointers_.count(displayInfo.id)) {
2169             auto sp = screenPointers_[displayInfo.id];
2170             CHKPV(sp);
2171             if (sp->IsMain()) {
2172                 UpdateMirrorScreens(sp, displayInfo);
2173             }
2174             sp->OnDisplayInfo(displayInfo);
2175         }
2176     }
2177 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2178 
2179     hasDisplay_ = true;
2180     displayInfo_ = displayInfo;
2181     int32_t size = GetPointerSize();
2182     imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * GetIndependentPixels() / BASELINE_DENSITY;
2183     imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * GetIndependentPixels() / BASELINE_DENSITY;
2184     canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
2185     canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
2186 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2187     MAGIC_CURSOR->SetDisplayInfo(displayInfo);
2188 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2189 }
2190 
GetIndependentPixels()2191 int32_t PointerDrawingManager::GetIndependentPixels()
2192 {
2193     CALL_DEBUG_ENTER;
2194 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2195     if (HasMagicCursor()) {
2196         return MAGIC_INDEPENDENT_PIXELS;
2197     } else {
2198         return DEVICE_INDEPENDENT_PIXELS;
2199     }
2200 #else
2201     return DEVICE_INDEPENDENT_PIXELS;
2202 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2203 }
2204 
SetPointerSize(int32_t size)2205 int32_t PointerDrawingManager::SetPointerSize(int32_t size)
2206 {
2207     CALL_DEBUG_ENTER;
2208     if (size < MIN_POINTER_SIZE) {
2209         size = MIN_POINTER_SIZE;
2210     } else if (size > MAX_POINTER_SIZE) {
2211         size = MAX_POINTER_SIZE;
2212     }
2213     std::string name = POINTER_SIZE;
2214     GetPreferenceKey(name);
2215     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, size);
2216     if (ret != RET_OK) {
2217         MMI_HILOGE("Set pointer size failed, code:%{public}d", ret);
2218         return ret;
2219     }
2220 
2221     CHKPR(surfaceNode_, RET_OK);
2222     imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
2223     imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
2224     canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
2225     canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
2226     int32_t physicalX = lastPhysicalX_;
2227     int32_t physicalY = lastPhysicalY_;
2228 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2229     MAGIC_CURSOR->SetPointerSize(imageWidth_, imageHeight_);
2230 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2231     Direction direction = static_cast<Direction>((
2232         ((displayInfo_.direction - displayInfo_.displayDirection) * ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
2233     auto& iconPath = GetMouseIconPath();
2234     AdjustMouseFocus(direction, ICON_TYPE(iconPath.at(MOUSE_ICON(lastMouseStyle_.id)).alignmentWay),
2235         physicalX, physicalY);
2236 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2237     if (HasMagicCursor()) {
2238         MAGIC_CURSOR->CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction, surfaceNode_);
2239     } else {
2240         CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
2241     }
2242 #else
2243     CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
2244 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2245     if (lastMouseStyle_.id == MOUSE_ICON::CURSOR_CIRCLE) {
2246         MMI_HILOGE("Cursor circle does not need to draw size");
2247     }
2248     if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
2249         MMI_HILOGE("Init layer failed");
2250         return RET_ERR;
2251     }
2252     UpdatePointerVisible();
2253     SetHardwareCursorPosition(displayInfo_.id, physicalX, physicalY, lastMouseStyle_);
2254     return RET_OK;
2255 }
2256 
GetPointerSize()2257 int32_t PointerDrawingManager::GetPointerSize()
2258 {
2259     CALL_DEBUG_ENTER;
2260     std::string name = POINTER_SIZE;
2261     GetPreferenceKey(name);
2262     int32_t pointerSize = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_SIZE);
2263     MMI_HILOGD("Get pointer size successfully, pointerSize:%{public}d", pointerSize);
2264     return pointerSize;
2265 }
2266 
GetPointerImageSize(int32_t & width,int32_t & height)2267 void PointerDrawingManager::GetPointerImageSize(int32_t &width, int32_t &height)
2268 {
2269     width = imageWidth_;
2270     height = imageHeight_;
2271 }
2272 
GetCursorSurfaceId(uint64_t & surfaceId)2273 int32_t PointerDrawingManager::GetCursorSurfaceId(uint64_t &surfaceId)
2274 {
2275     surfaceId = (surfaceNode_ != nullptr ? surfaceNode_->GetId() : Rosen::INVALID_NODEID);
2276     MMI_HILOGI("CursorSurfaceId:%{public}" PRIu64, surfaceId);
2277     return RET_OK;
2278 }
2279 
OnDisplayInfo(const DisplayGroupInfo & displayGroupInfo)2280 void PointerDrawingManager::OnDisplayInfo(const DisplayGroupInfo &displayGroupInfo)
2281 {
2282     CALL_DEBUG_ENTER;
2283     for (const auto& item : displayGroupInfo.displaysInfo) {
2284         if (item.id == displayInfo_.id) {
2285             UpdateDisplayInfo(item);
2286             DrawManager();
2287             return;
2288         }
2289     }
2290     DisplayInfo displayInfo = displayGroupInfo.displaysInfo[0];
2291 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2292     (void)GetMainScreenDisplayInfo(displayGroupInfo, displayInfo);
2293 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2294     UpdateDisplayInfo(displayInfo);
2295     lastPhysicalX_ = displayInfo.validWidth / CALCULATE_MIDDLE;
2296     lastPhysicalY_ = displayInfo.validHeight / CALCULATE_MIDDLE;
2297     MouseEventHdr->OnDisplayLost(displayInfo_.id);
2298     if (surfaceNode_ != nullptr) {
2299 #ifndef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2300         surfaceNode_->DetachToDisplay(screenId_);
2301         surfaceNode_ = nullptr;
2302 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2303         Rosen::RSTransaction::FlushImplicitTransaction();
2304         MMI_HILOGD("Pointer window destroy success");
2305     }
2306     MMI_HILOGD("displayId_:%{public}d, displayWidth_:%{public}d, displayHeight_:%{public}d",
2307         displayInfo_.id, displayInfo_.validWidth, displayInfo_.validHeight);
2308 }
2309 
OnWindowInfo(const WinInfo & info)2310 void PointerDrawingManager::OnWindowInfo(const WinInfo &info)
2311 {
2312     CALL_DEBUG_ENTER;
2313     if (pid_ != info.windowPid) {
2314         windowId_ = info.windowId;
2315         pid_ = info.windowPid;
2316 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2317         PostTask([this]() {
2318             UpdatePointerVisible();
2319         });
2320 #else
2321         UpdatePointerVisible();
2322 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2323     }
2324 }
2325 
UpdatePointerDevice(bool hasPointerDevice,bool isPointerVisible,bool isHotPlug)2326 void PointerDrawingManager::UpdatePointerDevice(bool hasPointerDevice, bool isPointerVisible,
2327     bool isHotPlug)
2328 {
2329     CALL_DEBUG_ENTER;
2330     MMI_HILOGD("The hasPointerDevice:%{public}s, isPointerVisible:%{public}s",
2331         hasPointerDevice ? "true" : "false", isPointerVisible? "true" : "false");
2332     hasPointerDevice_ = hasPointerDevice;
2333     if (hasPointerDevice_) {
2334         bool pointerVisible = isPointerVisible;
2335         if (!isHotPlug) {
2336             pointerVisible = (pointerVisible && IsPointerVisible());
2337         }
2338         SetPointerVisible(getpid(), pointerVisible, 0, false);
2339 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2340         AttachAllSurfaceNode();
2341 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2342     } else {
2343         DeletePointerVisible(getpid());
2344     }
2345     DrawManager();
2346     if (!hasPointerDevice_) {
2347         MMI_HILOGD("Pointer window destroy start");
2348 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2349         DetachAllSurfaceNode();
2350 #else
2351         if (surfaceNode_ != nullptr) {
2352             surfaceNode_->DetachToDisplay(screenId_);
2353             surfaceNode_ = nullptr;
2354         }
2355 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2356         Rosen::RSTransaction::FlushImplicitTransaction();
2357         MMI_HILOGD("Pointer window destroy success");
2358     }
2359 }
2360 
2361 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
AttachAllSurfaceNode()2362 void PointerDrawingManager::AttachAllSurfaceNode()
2363 {
2364     std::lock_guard<std::mutex> lock(mtx_);
2365     for (auto sp : screenPointers_) {
2366         if (sp.second != nullptr) {
2367             auto surfaceNode = sp.second->GetSurfaceNode();
2368             if (surfaceNode != nullptr) {
2369                 auto screenId = sp.second->GetScreenId();
2370                 MMI_HILOGI("Attach screenId:%{public}u", screenId);
2371                 surfaceNode->AttachToDisplay(screenId);
2372             }
2373         }
2374     }
2375 }
2376 
DetachAllSurfaceNode()2377 void PointerDrawingManager::DetachAllSurfaceNode()
2378 {
2379     std::lock_guard<std::mutex> lock(mtx_);
2380     for (auto sp : screenPointers_) {
2381         if (sp.second != nullptr) {
2382             auto surfaceNode = sp.second->GetSurfaceNode();
2383             if (surfaceNode != nullptr) {
2384                 auto screenId = sp.second->GetScreenId();
2385                 MMI_HILOGI("Detach screenId:%{public}u", screenId);
2386                 surfaceNode->DetachToDisplay(screenId);
2387             }
2388         }
2389     }
2390 }
2391 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2392 
DrawManager()2393 void PointerDrawingManager::DrawManager()
2394 {
2395     CALL_DEBUG_ENTER;
2396 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2397     if (HasMagicCursor() && lastDrawPointerStyle_.id != currentMouseStyle_.id
2398         && (lastDrawPointerStyle_.id == DEVELOPER_DEFINED_ICON
2399         || currentMouseStyle_.id == DEVELOPER_DEFINED_ICON)) {
2400         if (surfaceNode_ != nullptr) {
2401             surfaceNode_->DetachToDisplay(screenId_);
2402             surfaceNode_ = nullptr;
2403             Rosen::RSTransaction::FlushImplicitTransaction();
2404         }
2405     }
2406 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2407     if (hasDisplay_ && hasPointerDevice_ && surfaceNode_ == nullptr) {
2408         MMI_HILOGD("Draw pointer begin");
2409         PointerStyle pointerStyle;
2410         WIN_MGR->GetPointerStyle(pid_, windowId_, pointerStyle);
2411         MMI_HILOGD("Get pid %{public}d with pointerStyle %{public}d", pid_, pointerStyle.id);
2412         Direction direction = static_cast<Direction>((
2413             ((displayInfo_.direction - displayInfo_.displayDirection) * ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
2414         lastDrawPointerStyle_ = pointerStyle;
2415         if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
2416             DrawPointer(displayInfo_.id, displayInfo_.validWidth / CALCULATE_MIDDLE,
2417                 displayInfo_.validHeight / CALCULATE_MIDDLE, pointerStyle, direction);
2418             MMI_HILOGD("Draw manager, mouseStyle:%{public}d, last physical is initial value", pointerStyle.id);
2419             return;
2420         }
2421         DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
2422         MMI_HILOGD("Draw manager, mouseStyle:%{public}d", pointerStyle.id);
2423         return;
2424     }
2425 }
2426 
InitPixelMaps()2427 void PointerDrawingManager::InitPixelMaps()
2428 {
2429     auto pointerColor = GetPointerColor();
2430     std::lock_guard<std::mutex> guard(mousePixelMapMutex_);
2431     mousePixelMap_[MOUSE_ICON::LOADING];
2432     mousePixelMap_[MOUSE_ICON::RUNNING];
2433     ReloadPixelMaps(mousePixelMap_, pointerColor);
2434 }
2435 
Init()2436 bool PointerDrawingManager::Init()
2437 {
2438     CALL_DEBUG_ENTER;
2439     auto self = std::shared_ptr<PointerDrawingManager>(this, [](PointerDrawingManager*) {});
2440     INPUT_DEV_MGR->Attach(self);
2441     pidInfos_.clear();
2442     hapPidInfos_.clear();
2443     {
2444         std::lock_guard<std::mutex> guard(mousePixelMapMutex_);
2445         mousePixelMap_.clear();
2446     }
2447     InitPixelMaps();
2448     return true;
2449 }
2450 
GetInstance()2451 IPointerDrawingManager* IPointerDrawingManager::GetInstance()
2452 {
2453     static PointerDrawingManager instance;
2454     return &instance;
2455 }
2456 
UpdatePointerVisible()2457 void PointerDrawingManager::UpdatePointerVisible()
2458 {
2459     CALL_DEBUG_ENTER;
2460     CHKPV(surfaceNode_);
2461     if (IsPointerVisible() && mouseDisplayState_) {
2462         surfaceNode_->SetVisible(true);
2463 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2464         CHKPV(hardwareCursorPointerManager_);
2465         if (g_isHdiRemoteDied) {
2466             hardwareCursorPointerManager_->SetHdiServiceState(false);
2467         }
2468         if (hardwareCursorPointerManager_->IsSupported()) {
2469             if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
2470                 MMI_HILOGE("Init Layer failed");
2471                 return;
2472             }
2473             auto align = MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id));
2474             if (!SetCursorLocation(displayId_, lastPhysicalX_, lastPhysicalY_, align)) {
2475                 MMI_HILOGE("SetCursorLocation fail");
2476             }
2477         }
2478 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2479         MMI_HILOGI("Pointer window show success, mouseDisplayState_:%{public}s, displayId_:%{public}d",
2480             mouseDisplayState_ ? "true" : "false", displayId_);
2481     } else {
2482 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2483         CHKPV(hardwareCursorPointerManager_);
2484         if (g_isHdiRemoteDied) {
2485             hardwareCursorPointerManager_->SetHdiServiceState(false);
2486         }
2487         if (hardwareCursorPointerManager_->IsSupported()) {
2488             PostSoftCursorTask([this]() {
2489                 SoftwareCursorRender(MOUSE_ICON::TRANSPARENT_ICON);
2490             });
2491             HideHardwareCursors();
2492         }
2493 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2494         surfaceNode_->SetVisible(false);
2495         MMI_HILOGI("Pointer window hide success, mouseDisplayState_:%{public}s",
2496             mouseDisplayState_ ? "true" : "false");
2497     }
2498     Rosen::RSTransaction::FlushImplicitTransaction();
2499 }
2500 
IsPointerVisible()2501 bool PointerDrawingManager::IsPointerVisible()
2502 {
2503     CALL_DEBUG_ENTER;
2504     if (!pidInfos_.empty()) {
2505         auto info = pidInfos_.back();
2506         if (!info.visible) {
2507             MMI_HILOGI("High priority visible property:%{public}zu.%{public}d-visible:%{public}s",
2508                 pidInfos_.size(), info.pid, info.visible?"true":"false");
2509             return info.visible;
2510         }
2511     }
2512     if (!hapPidInfos_.empty()) {
2513         for (auto& item : hapPidInfos_) {
2514             if (item.pid == pid_) {
2515                 MMI_HILOGI("Visible pid:%{public}d-visible:%{public}s",
2516                     item.pid, item.visible ? "true" : "false");
2517                 return item.visible;
2518             }
2519         }
2520         if (!(INPUT_DEV_MGR->HasPointerDevice() || WIN_MGR->IsMouseSimulate()) || pid_ == 0) {
2521             auto info = hapPidInfos_.back();
2522             MMI_HILOGI("Only hap visible pid:%{public}d-visible:%{public}s",
2523                 info.pid, info.visible ? "true" : "false");
2524             return info.visible;
2525         }
2526     }
2527     if (pidInfos_.empty()) {
2528         MMI_HILOGD("Visible property is true");
2529         return true;
2530     }
2531     auto info = pidInfos_.back();
2532     MMI_HILOGI("Visible property:%{public}zu.%{public}d-visible:%{public}s",
2533         pidInfos_.size(), info.pid, info.visible ? "true" : "false");
2534     return info.visible;
2535 }
2536 
DeletePointerVisible(int32_t pid)2537 void PointerDrawingManager::DeletePointerVisible(int32_t pid)
2538 {
2539     CALL_DEBUG_ENTER;
2540     MMI_HILOGI("The g_isRsRemoteDied:%{public}d", g_isRsRemoteDied ? 1 : 0);
2541     if (g_isRsRemoteDied && surfaceNode_ != nullptr) {
2542         g_isRsRemoteDied = false;
2543         surfaceNode_->DetachToDisplay(screenId_);
2544         surfaceNode_ = nullptr;
2545         Rosen::RSTransaction::FlushImplicitTransaction();
2546     }
2547     if (pidInfos_.empty()) {
2548         return;
2549     }
2550     auto it = pidInfos_.begin();
2551     for (; it != pidInfos_.end(); ++it) {
2552         if (it->pid == pid) {
2553             pidInfos_.erase(it);
2554             break;
2555         }
2556     }
2557     if (it != pidInfos_.end()) {
2558         if (IsPointerVisible()) {
2559             InitLayer(MOUSE_ICON(lastMouseStyle_.id));
2560         }
2561         UpdatePointerVisible();
2562     }
2563 }
2564 
GetPointerVisible(int32_t pid)2565 bool PointerDrawingManager::GetPointerVisible(int32_t pid)
2566 {
2567     bool ret = true;
2568     int32_t count = 0;
2569     for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
2570         if (it->pid == pid) {
2571             count++;
2572             ret = it->visible;
2573             break;
2574         }
2575     }
2576     if (count == 0 && !hapPidInfos_.empty()) {
2577         for (auto& item : hapPidInfos_) {
2578             if (item.pid == pid_) {
2579                 MMI_HILOGI("Visible pid:%{public}d-visible:%{public}s",
2580                     item.pid, item.visible ? "true" : "false");
2581                 count++;
2582                 ret = item.visible;
2583                 break;
2584             }
2585         }
2586     }
2587     return ret;
2588 }
2589 
OnSessionLost(int32_t pid)2590 void PointerDrawingManager::OnSessionLost(int32_t pid)
2591 {
2592     for (auto it = hapPidInfos_.begin(); it != hapPidInfos_.end(); ++it) {
2593         if (it->pid == pid) {
2594             hapPidInfos_.erase(it);
2595             break;
2596         }
2597     }
2598 }
2599 
SetPointerVisible(int32_t pid,bool visible,int32_t priority,bool isHap)2600 int32_t PointerDrawingManager::SetPointerVisible(int32_t pid, bool visible, int32_t priority, bool isHap)
2601 {
2602     MMI_HILOGI("The pid:%{public}d,visible:%{public}s,priority:%{public}d,isHap:%{public}s", pid,
2603         visible ? "true" : "false", priority, isHap ? "true" : "false");
2604     if (isHap) {
2605         for (auto it = hapPidInfos_.begin(); it != hapPidInfos_.end(); ++it) {
2606             if (it->pid == pid) {
2607                 hapPidInfos_.erase(it);
2608                 break;
2609             }
2610         }
2611         PidInfo info = { .pid = pid, .visible = visible };
2612         hapPidInfos_.push_back(info);
2613         if (hapPidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
2614             hapPidInfos_.pop_front();
2615         }
2616         UpdatePointerVisible();
2617         return RET_OK;
2618     }
2619     if (WIN_MGR->GetExtraData().appended && visible && priority == 0) {
2620         MMI_HILOGE("current is drag state, can not set pointer visible");
2621         return RET_ERR;
2622     }
2623     for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
2624         if (it->pid == pid) {
2625             pidInfos_.erase(it);
2626             break;
2627         }
2628     }
2629     PidInfo info = { .pid = pid, .visible = visible };
2630     pidInfos_.push_back(info);
2631     if (pidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
2632         pidInfos_.pop_front();
2633     }
2634     if (!WIN_MGR->HasMouseHideFlag() || INPUT_DEV_MGR->HasPointerDevice() || INPUT_DEV_MGR->HasVirtualPointerDevice()) {
2635         UpdatePointerVisible();
2636     }
2637     return RET_OK;
2638 }
2639 
SetPointerLocation(int32_t x,int32_t y,int32_t displayId)2640 void PointerDrawingManager::SetPointerLocation(int32_t x, int32_t y, int32_t displayId)
2641 {
2642     CALL_DEBUG_ENTER;
2643     FixCursorPosition(x, y);
2644     lastPhysicalX_ = x;
2645     lastPhysicalY_ = y;
2646     MMI_HILOGD("Pointer window move, x:%{public}d, y:%{public}d", lastPhysicalX_, lastPhysicalY_);
2647     CHKPV(surfaceNode_);
2648     displayId_ = displayId;
2649 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2650     CHKPV(hardwareCursorPointerManager_);
2651     if (g_isHdiRemoteDied) {
2652         hardwareCursorPointerManager_->SetHdiServiceState(false);
2653     }
2654     if (hardwareCursorPointerManager_->IsSupported()) {
2655         if (!SetCursorLocation(displayId_, x, y, MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id)))) {
2656             MMI_HILOGE("SetCursorLocation fail");
2657             return;
2658         }
2659     }
2660 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2661     MMI_HILOGD("Pointer window move success");
2662 }
2663 
UpdateDefaultPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle,bool isUiExtension)2664 int32_t PointerDrawingManager::UpdateDefaultPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle,
2665     bool isUiExtension)
2666 {
2667     if (windowId != GLOBAL_WINDOW_ID) {
2668         MMI_HILOGD("No need to change the default icon style");
2669         return RET_OK;
2670     }
2671     PointerStyle style;
2672     WIN_MGR->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style, isUiExtension);
2673     if (pointerStyle.id != style.id) {
2674         auto iconPath = GetMouseIconPath();
2675         auto it = iconPath.find(MOUSE_ICON(MOUSE_ICON::DEFAULT));
2676         if (it == iconPath.end()) {
2677             MMI_HILOGE("Cannot find the default style");
2678             return RET_ERR;
2679         }
2680         std::string newIconPath;
2681         if (pointerStyle.id == MOUSE_ICON::DEFAULT) {
2682             newIconPath = DefaultIconPath;
2683         } else {
2684             newIconPath = iconPath.at(MOUSE_ICON(pointerStyle.id)).iconPath;
2685         }
2686         MMI_HILOGD("Default path has changed from %{public}s to %{public}s",
2687             it->second.iconPath.c_str(), newIconPath.c_str());
2688         UpdateIconPath(MOUSE_ICON(MOUSE_ICON::DEFAULT), newIconPath);
2689     }
2690     lastMouseStyle_ = style;
2691     return RET_OK;
2692 }
2693 
GetMouseIconPath()2694 const std::map<MOUSE_ICON, IconStyle>& PointerDrawingManager::GetMouseIconPath()
2695 {
2696     CALL_DEBUG_ENTER;
2697 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2698     if (HasMagicCursor()) {
2699         MMI_HILOGD("Magiccurosr get magic mouse map");
2700         return MAGIC_CURSOR->magicMouseIcons_;
2701     } else {
2702         MMI_HILOGD("Magiccurosr get mouse icon, HasMagicCursor is false");
2703         return mouseIcons_;
2704     }
2705 #else
2706     return mouseIcons_;
2707 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2708 }
2709 
GetIconStyle(const MOUSE_ICON mouseStyle)2710 IconStyle PointerDrawingManager::GetIconStyle(const MOUSE_ICON mouseStyle)
2711 {
2712     std::map<MOUSE_ICON, IconStyle> mouseIcons = GetMouseIcons();
2713     auto iter = mouseIcons.find(mouseStyle);
2714     if (iter == mouseIcons.end()) {
2715         MMI_HILOGE("Cannot find the mouseStyle:%{public}d", static_cast<int32_t>(mouseStyle));
2716         return IconStyle();
2717     }
2718     return iter->second;
2719 }
2720 
GetMouseIcons()2721 std::map<MOUSE_ICON, IconStyle>& PointerDrawingManager::GetMouseIcons()
2722 {
2723 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
2724     if (HasMagicCursor()) {
2725         MMI_HILOGD("Magiccurosr get magic mouse map");
2726         return MAGIC_CURSOR->magicMouseIcons_;
2727     } else {
2728         MMI_HILOGD("Magiccurosr get mouse icon, HasMagicCursor is false");
2729         return mouseIcons_;
2730     }
2731 #else
2732     return mouseIcons_;
2733 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
2734 }
2735 
UpdateIconPath(const MOUSE_ICON mouseStyle,std::string iconPath)2736 void PointerDrawingManager::UpdateIconPath(const MOUSE_ICON mouseStyle, std::string iconPath)
2737 {
2738     auto iter = mouseIcons_.find(mouseStyle);
2739     if (iter == mouseIcons_.end()) {
2740         MMI_HILOGE("Cannot find the mouseStyle:%{public}d", static_cast<int32_t>(mouseStyle));
2741         return;
2742     }
2743     iter->second.iconPath = iconPath;
2744 }
2745 
SetPointerStylePreference(PointerStyle pointerStyle)2746 int32_t PointerDrawingManager::SetPointerStylePreference(PointerStyle pointerStyle)
2747 {
2748     CALL_DEBUG_ENTER;
2749     std::string name = "pointerStyle";
2750     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, pointerStyle.id);
2751     if (ret == RET_OK) {
2752         MMI_HILOGE("Set pointer style successfully, style:%{public}d", pointerStyle.id);
2753     }
2754     return RET_OK;
2755 }
2756 
CheckPointerStyleParam(int32_t windowId,PointerStyle pointerStyle)2757 bool PointerDrawingManager::CheckPointerStyleParam(int32_t windowId, PointerStyle pointerStyle)
2758 {
2759     CALL_DEBUG_ENTER;
2760     if (windowId < -1) {
2761         return false;
2762     }
2763     if ((pointerStyle.id < MOUSE_ICON::DEFAULT && pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) ||
2764         pointerStyle.id > MOUSE_ICON::AECH_DEVELOPER_DEFINED_ICON) {
2765         return false;
2766     }
2767     return true;
2768 }
2769 
SetPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle,bool isUiExtension)2770 int32_t PointerDrawingManager::SetPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle,
2771     bool isUiExtension)
2772 {
2773     CALL_DEBUG_ENTER;
2774     if (!CheckPointerStyleParam(windowId, pointerStyle)) {
2775         MMI_HILOGE("PointerStyle param is invalid");
2776         return RET_ERR;
2777     }
2778     if (windowId == GLOBAL_WINDOW_ID) {
2779         int32_t ret = SetPointerStylePreference(pointerStyle);
2780         if (ret != RET_OK) {
2781             MMI_HILOGE("Set style preference is failed, ret:%{public}d", ret);
2782             return RET_ERR;
2783         }
2784     }
2785     auto& iconPath = GetMouseIconPath();
2786     if (iconPath.find(MOUSE_ICON(pointerStyle.id)) == iconPath.end()) {
2787         MMI_HILOGE("The param pointerStyle is invalid");
2788         return RET_ERR;
2789     }
2790     if (UpdateDefaultPointerStyle(pid, windowId, pointerStyle) != RET_OK) {
2791         MMI_HILOGE("Update default pointer iconPath failed");
2792         return RET_ERR;
2793     }
2794     if (WIN_MGR->SetPointerStyle(pid, windowId, pointerStyle, isUiExtension) != RET_OK) {
2795         MMI_HILOGE("Set pointer style failed");
2796         return RET_ERR;
2797     }
2798     if (!INPUT_DEV_MGR->HasPointerDevice() && !INPUT_DEV_MGR->HasVirtualPointerDevice()) {
2799         MMI_HILOGD("The pointer device is not exist");
2800         return RET_OK;
2801     }
2802     if (!WIN_MGR->IsNeedRefreshLayer(windowId)) {
2803         MMI_HILOGD("Not need refresh layer, window type:%{public}d, pointer style:%{public}d",
2804             windowId, pointerStyle.id);
2805         return RET_OK;
2806     }
2807     if (windowId != GLOBAL_WINDOW_ID && (pointerStyle.id == MOUSE_ICON::DEFAULT &&
2808         iconPath.at(MOUSE_ICON(pointerStyle.id)).iconPath != DefaultIconPath)) {
2809         PointerStyle style;
2810         WIN_MGR->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style);
2811         pointerStyle = style;
2812     }
2813     if (windowId == windowId_ || windowId == GLOBAL_WINDOW_ID) {
2814         // Draw mouse style only when the current window is the top-level window
2815         if (!WIN_MGR->SelectPointerChangeArea(windowId, lastPhysicalX_ + displayInfo_.x,
2816             lastPhysicalY_ + displayInfo_.y)) {
2817             if (!WIN_MGR->GetExtraData().drawCursor) {
2818                 DrawPointerStyle(pointerStyle);
2819             }
2820         } else {
2821             MMI_HILOGW("skip the pointerstyle");
2822         }
2823     } else {
2824         MMI_HILOGW("set windowid:%{public}d, top windowid:%{public}d, dont draw pointer", windowId, windowId_);
2825     }
2826     MMI_HILOGI("Window id:%{public}d set pointer style:%{public}d success", windowId, pointerStyle.id);
2827     return RET_OK;
2828 }
2829 
GetPointerStyle(int32_t pid,int32_t windowId,PointerStyle & pointerStyle,bool isUiExtension)2830 int32_t PointerDrawingManager::GetPointerStyle(int32_t pid, int32_t windowId, PointerStyle &pointerStyle,
2831     bool isUiExtension)
2832 {
2833     CALL_DEBUG_ENTER;
2834     if (windowId == GLOBAL_WINDOW_ID) {
2835         std::string name = POINTER_COLOR;
2836         pointerStyle.color = PREFERENCES_MGR->GetIntValue(name, DEFAULT_VALUE);
2837         name = POINTER_SIZE;
2838         pointerStyle.size = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_SIZE);
2839         name = "pointerStyle";
2840         int32_t style = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_STYLE);
2841         MMI_HILOGD("Get pointer style successfully, pointerStyle:%{public}d", style);
2842         if (style == CURSOR_CIRCLE_STYLE || style == AECH_DEVELOPER_DEFINED_STYLE) {
2843             pointerStyle.id = style;
2844             return RET_OK;
2845         }
2846     }
2847     WIN_MGR->GetPointerStyle(pid, windowId, pointerStyle, isUiExtension);
2848     MMI_HILOGD("Window id:%{public}d get pointer style:%{public}d success", windowId, pointerStyle.id);
2849     return RET_OK;
2850 }
2851 
ClearWindowPointerStyle(int32_t pid,int32_t windowId)2852 int32_t PointerDrawingManager::ClearWindowPointerStyle(int32_t pid, int32_t windowId)
2853 {
2854     CALL_DEBUG_ENTER;
2855     return WIN_MGR->ClearWindowPointerStyle(pid, windowId);
2856 }
2857 
DrawPointerStyle(const PointerStyle & pointerStyle)2858 void PointerDrawingManager::DrawPointerStyle(const PointerStyle& pointerStyle)
2859 {
2860     CALL_DEBUG_ENTER;
2861     bool simulate = WIN_MGR->IsMouseSimulate();
2862     if (hasDisplay_ && (hasPointerDevice_ || simulate)) {
2863         if (surfaceNode_ != nullptr) {
2864             AttachToDisplay();
2865 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2866             PostTask([]() {
2867                 Rosen::RSTransaction::FlushImplicitTransaction();
2868             });
2869 #else
2870             Rosen::RSTransaction::FlushImplicitTransaction();
2871 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2872         }
2873         Direction direction = static_cast<Direction>((
2874             ((displayInfo_.direction - displayInfo_.displayDirection) * ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
2875 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2876         CHKPV(hardwareCursorPointerManager_);
2877         if (g_isHdiRemoteDied) {
2878             hardwareCursorPointerManager_->SetHdiServiceState(false);
2879         }
2880         if (hardwareCursorPointerManager_->IsSupported()) {
2881             direction = static_cast<Direction>((
2882                 (displayInfo_.direction * ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
2883         }
2884 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2885         if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
2886             DrawPointer(displayInfo_.id, displayInfo_.validWidth / CALCULATE_MIDDLE,
2887                 displayInfo_.validHeight / CALCULATE_MIDDLE, pointerStyle, direction);
2888             MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
2889             return;
2890         }
2891 
2892         DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
2893         MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
2894     }
2895 }
2896 
CheckMouseIconPath()2897 void PointerDrawingManager::CheckMouseIconPath()
2898 {
2899     for (auto iter = mouseIcons_.begin(); iter != mouseIcons_.end();) {
2900         if ((ReadCursorStyleFile(iter->second.iconPath)) != RET_OK) {
2901             iter = mouseIcons_.erase(iter);
2902             continue;
2903         }
2904         ++iter;
2905     }
2906 }
2907 
EnableHardwareCursorStats(int32_t pid,bool enable)2908 int32_t PointerDrawingManager::EnableHardwareCursorStats(int32_t pid, bool enable)
2909 {
2910     CALL_DEBUG_ENTER;
2911 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2912     CHKPR(hardwareCursorPointerManager_, ERROR_NULL_POINTER);
2913     if (g_isHdiRemoteDied) {
2914         hardwareCursorPointerManager_->SetHdiServiceState(false);
2915     }
2916     if (hardwareCursorPointerManager_->IsSupported()) {
2917         if ((hardwareCursorPointerManager_->EnableStats(enable)) != RET_OK) {
2918             MMI_HILOGE("Enable stats failed");
2919             return RET_ERR;
2920         }
2921     }
2922 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2923     MMI_HILOGI("EnableHardwareCursorStats, enable:%{private}d", enable);
2924     return RET_OK;
2925 }
2926 
GetHardwareCursorStats(int32_t pid,uint32_t & frameCount,uint32_t & vsyncCount)2927 int32_t PointerDrawingManager::GetHardwareCursorStats(int32_t pid, uint32_t &frameCount, uint32_t &vsyncCount)
2928 {
2929     CALL_DEBUG_ENTER;
2930 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2931     CHKPR(hardwareCursorPointerManager_, ERROR_NULL_POINTER);
2932     if (g_isHdiRemoteDied) {
2933         hardwareCursorPointerManager_->SetHdiServiceState(false);
2934     }
2935     if (hardwareCursorPointerManager_->IsSupported()) {
2936         if ((hardwareCursorPointerManager_->GetCursorStats(frameCount, vsyncCount)) != RET_OK) {
2937             MMI_HILOGE("Query stats failed");
2938             return RET_ERR;
2939         }
2940     }
2941 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2942     MMI_HILOGI("GetHardwareCursorStats, frameCount:%{private}d, vsyncCount:%{private}d", frameCount, vsyncCount);
2943     return RET_OK;
2944 }
2945 
SubscribeScreenModeChange()2946 void PointerDrawingManager::SubscribeScreenModeChange()
2947 {
2948 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2949     std::vector<sptr<OHOS::Rosen::ScreenInfo>> screenInfos;
2950     OHOS::Rosen::ScreenManagerLite::GetInstance().GetPhysicalScreenInfos(screenInfos);
2951     if (!screenInfos.empty()) {
2952         OnScreenModeChange(screenInfos);
2953     }
2954 
2955     auto callback = [this](const std::vector<sptr<OHOS::Rosen::ScreenInfo>> &screens) {
2956         CHKPV(hardwareCursorPointerManager_);
2957         if (g_isHdiRemoteDied) {
2958             hardwareCursorPointerManager_->SetHdiServiceState(false);
2959         }
2960         if (hardwareCursorPointerManager_->IsSupported()) {
2961             this->OnScreenModeChange(screens);
2962         }
2963     };
2964     screenModeChangeListener_ = new ScreenModeChangeListener(callback);
2965     auto begin = std::chrono::high_resolution_clock::now();
2966     auto ret = OHOS::Rosen::ScreenManagerLite::GetInstance().RegisterScreenModeChangeListener(
2967         screenModeChangeListener_);
2968     auto durationMS = std::chrono::duration_cast<std::chrono::milliseconds>(
2969         std::chrono::high_resolution_clock::now() - begin).count();
2970 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
2971     DfxHisysevent::ReportApiCallTimes(ApiDurationStatistics::Api::RE_SCREEN_MODE_CHANGE_LISTENER, durationMS);
2972 #endif // OHOS_BUILD_ENABLE_DFX_RADAR
2973     if (ret != OHOS::Rosen::DMError::DM_OK) {
2974         MMI_HILOGE("RegisterScreenModeChangeListener failed, ret=%{public}d", ret);
2975         return;
2976     }
2977     MMI_HILOGI("SubscribeScreenModeChange success");
2978 
2979     EventFwk::MatchingSkills matchingSkills;
2980     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON);
2981     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
2982     EventFwk::CommonEventSubscribeInfo commonEventSubscribeInfo(matchingSkills);
2983     OHOS::EventFwk::CommonEventManager::SubscribeCommonEvent(
2984         std::make_shared<DisplyStatusReceiver>(commonEventSubscribeInfo));
2985 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2986 }
2987 
InitStyle()2988 void PointerDrawingManager::InitStyle()
2989 {
2990     CALL_DEBUG_ENTER;
2991     mouseIcons_ = {
2992         {DEFAULT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
2993         {EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "East.svg"}},
2994         {WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West.svg"}},
2995         {SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South.svg"}},
2996         {NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North.svg"}},
2997         {WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West_East.svg"}},
2998         {NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_South.svg"}},
2999         {NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East.svg"}},
3000         {NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West.svg"}},
3001         {SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_East.svg"}},
3002         {SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_West.svg"}},
3003         {NORTH_EAST_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East_South_West.svg"}},
3004         {NORTH_WEST_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West_South_East.svg"}},
3005         {CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cross.svg"}},
3006         {CURSOR_COPY, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Copy.svg"}},
3007         {CURSOR_FORBID, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Forbid.svg"}},
3008         {COLOR_SUCKER, {ANGLE_SW, IMAGE_POINTER_DEFAULT_PATH + "Colorsucker.svg"}},
3009         {HAND_GRABBING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Grabbing.svg"}},
3010         {HAND_OPEN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Open.svg"}},
3011         {HAND_POINTING, {ANGLE_NW_RIGHT, IMAGE_POINTER_DEFAULT_PATH + "Hand_Pointing.svg"}},
3012         {HELP, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Help.svg"}},
3013         {CURSOR_MOVE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Move.svg"}},
3014         {RESIZE_LEFT_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Left_Right.svg"}},
3015         {RESIZE_UP_DOWN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Up_Down.svg"}},
3016         {SCREENSHOT_CHOOSE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cross.svg"}},
3017         {SCREENSHOT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cursor.svg"}},
3018         {TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Text_Cursor.svg"}},
3019         {ZOOM_IN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_In.svg"}},
3020         {ZOOM_OUT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_Out.svg"}},
3021         {MIDDLE_BTN_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_East.svg"}},
3022         {MIDDLE_BTN_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_West.svg"}},
3023         {MIDDLE_BTN_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South.svg"}},
3024         {MIDDLE_BTN_NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North.svg"}},
3025         {MIDDLE_BTN_NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_South.svg"}},
3026         {MIDDLE_BTN_EAST_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MIDDLE_BTN_EAST_WEST.svg"}},
3027         {MIDDLE_BTN_NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_East.svg"}},
3028         {MIDDLE_BTN_NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_West.svg"}},
3029         {MIDDLE_BTN_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_East.svg"}},
3030         {MIDDLE_BTN_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_West.svg"}},
3031         {MIDDLE_BTN_NORTH_SOUTH_WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH +
3032             "MID_Btn_North_South_West_East.svg"}},
3033         {HORIZONTAL_TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Horizontal_Text_Cursor.svg"}},
3034         {CURSOR_CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Cross.svg"}},
3035         {CURSOR_CIRCLE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png"}},
3036         {LOADING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"}},
3037         {RUNNING, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
3038         {RUNNING_LEFT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
3039         {RUNNING_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading_Right.svg"}},
3040         {AECH_DEVELOPER_DEFINED_ICON, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Custom_Cursor_Circle.svg"}},
3041         {DEVELOPER_DEFINED_ICON, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
3042         {TRANSPARENT_ICON, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
3043     };
3044     CheckMouseIconPath();
3045 }
3046 
RotateDegree(Direction direction)3047 void PointerDrawingManager::RotateDegree(Direction direction)
3048 {
3049 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
3050         CHKPV(hardwareCursorPointerManager_);
3051         if (g_isHdiRemoteDied) {
3052             hardwareCursorPointerManager_->SetHdiServiceState(false);
3053         }
3054         if (hardwareCursorPointerManager_->IsSupported()) {
3055             return;
3056         }
3057 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
3058     CHKPV(surfaceNode_);
3059     surfaceNode_->SetPivot(0, 0);
3060     float degree = (static_cast<int>(DIRECTION0) - static_cast<int>(direction)) * ROTATION_ANGLE90;
3061     surfaceNode_->SetRotation(degree);
3062 }
3063 
SkipPointerLayer(bool isSkip)3064 int32_t PointerDrawingManager::SkipPointerLayer(bool isSkip)
3065 {
3066     CALL_INFO_TRACE;
3067     if (surfaceNode_ != nullptr) {
3068         surfaceNode_->SetSkipLayer(isSkip);
3069     }
3070     return RET_OK;
3071 }
3072 
GetDisplayInfo(DisplayInfo & di)3073 std::vector<std::vector<std::string>> PointerDrawingManager::GetDisplayInfo(DisplayInfo &di)
3074 {
3075     std::vector<std::vector<std::string>> displayInfo = {
3076         {std::to_string(di.id), std::to_string(di.x), std::to_string(di.y), std::to_string(di.width),
3077          std::to_string(di.height), std::to_string(di.dpi), di.name, di.uniq,
3078          std::to_string(static_cast<int32_t>(di.direction)), std::to_string(static_cast<int32_t>(di.displayDirection)),
3079          std::to_string(static_cast<int32_t>(di.displayMode)), std::to_string(di.isCurrentOffScreenRendering),
3080          std::to_string(di.screenRealWidth), std::to_string(di.screenRealHeight), std::to_string(di.screenRealPPI),
3081          std::to_string(di.screenRealDPI), std::to_string(static_cast<int32_t>(di.screenCombination))}};
3082     return displayInfo;
3083 }
3084 
Dump(int32_t fd,const std::vector<std::string> & args)3085 void PointerDrawingManager::Dump(int32_t fd, const std::vector<std::string> &args)
3086 {
3087     CALL_DEBUG_ENTER;
3088     std::ostringstream oss;
3089     oss << std::endl;
3090 
3091     std::vector<std::string> displayTitles = {"ID", "X", "Y", "Width", "Height", "DPI", "Name", "Uniq",
3092                                               "Direction", "Display Direction", "Display Mode",
3093                                               "Is Current Off Screen Rendering", "Screen Real Width",
3094                                               "Screen Real Height", "Screen Real PPI", "Screen Real DPI",
3095                                               "Screen Combination"};
3096     std::vector<std::vector<std::string>> displayInfo = GetDisplayInfo(displayInfo_);
3097 
3098     DumpFullTable(oss, "Display Info", displayTitles, displayInfo);
3099     oss << std::endl;
3100 
3101     std::vector<std::string> titles1 = {"hasDisplay", "hasPointerDevice", "lastPhysicalX", "lastPhysicalY",
3102                                         "pid", "windowId", "imageWidth", "imageHeight", "canvasWidth", "canvasHeight"};
3103     std::vector<std::vector<std::string>> data1 = {
3104         {std::to_string(hasDisplay_), std::to_string(hasPointerDevice_), std::to_string(lastPhysicalX_),
3105          std::to_string(lastPhysicalY_), std::to_string(pid_), std::to_string(windowId_),
3106          std::to_string(imageWidth_), std::to_string(imageHeight_), std::to_string(canvasWidth_),
3107          std::to_string(canvasHeight_)}};
3108 
3109     DumpFullTable(oss, "Cursor Info", titles1, data1);
3110     oss << std::endl;
3111 
3112     std::vector<std::string> titles2 = {"mouseDisplayState", "mouseIconUpdate", "screenId", "userIconHotSpotX",
3113                                         "userIconHotSpotY", "tempPointerColor", "lastDirection", "currentDirection"};
3114     std::vector<std::vector<std::string>> data2 = {
3115         {std::to_string(mouseDisplayState_), std::to_string(mouseIconUpdate_), std::to_string(screenId_),
3116          std::to_string(userIconHotSpotX_), std::to_string(userIconHotSpotY_), std::to_string(tempPointerColor_),
3117          std::to_string(lastDirection_), std::to_string(currentDirection_)}};
3118 
3119     DumpFullTable(oss, "Cursor Info", titles2, data2);
3120     oss << std::endl;
3121 
3122     std::vector<std::string> styleTitles = {"name", "Size", "Color", "ID"};
3123     std::vector<std::vector<std::string>> styleData = {
3124         {"lastMouseStyle", std::to_string(lastMouseStyle_.size), std::to_string(lastMouseStyle_.color),
3125          std::to_string(lastMouseStyle_.id)},
3126         {"currentMouseStyle", std::to_string(currentMouseStyle_.size), std::to_string(currentMouseStyle_.color),
3127          std::to_string(currentMouseStyle_.id)}};
3128 
3129     DumpFullTable(oss, "Cursor Style Info", styleTitles, styleData);
3130     oss << std::endl;
3131 
3132     std::vector<std::string> pidTitles = {"pid", "visible"};
3133     std::vector<std::vector<std::string>> pidInfos;
3134     for (const auto &pidInfo : pidInfos_) {
3135         pidInfos.push_back({std::to_string(pidInfo.pid), pidInfo.visible ? "true" : "false"});
3136     }
3137     DumpFullTable(oss, "Visible Info", pidTitles, pidInfos);
3138     oss << std::endl;
3139 
3140     std::string dumpInfo = oss.str();
3141     dprintf(fd, dumpInfo.c_str());
3142 }
3143 
3144 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
UpdateBindDisplayId(int32_t displayId)3145 void PointerDrawingManager::UpdateBindDisplayId(int32_t displayId)
3146 {
3147     if (lastDisplayId_ == displayId) {
3148         return;
3149     }
3150     MMI_HILOGI("Mouse traversal occurs, lastDisplayId_:%{public}d, displayId:%{public}d",
3151         lastDisplayId_, displayId);
3152 
3153     CHKPV(hardwareCursorPointerManager_);
3154     if (g_isHdiRemoteDied) {
3155         hardwareCursorPointerManager_->SetHdiServiceState(false);
3156     }
3157     if (hardwareCursorPointerManager_->IsSupported()) {
3158         // 隐藏上一个屏幕的软、硬光标
3159         PostSoftCursorTask([this]() {
3160             SoftwareCursorRender(MOUSE_ICON::TRANSPARENT_ICON);
3161         });
3162         HideHardwareCursors();
3163         Rosen::RSTransaction::FlushImplicitTransaction();
3164 
3165         // 绑定新屏幕 SurfaceNode 到全局 surfaceNode_
3166         screenId_ = static_cast<uint64_t>(displayId);
3167         MMI_HILOGI("The screenId_:%{public}" PRIu64, screenId_);
3168         AttachToDisplay();
3169 
3170         // 新屏幕上重新绘制软硬光标
3171         UpdatePointerVisible();
3172     }
3173 
3174     // 绑定新屏幕 SurfaceNode 到全局 surfaceNode_
3175     screenId_ = static_cast<uint64_t>(displayId);
3176     MMI_HILOGI("The screenId_:%{public}" PRIu64, screenId_);
3177     AttachToDisplay();
3178 
3179     // 新屏幕上软硬光标位置更新
3180     auto align = MouseIcon2IconType(MOUSE_ICON(lastMouseStyle_.id));
3181     if (!SetCursorLocation(displayId, lastPhysicalX_, lastPhysicalY_, align)) {
3182         MMI_HILOGE("SetCursorLocation fail");
3183     }
3184 
3185     lastDisplayId_ = displayId;
3186 }
3187 
IsSupported()3188 bool PointerDrawingManager::IsSupported()
3189 {
3190     return hardwareCursorPointerManager_->IsSupported();
3191 }
3192 
OnScreenModeChange(const std::vector<sptr<OHOS::Rosen::ScreenInfo>> & screens)3193 void PointerDrawingManager::OnScreenModeChange(const std::vector<sptr<OHOS::Rosen::ScreenInfo>> &screens)
3194 {
3195     MMI_HILOGI("OnScreenModeChange enter, screen size:%{public}lu", screens.size());
3196     std::set<uint32_t> sids;
3197     uint32_t mainWidth = 0;
3198     uint32_t mainHeight = 0;
3199     rotation_t mainRotation = static_cast<rotation_t>(DIRECTION0);
3200     {
3201         std::lock_guard<std::mutex> lock(mtx_);
3202         // construct ScreenPointers for new screens
3203         for (auto si : screens) {
3204             MMI_HILOGI("Got screen, id:%{public}lu, shape=(%{public}u,%{public}u), rotation=%{public}u, "
3205                 "dpi=%{public}f", si->GetScreenId(), GetScreenInfoWidth(si), GetScreenInfoHeight(si),
3206                 si->GetRotation(), si->GetVirtualPixelRatio());
3207             if (si->GetType() != OHOS::Rosen::ScreenType::REAL) {
3208                 continue;
3209             }
3210 
3211             uint32_t sid = si->GetScreenId();
3212             sids.insert(sid);
3213 
3214             if (si->GetSourceMode() == OHOS::Rosen::ScreenSourceMode::SCREEN_MAIN) {
3215                 mainWidth = GetScreenInfoWidth(si);
3216                 mainHeight = GetScreenInfoHeight(si);
3217                 mainRotation = static_cast<rotation_t>(si->GetRotation());
3218             }
3219 
3220             auto it = screenPointers_.find(sid);
3221             if (it != screenPointers_.end()) {
3222                 // ScreenPointer already exist
3223                 MMI_HILOGI("OnScreenModeChange screen %{public}u info update", sid);
3224                 it->second->UpdateScreenInfo(si);
3225             } else {
3226                 // Create & Init ScreenPointer
3227                 MMI_HILOGI("OnScreenModeChange got new screen %{public}u", sid);
3228                 auto sp = std::make_shared<ScreenPointer>(hardwareCursorPointerManager_, handler_, si);
3229                 screenPointers_[sid] = sp;
3230                 if (!sp->Init()) {
3231                     MMI_HILOGE("ScreenPointer::Init failed, screenId=%{public}u", sid);
3232                 }
3233             }
3234         }
3235 
3236         // delete ScreenPointers that disappeared
3237         for (auto it = screenPointers_.begin(); it != screenPointers_.end();) {
3238             if (!sids.count(it->first)) {
3239                 MMI_HILOGI("OnScreenModeChange, delete screen %{public}u", it->first);
3240                 it = screenPointers_.erase(it);
3241             } else {
3242                 it++;
3243             }
3244         }
3245 
3246         // update screen scale and padding
3247         for (auto sp : screenPointers_) {
3248             if (sp.second->IsMirror()) {
3249                 sp.second->SetRotation(mainRotation);
3250                 sp.second->UpdatePadding(mainWidth, mainHeight);
3251             }
3252         }
3253     }
3254     UpdatePointerVisible();
3255 }
3256 
CreateRenderConfig(RenderConfig & cfg,std::shared_ptr<ScreenPointer> sp,MOUSE_ICON mouseStyle,bool isHard)3257 void PointerDrawingManager::CreateRenderConfig(RenderConfig& cfg, std::shared_ptr<ScreenPointer> sp,
3258     MOUSE_ICON mouseStyle, bool isHard)
3259 {
3260     CHKPV(sp);
3261     cfg.style = mouseStyle;
3262     cfg.align = MouseIcon2IconType(mouseStyle);
3263     cfg.path = mouseIcons_[mouseStyle].iconPath;
3264     cfg.color = GetPointerColor();
3265     cfg.size = GetPointerSize();
3266     cfg.isHard = isHard;
3267     cfg.dpi = sp->GetRenderDPI();
3268     cfg.direction = sp->IsMirror() ? DIRECTION0 : displayInfo_.direction;
3269     if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
3270         MMI_HILOGD("Set mouseIcon by userIcon_");
3271         float scale = sp->IsMirror() ? sp->GetScale() : 1.0f;
3272         scale = (sp->IsExtend() && sp->GetIsCurrentOffScreenRendering()) ? sp->GetOffRenderScale() : scale;
3273         cfg.userIconPixelMap = GetUserIconCopy();
3274         cfg.userIconHotSpotX = userIconHotSpotX_ * scale;
3275         cfg.userIconHotSpotY = userIconHotSpotY_ * scale;
3276         cfg.userIconFollowSystem = userIconFollowSystem_;
3277         cfg.userIconPixelMap->scale(scale, scale, Media::AntiAliasingOption::LOW);
3278     }
3279 }
3280 
HardwareCursorRender(MOUSE_ICON mouseStyle)3281 void PointerDrawingManager::HardwareCursorRender(MOUSE_ICON mouseStyle)
3282 {
3283     std::unordered_map<uint32_t, std::shared_ptr<ScreenPointer>> screenPointers;
3284     {
3285         std::lock_guard<std::mutex> lock(mtx_);
3286         screenPointers = screenPointers_;
3287     }
3288 
3289     for (auto it : screenPointers) {
3290         CHKPV(it.second);
3291         RenderConfig cfg;
3292         CreateRenderConfig(cfg, it.second, mouseStyle, true);
3293         MMI_HILOGD("HardwareCursorRender, screen=%{public}u, dpi=%{public}f", it.first, cfg.dpi);
3294         if (it.second->IsMirror() || it.first == screenId_) {
3295             DrawHardCursor(it.second, cfg);
3296         } else {
3297             it.second->SetInvisible();
3298         }
3299     }
3300     MMI_HILOGD("HardwareCursorRender success");
3301 }
3302 
SoftwareCursorRender(MOUSE_ICON mouseStyle)3303 void PointerDrawingManager::SoftwareCursorRender(MOUSE_ICON mouseStyle)
3304 {
3305     std::unordered_map<uint32_t, std::shared_ptr<ScreenPointer>> screenPointers;
3306     {
3307         std::lock_guard<std::mutex> lock(mtx_);
3308         screenPointers = screenPointers_;
3309     }
3310 
3311     for (auto it : screenPointers) {
3312         CHKPV(it.second);
3313         RenderConfig cfg;
3314         CreateRenderConfig(cfg, it.second, mouseStyle, false);
3315         MMI_HILOGD("SoftwareCursorRender, screen = %{public}u, dpi = %{public}f,direction = %{public}d",
3316             it.first, cfg.dpi, cfg.direction);
3317         if (!it.second->IsMirror() && it.first != screenId_) {
3318             cfg.style = MOUSE_ICON::TRANSPARENT_ICON;
3319             cfg.align = MouseIcon2IconType(cfg.style);
3320             cfg.path = mouseIcons_[cfg.style].iconPath;
3321         }
3322         DrawSoftCursor(it.second->GetSurfaceNode(), cfg);
3323     }
3324     MMI_HILOGD("SoftwareCursorRender success");
3325 }
3326 
DrawSoftCursor(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,const RenderConfig & cfg)3327 int32_t PointerDrawingManager::DrawSoftCursor(std::shared_ptr<Rosen::RSSurfaceNode> surfaceNode,
3328     const RenderConfig &cfg)
3329 {
3330     CHKPR(surfaceNode, RET_ERR);
3331 
3332     auto layer = surfaceNode->GetSurface();
3333     CHKPR(layer, RET_ERR);
3334     auto buffer = GetSurfaceBuffer(layer);
3335     if (buffer == nullptr || buffer->GetVirAddr() == nullptr) {
3336         buffer = RetryGetSurfaceBuffer(layer);
3337     }
3338     CHKPR(buffer, RET_ERR);
3339     CHKPR(buffer->GetVirAddr(), RET_ERR);
3340     auto addr = static_cast<uint8_t*>(buffer->GetVirAddr());
3341     CHKPR(addr, RET_ERR);
3342     pointerRenderer_.Render(addr, buffer->GetWidth(), buffer->GetHeight(), cfg);
3343 
3344     OHOS::BufferFlushConfig flushConfig = {
3345         .damage = {
3346             .w = buffer->GetWidth(),
3347             .h = buffer->GetHeight(),
3348         }
3349     };
3350     OHOS::SurfaceError ret = layer->FlushBuffer(buffer, -1, flushConfig);
3351     if (ret != OHOS::SURFACE_ERROR_OK) {
3352         MMI_HILOGE("FlushBuffer failed, return: %{public}s", SurfaceErrorStr(ret).data());
3353         layer->CancelBuffer(buffer);
3354         return RET_ERR;
3355     }
3356     MMI_HILOGD("DrawSoftCursor on SurfaceNode success");
3357     return RET_OK;
3358 }
3359 
DrawCursor(std::shared_ptr<ScreenPointer> sp,const RenderConfig & cfg)3360 int32_t PointerDrawingManager::DrawCursor(std::shared_ptr<ScreenPointer> sp, const RenderConfig &cfg)
3361 {
3362     CHKPR(sp, RET_ERR);
3363 
3364     auto buffer = sp->RequestBuffer();
3365     CHKPR(buffer, RET_ERR);
3366 
3367     auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
3368     CHKPR(addr, RET_ERR);
3369     pointerRenderer_.Render(addr, buffer->GetWidth(), buffer->GetHeight(), cfg);
3370 
3371     MMI_HILOGI("DrawHardCursor on ScreenPointer success, screenId=%{public}u", sp->GetScreenId());
3372     return RET_OK;
3373 }
3374 
UpdateMirrorScreens(std::shared_ptr<ScreenPointer> sp,DisplayInfo displayInfo)3375 void PointerDrawingManager::UpdateMirrorScreens(std::shared_ptr<ScreenPointer> sp, DisplayInfo displayInfo)
3376 {
3377     if (sp->GetRotation() != static_cast<rotation_t>(displayInfo.direction)) {
3378         uint32_t mainWidth = sp->GetScreenWidth();
3379         uint32_t mainHeight = sp->GetScreenHeight();
3380         auto mirrorScreens = GetMirrorScreenPointers();
3381         for (auto mirrorScreen : mirrorScreens) {
3382             if (mirrorScreen != nullptr) {
3383                 mirrorScreen->SetRotation(static_cast<rotation_t>(displayInfo.direction));
3384                 mirrorScreen->UpdatePadding(mainWidth, mainHeight);
3385             }
3386         }
3387     }
3388 }
3389 
GetMirrorScreenPointers()3390 std::vector<std::shared_ptr<ScreenPointer>> PointerDrawingManager::GetMirrorScreenPointers()
3391 {
3392     std::vector<std::shared_ptr<ScreenPointer>> mirrors;
3393     std::lock_guard<std::mutex> lock(mtx_);
3394     for (auto it : screenPointers_) {
3395         if (it.second->IsMirror()) {
3396             mirrors.push_back(it.second);
3397         }
3398     }
3399     return mirrors;
3400 }
3401 
GetScreenPointer(uint32_t sid)3402 std::shared_ptr<ScreenPointer> PointerDrawingManager::GetScreenPointer(uint32_t sid)
3403 {
3404     std::lock_guard<std::mutex> lock(mtx_);
3405     if (screenPointers_.count(sid)) {
3406         return screenPointers_[sid];
3407     }
3408     return nullptr;
3409 }
3410 
HardwareCursorMove(int32_t x,int32_t y,ICON_TYPE align)3411 void PointerDrawingManager::HardwareCursorMove(int32_t x, int32_t y, ICON_TYPE align)
3412 {
3413     MMI_HILOGD("HardwareCursorMove loc: (%{public}d, %{public}d), align type: %{public}d", x, y, align);
3414     auto sp = GetScreenPointer(displayId_);
3415     CHKPV(sp);
3416     if (!sp->Move(x, y, align)) {
3417         MMI_HILOGE("ScreenPointer::Move failed, screenId: %{public}u", displayId_);
3418     }
3419     std::unordered_map<uint32_t, std::shared_ptr<ScreenPointer>> screenPointers;
3420     {
3421         std::lock_guard<std::mutex> lock(mtx_);
3422         screenPointers = screenPointers_;
3423     }
3424     for (auto it : screenPointers) {
3425         if (it.second->IsMirror()) {
3426             if (!it.second->Move(x, y, align)) {
3427                 MMI_HILOGE("ScreenPointer::Move failed, screenId: %{public}u", it.first);
3428             }
3429         } else if (it.first != displayId_) {
3430             if (!it.second->Move(0, 0, align)) {
3431                 MMI_HILOGE("ScreenPointer::Move failed, screenId: %{public}u", it.first);
3432             }
3433         }
3434     }
3435 }
3436 
SoftwareCursorMove(int32_t x,int32_t y,ICON_TYPE align)3437 void PointerDrawingManager::SoftwareCursorMove(int32_t x, int32_t y, ICON_TYPE align)
3438 {
3439     auto sp = GetScreenPointer(displayId_);
3440     CHKPV(sp);
3441     sp->MoveSoft(x, y, align);
3442 
3443     for (auto msp : GetMirrorScreenPointers()) {
3444         msp->MoveSoft(x, y, align);
3445     }
3446     Rosen::RSTransaction::FlushImplicitTransaction();
3447 }
3448 
SoftwareCursorMoveAsync(int32_t x,int32_t y,ICON_TYPE align)3449 void PointerDrawingManager::SoftwareCursorMoveAsync(int32_t x, int32_t y, ICON_TYPE align)
3450 {
3451     PostSoftCursorTask([this, x, y, align]() {
3452         SoftwareCursorMove(x, y, align);
3453     });
3454 }
3455 
HideHardwareCursors()3456 void PointerDrawingManager::HideHardwareCursors()
3457 {
3458     auto curSp = GetScreenPointer(screenId_);
3459     CHKPV(curSp);
3460     if (!curSp->SetInvisible()) {
3461         MMI_HILOGE("Hide cursor of current screen failed, screen %{public}" PRIu64, screenId_);
3462     }
3463 
3464     for (auto msp : GetMirrorScreenPointers()) {
3465         if (!msp->SetInvisible()) {
3466             MMI_HILOGE("Hide cursor of mirror screen failed, screen %{public}u", msp->GetScreenId());
3467         }
3468     }
3469 }
3470 
3471 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
3472 
DrawScreenCenterPointer(const PointerStyle & pointerStyle)3473 void PointerDrawingManager::DrawScreenCenterPointer(const PointerStyle& pointerStyle)
3474 {
3475     CALL_DEBUG_ENTER;
3476     if (hasDisplay_ && hasPointerDevice_) {
3477         if (surfaceNode_ != nullptr) {
3478             AttachToDisplay();
3479             Rosen::RSTransaction::FlushImplicitTransaction();
3480         }
3481         Direction direction = static_cast<Direction>((
3482             ((displayInfo_.direction - displayInfo_.displayDirection) * ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
3483 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
3484         if (IsSupported()) {
3485             direction = displayInfo_.direction;
3486             int32_t x = displayInfo_.width / CALCULATE_MIDDLE;
3487             int32_t y = displayInfo_.height / CALCULATE_MIDDLE;
3488             if (direction == DIRECTION90 || direction == DIRECTION270) {
3489                 std::swap(x, y);
3490             }
3491             MMI_HILOGD("DrawScreenCenterPointer, x=%{public}d, y=%{public}d", x, y);
3492             DrawPointer(displayInfo_.id, x, y, pointerStyle, direction);
3493         }
3494 #else
3495         DrawPointer(displayInfo_.id, displayInfo_.validWidth / CALCULATE_MIDDLE,
3496             displayInfo_.validHeight / CALCULATE_MIDDLE, pointerStyle, direction);
3497 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
3498     }
3499 }
3500 
GetUserIconCopy()3501 std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::GetUserIconCopy()
3502 {
3503     std::lock_guard<std::mutex> guard(mtx_);
3504     if (userIcon_ == nullptr) {
3505         MMI_HILOGI("userIcon_ is nullptr");
3506         return nullptr;
3507     }
3508     MessageParcel data;
3509     userIcon_->Marshalling(data);
3510     std::shared_ptr<OHOS::Media::PixelMap> pixelMapPtr(OHOS::Media::PixelMap::Unmarshalling(data));
3511     if (pixelMapPtr == nullptr) {
3512         MMI_HILOGE("pixelMapPtr is nullptr");
3513         return nullptr;
3514     }
3515     if (followSystem_) {
3516         Media::ImageInfo imageInfo;
3517         pixelMapPtr->GetImageInfo(imageInfo);
3518         int32_t cursorSize = GetPointerSize();
3519         float axis = 1.0f;
3520         cursorWidth_ = pow(INCREASE_RATIO, cursorSize - 1) * imageInfo.size.width;
3521         cursorHeight_ = pow(INCREASE_RATIO, cursorSize - 1) * imageInfo.size.height;
3522         int32_t maxValue = imageInfo.size.width > imageInfo.size.height ? cursorWidth_ : cursorHeight_;
3523         if (maxValue > MAX_CUSTOM_CURSOR_DIMENSION) {
3524             axis = (float)MAX_CUSTOM_CURSOR_DIMENSION / (float)std::max(imageInfo.size.width, imageInfo.size.height);
3525         } else {
3526             axis = (float)std::max(cursorWidth_, cursorHeight_) /
3527                 (float)std::max(imageInfo.size.width, imageInfo.size.height);
3528         }
3529         pixelMapPtr->scale(axis, axis, Media::AntiAliasingOption::LOW);
3530         cursorWidth_ = static_cast<int32_t>((float)imageInfo.size.width * axis);
3531         cursorHeight_ = static_cast<int32_t>((float)imageInfo.size.height * axis);
3532         userIconHotSpotX_ = static_cast<int32_t>((float)focusX_ * axis);
3533         userIconHotSpotY_ = static_cast<int32_t>((float)focusY_ * axis);
3534         MMI_HILOGI("cursorWidth:%{public}d, cursorHeight:%{public}d, imageWidth:%{public}d,"
3535             "imageHeight:%{public}d, focusX:%{public}d, focusY:%{public}d, axis:%{public}f,"
3536             "userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
3537             cursorWidth_, cursorHeight_, imageInfo.size.width, imageInfo.size.height,
3538             focusX_, focusY_, axis, userIconHotSpotX_, userIconHotSpotY_);
3539     }
3540     SetFaceNodeBounds();
3541     return pixelMapPtr;
3542 }
3543 
SetFaceNodeBounds()3544 void PointerDrawingManager::SetFaceNodeBounds()
3545 {
3546     if (canvasWidth_ < cursorWidth_ && canvasHeight_ < cursorHeight_) {
3547         canvasWidth_ = cursorWidth_;
3548         canvasHeight_ = cursorHeight_;
3549     }
3550     CHKPV(surfaceNode_);
3551     surfaceNode_->SetBounds(lastPhysicalX_, lastPhysicalY_, canvasWidth_, canvasHeight_);
3552 }
3553 
SetCustomCursor(int32_t pid,int32_t windowId,CustomCursor cursor,CursorOptions options)3554 int32_t PointerDrawingManager::SetCustomCursor(int32_t pid, int32_t windowId, CustomCursor cursor,
3555     CursorOptions options)
3556 {
3557     CALL_DEBUG_ENTER;
3558     followSystem_ = options.followSystem;
3559 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
3560     userIconFollowSystem_ = false;
3561 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
3562     int32_t ret = UpdateCursorProperty(cursor);
3563     if (ret != RET_OK) {
3564         MMI_HILOGE("UpdateCursorProperty is failed");
3565         return ret;
3566     }
3567     mouseIconUpdate_ = true;
3568     PointerStyle style;
3569     style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
3570     lastMouseStyle_ = style;
3571     ret = SetPointerStyle(pid, windowId, style);
3572     if (ret == RET_ERR) {
3573         MMI_HILOGE("SetPointerStyle is failed");
3574     }
3575     MMI_HILOGD("style.id:%{public}d, userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
3576         style.id, userIconHotSpotX_, userIconHotSpotY_);
3577     return ret;
3578 }
3579 
UpdateCursorProperty(CustomCursor cursor)3580 int32_t PointerDrawingManager::UpdateCursorProperty(CustomCursor cursor)
3581 {
3582     CHKPR(cursor.pixelMap, RET_ERR);
3583     Media::PixelMap* newPixelMap = static_cast<Media::PixelMap*>(cursor.pixelMap);
3584     CHKPR(newPixelMap, RET_ERR);
3585     Media::ImageInfo imageInfo;
3586     newPixelMap->GetImageInfo(imageInfo);
3587     if (imageInfo.size.width < cursor.focusX || imageInfo.size.width < cursor.focusY) {
3588         MMI_HILOGE("The focus is invalid");
3589         return RET_ERR;
3590     }
3591     if (imageInfo.size.width > MAX_CUSTOM_CURSOR_SIZE || imageInfo.size.height > MAX_CUSTOM_CURSOR_SIZE ||
3592         imageInfo.size.width <= 0 || imageInfo.size.height <= 0) {
3593         MMI_HILOGE("PixelMap is invalid");
3594         return RET_ERR;
3595     }
3596     cursorWidth_ = imageInfo.size.width;
3597     cursorHeight_ = imageInfo.size.height;
3598     {
3599         std::lock_guard<std::mutex> guard(mtx_);
3600         userIcon_.reset(newPixelMap);
3601     }
3602     focusX_ = cursor.focusX;
3603     focusY_ = cursor.focusY;
3604     userIconHotSpotX_ = cursor.focusX;
3605     userIconHotSpotY_ = cursor.focusY;
3606     MMI_HILOGI("imageWidth:%{public}d, imageHeight:%{public}d, focusX:%{public}d, focusY:%{public}d",
3607         imageInfo.size.width, imageInfo.size.height, cursor.focusX, cursor.focusY);
3608     return RET_OK;
3609 }
3610 
DrawNewDpiPointer()3611 int32_t PointerDrawingManager::DrawNewDpiPointer()
3612 {
3613     mouseIconUpdate_ = true;
3614     int32_t updateRes = DrawMovePointer(lastDisplayId_, lastPhysicalX_, lastPhysicalY_,
3615         lastMouseStyle_, currentDirection_);
3616     if (updateRes != RET_OK) {
3617         MMI_HILOGE("Forced refresh DPI drawing failed.");
3618         return RET_ERR;
3619     }
3620     return RET_OK;
3621 }
3622 } // namespace MMI
3623 } // namespace OHOS
3624