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