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 "image/bitmap.h"
19 #include "image_source.h"
20 #include "image_type.h"
21 #include "image_utils.h"
22 #include "table_dump.h"
23 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
24 #include "magic_pointer_drawing_manager.h"
25 #include "magic_pointer_velocity_tracker.h"
26 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
27
28 #include "define_multimodal.h"
29 #include "event_log_helper.h"
30 #include "i_multimodal_input_connect.h"
31 #include "input_device_manager.h"
32 #include "i_input_windows_manager.h"
33 #include "ipc_skeleton.h"
34 #include "mmi_log.h"
35 #include "i_preference_manager.h"
36 #include "parameters.h"
37 #include "pipeline/rs_recording_canvas.h"
38 #include "preferences.h"
39 #include "preferences_errno.h"
40 #include "preferences_helper.h"
41 #include "render/rs_pixel_map_util.h"
42 #include "scene_board_judgement.h"
43 #include "setting_datashare.h"
44 #include "util.h"
45 #include "timer_manager.h"
46 #include "system_ability_definition.h"
47
48 #undef MMI_LOG_DOMAIN
49 #define MMI_LOG_DOMAIN MMI_LOG_CURSOR
50 #undef MMI_LOG_TAG
51 #define MMI_LOG_TAG "PointerDrawingManager"
52
53 namespace OHOS {
54 namespace MMI {
55 namespace {
56 const std::string FOLD_SCREEN_FLAG = system::GetParameter("const.window.foldscreen.type", "");
57 const std::string IMAGE_POINTER_DEFAULT_PATH = "/system/etc/multimodalinput/mouse_icon/";
58 const std::string DefaultIconPath = IMAGE_POINTER_DEFAULT_PATH + "Default.svg";
59 const std::string CursorIconPath = IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png";
60 const std::string POINTER_COLOR { "pointerColor" };
61 const std::string POINTER_SIZE { "pointerSize" };
62 const std::string MAGIC_POINTER_COLOR { "magicPointerColor" };
63 const std::string MAGIC_POINTER_SIZE { "magicPointerSize"};
64 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
65 const std::string FOLDABLE_DEVICE_POLICY = system::GetParameter("const.window.foldabledevice.rotate_policy", "");
66 constexpr int32_t WINDOW_ROTATE { 0 };
67 constexpr char ROTATE_WINDOW_ROTATE { '0' };
68 constexpr int32_t FOLDABLE_DEVICE { 2 };
69 constexpr int32_t BASELINE_DENSITY { 160 };
70 constexpr int32_t CALCULATE_MIDDLE { 2 };
71 constexpr int32_t MAGIC_INDEPENDENT_PIXELS { 30 };
72 constexpr int32_t DEVICE_INDEPENDENT_PIXELS { 40 };
73 constexpr int32_t POINTER_WINDOW_INIT_SIZE { 64 };
74 constexpr int32_t DEFAULT_POINTER_SIZE { 1 };
75 constexpr int32_t MIN_POINTER_SIZE { 1 };
76 constexpr int32_t MAX_POINTER_SIZE { 7 };
77 constexpr int32_t DEFAULT_VALUE { -1 };
78 constexpr int32_t ANIMATION_DURATION { 500 };
79 constexpr int32_t DEFAULT_POINTER_STYLE { 0 };
80 constexpr int32_t CURSOR_CIRCLE_STYLE { 41 };
81 constexpr int32_t MOUSE_ICON_BAIS { 5 };
82 constexpr int32_t VISIBLE_LIST_MAX_SIZE { 100 };
83 constexpr int32_t WAIT_TIME_FOR_MAGIC_CURSOR { 6000 };
84 constexpr float ROTATION_ANGLE { 360.f };
85 constexpr float LOADING_CENTER_RATIO { 0.5f };
86 constexpr float RUNNING_X_RATIO { 0.3f };
87 constexpr float RUNNING_Y_RATIO { 0.675f };
88 constexpr float INCREASE_RATIO { 1.22f };
89 constexpr float ROTATION_ANGLE90 { 90.f };
90 constexpr int32_t MIN_POINTER_COLOR { 0x000000 };
91 constexpr int32_t MAX_POINTER_COLOR { 0xffffff };
92 constexpr int32_t MIN_CURSOR_SIZE { 64 };
93 constexpr uint32_t RGB_CHANNEL_BITS_LENGTH { 24 };
94 constexpr float MAX_ALPHA_VALUE { 255.f };
95 constexpr int32_t MOUSE_STYLE_OPT { 0 };
96 constexpr int32_t MAGIC_STYLE_OPT { 1 };
97 constexpr int32_t MAX_TRY_TIMES { 10 };
98 const std::string MOUSE_FILE_NAME { "mouse_settings.xml" };
99 bool g_isRsRemoteDied { false };
100 constexpr uint64_t FOLD_SCREEN_ID_FULL { 0 };
101 constexpr uint64_t FOLD_SCREEN_ID_MAIN { 5 };
102 constexpr int32_t CANVAS_SIZE { 256 };
103 constexpr float IMAGE_PIXEL { 0.0f };
104 constexpr int32_t QUEUE_SIZE { 5 };
105 constexpr int32_t MAX_CUSTOM_CURSOR_SIZE { 256 };
106 constexpr float MAX_CUSTOM_CURSOR_DIMENSION { 256.0f };
107 const int32_t ERROR_WINDOW_ID_PERMISSION_DENIED = 26500001;
108 std::mutex mutex_;
109 } // namespace
110 } // namespace MMI
111 } // namespace OHOS
112
113 namespace OHOS {
114 namespace MMI {
115
IsSingleDisplayFoldDevice()116 static bool IsSingleDisplayFoldDevice()
117 {
118 return (!FOLD_SCREEN_FLAG.empty() && FOLD_SCREEN_FLAG[0] == '1');
119 }
120
RsRemoteDiedCallback()121 void RsRemoteDiedCallback()
122 {
123 CALL_INFO_TRACE;
124 g_isRsRemoteDied = true;
125 MMI_HILOGI("Death callback for RS");
126 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
127 MAGIC_CURSOR->RsRemoteDiedCallbackForMagicCursor();
128 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
129 IPointerDrawingManager::GetInstance()->DestroyPointerWindow();
130 }
131
InitPointerCallback()132 void PointerDrawingManager::InitPointerCallback()
133 {
134 MMI_HILOGI("Init RS observer start");
135 g_isRsRemoteDied = false;
136 Rosen::OnRemoteDiedCallback callback = RsRemoteDiedCallback;
137 Rosen::RSInterfaces::GetInstance().SetOnRemoteDiedCallback(callback);
138 }
139
DestroyPointerWindow()140 void PointerDrawingManager::DestroyPointerWindow()
141 {
142 CALL_INFO_TRACE;
143 CHKPV(delegateProxy_);
144 delegateProxy_->OnPostSyncTask([this] {
145 if (surfaceNode_ != nullptr) {
146 MMI_HILOGI("Pointer window destroy start");
147 g_isRsRemoteDied = false;
148 surfaceNode_->DetachToDisplay(screenId_);
149 surfaceNode_ = nullptr;
150 Rosen::RSTransaction::FlushImplicitTransaction();
151 MMI_HILOGI("Pointer window destroy success");
152 }
153 return RET_OK;
154 });
155 }
156
PointerDrawingManager()157 PointerDrawingManager::PointerDrawingManager()
158 {
159 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
160 MMI_HILOGI("magiccurosr InitStyle");
161 int32_t counter_ = 0;
162 hasMagicCursor_.name = "isMagicCursor";
163 MAGIC_CURSOR->InitStyle();
164 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
165 InitStyle();
166 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
167 hardwareCursorPointerManager_ = std::make_shared<HardwareCursorPointerManager>();
168 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
169 }
170
GetLastMouseStyle()171 PointerStyle PointerDrawingManager::GetLastMouseStyle()
172 {
173 CALL_DEBUG_ENTER;
174 return lastMouseStyle_;
175 }
176
ForceClearPointerVisiableStatus()177 void PointerDrawingManager::ForceClearPointerVisiableStatus()
178 {
179 MMI_HILOGI("force clear all pointer visiable status");
180 pidInfos_.clear();
181 if (!WIN_MGR->HasMouseHideFlag() || INPUT_DEV_MGR->HasPointerDevice() || INPUT_DEV_MGR->HasVirtualPointerDevice()) {
182 UpdatePointerVisible();
183 }
184 }
185
SetHardWareLocation(int32_t displayId,int32_t physicalX,int32_t physicalY)186 bool PointerDrawingManager::SetHardWareLocation(int32_t displayId, int32_t physicalX, int32_t physicalY)
187 {
188 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
189 CHKPF(hardwareCursorPointerManager_);
190 hardwareCursorPointerManager_->SetTargetDevice(displayId);
191 if (hardwareCursorPointerManager_->IsSupported()) {
192 if (hardwareCursorPointerManager_->SetPosition(physicalX, physicalY) != RET_OK) {
193 MMI_HILOGE("Set hardware cursor position error");
194 return false;
195 }
196 }
197 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
198 return true;
199 }
200
DrawMovePointer(int32_t displayId,int32_t physicalX,int32_t physicalY,PointerStyle pointerStyle,Direction direction)201 int32_t PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
202 PointerStyle pointerStyle, Direction direction)
203 {
204 if (surfaceNode_ == nullptr) {
205 return RET_ERR;
206 }
207 MMI_HILOGD("Pointer window move success, pointerStyle id: %{public}d", pointerStyle.id);
208 if (!SetHardWareLocation(displayId, physicalX, physicalY)) {
209 return RET_ERR;
210 }
211 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
212 bool cursorEnlarged = MAGIC_POINTER_VELOCITY_TRACKER->GetCursorEnlargedStatus();
213 if (cursorEnlarged) {
214 MAGIC_POINTER_VELOCITY_TRACKER->SetLastPointerStyle(pointerStyle);
215 MAGIC_POINTER_VELOCITY_TRACKER->SetDirection(direction);
216 if (pointerStyle.id != MOUSE_ICON::DEFAULT && pointerStyle.id != MOUSE_ICON::CROSS) {
217 pointerStyle.id = MOUSE_ICON::DEFAULT;
218 }
219 }
220 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
221 if (lastMouseStyle_ == pointerStyle && !mouseIconUpdate_ && lastDirection_ == direction) {
222 UpdateSurfaceNodeBounds(physicalX, physicalY);
223 Rosen::RSTransaction::FlushImplicitTransaction();
224 MMI_HILOGD("The lastpointerStyle is equal with pointerStyle, id:%{public}d, size:%{public}d",
225 pointerStyle.id, pointerStyle.size);
226 return RET_OK;
227 }
228 if (lastDirection_ != direction) {
229 RotateDegree(direction);
230 lastDirection_ = direction;
231 }
232 lastMouseStyle_ = pointerStyle;
233 surfaceNode_->SetVisible(false);
234 int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
235 if (ret != RET_OK) {
236 mouseIconUpdate_ = false;
237 MMI_HILOGE("Init layer failed");
238 return RET_ERR;
239 }
240 UpdateSurfaceNodeBounds(physicalX, physicalY);
241 surfaceNode_->SetVisible(true);
242 Rosen::RSTransaction::FlushImplicitTransaction();
243 UpdatePointerVisible();
244 mouseIconUpdate_ = false;
245 MMI_HILOGD("Leave, display:%{public}d, physicalX:%{private}d, physicalY:%{private}d",
246 displayId, physicalX, physicalY);
247 return RET_OK;
248 }
249
UpdateSurfaceNodeBounds(int32_t physicalX,int32_t physicalY)250 void PointerDrawingManager::UpdateSurfaceNodeBounds(int32_t physicalX, int32_t physicalY)
251 {
252 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
253 if (HasMagicCursor()) {
254 if (currentMouseStyle_.id == DEVELOPER_DEFINED_ICON) {
255 surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
256 canvasWidth_, canvasHeight_);
257 } else {
258 surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
259 imageWidth_, imageHeight_);
260 }
261 } else {
262 surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
263 surfaceNode_->GetStagingProperties().GetBounds().z_,
264 surfaceNode_->GetStagingProperties().GetBounds().w_);
265 }
266 #else
267 surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
268 surfaceNode_->GetStagingProperties().GetBounds().z_,
269 surfaceNode_->GetStagingProperties().GetBounds().w_);
270 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
271 }
272
DrawMovePointer(int32_t displayId,int32_t physicalX,int32_t physicalY)273 void PointerDrawingManager::DrawMovePointer(int32_t displayId, int32_t physicalX, int32_t physicalY)
274 {
275 CALL_DEBUG_ENTER;
276 if (surfaceNode_ != nullptr) {
277 surfaceNode_->SetBounds(physicalX + displayInfo_.x, physicalY + displayInfo_.y,
278 surfaceNode_->GetStagingProperties().GetBounds().z_,
279 surfaceNode_->GetStagingProperties().GetBounds().w_);
280 Rosen::RSTransaction::FlushImplicitTransaction();
281 MMI_HILOGD("Move pointer, physicalX:%d, physicalY:%d", physicalX, physicalY);
282 }
283 }
284
DrawPointer(int32_t displayId,int32_t physicalX,int32_t physicalY,const PointerStyle pointerStyle,Direction direction)285 void PointerDrawingManager::DrawPointer(int32_t displayId, int32_t physicalX, int32_t physicalY,
286 const PointerStyle pointerStyle, Direction direction)
287 {
288 CALL_DEBUG_ENTER;
289 MMI_HILOGD("Display:%{public}d, physicalX:%{private}d, physicalY:%{private}d, pointerStyle:%{public}d",
290 displayId, physicalX, physicalY, pointerStyle.id);
291 FixCursorPosition(physicalX, physicalY);
292 lastPhysicalX_ = physicalX;
293 lastPhysicalY_ = physicalY;
294 currentMouseStyle_ = pointerStyle;
295 currentDirection_ = direction;
296 std::map<MOUSE_ICON, IconStyle> iconPath = GetMouseIconPath();
297 if (pointerStyle.id == MOUSE_ICON::DEFAULT && iconPath[MOUSE_ICON(pointerStyle.id)].iconPath == CursorIconPath) {
298 AdjustMouseFocus(direction, ICON_TYPE(GetMouseIconPath()[MOUSE_ICON(MOUSE_ICON::CURSOR_CIRCLE)].alignmentWay),
299 physicalX, physicalY);
300 } else {
301 AdjustMouseFocus(direction, ICON_TYPE(GetMouseIconPath()[MOUSE_ICON(pointerStyle.id)].alignmentWay),
302 physicalX, physicalY);
303 }
304 // Log printing only occurs when the mouse style changes
305 if (currentMouseStyle_.id != lastMouseStyle_.id) {
306 MMI_HILOGD("MagicCursor AdjustMouseFocus:%{public}d",
307 ICON_TYPE(GetMouseIconPath()[MOUSE_ICON(pointerStyle.id)].alignmentWay));
308 }
309 if (DrawMovePointer(displayId, physicalX, physicalY, pointerStyle, direction) == RET_OK) {
310 return;
311 }
312 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
313 if (HasMagicCursor() && currentMouseStyle_.id != DEVELOPER_DEFINED_ICON) {
314 MMI_HILOGD("magicCursor DrawPointer enter CreatePointerWindow");
315 MAGIC_CURSOR->CreatePointerWindow(displayId, physicalX, physicalY, direction, surfaceNode_);
316 } else {
317 CreatePointerWindow(displayId, physicalX, physicalY, direction);
318 }
319 #else
320 CreatePointerWindow(displayId, physicalX, physicalY, direction);
321 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
322 CHKPV(surfaceNode_);
323 UpdateMouseStyle();
324 int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
325 if (ret != RET_OK) {
326 MMI_HILOGE("Init layer failed");
327 return;
328 }
329 UpdatePointerVisible();
330 MMI_HILOGI("Leave, display:%{public}d, physicalX:%d, physicalY:%d", displayId, physicalX, physicalY);
331 }
332
UpdateMouseStyle()333 void PointerDrawingManager::UpdateMouseStyle()
334 {
335 CALL_DEBUG_ENTER;
336 PointerStyle curPointerStyle;
337 GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
338 if (curPointerStyle.id == CURSOR_CIRCLE_STYLE) {
339 lastMouseStyle_.id = curPointerStyle.id;
340 int ret = SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
341 if (ret != RET_OK) {
342 MMI_HILOGE("Set pointer style failed");
343 }
344 return;
345 }
346 }
347
SwitchPointerStyle()348 int32_t PointerDrawingManager::SwitchPointerStyle()
349 {
350 CALL_DEBUG_ENTER;
351 int32_t size = GetPointerSize();
352 if (size < MIN_POINTER_SIZE) {
353 size = MIN_POINTER_SIZE;
354 } else if (size > MAX_POINTER_SIZE) {
355 size = MAX_POINTER_SIZE;
356 }
357 MMI_HILOGD("imageWidth_: %{public}d before", imageWidth_);
358 imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
359 imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
360 MMI_HILOGD("imageWidth_: %{public}d after", imageWidth_);
361 canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
362 canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
363 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
364 MAGIC_CURSOR->SetPointerSize(imageWidth_, imageHeight_);
365 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
366 Direction direction = DIRECTION0;
367 int32_t physicalX = lastPhysicalX_;
368 int32_t physicalY = lastPhysicalY_;
369 AdjustMouseFocus(
370 direction, ICON_TYPE(GetIconStyle(MOUSE_ICON(lastMouseStyle_.id)).alignmentWay), physicalX, physicalY);
371 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
372 if (HasMagicCursor()) {
373 MAGIC_CURSOR->CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction, surfaceNode_);
374 } else {
375 CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
376 }
377 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
378 int32_t ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
379 if (ret != RET_OK) {
380 MMI_HILOGE("Init layer failed");
381 return ret;
382 }
383 UpdatePointerVisible();
384 return RET_OK;
385 }
386
CreateMagicCursorChangeObserver()387 void PointerDrawingManager::CreateMagicCursorChangeObserver()
388 {
389 // Listening enabling cursor deformation and color inversion
390 SettingObserver::UpdateFunc func = [](const std::string& key) {
391 bool statusValue = false;
392 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue);
393 if (ret != RET_OK) {
394 MMI_HILOGE("Get value from setting date fail");
395 return;
396 }
397 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
398 MAGIC_CURSOR->UpdateMagicCursorChangeState(statusValue);
399 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
400 };
401 std::string dynamicallyKey = "smartChange";
402 sptr<SettingObserver> magicCursorChangeObserver = SettingDataShare::GetInstance(
403 MULTIMODAL_INPUT_SERVICE_ID).CreateObserver(dynamicallyKey, func);
404 ErrCode ret =
405 SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(magicCursorChangeObserver);
406 if (ret != ERR_OK) {
407 MMI_HILOGE("Register magic cursor change observer failed, ret:%{public}d", ret);
408 magicCursorChangeObserver = nullptr;
409 }
410 }
411
UpdateStyleOptions()412 void PointerDrawingManager::UpdateStyleOptions()
413 {
414 CALL_DEBUG_ENTER;
415 PointerStyle curPointerStyle;
416 WIN_MGR->GetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
417 curPointerStyle.options = HasMagicCursor() ? MAGIC_STYLE_OPT : MOUSE_STYLE_OPT;
418 int ret = WIN_MGR->SetPointerStyle(pid_, GLOBAL_WINDOW_ID, curPointerStyle);
419 if (ret != RET_OK) {
420 MMI_HILOGE("Set pointer style failed");
421 }
422 }
423
InitPointerObserver()424 void PointerDrawingManager::InitPointerObserver()
425 {
426 CALL_INFO_TRACE;
427 if (hasInitObserver_) {
428 MMI_HILOGI("Settingdata observer has init");
429 return;
430 }
431 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
432 int32_t ret = CreatePointerSwitchObserver(hasMagicCursor_);
433 if (ret == RET_OK) {
434 hasInitObserver_ = true;
435 MMI_HILOGD("Create pointer switch observer success");
436 }
437 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
438 }
439
CreatePointerSwitchObserver(isMagicCursor & item)440 int32_t PointerDrawingManager::CreatePointerSwitchObserver(isMagicCursor& item)
441 {
442 CALL_DEBUG_ENTER;
443 SettingObserver::UpdateFunc updateFunc = [this, &item](const std::string& key) {
444 bool statusValue = false;
445 auto ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).GetBoolValue(key, statusValue);
446 if (ret != RET_OK) {
447 MMI_HILOGE("Get value from setting date fail");
448 return;
449 }
450 bool tmp = item.isShow;
451 item.isShow = statusValue;
452 this->UpdateStyleOptions();
453 if (item.isShow != tmp) {
454 if (surfaceNode_ == nullptr) {
455 MMI_HILOGE("surfaceNode_ is nullptr, no need detach");
456 return;
457 }
458 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
459 MMI_HILOGI("switch pointer style");
460 int64_t nodeId = surfaceNode_->GetId();
461 if (nodeId != MAGIC_CURSOR->GetSurfaceNodeId(nodeId)) {
462 surfaceNode_->DetachToDisplay(screenId_);
463 Rosen::RSTransaction::FlushImplicitTransaction();
464 }
465 MAGIC_CURSOR->DetachDisplayNode();
466 this->SwitchPointerStyle();
467 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
468 }
469 };
470 sptr<SettingObserver> statusObserver = SettingDataShare::GetInstance(
471 MULTIMODAL_INPUT_SERVICE_ID).CreateObserver(item.name, updateFunc);
472 ErrCode ret = SettingDataShare::GetInstance(MULTIMODAL_INPUT_SERVICE_ID).RegisterObserver(statusObserver);
473 if (ret != ERR_OK) {
474 MMI_HILOGE("Register setting observer failed, ret:%{public}d", ret);
475 statusObserver = nullptr;
476 return RET_ERR;
477 }
478 CreateMagicCursorChangeObserver();
479 return RET_OK;
480 }
481
HasMagicCursor()482 bool PointerDrawingManager::HasMagicCursor()
483 {
484 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
485 if (!MAGIC_CURSOR->isExistDefaultStyle) {
486 MMI_HILOGE("MagicCursor default icon file is not exist");
487 return false;
488 }
489 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
490 return hasMagicCursor_.isShow;
491 }
492
InitLayer(const MOUSE_ICON mouseStyle)493 int32_t PointerDrawingManager::InitLayer(const MOUSE_ICON mouseStyle)
494 {
495 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
496 if (HasMagicCursor() && mouseStyle != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
497 MMI_HILOGD("magiccursor enter MAGIC_CURSOR->Initlayer");
498 return MAGIC_CURSOR->InitLayer(mouseStyle);
499 } else {
500 MMI_HILOGD("magiccursor not enter MAGIC_CURSOR->Initlayer");
501 return DrawCursor(mouseStyle);
502 }
503 #else
504 return DrawCursor(mouseStyle);
505 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
506 }
507
DrawCursor(const MOUSE_ICON mouseStyle)508 int32_t PointerDrawingManager::DrawCursor(const MOUSE_ICON mouseStyle)
509 {
510 CALL_DEBUG_ENTER;
511 CHKPR(surfaceNode_, RET_ERR);
512 DrawLoadingPointerStyle(mouseStyle);
513 DrawRunningPointerAnimate(mouseStyle);
514 sptr<OHOS::Surface> layer = GetLayer();
515 if (layer == nullptr) {
516 MMI_HILOGE("Init layer is failed, Layer is nullptr");
517 surfaceNode_->DetachToDisplay(screenId_);
518 surfaceNode_ = nullptr;
519 Rosen::RSTransaction::FlushImplicitTransaction();
520 MMI_HILOGE("Pointer window destroy success");
521 return RET_ERR;
522 }
523 if (!isInit_) {
524 layer->SetQueueSize(QUEUE_SIZE);
525 isInit_ = true;
526 }
527 sptr<OHOS::SurfaceBuffer> buffer = GetSurfaceBuffer(layer);
528 if (buffer == nullptr || buffer->GetVirAddr() == nullptr) {
529 MMI_HILOGE("Init layer is failed, buffer or virAddr is nullptr");
530 surfaceNode_->DetachToDisplay(screenId_);
531 surfaceNode_ = nullptr;
532 Rosen::RSTransaction::FlushImplicitTransaction();
533 MMI_HILOGE("Pointer window destroy success");
534 return RET_ERR;
535 }
536
537 auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
538 DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), mouseStyle);
539 OHOS::BufferFlushConfig flushConfig = {
540 .damage = {
541 .w = buffer->GetWidth(),
542 .h = buffer->GetHeight(),
543 },
544 };
545 OHOS::SurfaceError ret = layer->FlushBuffer(buffer, -1, flushConfig);
546 if (ret != OHOS::SURFACE_ERROR_OK) {
547 MMI_HILOGE("Init layer failed, FlushBuffer return ret:%{public}s", SurfaceErrorStr(ret).c_str());
548 return RET_ERR;
549 }
550 MMI_HILOGD("Init layer success");
551 return RET_OK;
552 }
553
DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)554 void PointerDrawingManager::DrawLoadingPointerStyle(const MOUSE_ICON mouseStyle)
555 {
556 CALL_DEBUG_ENTER;
557 CHKPV(surfaceNode_);
558 Rosen::RSAnimationTimingProtocol protocol;
559 if (mouseStyle != MOUSE_ICON::LOADING &&
560 (mouseStyle != MOUSE_ICON::DEFAULT ||
561 mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"))) {
562 protocol.SetDuration(0);
563 Rosen::RSNode::Animate(
564 protocol,
565 Rosen::RSAnimationTimingCurve::LINEAR,
566 [this]() {
567 if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
568 RotateDegree(DIRECTION0);
569 return;
570 }
571 RotateDegree(currentDirection_);
572 });
573 MMI_HILOGE("current pointer is not loading");
574 Rosen::RSTransaction::FlushImplicitTransaction();
575 return;
576 }
577 float ratio = imageWidth_ * 1.0 / canvasWidth_;
578 surfaceNode_->SetPivot({LOADING_CENTER_RATIO * ratio, LOADING_CENTER_RATIO * ratio});
579 protocol.SetDuration(ANIMATION_DURATION);
580 protocol.SetRepeatCount(DEFAULT_VALUE);
581
582 // create property animation
583 Rosen::RSNode::Animate(
584 protocol,
585 Rosen::RSAnimationTimingCurve::LINEAR,
586 [this]() { surfaceNode_->SetRotation(ROTATION_ANGLE); });
587
588 Rosen::RSTransaction::FlushImplicitTransaction();
589 }
590
ConvertToColorSpace(Media::ColorSpace colorSpace)591 std::shared_ptr<Rosen::Drawing::ColorSpace> PointerDrawingManager::ConvertToColorSpace(
592 Media::ColorSpace colorSpace)
593 {
594 switch (colorSpace) {
595 case Media::ColorSpace::DISPLAY_P3:
596 return Rosen::Drawing::ColorSpace::CreateRGB(
597 Rosen::Drawing::CMSTransferFuncType::SRGB, Rosen::Drawing::CMSMatrixType::DCIP3);
598 case Media::ColorSpace::LINEAR_SRGB:
599 return Rosen::Drawing::ColorSpace::CreateSRGBLinear();
600 case Media::ColorSpace::SRGB:
601 return Rosen::Drawing::ColorSpace::CreateSRGB();
602 default:
603 return Rosen::Drawing::ColorSpace::CreateSRGB();
604 }
605 }
606
PixelFormatToColorType(Media::PixelFormat pixelFormat)607 Rosen::Drawing::ColorType PointerDrawingManager::PixelFormatToColorType(Media::PixelFormat pixelFormat)
608 {
609 switch (pixelFormat) {
610 case Media::PixelFormat::RGB_565:
611 return Rosen::Drawing::ColorType::COLORTYPE_RGB_565;
612 case Media::PixelFormat::RGBA_8888:
613 return Rosen::Drawing::ColorType::COLORTYPE_RGBA_8888;
614 case Media::PixelFormat::BGRA_8888:
615 return Rosen::Drawing::ColorType::COLORTYPE_BGRA_8888;
616 case Media::PixelFormat::ALPHA_8:
617 return Rosen::Drawing::ColorType::COLORTYPE_ALPHA_8;
618 case Media::PixelFormat::RGBA_F16:
619 return Rosen::Drawing::ColorType::COLORTYPE_RGBA_F16;
620 case Media::PixelFormat::UNKNOWN:
621 case Media::PixelFormat::ARGB_8888:
622 case Media::PixelFormat::RGB_888:
623 case Media::PixelFormat::NV21:
624 case Media::PixelFormat::NV12:
625 case Media::PixelFormat::CMYK:
626 default:
627 return Rosen::Drawing::ColorType::COLORTYPE_UNKNOWN;
628 }
629 }
630
AlphaTypeToAlphaType(Media::AlphaType alphaType)631 Rosen::Drawing::AlphaType PointerDrawingManager::AlphaTypeToAlphaType(Media::AlphaType alphaType)
632 {
633 switch (alphaType) {
634 case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
635 return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
636 case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
637 return Rosen::Drawing::AlphaType::ALPHATYPE_OPAQUE;
638 case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
639 return Rosen::Drawing::AlphaType::ALPHATYPE_PREMUL;
640 case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
641 return Rosen::Drawing::AlphaType::ALPHATYPE_UNPREMUL;
642 default:
643 return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
644 }
645 }
646
PixelMapReleaseProc(const void *,void * context)647 static void PixelMapReleaseProc(const void* /* pixels */, void* context)
648 {
649 PixelMapReleaseContext* ctx = static_cast<PixelMapReleaseContext*>(context);
650 if (ctx != nullptr) {
651 delete ctx;
652 }
653 }
654
ExtractDrawingImage(std::shared_ptr<Media::PixelMap> pixelMap)655 std::shared_ptr<Rosen::Drawing::Image> PointerDrawingManager::ExtractDrawingImage(
656 std::shared_ptr<Media::PixelMap> pixelMap)
657 {
658 CHKPP(pixelMap);
659 Media::ImageInfo imageInfo;
660 pixelMap->GetImageInfo(imageInfo);
661 Rosen::Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
662 PixelFormatToColorType(imageInfo.pixelFormat),
663 AlphaTypeToAlphaType(imageInfo.alphaType),
664 ConvertToColorSpace(imageInfo.colorSpace) };
665 Rosen::Drawing::Pixmap imagePixmap(drawingImageInfo,
666 reinterpret_cast<const void*>(pixelMap->GetPixels()), pixelMap->GetRowBytes());
667 PixelMapReleaseContext* releaseContext = new (std::nothrow) PixelMapReleaseContext(pixelMap);
668 CHKPP(releaseContext);
669 auto image = Rosen::Drawing::Image::MakeFromRaster(imagePixmap, PixelMapReleaseProc, releaseContext);
670 if (image == nullptr) {
671 MMI_HILOGE("ExtractDrawingImage image fail");
672 delete releaseContext;
673 }
674 return image;
675 }
676
DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)677 void PointerDrawingManager::DrawRunningPointerAnimate(const MOUSE_ICON mouseStyle)
678 {
679 CALL_DEBUG_ENTER;
680 CHKPV(surfaceNode_);
681 CHKPV(canvasNode_);
682 if (mouseStyle != MOUSE_ICON::RUNNING &&
683 (mouseStyle != MOUSE_ICON::DEFAULT ||
684 mouseIcons_[mouseStyle].iconPath != (IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"))) {
685 if (canvasNode_ != nullptr) {
686 canvasNode_->SetVisible(false);
687 }
688 MMI_HILOGE("current pointer is not running");
689 return;
690 }
691 canvasNode_->SetVisible(true);
692 float ratio = imageWidth_ * 1.0 / canvasWidth_;
693 canvasNode_->SetPivot({RUNNING_X_RATIO * ratio, RUNNING_Y_RATIO * ratio});
694 std::shared_ptr<OHOS::Media::PixelMap> pixelmap =
695 DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_RIGHT].iconPath);
696 CHKPV(pixelmap);
697 MMI_HILOGD("Set mouseicon to OHOS system");
698
699 #ifndef USE_ROSEN_DRAWING
700 auto canvas = static_cast<Rosen::RSRecordingCanvas *>(canvasNode_->BeginRecording(CANVAS_SIZE, CANVAS_SIZE));
701 OHOS::Rosen::Drawing::Brush brush;
702 brush.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
703 canvas->DrawBackground(brush);
704 canvas->DrawPixelMap(pixelmap, 0, 0, SkSamplingOptions(), nullptr);
705 #else
706 Rosen::Drawing::Brush brush;
707 Rosen::Drawing::Rect src = Rosen::Drawing::Rect(0, 0, pixelmap->GetWidth(), pixelmap->GetHeight());
708 Rosen::Drawing::Rect dst = Rosen::Drawing::Rect(src);
709 auto canvas =
710 static_cast<Rosen::ExtendRecordingCanvas *>(canvasNode_->BeginRecording(CANVAS_SIZE, CANVAS_SIZE));
711 OHOS::Rosen::Drawing::Brush brushBackGround;
712 brushBackGround.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
713 canvas->AttachBrush(brush);
714 canvas->DrawBackground(brushBackGround);
715 canvas->DrawPixelMapRect(pixelmap, src, dst, Rosen::Drawing::SamplingOptions());
716 canvas->DetachBrush();
717 #endif // USE_ROSEN_DRAWING
718
719 canvasNode_->FinishRecording();
720
721 Rosen::RSAnimationTimingProtocol protocol;
722 protocol.SetDuration(ANIMATION_DURATION);
723 protocol.SetRepeatCount(DEFAULT_VALUE);
724
725 // create property animation
726 Rosen::RSNode::Animate(
727 protocol,
728 Rosen::RSAnimationTimingCurve::LINEAR,
729 [this]() { canvasNode_->SetRotation(ROTATION_ANGLE); });
730
731 Rosen::RSTransaction::FlushImplicitTransaction();
732 }
733
AdjustMouseFocus(Direction direction,ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)734 void PointerDrawingManager::AdjustMouseFocus(Direction direction, ICON_TYPE iconType,
735 int32_t &physicalX, int32_t &physicalY)
736 {
737 CALL_DEBUG_ENTER;
738 switch (direction) {
739 case DIRECTION0: {
740 AdjustMouseFocusByDirection0(iconType, physicalX, physicalY);
741 break;
742 }
743 case DIRECTION90: {
744 AdjustMouseFocusByDirection90(iconType, physicalX, physicalY);
745 break;
746 }
747 case DIRECTION180: {
748 AdjustMouseFocusByDirection180(iconType, physicalX, physicalY);
749 break;
750 }
751 case DIRECTION270: {
752 AdjustMouseFocusByDirection270(iconType, physicalX, physicalY);
753 break;
754 }
755 default: {
756 MMI_HILOGW("direction is invalid,direction:%{public}d", direction);
757 break;
758 }
759 }
760 }
761
AdjustMouseFocusByDirection0(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)762 void PointerDrawingManager::AdjustMouseFocusByDirection0(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
763 {
764 CALL_DEBUG_ENTER;
765 switch (iconType) {
766 case ANGLE_SW: {
767 physicalY -= imageHeight_;
768 break;
769 }
770 case ANGLE_CENTER: {
771 physicalX -= imageWidth_ / CALCULATE_MIDDLE;
772 physicalY -= imageHeight_ / CALCULATE_MIDDLE;
773 break;
774 }
775 case ANGLE_NW_RIGHT: {
776 physicalX -= MOUSE_ICON_BAIS;
777 [[fallthrough]];
778 }
779 case ANGLE_NW: {
780 if (GetUserIconCopy() != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
781 physicalX -= userIconHotSpotX_;
782 physicalY -= userIconHotSpotY_;
783 }
784 break;
785 }
786 default: {
787 MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
788 break;
789 }
790 }
791 }
792
AdjustMouseFocusByDirection90(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)793 void PointerDrawingManager::AdjustMouseFocusByDirection90(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
794 {
795 CALL_DEBUG_ENTER;
796 switch (iconType) {
797 case ANGLE_SW: {
798 physicalY += imageHeight_;
799 break;
800 }
801 case ANGLE_CENTER: {
802 physicalX -= imageWidth_ / CALCULATE_MIDDLE;
803 physicalY += imageHeight_ / CALCULATE_MIDDLE;
804 break;
805 }
806 case ANGLE_NW_RIGHT: {
807 physicalX -= MOUSE_ICON_BAIS;
808 [[fallthrough]];
809 }
810 case ANGLE_NW: {
811 if (GetUserIconCopy() != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
812 physicalX -= userIconHotSpotX_;
813 physicalY += userIconHotSpotY_;
814 }
815 break;
816 }
817 default: {
818 MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
819 break;
820 }
821 }
822 }
823
AdjustMouseFocusByDirection180(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)824 void PointerDrawingManager::AdjustMouseFocusByDirection180(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
825 {
826 CALL_DEBUG_ENTER;
827 switch (iconType) {
828 case ANGLE_SW: {
829 physicalY += imageHeight_;
830 break;
831 }
832 case ANGLE_CENTER: {
833 physicalX += imageWidth_ / CALCULATE_MIDDLE;
834 physicalY += imageHeight_ / CALCULATE_MIDDLE;
835 break;
836 }
837 case ANGLE_NW_RIGHT: {
838 physicalX += MOUSE_ICON_BAIS;
839 [[fallthrough]];
840 }
841 case ANGLE_NW: {
842 if (GetUserIconCopy() != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
843 physicalX += userIconHotSpotX_;
844 physicalY += userIconHotSpotY_;
845 }
846 break;
847 }
848 default: {
849 MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
850 break;
851 }
852 }
853 }
854
AdjustMouseFocusByDirection270(ICON_TYPE iconType,int32_t & physicalX,int32_t & physicalY)855 void PointerDrawingManager::AdjustMouseFocusByDirection270(ICON_TYPE iconType, int32_t &physicalX, int32_t &physicalY)
856 {
857 CALL_DEBUG_ENTER;
858 switch (iconType) {
859 case ANGLE_SW: {
860 physicalY -= imageHeight_;
861 break;
862 }
863 case ANGLE_CENTER: {
864 physicalX += imageWidth_ / CALCULATE_MIDDLE;
865 physicalY -= imageHeight_ / CALCULATE_MIDDLE;
866 break;
867 }
868 case ANGLE_NW_RIGHT: {
869 physicalX += MOUSE_ICON_BAIS;
870 [[fallthrough]];
871 }
872 case ANGLE_NW: {
873 if (GetUserIconCopy() != nullptr && currentMouseStyle_.id == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
874 physicalX += userIconHotSpotX_;
875 physicalY -= userIconHotSpotY_;
876 }
877 break;
878 }
879 default: {
880 MMI_HILOGW("No need adjust mouse focus,iconType:%{public}d", iconType);
881 break;
882 }
883 }
884 }
885
SetMouseDisplayState(bool state)886 void PointerDrawingManager::SetMouseDisplayState(bool state)
887 {
888 CALL_DEBUG_ENTER;
889 if (mouseDisplayState_ != state) {
890 mouseDisplayState_ = state;
891 if (mouseDisplayState_) {
892 InitLayer(MOUSE_ICON(lastMouseStyle_.id));
893 }
894 MMI_HILOGI("state:%{public}s", state ? "true" : "false");
895 UpdatePointerVisible();
896 }
897 }
898
GetMouseDisplayState() const899 bool PointerDrawingManager::GetMouseDisplayState() const
900 {
901 return mouseDisplayState_;
902 }
903
IsWindowRotation()904 bool PointerDrawingManager::IsWindowRotation()
905 {
906 MMI_HILOGD("ROTATE_POLICY: %{public}d, FOLDABLE_DEVICE_POLICY:%{public}s",
907 ROTATE_POLICY, FOLDABLE_DEVICE_POLICY.c_str());
908 return (ROTATE_POLICY == WINDOW_ROTATE ||
909 (ROTATE_POLICY == FOLDABLE_DEVICE &&
910 ((displayInfo_.displayMode == DisplayMode::MAIN &&
911 FOLDABLE_DEVICE_POLICY[0] == ROTATE_WINDOW_ROTATE) ||
912 (displayInfo_.displayMode == DisplayMode::FULL &&
913 FOLDABLE_DEVICE_POLICY[FOLDABLE_DEVICE] == ROTATE_WINDOW_ROTATE))));
914 }
915
FixCursorPosition(int32_t & physicalX,int32_t & physicalY)916 void PointerDrawingManager::FixCursorPosition(int32_t &physicalX, int32_t &physicalY)
917 {
918 if (physicalX < 0) {
919 physicalX = 0;
920 }
921
922 if (physicalY < 0) {
923 physicalY = 0;
924 }
925 const int32_t cursorUnit = 16;
926 if (IsWindowRotation()) {
927 if (displayInfo_.direction == DIRECTION0 || displayInfo_.direction == DIRECTION180) {
928 if (physicalX > (displayInfo_.width - imageWidth_ / cursorUnit)) {
929 physicalX = displayInfo_.width - imageWidth_ / cursorUnit;
930 }
931 if (physicalY > (displayInfo_.height - imageHeight_ / cursorUnit)) {
932 physicalY = displayInfo_.height - imageHeight_ / cursorUnit;
933 }
934 } else {
935 if (physicalX > (displayInfo_.height - imageHeight_ / cursorUnit)) {
936 physicalX = displayInfo_.height - imageHeight_ / cursorUnit;
937 }
938 if (physicalY > (displayInfo_.width - imageWidth_ / cursorUnit)) {
939 physicalY = displayInfo_.width - imageWidth_ / cursorUnit;
940 }
941 }
942 } else {
943 if (physicalX > (displayInfo_.width - imageWidth_ / cursorUnit)) {
944 physicalX = displayInfo_.width - imageWidth_ / cursorUnit;
945 }
946 if (physicalY > (displayInfo_.height - imageHeight_ / cursorUnit)) {
947 physicalY = displayInfo_.height - imageHeight_ / cursorUnit;
948 }
949 }
950 }
951
AttachToDisplay()952 void PointerDrawingManager::AttachToDisplay()
953 {
954 CALL_DEBUG_ENTER;
955 CHKPV(surfaceNode_);
956 if (IsSingleDisplayFoldDevice() && (WIN_MGR->GetDisplayMode() == DisplayMode::MAIN)
957 && (screenId_ == FOLD_SCREEN_ID_FULL)) {
958 screenId_ = FOLD_SCREEN_ID_MAIN;
959 }
960 MMI_HILOGI("screenId_: %{public}" PRIu64"", screenId_);
961 surfaceNode_->AttachToDisplay(screenId_);
962 }
963
CreatePointerWindow(int32_t displayId,int32_t physicalX,int32_t physicalY,Direction direction)964 void PointerDrawingManager::CreatePointerWindow(int32_t displayId, int32_t physicalX, int32_t physicalY,
965 Direction direction)
966 {
967 CALL_DEBUG_ENTER;
968 CALL_INFO_TRACE;
969 std::lock_guard<std::mutex> guard(mutex_);
970 Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
971 surfaceNodeConfig.SurfaceNodeName = "pointer window";
972 Rosen::RSSurfaceNodeType surfaceNodeType = Rosen::RSSurfaceNodeType::SELF_DRAWING_WINDOW_NODE;
973 surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
974 CHKPV(surfaceNode_);
975 surfaceNode_->SetFrameGravity(Rosen::Gravity::RESIZE_ASPECT_FILL);
976 surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
977 surfaceNode_->SetBounds(physicalX, physicalY, canvasWidth_, canvasHeight_);
978 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
979 CHKPV(hardwareCursorPointerManager_);
980 hardwareCursorPointerManager_->SetTargetDevice(displayId);
981 if (hardwareCursorPointerManager_->IsSupported()) {
982 if (hardwareCursorPointerManager_->SetPosition(physicalX, physicalY) != RET_OK) {
983 MMI_HILOGE("Set hardware cursor position error");
984 return;
985 }
986 }
987 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
988 #ifndef USE_ROSEN_DRAWING
989 surfaceNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
990 #else
991 surfaceNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
992 #endif
993
994 screenId_ = static_cast<uint64_t>(displayId);
995 std::cout << "ScreenId: " << screenId_ << std::endl;
996 AttachToDisplay();
997 RotateDegree(direction);
998 lastDirection_ = direction;
999
1000 canvasNode_ = Rosen::RSCanvasNode::Create();
1001 canvasNode_->SetBounds(0, 0, canvasWidth_, canvasHeight_);
1002 canvasNode_->SetFrame(0, 0, canvasWidth_, canvasHeight_);
1003 #ifndef USE_ROSEN_DRAWING
1004 canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
1005 #else
1006 canvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1007 #endif
1008 canvasNode_->SetCornerRadius(1);
1009 canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
1010 canvasNode_->SetRotation(0);
1011 surfaceNode_->AddChild(canvasNode_, DEFAULT_VALUE);
1012 Rosen::RSTransaction::FlushImplicitTransaction();
1013 }
1014
GetLayer()1015 sptr<OHOS::Surface> PointerDrawingManager::GetLayer()
1016 {
1017 CALL_DEBUG_ENTER;
1018 CHKPP(surfaceNode_);
1019 return surfaceNode_->GetSurface();
1020 }
1021
GetSurfaceBuffer(sptr<OHOS::Surface> layer) const1022 sptr<OHOS::SurfaceBuffer> PointerDrawingManager::GetSurfaceBuffer(sptr<OHOS::Surface> layer) const
1023 {
1024 CALL_DEBUG_ENTER;
1025 sptr<OHOS::SurfaceBuffer> buffer;
1026 int32_t releaseFence = -1;
1027 OHOS::BufferRequestConfig config = {
1028 .width = canvasWidth_,
1029 .height = canvasHeight_,
1030 .strideAlignment = 0x8,
1031 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
1032 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
1033 .timeout = 100,
1034 };
1035
1036 OHOS::SurfaceError ret = layer->RequestBuffer(buffer, releaseFence, config);
1037 close(releaseFence);
1038 if (ret != OHOS::SURFACE_ERROR_OK) {
1039 MMI_HILOGE("Request buffer ret:%{public}s", SurfaceErrorStr(ret).c_str());
1040 return nullptr;
1041 }
1042 return buffer;
1043 }
1044
DrawImage(OHOS::Rosen::Drawing::Canvas & canvas,MOUSE_ICON mouseStyle)1045 void PointerDrawingManager::DrawImage(OHOS::Rosen::Drawing::Canvas &canvas, MOUSE_ICON mouseStyle)
1046 {
1047 MMI_HILOGI("Draw mouse icon of style(%{public}d)", static_cast<int32_t>(mouseStyle));
1048 OHOS::Rosen::Drawing::Pen pen;
1049 pen.SetAntiAlias(true);
1050 pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1051 OHOS::Rosen::Drawing::scalar penWidth = 1;
1052 pen.SetWidth(penWidth);
1053 canvas.AttachPen(pen);
1054 std::shared_ptr<Rosen::Drawing::Image> image;
1055 std::shared_ptr<OHOS::Media::PixelMap> pixelmap;
1056 if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1057 MMI_HILOGD("Set mouseicon by userIcon_");
1058 auto userIconCopy = GetUserIconCopy();
1059 image = ExtractDrawingImage(userIconCopy);
1060 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1061 SetPixelMap(userIconCopy);
1062 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1063 } else {
1064 if (mouseStyle == MOUSE_ICON::RUNNING) {
1065 pixelmap = DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_LEFT].iconPath);
1066 } else {
1067 pixelmap = DecodeImageToPixelMap(mouseIcons_[mouseStyle].iconPath);
1068 }
1069 CHKPV(pixelmap);
1070 image = ExtractDrawingImage(pixelmap);
1071 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1072 if ((mouseStyle == MOUSE_ICON::DEFAULT) || (mouseStyle == MOUSE_ICON::CURSOR_CIRCLE)) {
1073 SetPixelMap(pixelmap);
1074 }
1075 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1076 MMI_HILOGI("Set mouseicon to system");
1077 }
1078 CHKPV(image);
1079 OHOS::Rosen::Drawing::Brush brush;
1080 brush.SetColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
1081 canvas.DrawBackground(brush);
1082 canvas.DrawImage(*image, IMAGE_PIXEL, IMAGE_PIXEL, Rosen::Drawing::SamplingOptions());
1083 MMI_HILOGD("Canvas draw image, success");
1084 }
1085
1086 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)1087 void PointerDrawingManager::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
1088 {
1089 MMI_HILOGI("Set pointer snapshot");
1090 pixelMap_ = pixelMap;
1091 }
1092
GetPointerSnapshot(void * pixelMapPtr)1093 int32_t PointerDrawingManager::GetPointerSnapshot(void *pixelMapPtr)
1094 {
1095 CALL_DEBUG_ENTER;
1096 std::shared_ptr<Media::PixelMap> *newPixelMapPtr = static_cast<std::shared_ptr<Media::PixelMap> *>(pixelMapPtr);
1097 MMI_HILOGI("Get pointer snapshot");
1098 *newPixelMapPtr = pixelMap_;
1099 if (HasMagicCursor()) {
1100 MMI_HILOGE("magic pixelmap");
1101 *newPixelMapPtr = MAGIC_CURSOR->GetPixelMap();
1102 }
1103 CHKPR(*newPixelMapPtr, ERROR_NULL_POINTER);
1104 return RET_OK;
1105 }
1106 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1107
DoDraw(uint8_t * addr,uint32_t width,uint32_t height,const MOUSE_ICON mouseStyle)1108 void PointerDrawingManager::DoDraw(uint8_t *addr, uint32_t width, uint32_t height, const MOUSE_ICON mouseStyle)
1109 {
1110 CALL_DEBUG_ENTER;
1111 OHOS::Rosen::Drawing::Bitmap bitmap;
1112 OHOS::Rosen::Drawing::BitmapFormat format { OHOS::Rosen::Drawing::COLORTYPE_RGBA_8888,
1113 OHOS::Rosen::Drawing::ALPHATYPE_OPAQUE };
1114 bitmap.Build(width, height, format);
1115 OHOS::Rosen::Drawing::Canvas canvas(CANVAS_SIZE, CANVAS_SIZE);
1116 canvas.Bind(bitmap);
1117 canvas.Clear(OHOS::Rosen::Drawing::Color::COLOR_TRANSPARENT);
1118 DrawImage(canvas, mouseStyle);
1119 static constexpr uint32_t stride = 4;
1120 uint32_t addrSize = width * height * stride;
1121 errno_t ret = memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize);
1122 if (ret != EOK) {
1123 MMI_HILOGE("Memcpy data is error, ret:%{public}d", ret);
1124 return;
1125 }
1126 }
1127
DrawPixelmap(OHOS::Rosen::Drawing::Canvas & canvas,const MOUSE_ICON mouseStyle)1128 void PointerDrawingManager::DrawPixelmap(OHOS::Rosen::Drawing::Canvas &canvas, const MOUSE_ICON mouseStyle)
1129 {
1130 CALL_DEBUG_ENTER;
1131 OHOS::Rosen::Drawing::Pen pen;
1132 pen.SetAntiAlias(true);
1133 pen.SetColor(OHOS::Rosen::Drawing::Color::COLOR_BLUE);
1134 OHOS::Rosen::Drawing::scalar penWidth = 1;
1135 pen.SetWidth(penWidth);
1136 canvas.AttachPen(pen);
1137 if (mouseStyle == MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1138 MMI_HILOGD("set mouseicon by userIcon_");
1139 auto userIconCopy = GetUserIconCopy();
1140 CHKPV(userIconCopy);
1141 OHOS::Rosen::RSPixelMapUtil::DrawPixelMap(canvas, *userIconCopy, 0, 0);
1142 } else {
1143 std::shared_ptr<OHOS::Media::PixelMap> pixelmap;
1144 if (mouseStyle == MOUSE_ICON::RUNNING) {
1145 pixelmap = DecodeImageToPixelMap(mouseIcons_[MOUSE_ICON::RUNNING_LEFT].iconPath);
1146 } else {
1147 pixelmap = DecodeImageToPixelMap(mouseIcons_[mouseStyle].iconPath);
1148 }
1149 CHKPV(pixelmap);
1150 MMI_HILOGD("Set mouseicon to OHOS system");
1151 OHOS::Rosen::RSPixelMapUtil::DrawPixelMap(canvas, *pixelmap, 0, 0);
1152 }
1153 }
1154
SetCustomCursor(void * pixelMap,int32_t pid,int32_t windowId,int32_t focusX,int32_t focusY)1155 int32_t PointerDrawingManager::SetCustomCursor(void* pixelMap, int32_t pid, int32_t windowId, int32_t focusX,
1156 int32_t focusY)
1157 {
1158 CALL_DEBUG_ENTER;
1159 followSystem_ = false;
1160 CHKPR(pixelMap, RET_ERR);
1161 if (pid == -1) {
1162 MMI_HILOGE("pid is invalid");
1163 return RET_ERR;
1164 }
1165 if (windowId < 0) {
1166 MMI_HILOGE("windowId is invalid, windowId:%{public}d", windowId);
1167 return RET_ERR;
1168 }
1169 if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1170 MMI_HILOGE("windowId not in right pid");
1171 return RET_ERR;
1172 }
1173 int32_t ret = UpdateCursorProperty(pixelMap, focusX, focusY);
1174 if (ret != RET_OK) {
1175 MMI_HILOGE("UpdateCursorProperty is failed");
1176 return ret;
1177 }
1178 mouseIconUpdate_ = true;
1179 PointerStyle style;
1180 style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
1181 lastMouseStyle_ = style;
1182
1183 ret = SetPointerStyle(pid, windowId, style);
1184 if (ret == RET_ERR) {
1185 MMI_HILOGE("SetPointerStyle is failed");
1186 }
1187 MMI_HILOGD("style.id:%{public}d, userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
1188 style.id, userIconHotSpotX_, userIconHotSpotY_);
1189 return ret;
1190 }
1191
UpdateCursorProperty(void * pixelMap,const int32_t & focusX,const int32_t & focusY)1192 int32_t PointerDrawingManager::UpdateCursorProperty(void* pixelMap, const int32_t &focusX, const int32_t &focusY)
1193 {
1194 CHKPR(pixelMap, RET_ERR);
1195 Media::PixelMap* newPixelMap = static_cast<Media::PixelMap*>(pixelMap);
1196 CHKPR(newPixelMap, RET_ERR);
1197 Media::ImageInfo imageInfo;
1198 newPixelMap->GetImageInfo(imageInfo);
1199 int32_t cursorSize = GetPointerSize();
1200 int32_t cursorWidth =
1201 pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1202 int32_t cursorHeight =
1203 pow(INCREASE_RATIO, cursorSize - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1204 cursorWidth = cursorWidth < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorWidth;
1205 cursorHeight = cursorHeight < MIN_CURSOR_SIZE ? MIN_CURSOR_SIZE : cursorHeight;
1206 float xAxis = (float)cursorWidth / (float)imageInfo.size.width;
1207 float yAxis = (float)cursorHeight / (float)imageInfo.size.height;
1208 newPixelMap->scale(xAxis, yAxis, Media::AntiAliasingOption::LOW);
1209 userIcon_.reset(newPixelMap);
1210 userIconHotSpotX_ = static_cast<int32_t>((float)focusX * xAxis);
1211 userIconHotSpotY_ = static_cast<int32_t>((float)focusY * yAxis);
1212 if (EventLogHelper::IsBetaVersion()) {
1213 MMI_HILOGI("cursorWidth:%{private}d, cursorHeight:%{private}d, imageWidth:%{public}d, imageHeight:%{public}d,"
1214 "focusX:%{private}d, focuxY:%{private}d, xAxis:%{public}f, yAxis:%{public}f, userIconHotSpotX_:%{private}d,"
1215 "userIconHotSpotY_:%{private}d", cursorWidth, cursorHeight, imageInfo.size.width, imageInfo.size.height,
1216 focusX, focusY, xAxis, yAxis, userIconHotSpotX_, userIconHotSpotY_);
1217 }
1218 return RET_OK;
1219 }
1220
SetMouseIcon(int32_t pid,int32_t windowId,void * pixelMap)1221 int32_t PointerDrawingManager::SetMouseIcon(int32_t pid, int32_t windowId, void* pixelMap)
1222 __attribute__((no_sanitize("cfi")))
1223 {
1224 CALL_DEBUG_ENTER;
1225 if (pid == -1) {
1226 MMI_HILOGE("pid is invalid return -1");
1227 return RET_ERR;
1228 }
1229 CHKPR(pixelMap, RET_ERR);
1230 if (windowId < 0) {
1231 MMI_HILOGE("get invalid windowId, %{public}d", windowId);
1232 return RET_ERR;
1233 }
1234 if (!WIN_MGR->CheckPidInSession(pid)) {
1235 MMI_HILOGE("The pid not exists in current session");
1236 return RET_ERR;
1237 }
1238 OHOS::Media::PixelMap* pixelMapPtr = static_cast<OHOS::Media::PixelMap*>(pixelMap);
1239 userIcon_.reset(pixelMapPtr);
1240 mouseIconUpdate_ = true;
1241 PointerStyle style;
1242 style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
1243 int32_t ret = SetPointerStyle(pid, windowId, style);
1244 if (ret == RET_ERR) {
1245 MMI_HILOGE("SetPointerStyle return RET_ERR here");
1246 }
1247 return ret;
1248 }
1249
SetMouseHotSpot(int32_t pid,int32_t windowId,int32_t hotSpotX,int32_t hotSpotY)1250 int32_t PointerDrawingManager::SetMouseHotSpot(int32_t pid, int32_t windowId, int32_t hotSpotX, int32_t hotSpotY)
1251 {
1252 CALL_DEBUG_ENTER;
1253 if (pid == -1) {
1254 MMI_HILOGE("pid is invalid return -1");
1255 return RET_ERR;
1256 }
1257 if (windowId < 0) {
1258 MMI_HILOGE("invalid windowId, %{public}d", windowId);
1259 return RET_ERR;
1260 }
1261 if (WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
1262 MMI_HILOGE("windowId not in right pid");
1263 return RET_ERR;
1264 }
1265 auto userIconCopy = GetUserIconCopy();
1266 if (hotSpotX < 0 || hotSpotY < 0 || userIconCopy == nullptr) {
1267 MMI_HILOGE("invalid value");
1268 return RET_ERR;
1269 }
1270 PointerStyle pointerStyle;
1271 WIN_MGR->GetPointerStyle(pid, windowId, pointerStyle);
1272 if (pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) {
1273 MMI_HILOGE("Get pointer style failed, pid %{publid}d, pointerStyle %{public}d", pid, pointerStyle.id);
1274 return RET_ERR;
1275 }
1276 userIconHotSpotX_ = hotSpotX;
1277 userIconHotSpotY_ = hotSpotY;
1278 return RET_OK;
1279 }
1280
DecodeImageToPixelMap(const std::string & imagePath)1281 std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::DecodeImageToPixelMap(const std::string &imagePath)
1282 {
1283 CALL_DEBUG_ENTER;
1284 OHOS::Media::SourceOptions opts;
1285 uint32_t ret = 0;
1286 auto imageSource = OHOS::Media::ImageSource::CreateImageSource(imagePath, opts, ret);
1287 CHKPP(imageSource);
1288 std::set<std::string> formats;
1289 ret = imageSource->GetSupportedFormats(formats);
1290 MMI_HILOGD("Get supported format ret:%{public}u", ret);
1291
1292 OHOS::Media::DecodeOptions decodeOpts;
1293 decodeOpts.desiredSize = {
1294 .width = imageWidth_,
1295 .height = imageHeight_
1296 };
1297 int32_t pointerColor = GetPointerColor();
1298 if (tempPointerColor_ != DEFAULT_VALUE) {
1299 decodeOpts.SVGOpts.fillColor = {.isValidColor = true, .color = pointerColor};
1300 if (pointerColor == MAX_POINTER_COLOR) {
1301 decodeOpts.SVGOpts.strokeColor = {.isValidColor = true, .color = MIN_POINTER_COLOR};
1302 } else {
1303 decodeOpts.SVGOpts.strokeColor = {.isValidColor = true, .color = MAX_POINTER_COLOR};
1304 }
1305 }
1306
1307 std::shared_ptr<OHOS::Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, ret);
1308 CHKPL(pixelMap);
1309 return pixelMap;
1310 }
1311
GetPreferenceKey(std::string & name)1312 void PointerDrawingManager::GetPreferenceKey(std::string &name)
1313 {
1314 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1315 if (HasMagicCursor()) {
1316 if (name == POINTER_COLOR) {
1317 name = MAGIC_POINTER_COLOR;
1318 } else if (name == POINTER_SIZE) {
1319 name = MAGIC_POINTER_SIZE;
1320 }
1321 }
1322 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1323 }
1324
SetPointerColor(int32_t color)1325 int32_t PointerDrawingManager::SetPointerColor(int32_t color)
1326 {
1327 CALL_DEBUG_ENTER;
1328 if (surfaceNode_ != nullptr) {
1329 float alphaRatio = (static_cast<uint32_t>(color) >> RGB_CHANNEL_BITS_LENGTH) / MAX_ALPHA_VALUE;
1330 if (alphaRatio > 1) {
1331 MMI_HILOGW("Invalid alphaRatio:%{public}f", alphaRatio);
1332 } else {
1333 surfaceNode_->SetAlpha(1 - alphaRatio);
1334 }
1335 }
1336 MMI_HILOGI("PointerColor:%{public}x", color);
1337 // ARGB从表面看比RGB多了个A,也是一种色彩模式,是在RGB的基础上添加了Alpha(透明度)通道。
1338 // 透明度也是以0到255表示的,所以也是总共有256级,透明是0,不透明是255。
1339 // 这个color每8位代表一个通道值,分别是alpha和rgb,总共32位。
1340 color = static_cast<int32_t>(static_cast<uint32_t>(color) & static_cast<uint32_t>(MAX_POINTER_COLOR));
1341 std::string name = POINTER_COLOR;
1342 GetPreferenceKey(name);
1343 int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, color);
1344 if (ret != RET_OK) {
1345 MMI_HILOGE("Set pointer color failed, color:%{public}d", color);
1346 return ret;
1347 }
1348 MMI_HILOGD("Set pointer color successfully, color:%{public}d", color);
1349 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1350 if (HasMagicCursor()) {
1351 ret = MAGIC_CURSOR->SetPointerColor(color);
1352 } else {
1353 ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
1354 }
1355 #else
1356 ret = InitLayer(MOUSE_ICON(lastMouseStyle_.id));
1357 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1358 if (ret != RET_OK) {
1359 MMI_HILOGE("Init layer failed");
1360 return RET_ERR;
1361 }
1362 UpdatePointerVisible();
1363 return RET_OK;
1364 }
1365
GetPointerColor()1366 int32_t PointerDrawingManager::GetPointerColor()
1367 {
1368 CALL_DEBUG_ENTER;
1369 std::string name = POINTER_COLOR;
1370 GetPreferenceKey(name);
1371 int32_t pointerColor = PREFERENCES_MGR->GetIntValue(name, DEFAULT_VALUE);
1372 tempPointerColor_ = pointerColor;
1373 if (pointerColor == DEFAULT_VALUE) {
1374 pointerColor = MIN_POINTER_COLOR;
1375 }
1376 MMI_HILOGD("Get pointer color successfully, pointerColor:%{public}d", pointerColor);
1377 return pointerColor;
1378 }
1379
UpdateDisplayInfo(const DisplayInfo & displayInfo)1380 void PointerDrawingManager::UpdateDisplayInfo(const DisplayInfo &displayInfo)
1381 {
1382 CALL_DEBUG_ENTER;
1383 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1384 CHKPV(hardwareCursorPointerManager_);
1385 hardwareCursorPointerManager_->SetTargetDevice(displayInfo.id);
1386 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1387 hasDisplay_ = true;
1388 displayInfo_ = displayInfo;
1389 int32_t size = GetPointerSize();
1390 imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1391 imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1392 canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
1393 canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
1394 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1395 MAGIC_CURSOR->SetDisplayInfo(displayInfo);
1396 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1397 }
1398
GetIndependentPixels()1399 int32_t PointerDrawingManager::GetIndependentPixels()
1400 {
1401 CALL_DEBUG_ENTER;
1402 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1403 if (HasMagicCursor()) {
1404 return MAGIC_INDEPENDENT_PIXELS;
1405 } else {
1406 return DEVICE_INDEPENDENT_PIXELS;
1407 }
1408 #else
1409 return DEVICE_INDEPENDENT_PIXELS;
1410 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1411 }
1412
SetPointerSize(int32_t size)1413 int32_t PointerDrawingManager::SetPointerSize(int32_t size)
1414 {
1415 CALL_DEBUG_ENTER;
1416 if (size < MIN_POINTER_SIZE) {
1417 size = MIN_POINTER_SIZE;
1418 } else if (size > MAX_POINTER_SIZE) {
1419 size = MAX_POINTER_SIZE;
1420 }
1421 std::string name = POINTER_SIZE;
1422 GetPreferenceKey(name);
1423 int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, size);
1424 if (ret != RET_OK) {
1425 MMI_HILOGD("Set pointer size failed, code:%{public}d", ret);
1426 return ret;
1427 }
1428 MMI_HILOGD("Set pointer size successfully, size:%{public}d", size);
1429
1430 if (surfaceNode_ == nullptr) {
1431 MMI_HILOGI("surfaceNode_ is nullptr");
1432 return RET_OK;
1433 }
1434 imageWidth_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1435 imageHeight_ = pow(INCREASE_RATIO, size - 1) * displayInfo_.dpi * GetIndependentPixels() / BASELINE_DENSITY;
1436 canvasWidth_ = (imageWidth_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
1437 canvasHeight_ = (imageHeight_ / POINTER_WINDOW_INIT_SIZE + 1) * POINTER_WINDOW_INIT_SIZE;
1438 int32_t physicalX = lastPhysicalX_;
1439 int32_t physicalY = lastPhysicalY_;
1440 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1441 MAGIC_CURSOR->SetPointerSize(imageWidth_, imageHeight_);
1442 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1443 Direction direction = DIRECTION0;
1444 if (IsWindowRotation()) {
1445 direction = displayInfo_.direction;
1446 }
1447 AdjustMouseFocus(direction, ICON_TYPE(GetMouseIconPath()[MOUSE_ICON(lastMouseStyle_.id)].alignmentWay),
1448 physicalX, physicalY);
1449 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1450 if (HasMagicCursor()) {
1451 MAGIC_CURSOR->CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction, surfaceNode_);
1452 } else {
1453 CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
1454 }
1455 #else
1456 CreatePointerWindow(displayInfo_.id, physicalX, physicalY, direction);
1457 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1458 if (InitLayer(MOUSE_ICON(lastMouseStyle_.id)) != RET_OK) {
1459 MMI_HILOGE("Init layer failed");
1460 return RET_ERR;
1461 }
1462 UpdatePointerVisible();
1463 return RET_OK;
1464 }
1465
GetPointerSize()1466 int32_t PointerDrawingManager::GetPointerSize()
1467 {
1468 CALL_DEBUG_ENTER;
1469 std::string name = POINTER_SIZE;
1470 GetPreferenceKey(name);
1471 int32_t pointerSize = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_SIZE);
1472 MMI_HILOGD("Get pointer size successfully, pointerSize:%{public}d", pointerSize);
1473 return pointerSize;
1474 }
1475
GetCursorSurfaceId(uint64_t & surfaceId)1476 int32_t PointerDrawingManager::GetCursorSurfaceId(uint64_t &surfaceId)
1477 {
1478 surfaceId = (surfaceNode_ != nullptr ? surfaceNode_->GetId() : Rosen::INVALID_NODEID);
1479 MMI_HILOGI("CursorSurfaceId:%{public}" PRIu64, surfaceId);
1480 return RET_OK;
1481 }
1482
OnDisplayInfo(const DisplayGroupInfo & displayGroupInfo)1483 void PointerDrawingManager::OnDisplayInfo(const DisplayGroupInfo &displayGroupInfo)
1484 {
1485 CALL_DEBUG_ENTER;
1486 for (const auto& item : displayGroupInfo.displaysInfo) {
1487 if (item.id == displayInfo_.id) {
1488 UpdateDisplayInfo(item);
1489 DrawManager();
1490 return;
1491 }
1492 }
1493 UpdateDisplayInfo(displayGroupInfo.displaysInfo[0]);
1494 lastPhysicalX_ = displayGroupInfo.displaysInfo[0].width / CALCULATE_MIDDLE;
1495 lastPhysicalY_ = displayGroupInfo.displaysInfo[0].height / CALCULATE_MIDDLE;
1496 MouseEventHdr->OnDisplayLost(displayInfo_.id);
1497 if (surfaceNode_ != nullptr) {
1498 surfaceNode_->DetachToDisplay(screenId_);
1499 surfaceNode_ = nullptr;
1500 Rosen::RSTransaction::FlushImplicitTransaction();
1501 MMI_HILOGD("Pointer window destroy success");
1502 }
1503 MMI_HILOGD("displayId_:%{public}d, displayWidth_:%{public}d, displayHeight_:%{public}d",
1504 displayInfo_.id, displayInfo_.width, displayInfo_.height);
1505 }
1506
OnWindowInfo(const WinInfo & info)1507 void PointerDrawingManager::OnWindowInfo(const WinInfo &info)
1508 {
1509 CALL_DEBUG_ENTER;
1510 if (pid_ != info.windowPid) {
1511 windowId_ = info.windowId;
1512 pid_ = info.windowPid;
1513 UpdatePointerVisible();
1514 }
1515 }
1516
UpdatePointerDevice(bool hasPointerDevice,bool isPointerVisible,bool isHotPlug)1517 void PointerDrawingManager::UpdatePointerDevice(bool hasPointerDevice, bool isPointerVisible,
1518 bool isHotPlug)
1519 {
1520 CALL_DEBUG_ENTER;
1521 MMI_HILOGD("hasPointerDevice:%{public}s, isPointerVisible:%{public}s",
1522 hasPointerDevice ? "true" : "false", isPointerVisible? "true" : "false");
1523 hasPointerDevice_ = hasPointerDevice;
1524 if (hasPointerDevice_) {
1525 bool pointerVisible = isPointerVisible;
1526 if (!isHotPlug) {
1527 pointerVisible = (pointerVisible && IsPointerVisible());
1528 }
1529 SetPointerVisible(getpid(), pointerVisible, 0, false);
1530 } else {
1531 DeletePointerVisible(getpid());
1532 }
1533 DrawManager();
1534 if (!hasPointerDevice_ && surfaceNode_ != nullptr) {
1535 MMI_HILOGD("Pointer window destroy start");
1536 surfaceNode_->DetachToDisplay(screenId_);
1537 surfaceNode_ = nullptr;
1538 Rosen::RSTransaction::FlushImplicitTransaction();
1539 MMI_HILOGD("Pointer window destroy success");
1540 }
1541 }
1542
DrawManager()1543 void PointerDrawingManager::DrawManager()
1544 {
1545 CALL_DEBUG_ENTER;
1546 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1547 if (HasMagicCursor() && lastDrawPointerStyle_.id != currentMouseStyle_.id) {
1548 if (surfaceNode_ != nullptr) {
1549 surfaceNode_->DetachToDisplay(screenId_);
1550 surfaceNode_ = nullptr;
1551 Rosen::RSTransaction::FlushImplicitTransaction();
1552 }
1553 }
1554 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1555 if (hasDisplay_ && hasPointerDevice_ && surfaceNode_ == nullptr) {
1556 MMI_HILOGD("Draw pointer begin");
1557 PointerStyle pointerStyle;
1558 WIN_MGR->GetPointerStyle(pid_, windowId_, pointerStyle);
1559 MMI_HILOGD("get pid %{publid}d with pointerStyle %{public}d", pid_, pointerStyle.id);
1560 Direction direction = DIRECTION0;
1561 if (IsWindowRotation()) {
1562 direction = displayInfo_.direction;
1563 }
1564 lastDrawPointerStyle_ = pointerStyle;
1565 if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
1566 DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
1567 pointerStyle, direction);
1568 MMI_HILOGD("Draw manager, mouseStyle:%{public}d, last physical is initial value", pointerStyle.id);
1569 return;
1570 }
1571 DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
1572 MMI_HILOGD("Draw manager, mouseStyle:%{public}d", pointerStyle.id);
1573 return;
1574 }
1575 }
1576
Init()1577 bool PointerDrawingManager::Init()
1578 {
1579 CALL_DEBUG_ENTER;
1580 INPUT_DEV_MGR->Attach(shared_from_this());
1581 pidInfos_.clear();
1582 hapPidInfos_.clear();
1583 return true;
1584 }
1585
GetInstance()1586 std::shared_ptr<IPointerDrawingManager> IPointerDrawingManager::GetInstance()
1587 {
1588 if (iPointDrawMgr_ == nullptr) {
1589 iPointDrawMgr_ = std::make_shared<PointerDrawingManager>();
1590 }
1591 return iPointDrawMgr_;
1592 }
1593
UpdatePointerVisible()1594 void PointerDrawingManager::UpdatePointerVisible()
1595 {
1596 CALL_DEBUG_ENTER;
1597 CHKPV(surfaceNode_);
1598 if (IsPointerVisible() && mouseDisplayState_) {
1599 surfaceNode_->SetVisible(true);
1600 MMI_HILOGI("Pointer window show success, mouseDisplayState_:%{public}s",
1601 mouseDisplayState_ ? "true" : "false");
1602 } else {
1603 surfaceNode_->SetVisible(false);
1604 MMI_HILOGI("Pointer window hide success, mouseDisplayState_:%{public}s",
1605 mouseDisplayState_ ? "true" : "false");
1606 }
1607 Rosen::RSTransaction::FlushImplicitTransaction();
1608 }
1609
IsPointerVisible()1610 bool PointerDrawingManager::IsPointerVisible()
1611 {
1612 CALL_DEBUG_ENTER;
1613 if (!pidInfos_.empty()) {
1614 auto info = pidInfos_.back();
1615 if (!info.visible) {
1616 MMI_HILOGI("High priority visible property:%{public}zu.%{public}d-visible:%{public}s",
1617 pidInfos_.size(), info.pid, info.visible?"true":"false");
1618 return info.visible;
1619 }
1620 }
1621 if (!hapPidInfos_.empty()) {
1622 for (auto& item : hapPidInfos_) {
1623 if (item.pid == pid_) {
1624 MMI_HILOGI("Visible pid:%{public}d-visible:%{public}s",
1625 item.pid, item.visible ? "true" : "false");
1626 return item.visible;
1627 }
1628 }
1629 if (!(INPUT_DEV_MGR->HasPointerDevice() || WIN_MGR->IsMouseSimulate()) || pid_ == 0) {
1630 auto info = hapPidInfos_.back();
1631 MMI_HILOGI("Only hap visible pid:%{public}d-visible:%{public}s",
1632 info.pid, info.visible ? "true" : "false");
1633 return info.visible;
1634 }
1635 }
1636 if (pidInfos_.empty()) {
1637 MMI_HILOGD("Visible property is true");
1638 return true;
1639 }
1640 auto info = pidInfos_.back();
1641 MMI_HILOGI("Visible property:%{public}zu.%{public}d-visible:%{public}s",
1642 pidInfos_.size(), info.pid, info.visible ? "true" : "false");
1643 return info.visible;
1644 }
1645
DeletePointerVisible(int32_t pid)1646 void PointerDrawingManager::DeletePointerVisible(int32_t pid)
1647 {
1648 CALL_DEBUG_ENTER;
1649 std::lock_guard<std::mutex> guard(mutex_);
1650 MMI_HILOGI("isRsRemoteDied:%{public}d", g_isRsRemoteDied ? 1 : 0);
1651 if (g_isRsRemoteDied && surfaceNode_ != nullptr) {
1652 g_isRsRemoteDied = false;
1653 surfaceNode_->DetachToDisplay(screenId_);
1654 surfaceNode_ = nullptr;
1655 Rosen::RSTransaction::FlushImplicitTransaction();
1656 }
1657 if (pidInfos_.empty()) {
1658 return;
1659 }
1660 auto it = pidInfos_.begin();
1661 for (; it != pidInfos_.end(); ++it) {
1662 if (it->pid == pid) {
1663 pidInfos_.erase(it);
1664 break;
1665 }
1666 }
1667 if (it != pidInfos_.end()) {
1668 if (IsPointerVisible()) {
1669 InitLayer(MOUSE_ICON(lastMouseStyle_.id));
1670 }
1671 UpdatePointerVisible();
1672 }
1673 }
1674
GetPointerVisible(int32_t pid)1675 bool PointerDrawingManager::GetPointerVisible(int32_t pid)
1676 {
1677 bool ret = true;
1678 int32_t count = 0;
1679 for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
1680 if (it->pid == pid) {
1681 count++;
1682 ret = it->visible;
1683 break;
1684 }
1685 }
1686 if (count == 0 && !hapPidInfos_.empty()) {
1687 for (auto& item : hapPidInfos_) {
1688 if (item.pid == pid_) {
1689 MMI_HILOGI("Visible pid:%{public}d-visible:%{public}s",
1690 item.pid, item.visible ? "true" : "false");
1691 count++;
1692 ret = item.visible;
1693 break;
1694 }
1695 }
1696 }
1697 return ret;
1698 }
1699
OnSessionLost(int32_t pid)1700 void PointerDrawingManager::OnSessionLost(int32_t pid)
1701 {
1702 for (auto it = hapPidInfos_.begin(); it != hapPidInfos_.end(); ++it) {
1703 if (it->pid == pid) {
1704 hapPidInfos_.erase(it);
1705 break;
1706 }
1707 }
1708 }
1709
SetPointerVisible(int32_t pid,bool visible,int32_t priority,bool isHap)1710 int32_t PointerDrawingManager::SetPointerVisible(int32_t pid, bool visible, int32_t priority, bool isHap)
1711 {
1712 MMI_HILOGI("pid:%{public}d,visible:%{public}s,priority:%{public}d,isHap:%{public}s", pid,
1713 visible ? "true" : "false", priority, isHap ? "true" : "false");
1714 if (isHap) {
1715 for (auto it = hapPidInfos_.begin(); it != hapPidInfos_.end(); ++it) {
1716 if (it->pid == pid) {
1717 hapPidInfos_.erase(it);
1718 break;
1719 }
1720 }
1721 PidInfo info = { .pid = pid, .visible = visible };
1722 hapPidInfos_.push_back(info);
1723 if (hapPidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
1724 hapPidInfos_.pop_front();
1725 }
1726 UpdatePointerVisible();
1727 return RET_OK;
1728 }
1729 if (WIN_MGR->GetExtraData().appended && visible && priority == 0) {
1730 MMI_HILOGE("current is drag state, can not set pointer visible");
1731 return RET_ERR;
1732 }
1733 for (auto it = pidInfos_.begin(); it != pidInfos_.end(); ++it) {
1734 if (it->pid == pid) {
1735 pidInfos_.erase(it);
1736 break;
1737 }
1738 }
1739 PidInfo info = { .pid = pid, .visible = visible };
1740 pidInfos_.push_back(info);
1741 if (pidInfos_.size() > VISIBLE_LIST_MAX_SIZE) {
1742 pidInfos_.pop_front();
1743 }
1744 if (!WIN_MGR->HasMouseHideFlag() || INPUT_DEV_MGR->HasPointerDevice() || INPUT_DEV_MGR->HasVirtualPointerDevice()) {
1745 UpdatePointerVisible();
1746 }
1747 return RET_OK;
1748 }
1749
SetPointerLocation(int32_t x,int32_t y)1750 void PointerDrawingManager::SetPointerLocation(int32_t x, int32_t y)
1751 {
1752 CALL_DEBUG_ENTER;
1753 FixCursorPosition(x, y);
1754 lastPhysicalX_ = x;
1755 lastPhysicalY_ = y;
1756 MMI_HILOGD("Pointer window move, x:%{private}d, y:%{private}d", lastPhysicalX_, lastPhysicalY_);
1757 if (surfaceNode_ != nullptr) {
1758 surfaceNode_->SetBounds(x,
1759 y,
1760 surfaceNode_->GetStagingProperties().GetBounds().z_,
1761 surfaceNode_->GetStagingProperties().GetBounds().w_);
1762 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1763 CHKPV(hardwareCursorPointerManager_);
1764 if (hardwareCursorPointerManager_->IsSupported()) {
1765 if (hardwareCursorPointerManager_->SetPosition(lastPhysicalX_, lastPhysicalY_) != RET_OK) {
1766 MMI_HILOGE("Set hardware cursor position error.");
1767 return;
1768 }
1769 }
1770 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
1771 Rosen::RSTransaction::FlushImplicitTransaction();
1772 MMI_HILOGD("Pointer window move success");
1773 }
1774 }
1775
UpdateDefaultPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle,bool isUiExtension)1776 int32_t PointerDrawingManager::UpdateDefaultPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle,
1777 bool isUiExtension)
1778 {
1779 if (windowId != GLOBAL_WINDOW_ID) {
1780 MMI_HILOGD("No need to change the default icon style");
1781 return RET_OK;
1782 }
1783 PointerStyle style;
1784 WIN_MGR->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style, isUiExtension);
1785 if (pointerStyle.id != style.id) {
1786 auto iconPath = GetMouseIconPath();
1787 auto it = iconPath.find(MOUSE_ICON(MOUSE_ICON::DEFAULT));
1788 if (it == iconPath.end()) {
1789 MMI_HILOGE("Cannot find the default style");
1790 return RET_ERR;
1791 }
1792 std::string newIconPath;
1793 if (pointerStyle.id == MOUSE_ICON::DEFAULT) {
1794 newIconPath = DefaultIconPath;
1795 } else {
1796 newIconPath = iconPath[MOUSE_ICON(pointerStyle.id)].iconPath;
1797 }
1798 MMI_HILOGD("default path has changed from %{public}s to %{public}s",
1799 it->second.iconPath.c_str(), newIconPath.c_str());
1800 it->second.iconPath = newIconPath;
1801 UpdateIconPath(MOUSE_ICON(MOUSE_ICON::DEFAULT), newIconPath);
1802 }
1803 lastMouseStyle_ = style;
1804 return RET_OK;
1805 }
1806
GetMouseIconPath()1807 std::map<MOUSE_ICON, IconStyle> PointerDrawingManager::GetMouseIconPath()
1808 {
1809 CALL_DEBUG_ENTER;
1810 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1811 if (HasMagicCursor()) {
1812 MMI_HILOGD("Magiccurosr get magic mouse map");
1813 return MAGIC_CURSOR->magicMouseIcons_;
1814 } else {
1815 MMI_HILOGD("Magiccurosr get mouse icon, HasMagicCursor is false");
1816 return mouseIcons_;
1817 }
1818 #else
1819 return mouseIcons_;
1820 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1821 }
1822
GetIconStyle(const MOUSE_ICON mouseStyle)1823 IconStyle PointerDrawingManager::GetIconStyle(const MOUSE_ICON mouseStyle)
1824 {
1825 std::map<MOUSE_ICON, IconStyle> mouseIcons = GetMouseIcons();
1826 auto iter = mouseIcons.find(mouseStyle);
1827 if (iter == mouseIcons.end()) {
1828 MMI_HILOGE("Cannot find the mouseStyle:%{public}d", static_cast<int32_t>(mouseStyle));
1829 return IconStyle();
1830 }
1831 return iter->second;
1832 }
1833
GetMouseIcons()1834 std::map<MOUSE_ICON, IconStyle>& PointerDrawingManager::GetMouseIcons()
1835 {
1836 #ifdef OHOS_BUILD_ENABLE_MAGICCURSOR
1837 if (HasMagicCursor()) {
1838 MMI_HILOGD("Magiccurosr get magic mouse map");
1839 return MAGIC_CURSOR->magicMouseIcons_;
1840 } else {
1841 MMI_HILOGD("Magiccurosr get mouse icon, HasMagicCursor is false");
1842 return mouseIcons_;
1843 }
1844 #else
1845 return mouseIcons_;
1846 #endif // OHOS_BUILD_ENABLE_MAGICCURSOR
1847 }
1848
UpdateIconPath(const MOUSE_ICON mouseStyle,std::string iconPath)1849 void PointerDrawingManager::UpdateIconPath(const MOUSE_ICON mouseStyle, std::string iconPath)
1850 {
1851 CALL_DEBUG_ENTER;
1852 std::map<MOUSE_ICON, IconStyle> &mouseIcons = GetMouseIcons();
1853 auto iter = mouseIcons.find(mouseStyle);
1854 if (iter == mouseIcons.end()) {
1855 MMI_HILOGE("Cannot find the mouseStyle:%{public}d", static_cast<int32_t>(mouseStyle));
1856 return;
1857 }
1858 iter->second.iconPath = iconPath;
1859 }
1860
SetPointerStylePreference(PointerStyle pointerStyle)1861 int32_t PointerDrawingManager::SetPointerStylePreference(PointerStyle pointerStyle)
1862 {
1863 CALL_DEBUG_ENTER;
1864 std::string name = "pointerStyle";
1865 int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, pointerStyle.id);
1866 if (ret != RET_OK) {
1867 MMI_HILOGD("Set pointer style failed, code:%{public}d", ret);
1868 return ret;
1869 }
1870 MMI_HILOGD("Set pointer style successfully, style:%{public}d", pointerStyle.id);
1871 return RET_OK;
1872 }
1873
CheckPointerStyleParam(int32_t windowId,PointerStyle pointerStyle)1874 bool PointerDrawingManager::CheckPointerStyleParam(int32_t windowId, PointerStyle pointerStyle)
1875 {
1876 CALL_DEBUG_ENTER;
1877 if (windowId < -1) {
1878 return false;
1879 }
1880 if ((pointerStyle.id < MOUSE_ICON::DEFAULT && pointerStyle.id != MOUSE_ICON::DEVELOPER_DEFINED_ICON) ||
1881 pointerStyle.id > MOUSE_ICON::RUNNING_RIGHT) {
1882 return false;
1883 }
1884 return true;
1885 }
1886
SetPointerStyle(int32_t pid,int32_t windowId,PointerStyle pointerStyle,bool isUiExtension)1887 int32_t PointerDrawingManager::SetPointerStyle(int32_t pid, int32_t windowId, PointerStyle pointerStyle,
1888 bool isUiExtension)
1889 {
1890 CALL_DEBUG_ENTER;
1891 if (!CheckPointerStyleParam(windowId, pointerStyle)) {
1892 MMI_HILOGE("PointerStyle param is invalid");
1893 return RET_ERR;
1894 }
1895 if (windowId == GLOBAL_WINDOW_ID) {
1896 int32_t ret = SetPointerStylePreference(pointerStyle);
1897 if (ret != RET_OK) {
1898 MMI_HILOGE("Set style preference is failed, ret:%{public}d", ret);
1899 return RET_ERR;
1900 }
1901 }
1902 auto iconPath = GetMouseIconPath();
1903 if (iconPath.find(MOUSE_ICON(pointerStyle.id)) == iconPath.end()) {
1904 MMI_HILOGE("The param pointerStyle is invalid");
1905 return RET_ERR;
1906 }
1907 if (UpdateDefaultPointerStyle(pid, windowId, pointerStyle) != RET_OK) {
1908 MMI_HILOGE("Update default pointer iconPath failed");
1909 return RET_ERR;
1910 }
1911 if (WIN_MGR->SetPointerStyle(pid, windowId, pointerStyle, isUiExtension) != RET_OK) {
1912 MMI_HILOGE("Set pointer style failed");
1913 return RET_ERR;
1914 }
1915 if (!INPUT_DEV_MGR->HasPointerDevice() && !WIN_MGR->IsMouseSimulate()) {
1916 MMI_HILOGD("The pointer device is not exist");
1917 return RET_OK;
1918 }
1919 if (!WIN_MGR->IsNeedRefreshLayer(windowId)) {
1920 MMI_HILOGD("Not need refresh layer, window type:%{public}d, pointer style:%{public}d",
1921 windowId, pointerStyle.id);
1922 return RET_OK;
1923 }
1924 if (windowId != GLOBAL_WINDOW_ID && (pointerStyle.id == MOUSE_ICON::DEFAULT &&
1925 iconPath[MOUSE_ICON(pointerStyle.id)].iconPath != DefaultIconPath)) {
1926 PointerStyle style;
1927 WIN_MGR->GetPointerStyle(pid, GLOBAL_WINDOW_ID, style);
1928 pointerStyle = style;
1929 }
1930 if (windowId == windowId_ || windowId == GLOBAL_WINDOW_ID) {
1931 // Draw mouse style only when the current window is the top-level window
1932 DrawPointerStyle(pointerStyle);
1933 } else {
1934 MMI_HILOGW("set windowid:%{public}d, top windowid:%{public}d, dont draw pointer", windowId, windowId_);
1935 }
1936 MMI_HILOGI("Window id:%{public}d set pointer style:%{public}d success", windowId, pointerStyle.id);
1937 return RET_OK;
1938 }
1939
GetPointerStyle(int32_t pid,int32_t windowId,PointerStyle & pointerStyle,bool isUiExtension)1940 int32_t PointerDrawingManager::GetPointerStyle(int32_t pid, int32_t windowId, PointerStyle &pointerStyle,
1941 bool isUiExtension)
1942 {
1943 CALL_DEBUG_ENTER;
1944 if (windowId == GLOBAL_WINDOW_ID) {
1945 std::string name = POINTER_COLOR;
1946 pointerStyle.color = PREFERENCES_MGR->GetIntValue(name, DEFAULT_VALUE);
1947 name = POINTER_SIZE;
1948 pointerStyle.size = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_SIZE);
1949 name = "pointerStyle";
1950 int32_t style = PREFERENCES_MGR->GetIntValue(name, DEFAULT_POINTER_STYLE);
1951 MMI_HILOGD("Get pointer style successfully, pointerStyle:%{public}d", style);
1952 if (style == CURSOR_CIRCLE_STYLE) {
1953 pointerStyle.id = style;
1954 return RET_OK;
1955 }
1956 }
1957 WIN_MGR->GetPointerStyle(pid, windowId, pointerStyle, isUiExtension);
1958 MMI_HILOGD("Window id:%{public}d get pointer style:%{public}d success", windowId, pointerStyle.id);
1959 return RET_OK;
1960 }
1961
ClearWindowPointerStyle(int32_t pid,int32_t windowId)1962 int32_t PointerDrawingManager::ClearWindowPointerStyle(int32_t pid, int32_t windowId)
1963 {
1964 CALL_DEBUG_ENTER;
1965 return WIN_MGR->ClearWindowPointerStyle(pid, windowId);
1966 }
1967
DrawPointerStyle(const PointerStyle & pointerStyle)1968 void PointerDrawingManager::DrawPointerStyle(const PointerStyle& pointerStyle)
1969 {
1970 CALL_DEBUG_ENTER;
1971 bool simulate = WIN_MGR->IsMouseSimulate();
1972 if (hasDisplay_ && (hasPointerDevice_ || simulate)) {
1973 if (surfaceNode_ != nullptr) {
1974 AttachToDisplay();
1975 Rosen::RSTransaction::FlushImplicitTransaction();
1976 }
1977 Direction direction = DIRECTION0;
1978 if (IsWindowRotation()) {
1979 direction = displayInfo_.direction;
1980 }
1981 if (lastPhysicalX_ == -1 || lastPhysicalY_ == -1) {
1982 DrawPointer(displayInfo_.id, displayInfo_.width / CALCULATE_MIDDLE, displayInfo_.height / CALCULATE_MIDDLE,
1983 pointerStyle, direction);
1984 MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
1985 return;
1986 }
1987
1988 DrawPointer(displayInfo_.id, lastPhysicalX_, lastPhysicalY_, pointerStyle, direction);
1989 MMI_HILOGD("Draw pointer style, mouseStyle:%{public}d", pointerStyle.id);
1990 }
1991 }
1992
CheckMouseIconPath()1993 void PointerDrawingManager::CheckMouseIconPath()
1994 {
1995 for (auto iter = mouseIcons_.begin(); iter != mouseIcons_.end();) {
1996 if ((ReadCursorStyleFile(iter->second.iconPath)) != RET_OK) {
1997 iter = mouseIcons_.erase(iter);
1998 continue;
1999 }
2000 ++iter;
2001 }
2002 }
2003
EnableHardwareCursorStats(int32_t pid,bool enable)2004 int32_t PointerDrawingManager::EnableHardwareCursorStats(int32_t pid, bool enable)
2005 {
2006 CALL_DEBUG_ENTER;
2007 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2008 CHKPR(hardwareCursorPointerManager_, ERROR_NULL_POINTER);
2009 if ((hardwareCursorPointerManager_->EnableStats(enable)) != RET_OK) {
2010 MMI_HILOGE("Enable stats failed");
2011 return RET_ERR;
2012 }
2013 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2014 MMI_HILOGI("EnableHardwareCursorStats, enable:%{private}d", enable);
2015 return RET_OK;
2016 }
2017
GetHardwareCursorStats(int32_t pid,uint32_t & frameCount,uint32_t & vsyncCount)2018 int32_t PointerDrawingManager::GetHardwareCursorStats(int32_t pid, uint32_t &frameCount, uint32_t &vsyncCount)
2019 {
2020 CALL_DEBUG_ENTER;
2021 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2022 CHKPR(hardwareCursorPointerManager_, ERROR_NULL_POINTER);
2023 if ((hardwareCursorPointerManager_->GetCursorStats(frameCount, vsyncCount)) != RET_OK) {
2024 MMI_HILOGE("Query stats failed");
2025 return RET_ERR;
2026 }
2027 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
2028 MMI_HILOGI("GetHardwareCursorStats, frameCount:%{private}d, vsyncCount:%{private}d", frameCount, vsyncCount);
2029 return RET_OK;
2030 }
2031
InitStyle()2032 void PointerDrawingManager::InitStyle()
2033 {
2034 CALL_DEBUG_ENTER;
2035 mouseIcons_ = {
2036 {DEFAULT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
2037 {EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "East.svg"}},
2038 {WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West.svg"}},
2039 {SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South.svg"}},
2040 {NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North.svg"}},
2041 {WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "West_East.svg"}},
2042 {NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_South.svg"}},
2043 {NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East.svg"}},
2044 {NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West.svg"}},
2045 {SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_East.svg"}},
2046 {SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "South_West.svg"}},
2047 {NORTH_EAST_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_East_South_West.svg"}},
2048 {NORTH_WEST_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "North_West_South_East.svg"}},
2049 {CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cross.svg"}},
2050 {CURSOR_COPY, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Copy.svg"}},
2051 {CURSOR_FORBID, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Forbid.svg"}},
2052 {COLOR_SUCKER, {ANGLE_SW, IMAGE_POINTER_DEFAULT_PATH + "Colorsucker.svg"}},
2053 {HAND_GRABBING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Grabbing.svg"}},
2054 {HAND_OPEN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Hand_Open.svg"}},
2055 {HAND_POINTING, {ANGLE_NW_RIGHT, IMAGE_POINTER_DEFAULT_PATH + "Hand_Pointing.svg"}},
2056 {HELP, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Help.svg"}},
2057 {CURSOR_MOVE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Move.svg"}},
2058 {RESIZE_LEFT_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Left_Right.svg"}},
2059 {RESIZE_UP_DOWN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Resize_Up_Down.svg"}},
2060 {SCREENSHOT_CHOOSE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cross.svg"}},
2061 {SCREENSHOT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Screenshot_Cursor.png"}},
2062 {TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Text_Cursor.svg"}},
2063 {ZOOM_IN, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_In.svg"}},
2064 {ZOOM_OUT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Zoom_Out.svg"}},
2065 {MIDDLE_BTN_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_East.svg"}},
2066 {MIDDLE_BTN_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_West.svg"}},
2067 {MIDDLE_BTN_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South.svg"}},
2068 {MIDDLE_BTN_NORTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North.svg"}},
2069 {MIDDLE_BTN_NORTH_SOUTH, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_South.svg"}},
2070 {MIDDLE_BTN_NORTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_East.svg"}},
2071 {MIDDLE_BTN_NORTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_North_West.svg"}},
2072 {MIDDLE_BTN_SOUTH_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_East.svg"}},
2073 {MIDDLE_BTN_SOUTH_WEST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "MID_Btn_South_West.svg"}},
2074 {MIDDLE_BTN_NORTH_SOUTH_WEST_EAST, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH +
2075 "MID_Btn_North_South_West_East.svg"}},
2076 {HORIZONTAL_TEXT_CURSOR, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Horizontal_Text_Cursor.svg"}},
2077 {CURSOR_CROSS, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Cross.svg"}},
2078 {CURSOR_CIRCLE, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Cursor_Circle.png"}},
2079 {LOADING, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading.svg"}},
2080 {RUNNING, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
2081 {RUNNING_LEFT, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Loading_Left.svg"}},
2082 {RUNNING_RIGHT, {ANGLE_CENTER, IMAGE_POINTER_DEFAULT_PATH + "Loading_Right.svg"}},
2083 {DEVELOPER_DEFINED_ICON, {ANGLE_NW, IMAGE_POINTER_DEFAULT_PATH + "Default.svg"}},
2084 };
2085 CheckMouseIconPath();
2086 }
2087
RotateDegree(Direction direction)2088 void PointerDrawingManager::RotateDegree(Direction direction)
2089 {
2090 CHKPV(surfaceNode_);
2091 surfaceNode_->SetPivot(0, 0);
2092 float degree = (static_cast<int>(DIRECTION0) - static_cast<int>(direction)) * ROTATION_ANGLE90;
2093 surfaceNode_->SetRotation(degree);
2094 }
2095
SkipPointerLayer(bool isSkip)2096 int32_t PointerDrawingManager::SkipPointerLayer(bool isSkip)
2097 {
2098 CALL_INFO_TRACE;
2099 if (surfaceNode_ != nullptr) {
2100 surfaceNode_->SetSkipLayer(isSkip);
2101 }
2102 return RET_OK;
2103 }
2104
Dump(int32_t fd,const std::vector<std::string> & args)2105 void PointerDrawingManager::Dump(int32_t fd, const std::vector<std::string> &args)
2106 {
2107 CALL_DEBUG_ENTER;
2108 std::ostringstream oss;
2109 oss << std::endl;
2110
2111 auto displayTitles = std::make_tuple("ID", "X", "Y", "Width", "Height", "DPI", "Name", "Uniq",
2112 "Direction", "Display Direction", "Display Mode");
2113 DisplayInfo &di = displayInfo_;
2114 auto displayInfo = std::vector{std::make_tuple(di.id, di.x, di.y, di.width, di.height, di.dpi, di.name, di.uniq,
2115 di.direction, di.displayDirection,
2116 static_cast<int32_t>(di.displayMode))};
2117 DumpFullTable(oss, "Display Info", displayTitles, displayInfo);
2118 oss << std::endl;
2119
2120 auto titles1 = std::make_tuple("hasDisplay", "hasPointerDevice", "lastPhysicalX", "lastPhysicalY",
2121 "pid", "windowId", "imageWidth", "imageHeight", "canvasWidth", "canvasHeight");
2122 auto data1 = std::vector{std::make_tuple(hasDisplay_, hasPointerDevice_, lastPhysicalX_, lastPhysicalY_,
2123 pid_, windowId_, imageWidth_, imageHeight_, canvasWidth_, canvasHeight_)};
2124 DumpFullTable(oss, "Cursor Info", titles1, data1);
2125 oss << std::endl;
2126
2127 auto titles2 = std::make_tuple("mouseDisplayState", "mouseIconUpdate", "screenId", "userIconHotSpotX",
2128 "userIconHotSpotY", "tempPointerColor", "lastDirection", "currentDirection");
2129 auto data2 = std::vector{std::make_tuple(mouseDisplayState_, mouseIconUpdate_, screenId_, userIconHotSpotX_,
2130 userIconHotSpotY_, tempPointerColor_, lastDirection_, currentDirection_)};
2131
2132 DumpFullTable(oss, "Cursor Info", titles2, data2);
2133 oss << std::endl;
2134
2135 auto styleTitles = std::make_tuple("name", "Size", "Color", "ID");
2136 auto styleData = std::vector{
2137 std::make_tuple("lastMouseStyle", lastMouseStyle_.size, lastMouseStyle_.color, lastMouseStyle_.id),
2138 std::make_tuple("currentMouseStyle", currentMouseStyle_.size, currentMouseStyle_.color,
2139 currentMouseStyle_.id)};
2140 DumpFullTable(oss, "Cursor Style Info", styleTitles, styleData);
2141 oss << std::endl;
2142
2143 auto pidTitles = std::make_tuple("pid", "visible");
2144 std::vector<std::tuple<int32_t, bool>> pidInfos;
2145 for (const auto &pidInfo: pidInfos_) {
2146 pidInfos.emplace_back(pidInfo.pid, pidInfo.visible);
2147 }
2148 DumpFullTable(oss, "Visible Info", pidTitles, pidInfos);
2149 oss << std::endl;
2150
2151 std::string dumpInfo = oss.str();
2152 dprintf(fd, dumpInfo.c_str());
2153 }
2154
GetUserIconCopy()2155 std::shared_ptr<OHOS::Media::PixelMap> PointerDrawingManager::GetUserIconCopy()
2156 {
2157 std::lock_guard<std::mutex> guard(mtx_);
2158 if (userIcon_ == nullptr) {
2159 MMI_HILOGI("userIcon_ is nullptr");
2160 return nullptr;
2161 }
2162 if (followSystem_) {
2163 Parcel data;
2164 userIcon_->Marshalling(data);
2165 std::shared_ptr<OHOS::Media::PixelMap> pixelMapPtr(OHOS::Media::PixelMap::Unmarshalling(data));
2166 if (pixelMapPtr == nullptr) {
2167 MMI_HILOGE("pixelMapPtr is nullptr");
2168 return nullptr;
2169 }
2170 Media::ImageInfo imageInfo;
2171 pixelMapPtr->GetImageInfo(imageInfo);
2172 int32_t cursorSize = GetPointerSize();
2173 float axis = 1.0f;
2174 cursorWidth_ = pow(INCREASE_RATIO, cursorSize - 1) * imageInfo.size.width;
2175 cursorHeight_ = pow(INCREASE_RATIO, cursorSize - 1) * imageInfo.size.height;
2176 int32_t maxValue = imageInfo.size.width > imageInfo.size.height ? cursorWidth_ : cursorHeight_;
2177 if (maxValue > MAX_CUSTOM_CURSOR_DIMENSION) {
2178 axis = (float)MAX_CUSTOM_CURSOR_DIMENSION / (float)std::max(imageInfo.size.width, imageInfo.size.height);
2179 } else {
2180 axis = (float)std::max(cursorWidth_, cursorHeight_) /
2181 (float)std::max(imageInfo.size.width, imageInfo.size.height);
2182 }
2183 pixelMapPtr->scale(axis, axis, Media::AntiAliasingOption::LOW);
2184 cursorWidth_ = static_cast<int32_t>((float)imageInfo.size.width * axis);
2185 cursorHeight_ = static_cast<int32_t>((float)imageInfo.size.height * axis);
2186 userIconHotSpotX_ = static_cast<int32_t>((float)focusX_ * axis);
2187 userIconHotSpotY_ = static_cast<int32_t>((float)focusY_ * axis);
2188 MMI_HILOGI("cursorWidth:%{public}d, cursorHeight:%{public}d, imageWidth:%{public}d,"
2189 "imageHeight:%{public}d, focusX:%{public}d, focusY:%{public}d, axis:%{public}f,"
2190 "userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
2191 cursorWidth_, cursorHeight_, imageInfo.size.width, imageInfo.size.height,
2192 focusX_, focusY_, axis, userIconHotSpotX_, userIconHotSpotY_);
2193 return pixelMapPtr;
2194 }
2195 return userIcon_;
2196 }
2197
SetCustomCursor(int32_t pid,int32_t windowId,CustomCursor cursor,CursorOptions options)2198 int32_t PointerDrawingManager::SetCustomCursor(int32_t pid, int32_t windowId, CustomCursor cursor,
2199 CursorOptions options)
2200 {
2201 CALL_DEBUG_ENTER;
2202 if (windowId < 0 || WIN_MGR->CheckWindowIdPermissionByPid(windowId, pid) != RET_OK) {
2203 MMI_HILOGE("The windowId not in right pid");
2204 return ERROR_WINDOW_ID_PERMISSION_DENIED;
2205 }
2206 followSystem_ = options.followSystem;
2207 int32_t ret = UpdateCursorProperty(cursor);
2208 if (ret != RET_OK) {
2209 MMI_HILOGE("UpdateCursorProperty is failed");
2210 return ret;
2211 }
2212 mouseIconUpdate_ = true;
2213 PointerStyle style;
2214 style.id = MOUSE_ICON::DEVELOPER_DEFINED_ICON;
2215 lastMouseStyle_ = style;
2216 ret = SetPointerStyle(pid, windowId, style);
2217 if (ret == RET_ERR) {
2218 MMI_HILOGE("SetPointerStyle is failed");
2219 }
2220 MMI_HILOGD("style.id:%{public}d, userIconHotSpotX_:%{public}d, userIconHotSpotY_:%{public}d",
2221 style.id, userIconHotSpotX_, userIconHotSpotY_);
2222 return ret;
2223 }
2224
UpdateCursorProperty(CustomCursor cursor)2225 int32_t PointerDrawingManager::UpdateCursorProperty(CustomCursor cursor)
2226 {
2227 CHKPR(cursor.pixelMap, RET_ERR);
2228 Media::PixelMap* newPixelMap = static_cast<Media::PixelMap*>(cursor.pixelMap);
2229 CHKPR(newPixelMap, RET_ERR);
2230 Media::ImageInfo imageInfo;
2231 newPixelMap->GetImageInfo(imageInfo);
2232 if (imageInfo.size.width < cursor.focusX || imageInfo.size.width < cursor.focusY) {
2233 MMI_HILOGE("focus is invalid");
2234 return RET_ERR;
2235 }
2236 if (imageInfo.size.width > MAX_CUSTOM_CURSOR_SIZE || imageInfo.size.height > MAX_CUSTOM_CURSOR_SIZE ||
2237 imageInfo.size.width <= 0 || imageInfo.size.height <= 0) {
2238 MMI_HILOGE("PixelMap is invalid");
2239 return RET_ERR;
2240 }
2241 cursorWidth_ = imageInfo.size.width;
2242 cursorHeight_ = imageInfo.size.height;
2243 {
2244 std::lock_guard<std::mutex> guard(mtx_);
2245 userIcon_.reset(newPixelMap);
2246 }
2247 focusX_ = cursor.focusX;
2248 focusY_ = cursor.focusY;
2249 userIconHotSpotX_ = cursor.focusX;
2250 userIconHotSpotY_ = cursor.focusY;
2251 MMI_HILOGI("imageWidth:%{public}d, imageHeight:%{public}d, focusX:%{public}d, focusY:%{public}d",
2252 imageInfo.size.width, imageInfo.size.height, cursor.focusX, cursor.focusY);
2253 return RET_OK;
2254 }
2255 } // namespace MMI
2256 } // namespace OHOS
2257