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