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, ¶m);
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