1 /*
2  * Copyright (c) 2022 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 "mouse_transform_processor.h"
17 
18 #include <cinttypes>
19 #include <chrono>
20 #include <functional>
21 #include <linux/input-event-codes.h>
22 
23 #include "define_multimodal.h"
24 #include "dfx_hisysevent.h"
25 #include "event_log_helper.h"
26 #include "i_input_windows_manager.h"
27 #include "i_pointer_drawing_manager.h"
28 #include "i_preference_manager.h"
29 #include "input_device_manager.h"
30 #include "input_event_handler.h"
31 #include "mouse_device_state.h"
32 #include "parameters.h"
33 #include "preferences.h"
34 #include "preferences_errno.h"
35 #include "preferences_helper.h"
36 #include "scene_board_judgement.h"
37 #include "timer_manager.h"
38 #include "util.h"
39 #include "util_ex.h"
40 
41 #undef MMI_LOG_DOMAIN
42 #define MMI_LOG_DOMAIN MMI_LOG_DISPATCH
43 #undef MMI_LOG_TAG
44 #define MMI_LOG_TAG "MouseTransformProcessor"
45 
46 namespace OHOS {
47 namespace MMI {
48 namespace {
49 constexpr int32_t MIN_SPEED { 1 };
50 constexpr int32_t MAX_SPEED { 11 };
51 constexpr int32_t DEFAULT_SPEED { 7 };
52 constexpr int32_t DEFAULT_TOUCHPAD_SPEED { 6 };
53 constexpr int32_t DEFAULT_ROWS { 3 };
54 constexpr int32_t MIN_ROWS { 1 };
55 constexpr int32_t MAX_ROWS { 100 };
56 constexpr int32_t BTN_RIGHT_MENUE_CODE { 0x118 };
57 constexpr int32_t RIGHT_CLICK_TYPE_MIN { 1 };
58 constexpr int32_t RIGHT_CLICK_TYPE_MAX { 3 };
59 constexpr int32_t TP_CLICK_FINGER_ONE { 1 };
60 constexpr int32_t TP_RIGHT_CLICK_FINGER_CNT { 2 };
61 constexpr int32_t HARD_PC_PRO_DEVICE_WIDTH { 2880 };
62 constexpr int32_t HARD_PC_PRO_DEVICE_HEIGHT { 1920 };
63 constexpr int32_t SOFT_PC_PRO_DEVICE_WIDTH { 3120 };
64 constexpr int32_t SOFT_PC_PRO_DEVICE_HEIGHT { 2080 };
65 constexpr int32_t TABLET_DEVICE_WIDTH { 2880 };
66 constexpr int32_t TABLET_DEVICE_HEIGHT { 1920 };
67 const std::string DEVICE_TYPE_TABLET { "WEB" };
68 const std::string DEVICE_TYPE_PCE { "PCEL" };
69 const std::string DEVICE_TYPE_PC_PRO { "HAD" };
70 const std::string PRODUCT_TYPE = OHOS::system::GetParameter("const.build.product", "HYM");
71 const std::string MOUSE_FILE_NAME = "mouse_settings.xml";
72 const int32_t ROTATE_POLICY = system::GetIntParameter("const.window.device.rotate_policy", 0);
73 const std::string FOLDABLE_DEVICE_POLICY = system::GetParameter("const.window.foldabledevice.rotate_policy", "");
74 constexpr int32_t WINDOW_ROTATE { 0 };
75 constexpr char ROTATE_WINDOW_ROTATE { '0' };
76 constexpr int32_t FOLDABLE_DEVICE { 2 };
77 constexpr int32_t WAIT_TIME_FOR_BUTTON_UP { 35 };
78 } // namespace
79 
80 int32_t MouseTransformProcessor::globalPointerSpeed_ = DEFAULT_SPEED;
81 
MouseTransformProcessor(int32_t deviceId)82 MouseTransformProcessor::MouseTransformProcessor(int32_t deviceId)
83     : pointerEvent_(PointerEvent::Create()), deviceId_(deviceId)
84 {
85     globalPointerSpeed_ = GetPointerSpeed();
86 }
87 
GetPointerEvent() const88 std::shared_ptr<PointerEvent> MouseTransformProcessor::GetPointerEvent() const
89 {
90     return pointerEvent_;
91 }
92 
HandleMotionInner(struct libinput_event_pointer * data,struct libinput_event * event)93 int32_t MouseTransformProcessor::HandleMotionInner(struct libinput_event_pointer* data, struct libinput_event* event)
94 {
95     CALL_DEBUG_ENTER;
96     CHKPR(data, ERROR_NULL_POINTER);
97     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
98     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
99     pointerEvent_->SetButtonId(buttonId_);
100 
101     CursorPosition cursorPos = WIN_MGR->GetCursorPos();
102     if (cursorPos.displayId < 0) {
103         MMI_HILOGE("No display");
104         return RET_ERR;
105     }
106     unaccelerated_.dx = libinput_event_pointer_get_dx_unaccelerated(data);
107     unaccelerated_.dy = libinput_event_pointer_get_dy_unaccelerated(data);
108 
109     Offset offset { unaccelerated_.dx, unaccelerated_.dy };
110     auto displayInfo = WIN_MGR->GetPhysicalDisplay(cursorPos.displayId);
111     CHKPR(displayInfo, ERROR_NULL_POINTER);
112 #ifndef OHOS_BUILD_EMULATOR
113     if (IsWindowRotation(displayInfo) && Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
114         CalculateOffset(displayInfo->direction, offset);
115     }
116 #endif // OHOS_BUILD_EMULATOR
117     const int32_t type = libinput_event_get_type(event);
118     int32_t ret = RET_ERR;
119     DeviceType deviceType = CheckDeviceType(displayInfo->width, displayInfo->height);
120     if (type == LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD) {
121         pointerEvent_->AddFlag(InputEvent::EVENT_FLAG_TOUCHPAD_POINTER);
122         ret = HandleMotionAccelerateTouchpad(&offset, WIN_MGR->GetMouseIsCaptureMode(),
123             &cursorPos.cursorPos.x, &cursorPos.cursorPos.y, GetTouchpadSpeed(), static_cast<int32_t>(deviceType));
124     } else {
125         pointerEvent_->ClearFlag(InputEvent::EVENT_FLAG_TOUCHPAD_POINTER);
126         ret = HandleMotionAccelerateMouse(&offset, WIN_MGR->GetMouseIsCaptureMode(),
127             &cursorPos.cursorPos.x, &cursorPos.cursorPos.y, globalPointerSpeed_, static_cast<int32_t>(deviceType));
128     }
129     if (ret != RET_OK) {
130         MMI_HILOGE("Failed to handle motion correction");
131         return ret;
132     }
133 #ifdef OHOS_BUILD_EMULATOR
134     cursorPos.cursorPos.x = offset.dx;
135     cursorPos.cursorPos.y = offset.dy;
136 #endif // OHOS_BUILD_EMULATOR
137     WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y);
138     pointerEvent_->SetTargetDisplayId(cursorPos.displayId);
139     MMI_HILOGD("Change coordinate: x:%.2f, y:%.2f, currentDisplayId:%d",
140         cursorPos.cursorPos.x, cursorPos.cursorPos.y, cursorPos.displayId);
141     return RET_OK;
142 }
143 
IsWindowRotation(const DisplayInfo * displayInfo)144 bool MouseTransformProcessor::IsWindowRotation(const DisplayInfo* displayInfo)
145 {
146     MMI_HILOGD("ROTATE_POLICY: %{public}d, FOLDABLE_DEVICE_POLICY:%{public}s",
147         ROTATE_POLICY, FOLDABLE_DEVICE_POLICY.c_str());
148     return (ROTATE_POLICY == WINDOW_ROTATE ||
149         (ROTATE_POLICY == FOLDABLE_DEVICE &&
150         ((displayInfo->displayMode == DisplayMode::MAIN &&
151         FOLDABLE_DEVICE_POLICY[0] == ROTATE_WINDOW_ROTATE) ||
152         (displayInfo->displayMode == DisplayMode::FULL &&
153         FOLDABLE_DEVICE_POLICY[FOLDABLE_DEVICE] == ROTATE_WINDOW_ROTATE))));
154 }
155 
CalculateOffset(Direction direction,Offset & offset)156 void MouseTransformProcessor::CalculateOffset(Direction direction, Offset &offset)
157 {
158     std::negate<double> neg;
159     if (direction == DIRECTION90) {
160         double tmp = offset.dx;
161         offset.dx = offset.dy;
162         offset.dy = neg(tmp);
163     } else if (direction == DIRECTION180) {
164         offset.dx = neg(offset.dx);
165         offset.dy = neg(offset.dy);
166     } else if (direction == DIRECTION270) {
167         double tmp = offset.dx;
168         offset.dx = neg(offset.dy);
169         offset.dy = tmp;
170     }
171 }
172 
HandleButtonInner(struct libinput_event_pointer * data,struct libinput_event * event)173 int32_t MouseTransformProcessor::HandleButtonInner(struct libinput_event_pointer* data, struct libinput_event* event)
174 {
175     CALL_DEBUG_ENTER;
176     CHKPR(data, ERROR_NULL_POINTER);
177     CHKPR(event, ERROR_NULL_POINTER);
178     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
179     MMI_HILOGD("Current action:%{public}d", pointerEvent_->GetPointerAction());
180 
181     uint32_t button = libinput_event_pointer_get_button(data);
182     uint32_t originButton = button;
183     const int32_t type = libinput_event_get_type(event);
184     bool tpTapSwitch = true;
185     GetTouchpadTapSwitch(tpTapSwitch);
186 
187     // touch pad tap switch is disable
188     if (type == LIBINPUT_EVENT_POINTER_TAP && !tpTapSwitch) {
189         MMI_HILOGD("Touch pad is disable");
190         return RET_ERR;
191     }
192 
193     TransTouchpadRightButton(data, type, button);
194 
195     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_MIDDLE_BUTTON_CODE &&
196         type == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
197         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
198     }
199 
200     auto ret = HandleButtonValueInner(data, button, type);
201     if (ret != RET_OK) {
202         MMI_HILOGE("The button value does not exist");
203         return RET_ERR;
204     }
205 
206     auto state = libinput_event_pointer_get_button_state(data);
207     if (state == LIBINPUT_BUTTON_STATE_RELEASED) {
208         int32_t switchTypeData = RIGHT_CLICK_TYPE_MIN;
209         GetTouchpadRightClickType(switchTypeData);
210         RightClickType switchType = RightClickType(switchTypeData);
211         if (type == LIBINPUT_EVENT_POINTER_TAP && switchType == RightClickType::TP_TWO_FINGER_TAP &&
212             button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE) {
213             MMI_HILOGI("Right click up, do sleep");
214             std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME_FOR_BUTTON_UP));
215         }
216         MouseState->MouseBtnStateCounts(button, BUTTON_STATE_RELEASED);
217         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP);
218         int32_t buttonId = MouseState->LibinputChangeToPointer(button);
219         pointerEvent_->DeleteReleaseButton(buttonId);
220         DeletePressedButton(originButton);
221         isPressed_ = false;
222         buttonId_ = PointerEvent::BUTTON_NONE;
223     } else if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
224         MouseState->MouseBtnStateCounts(button, BUTTON_STATE_PRESSED);
225         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN);
226         int32_t buttonId = MouseState->LibinputChangeToPointer(button);
227         pointerEvent_->SetButtonPressed(buttonId);
228         buttonMapping_[originButton] = buttonId;
229         isPressed_ = true;
230         buttonId_ = pointerEvent_->GetButtonId();
231         CursorPosition cursorPos = WIN_MGR->GetCursorPos();
232         if (cursorPos.displayId < 0) {
233             MMI_HILOGE("No display");
234             return RET_ERR;
235         }
236         auto displayInfo = WIN_MGR->GetPhysicalDisplay(cursorPos.displayId);
237         CHKPR(displayInfo, ERROR_NULL_POINTER);
238         if (cursorPos.direction != displayInfo->direction) {
239             WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y);
240         }
241     } else {
242         MMI_HILOGE("Unknown state, state:%{public}u", state);
243         return RET_ERR;
244     }
245     return RET_OK;
246 }
247 
DeletePressedButton(uint32_t originButton)248 void MouseTransformProcessor::DeletePressedButton(uint32_t originButton)
249 {
250     auto iter = buttonMapping_.find(originButton);
251     if (iter != buttonMapping_.end()) {
252         pointerEvent_->DeleteReleaseButton(iter->second);
253         buttonMapping_.erase(iter);
254     }
255 }
256 
HandleButtonValueInner(struct libinput_event_pointer * data,uint32_t button,int32_t type)257 int32_t MouseTransformProcessor::HandleButtonValueInner(struct libinput_event_pointer *data, uint32_t button,
258     int32_t type)
259 {
260     CALL_DEBUG_ENTER;
261     CHKPR(data, ERROR_NULL_POINTER);
262     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
263     int32_t buttonId = MouseState->LibinputChangeToPointer(button);
264     if (buttonId == PointerEvent::BUTTON_NONE) {
265         MMI_HILOGE("Unknown btn, btn:%{public}u", button);
266         return RET_ERR;
267     }
268 
269     std::string name = "primaryButton";
270     int32_t primaryButton = PREFERENCES_MGR->GetIntValue(name, 0);
271     MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
272     if (type == LIBINPUT_EVENT_POINTER_BUTTON && primaryButton == RIGHT_BUTTON) {
273         if (buttonId == PointerEvent::MOUSE_BUTTON_LEFT) {
274             buttonId = PointerEvent::MOUSE_BUTTON_RIGHT;
275         } else if (buttonId == PointerEvent::MOUSE_BUTTON_RIGHT) {
276             buttonId = PointerEvent::MOUSE_BUTTON_LEFT;
277         } else {
278             MMI_HILOGD("buttonId does not switch");
279         }
280     }
281 
282     pointerEvent_->SetButtonId(buttonId);
283     return RET_OK;
284 }
285 
SetMouseScrollRows(int32_t rows)286 int32_t MouseTransformProcessor::SetMouseScrollRows(int32_t rows)
287 {
288     CALL_DEBUG_ENTER;
289     if (rows < MIN_ROWS) {
290         rows = MIN_ROWS;
291     } else if (rows > MAX_ROWS) {
292         rows = MAX_ROWS;
293     }
294     std::string name = "rows";
295     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, rows);
296     if (ret != RET_OK) {
297         MMI_HILOGE("Set mouse scroll rows failed, code:%{public}d", ret);
298         return ret;
299     }
300     MMI_HILOGD("Set mouse scroll rows successfully, rows:%{public}d", rows);
301     return RET_OK;
302 }
303 
GetMouseScrollRows()304 int32_t MouseTransformProcessor::GetMouseScrollRows()
305 {
306     CALL_DEBUG_ENTER;
307     std::string name = "rows";
308     int32_t rows = PREFERENCES_MGR->GetIntValue(name, DEFAULT_ROWS);
309     MMI_HILOGD("Get mouse scroll rows successfully, rows:%{public}d", rows);
310     return rows;
311 }
312 
HandleTouchPadAxisState(libinput_pointer_axis_source source,int32_t & direction,bool & tpScrollSwitch)313 void MouseTransformProcessor::HandleTouchPadAxisState(libinput_pointer_axis_source source,
314     int32_t& direction, bool& tpScrollSwitch)
315 {
316     bool scrollDirectionState = true;
317     GetTouchpadScrollSwitch(tpScrollSwitch);
318     GetTouchpadScrollDirection(scrollDirectionState);
319     if (scrollDirectionState == true && source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
320         direction = -1;
321     }
322 }
323 
HandleAxisInner(struct libinput_event_pointer * data)324 int32_t MouseTransformProcessor::HandleAxisInner(struct libinput_event_pointer* data)
325 {
326     CALL_DEBUG_ENTER;
327     CHKPR(data, ERROR_NULL_POINTER);
328     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
329 
330     bool tpScrollSwitch = true;
331     int32_t tpScrollDirection = 1;
332 
333     libinput_pointer_axis_source source = libinput_event_pointer_get_axis_source(data);
334     HandleTouchPadAxisState(source, tpScrollDirection, tpScrollSwitch);
335     if (!tpScrollSwitch && source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
336         MMI_HILOGD("TouchPad axis event is disable");
337         return RET_ERR;
338     }
339 
340     if (buttonId_ == PointerEvent::BUTTON_NONE && pointerEvent_->GetButtonId() != PointerEvent::BUTTON_NONE) {
341         pointerEvent_->SetButtonId(PointerEvent::BUTTON_NONE);
342     }
343     if (libinput_event_pointer_get_axis_source(data) == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
344         MMI_HILOGD("Libinput event axis source type is finger");
345         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_UPDATE);
346         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
347     } else {
348         if (TimerMgr->IsExist(timerId_)) {
349             pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_UPDATE);
350             pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
351             TimerMgr->ResetTimer(timerId_);
352             MMI_HILOGD("Axis update");
353         } else {
354             static constexpr int32_t timeout = 100;
355             std::weak_ptr<MouseTransformProcessor> weakPtr = shared_from_this();
356             timerId_ = TimerMgr->AddTimer(timeout, 1, [weakPtr]() {
357                 CALL_DEBUG_ENTER;
358                 auto sharedPtr = weakPtr.lock();
359                 CHKPV(sharedPtr);
360                 MMI_HILOGI("Timer:%{public}d", sharedPtr->timerId_);
361                 sharedPtr->timerId_ = -1;
362                 auto pointerEvent = sharedPtr->GetPointerEvent();
363                 CHKPV(pointerEvent);
364                 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
365                 pointerEvent->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
366                 pointerEvent->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL, 0);
367                 pointerEvent->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL, 0);
368                 pointerEvent->UpdateId();
369                 LogTracer lt(pointerEvent->GetId(), pointerEvent->GetEventType(), pointerEvent->GetPointerAction());
370                 auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
371                 CHKPV(inputEventNormalizeHandler);
372                 inputEventNormalizeHandler->HandlePointerEvent(pointerEvent);
373             });
374 
375             pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_BEGIN);
376             pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
377             MMI_HILOGI("Axis begin");
378         }
379     }
380 
381     const int32_t initRows = 3;
382     if (libinput_event_pointer_has_axis(data, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
383         double axisValue = libinput_event_pointer_get_axis_value(data, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
384         if (source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
385             axisValue = HandleAxisAccelateTouchPad(axisValue) * tpScrollDirection;
386         } else {
387             axisValue = GetMouseScrollRows() * axisValue * tpScrollDirection;
388         }
389         pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL, axisValue);
390     }
391     if (libinput_event_pointer_has_axis(data, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
392         double axisValue = libinput_event_pointer_get_axis_value(data, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
393         if (source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
394             axisValue = HandleAxisAccelateTouchPad(axisValue) * tpScrollDirection;
395         } else {
396             axisValue = GetMouseScrollRows() * axisValue * tpScrollDirection;
397         }
398         pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL, axisValue);
399     }
400     return RET_OK;
401 }
402 
HandleAxisAccelateTouchPad(double axisValue)403 double MouseTransformProcessor::HandleAxisAccelateTouchPad(double axisValue)
404 {
405     const int32_t initRows = 3;
406     DeviceType deviceType = DeviceType::DEVICE_PC;
407     if (PRODUCT_TYPE == DEVICE_TYPE_PC_PRO) {
408         deviceType = DeviceType::DEVICE_SOFT_PC_PRO;
409     }
410     if (PRODUCT_TYPE == DEVICE_TYPE_TABLET || PRODUCT_TYPE == DEVICE_TYPE_PCE) {
411         deviceType = DeviceType::DEVICE_TABLET;
412     }
413     int32_t ret =
414         HandleAxisAccelerateTouchpad(WIN_MGR->GetMouseIsCaptureMode(), &axisValue, static_cast<int32_t>(deviceType));
415     if (ret != RET_OK) {
416         MMI_HILOGW("Fail accelerate axis");
417         axisValue = GetMouseScrollRows() * (axisValue / initRows);
418     }
419     return axisValue;
420 }
421 
HandleAxisBeginEndInner(struct libinput_event * event)422 int32_t MouseTransformProcessor::HandleAxisBeginEndInner(struct libinput_event *event)
423 {
424     CALL_DEBUG_ENTER;
425     CHKPR(event, ERROR_NULL_POINTER);
426     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
427     if (buttonId_ == PointerEvent::BUTTON_NONE && pointerEvent_->GetButtonId() != PointerEvent::BUTTON_NONE) {
428         pointerEvent_->SetButtonId(PointerEvent::BUTTON_NONE);
429     }
430     if (!isAxisBegin_ && isPressed_) {
431         MMI_HILOGE("Axis is invalid");
432         return RET_ERR;
433     }
434     if (isAxisBegin_ && isPressed_) {
435         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
436         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
437         isAxisBegin_ = false;
438         MMI_HILOGD("Axis end due to a pressed event");
439         return RET_OK;
440     }
441     if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCHPAD_DOWN && !isPressed_) {
442         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_BEGIN);
443         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
444         isAxisBegin_ = true;
445         MMI_HILOGD("Axis begin");
446         return RET_OK;
447     }
448     if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCHPAD_UP && !isPressed_) {
449         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
450         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
451         isAxisBegin_ = false;
452         MMI_HILOGD("Axis end");
453         return RET_OK;
454     }
455     MMI_HILOGE("Axis is invalid");
456     return RET_ERR;
457 }
458 
HandleScrollFingerInner(struct libinput_event * event)459 int32_t MouseTransformProcessor::HandleScrollFingerInner(struct libinput_event *event)
460 {
461     CALL_DEBUG_ENTER;
462     CHKPR(event, ERROR_NULL_POINTER);
463     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
464     if (buttonId_ == PointerEvent::BUTTON_NONE && pointerEvent_->GetButtonId() != PointerEvent::BUTTON_NONE) {
465         pointerEvent_->SetButtonId(PointerEvent::BUTTON_NONE);
466     }
467     if (libinput_event_get_type(event) == LIBINPUT_EVENT_POINTER_SCROLL_FINGER_BEGIN) {
468         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_BEGIN);
469         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
470         MMI_HILOGD("Axis begin");
471     } else if (libinput_event_get_type(event) == LIBINPUT_EVENT_POINTER_SCROLL_FINGER_END) {
472         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
473         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
474         MMI_HILOGD("Axis end");
475     } else {
476         MMI_HILOGE("Axis is invalid");
477         return RET_ERR;
478     }
479     return RET_OK;
480 }
481 
HandleAxisPostInner(PointerEvent::PointerItem & pointerItem)482 void MouseTransformProcessor::HandleAxisPostInner(PointerEvent::PointerItem &pointerItem)
483 {
484     CALL_DEBUG_ENTER;
485     CHKPV(pointerEvent_);
486     auto mouseInfo = WIN_MGR->GetMouseInfo();
487     MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
488     pointerItem.SetDisplayX(mouseInfo.physicalX);
489     pointerItem.SetDisplayY(mouseInfo.physicalY);
490     pointerItem.SetWindowX(0);
491     pointerItem.SetWindowY(0);
492     pointerItem.SetPointerId(0);
493     pointerItem.SetPressed(isPressed_);
494     int64_t time = GetSysClockTime();
495     pointerItem.SetDownTime(time);
496     pointerItem.SetWidth(0);
497     pointerItem.SetHeight(0);
498     pointerItem.SetPressure(0);
499     pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
500     pointerItem.SetDeviceId(deviceId_);
501     pointerItem.SetRawDx(0);
502     pointerItem.SetRawDy(0);
503     pointerEvent_->UpdateId();
504     StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
505     pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
506     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
507     pointerEvent_->SetActionTime(time);
508     pointerEvent_->SetActionStartTime(time);
509     pointerEvent_->SetPointerId(0);
510     pointerEvent_->SetDeviceId(deviceId_);
511     pointerEvent_->SetTargetDisplayId(mouseInfo.displayId);
512     pointerEvent_->SetTargetWindowId(-1);
513     pointerEvent_->SetAgentWindowId(-1);
514 }
515 
HandlePostInner(struct libinput_event_pointer * data,PointerEvent::PointerItem & pointerItem)516 bool MouseTransformProcessor::HandlePostInner(struct libinput_event_pointer* data,
517     PointerEvent::PointerItem &pointerItem)
518 {
519     CALL_DEBUG_ENTER;
520     CHKPF(pointerEvent_);
521     auto mouseInfo = WIN_MGR->GetMouseInfo();
522     MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
523     pointerItem.SetDisplayX(mouseInfo.physicalX);
524     pointerItem.SetDisplayY(mouseInfo.physicalY);
525     pointerItem.SetWindowX(0);
526     pointerItem.SetWindowY(0);
527     pointerItem.SetPointerId(0);
528     pointerItem.SetPressed(isPressed_);
529 
530     int64_t time = GetSysClockTime();
531     pointerItem.SetDownTime(time);
532     pointerItem.SetWidth(0);
533     pointerItem.SetHeight(0);
534     pointerItem.SetPressure(0);
535     pointerItem.SetDeviceId(deviceId_);
536     pointerItem.SetRawDx(static_cast<int32_t>(unaccelerated_.dx));
537     pointerItem.SetRawDy(static_cast<int32_t>(unaccelerated_.dy));
538 
539     pointerEvent_->UpdateId();
540     StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
541     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
542     pointerEvent_->SetActionTime(time);
543     pointerEvent_->SetActionStartTime(time);
544     pointerEvent_->SetDeviceId(deviceId_);
545     pointerEvent_->SetPointerId(0);
546     pointerEvent_->SetTargetDisplayId(mouseInfo.displayId);
547     pointerEvent_->SetTargetWindowId(-1);
548     pointerEvent_->SetAgentWindowId(-1);
549     if (data == nullptr) {
550         pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
551         return false;
552     }
553     if (libinput_event_pointer_get_axis_source(data) == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
554         pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
555         MMI_HILOGD("ToolType is touchpad");
556     } else {
557         pointerItem.SetToolType(PointerEvent::TOOL_TYPE_MOUSE);
558     }
559     pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
560     return true;
561 }
562 
CheckAndPackageAxisEvent()563 bool MouseTransformProcessor::CheckAndPackageAxisEvent()
564 {
565     CALL_INFO_TRACE;
566     if (!isAxisBegin_) {
567         return false;
568     }
569     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
570     isAxisBegin_ = false;
571     PointerEvent::PointerItem item;
572     HandleAxisPostInner(item);
573     WIN_MGR->UpdateTargetPointer(pointerEvent_);
574     return true;
575 }
576 
Normalize(struct libinput_event * event)577 int32_t MouseTransformProcessor::Normalize(struct libinput_event *event)
578 {
579     CALL_DEBUG_ENTER;
580     CHKPR(event, ERROR_NULL_POINTER);
581     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
582     const int32_t type = libinput_event_get_type(event);
583     auto data = libinput_event_get_pointer_event(event);
584     if (type != LIBINPUT_EVENT_TOUCHPAD_DOWN && type != LIBINPUT_EVENT_TOUCHPAD_UP) {
585         CHKPR(data, ERROR_NULL_POINTER);
586     }
587     pointerEvent_->ClearAxisValue();
588     int32_t result;
589     switch (type) {
590         case LIBINPUT_EVENT_POINTER_MOTION:
591         case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
592         case LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD:
593             result = HandleMotionInner(data, event);
594             break;
595         case LIBINPUT_EVENT_POINTER_TAP:
596         case LIBINPUT_EVENT_POINTER_BUTTON:
597         case LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD:
598             result = HandleButtonInner(data, event);
599             break;
600         case LIBINPUT_EVENT_POINTER_AXIS:
601             result = HandleAxisInner(data);
602             break;
603         case LIBINPUT_EVENT_POINTER_SCROLL_FINGER_BEGIN:
604         case LIBINPUT_EVENT_POINTER_SCROLL_FINGER_END:
605             result = HandleScrollFingerInner(event);
606             break;
607         default:
608             MMI_HILOGE("Unknown type:%{public}d", type);
609             return RET_ERR;
610     }
611     if (result == RET_ERR) {
612         return result;
613     }
614     PointerEvent::PointerItem pointerItem;
615     if (type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER_BEGIN || type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER_END) {
616         HandleAxisPostInner(pointerItem);
617     } else if (!HandlePostInner(data, pointerItem)) {
618         CHKPL(pointerEvent_);
619         return RET_ERR;
620     }
621     WIN_MGR->UpdateTargetPointer(pointerEvent_);
622     DumpInner();
623     return result;
624 }
625 
NormalizeRotateEvent(struct libinput_event * event,int32_t type,double angle)626 int32_t MouseTransformProcessor::NormalizeRotateEvent(struct libinput_event *event, int32_t type, double angle)
627 {
628     CALL_DEBUG_ENTER;
629     CHKPR(event, ERROR_NULL_POINTER);
630     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
631     auto data = libinput_event_get_pointer_event(event);
632     pointerEvent_->SetPointerAction(type);
633     pointerEvent_->ClearAxisValue();
634     pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_ROTATE, angle);
635     PointerEvent::PointerItem pointerItem;
636     pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
637     if (!HandlePostInner(data, pointerItem)) {
638         WIN_MGR->UpdateTargetPointer(pointerEvent_);
639         DumpInner();
640         return ERROR_NULL_POINTER;
641     }
642     WIN_MGR->UpdateTargetPointer(pointerEvent_);
643     DumpInner();
644     return RET_OK;
645 }
646 
647 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
HandleMotionMoveMouse(int32_t offsetX,int32_t offsetY)648 void MouseTransformProcessor::HandleMotionMoveMouse(int32_t offsetX, int32_t offsetY)
649 {
650     CALL_DEBUG_ENTER;
651     CHKPV(pointerEvent_);
652     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
653     CursorPosition cursorPos = WIN_MGR->GetCursorPos();
654     cursorPos.cursorPos.x += offsetX;
655     cursorPos.cursorPos.y += offsetY;
656     WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y);
657 }
658 
OnDisplayLost(int32_t displayId)659 void MouseTransformProcessor::OnDisplayLost(int32_t displayId)
660 {
661     CursorPosition cursorPos = WIN_MGR->GetCursorPos();
662     if (cursorPos.displayId != displayId) {
663         cursorPos = WIN_MGR->ResetCursorPos();
664         WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y);
665     }
666 }
667 
GetDisplayId()668 int32_t MouseTransformProcessor::GetDisplayId()
669 {
670     return WIN_MGR->GetCursorPos().displayId;
671 }
672 
HandlePostMoveMouse(PointerEvent::PointerItem & pointerItem)673 void MouseTransformProcessor::HandlePostMoveMouse(PointerEvent::PointerItem& pointerItem)
674 {
675     CALL_DEBUG_ENTER;
676     auto mouseInfo = WIN_MGR->GetMouseInfo();
677     CHKPV(pointerEvent_);
678     MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
679     pointerItem.SetDisplayX(mouseInfo.physicalX);
680     pointerItem.SetDisplayY(mouseInfo.physicalY);
681     pointerItem.SetWindowX(0);
682     pointerItem.SetWindowY(0);
683     pointerItem.SetPointerId(0);
684     pointerItem.SetPressed(isPressed_);
685 
686     int64_t time = GetSysClockTime();
687     pointerItem.SetDownTime(time);
688     pointerItem.SetWidth(0);
689     pointerItem.SetHeight(0);
690     pointerItem.SetPressure(0);
691 
692     pointerEvent_->UpdateId();
693     StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
694     pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
695     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
696     pointerEvent_->SetActionTime(time);
697     pointerEvent_->SetActionStartTime(time);
698 
699     pointerEvent_->SetPointerId(0);
700     pointerEvent_->SetTargetDisplayId(-1);
701     pointerEvent_->SetTargetWindowId(-1);
702     pointerEvent_->SetAgentWindowId(-1);
703 }
704 
NormalizeMoveMouse(int32_t offsetX,int32_t offsetY)705 bool MouseTransformProcessor::NormalizeMoveMouse(int32_t offsetX, int32_t offsetY)
706 {
707     CALL_DEBUG_ENTER;
708     CHKPF(pointerEvent_);
709     bool bHasPointerDevice = INPUT_DEV_MGR->HasPointerDevice();
710     if (!bHasPointerDevice) {
711         MMI_HILOGE("There hasn't any pointer device");
712         return false;
713     }
714 
715     PointerEvent::PointerItem pointerItem;
716     HandleMotionMoveMouse(offsetX, offsetY);
717     HandlePostMoveMouse(pointerItem);
718     DumpInner();
719     return bHasPointerDevice;
720 }
721 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
722 
DumpInner()723 void MouseTransformProcessor::DumpInner()
724 {
725     static int32_t lastDeviceId = -1;
726     static std::string lastDeviceName("default");
727     auto nowId = pointerEvent_->GetDeviceId();
728     if (lastDeviceId != nowId) {
729         auto device = INPUT_DEV_MGR->GetInputDevice(nowId);
730         CHKPV(device);
731         lastDeviceId = nowId;
732         lastDeviceName = device->GetName();
733     }
734     EventLogHelper::PrintEventData(pointerEvent_, MMI_LOG_FREEZE);
735     aggregator_.Record(MMI_LOG_FREEZE, lastDeviceName + ", TW: " +
736         std::to_string(pointerEvent_->GetTargetWindowId()), std::to_string(pointerEvent_->GetId()));
737 }
738 
CheckDeviceType(int32_t width,int32_t height)739 DeviceType MouseTransformProcessor::CheckDeviceType(int32_t width, int32_t height)
740 {
741     CALL_DEBUG_ENTER;
742     DeviceType ret = DeviceType::DEVICE_PC;
743     if (PRODUCT_TYPE == DEVICE_TYPE_PC_PRO) {
744         if (width == HARD_PC_PRO_DEVICE_WIDTH && height == HARD_PC_PRO_DEVICE_HEIGHT) {
745             ret = DeviceType::DEVICE_HARD_PC_PRO;
746         } else if (width == SOFT_PC_PRO_DEVICE_WIDTH && height == SOFT_PC_PRO_DEVICE_HEIGHT) {
747             ret = DeviceType::DEVICE_SOFT_PC_PRO;
748         } else if (EventLogHelper::IsBetaVersion()) {
749             MMI_HILOGE("Undefined width:%{private}d, height:%{private}d", width, height);
750         }
751         MMI_HILOGD("Device width:%{private}d, height:%{private}d", width, height);
752     }
753     if (PRODUCT_TYPE == DEVICE_TYPE_TABLET || PRODUCT_TYPE == DEVICE_TYPE_PCE) {
754         if (width == TABLET_DEVICE_WIDTH && height == TABLET_DEVICE_HEIGHT) {
755             ret = DeviceType::DEVICE_TABLET;
756         }
757     }
758     return ret;
759 }
760 
Dump(int32_t fd,const std::vector<std::string> & args)761 void MouseTransformProcessor::Dump(int32_t fd, const std::vector<std::string> &args)
762 {
763     CALL_DEBUG_ENTER;
764     PointerEvent::PointerItem item;
765     CHKPV(pointerEvent_);
766     pointerEvent_->GetPointerItem(pointerEvent_->GetPointerId(), item);
767     mprintf(fd, "Mouse device state information:\t");
768     mprintf(fd,
769             "PointerId:%d | SourceType:%s | PointerAction:%s | WindowX:%d | WindowY:%d | ButtonId:%d "
770             "| AgentWindowId:%d | TargetWindowId:%d | DownTime:%" PRId64 " | IsPressed:%s \t",
771             pointerEvent_->GetPointerId(), pointerEvent_->DumpSourceType(), pointerEvent_->DumpPointerAction(),
772             item.GetWindowX(), item.GetWindowY(), pointerEvent_->GetButtonId(), pointerEvent_->GetAgentWindowId(),
773             pointerEvent_->GetTargetWindowId(), item.GetDownTime(), item.IsPressed() ? "true" : "false");
774 }
775 
SetMousePrimaryButton(int32_t primaryButton)776 int32_t MouseTransformProcessor::SetMousePrimaryButton(int32_t primaryButton)
777 {
778     CALL_DEBUG_ENTER;
779     MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
780     std::string name = "primaryButton";
781     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, primaryButton);
782     if (ret != RET_OK) {
783         MMI_HILOGE("Set mouse primary button failed, code:%{public}d", ret);
784         return ret;
785     }
786     return RET_OK;
787 }
788 
GetMousePrimaryButton()789 int32_t MouseTransformProcessor::GetMousePrimaryButton()
790 {
791     CALL_DEBUG_ENTER;
792     std::string name = "primaryButton";
793     int32_t primaryButton = PREFERENCES_MGR->GetIntValue(name, 0);
794     MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
795     return primaryButton;
796 }
797 
SetPointerSpeed(int32_t speed)798 int32_t MouseTransformProcessor::SetPointerSpeed(int32_t speed)
799 {
800     CALL_DEBUG_ENTER;
801     if (speed < MIN_SPEED) {
802         speed = MIN_SPEED;
803     } else if (speed > MAX_SPEED) {
804         speed = MAX_SPEED;
805     }
806     globalPointerSpeed_ = speed;
807     std::string name = "speed";
808     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, speed);
809     if (ret != RET_OK) {
810         MMI_HILOGE("Set pointer speed failed, code:%{public}d", ret);
811         return ret;
812     }
813     MMI_HILOGD("Set pointer speed successfully, speed:%{public}d", speed);
814     return RET_OK;
815 }
816 
GetPointerSpeed()817 int32_t MouseTransformProcessor::GetPointerSpeed()
818 {
819     std::string name = "speed";
820     int32_t speed = PREFERENCES_MGR->GetIntValue(name, DEFAULT_SPEED);
821     MMI_HILOGD("Pointer speed:%{public}d", speed);
822     return speed;
823 }
824 
GetTouchpadSpeed()825 int32_t MouseTransformProcessor::GetTouchpadSpeed()
826 {
827     int32_t speed = DEFAULT_TOUCHPAD_SPEED;
828     GetTouchpadPointerSpeed(speed);
829     MMI_HILOGD("TouchPad pointer speed:%{public}d", speed);
830     return speed;
831 }
832 
SetPointerLocation(int32_t x,int32_t y)833 int32_t MouseTransformProcessor::SetPointerLocation(int32_t x, int32_t y)
834 {
835     MMI_HILOGI("SetPointerLocation x:%d, y:%d", x, y);
836     CursorPosition cursorPos = WIN_MGR->GetCursorPos();
837     if (cursorPos.displayId < 0) {
838         MMI_HILOGE("No display");
839         return RET_ERR;
840     }
841     cursorPos.cursorPos.x = x;
842     cursorPos.cursorPos.y = y;
843 
844     WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y, false);
845     auto mouseLoc = WIN_MGR->GetMouseInfo();
846     IPointerDrawingManager::GetInstance()->SetPointerLocation(mouseLoc.physicalX, mouseLoc.physicalY);
847     return RET_OK;
848 }
849 
HandleTouchpadRightButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)850 void MouseTransformProcessor::HandleTouchpadRightButton(struct libinput_event_pointer *data, const int32_t evenType,
851     uint32_t &button)
852 {
853     // touchpad left click 280 -> 272
854     if (button == BTN_RIGHT_MENUE_CODE) {
855         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
856         return;
857     }
858 
859     // touchpad two finger tap 273 -> 0
860     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
861         evenType == LIBINPUT_EVENT_POINTER_TAP) {
862         button = 0;
863         return;
864     }
865 
866     // touchpad two finger button 272 -> 0
867     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE &&
868         evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
869         return;
870     }
871 }
872 
HandleTouchpadLeftButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)873 void MouseTransformProcessor::HandleTouchpadLeftButton(struct libinput_event_pointer *data, const int32_t evenType,
874     uint32_t &button)
875 {
876     // touchpad left click 280 -> 273
877     if (button == BTN_RIGHT_MENUE_CODE) {
878         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE;
879         return;
880     }
881 
882     // touchpad right click 273 -> 272
883     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
884         evenType != LIBINPUT_EVENT_POINTER_TAP) {
885         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
886         return;
887     }
888 
889     // touchpad two finger tap 273 -> 0
890     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
891         evenType == LIBINPUT_EVENT_POINTER_TAP) {
892         button = 0;
893         return;
894     }
895 
896     // touchpad two finger button 272 -> 0
897     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE &&
898         evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
899         return;
900     }
901 }
902 
HandleTouchpadTwoFingerButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)903 void MouseTransformProcessor::HandleTouchpadTwoFingerButton(struct libinput_event_pointer *data, const int32_t evenType,
904     uint32_t &button)
905 {
906     // touchpad two finger button -> 273
907     uint32_t fingerCount = libinput_event_pointer_get_finger_count(data);
908     if (fingerCount == TP_RIGHT_CLICK_FINGER_CNT) {
909         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE;
910         return;
911     }
912 
913     // touchpad right click 273 -> 272
914     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
915         evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
916         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
917         return;
918     }
919 
920     // touchpad left click 280 -> 272
921     if (button == BTN_RIGHT_MENUE_CODE) {
922         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
923         return;
924     }
925 }
926 
TransTouchpadRightButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)927 void MouseTransformProcessor::TransTouchpadRightButton(struct libinput_event_pointer *data, const int32_t evenType,
928     uint32_t &button)
929 {
930     int32_t switchTypeData = RIGHT_CLICK_TYPE_MIN;
931     GetTouchpadRightClickType(switchTypeData);
932 
933     RightClickType switchType = RightClickType(switchTypeData);
934     if (evenType != LIBINPUT_EVENT_POINTER_TAP && evenType != LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
935         MMI_HILOGE("Event not from touchpad");
936         return;
937     }
938 
939     switch (switchType) {
940         case RightClickType::TP_RIGHT_BUTTON:
941             HandleTouchpadRightButton(data, evenType, button);
942             break;
943 
944         case RightClickType::TP_LEFT_BUTTON:
945             HandleTouchpadLeftButton(data, evenType, button);
946             break;
947 
948         case RightClickType::TP_TWO_FINGER_TAP:
949             HandleTouchpadTwoFingerButton(data, evenType, button);
950             break;
951         default:
952             MMI_HILOGD("Invalid type, switchType:%{public}d", switchType);
953             break;
954     }
955 }
956 
SetTouchpadScrollSwitch(bool switchFlag)957 int32_t MouseTransformProcessor::SetTouchpadScrollSwitch(bool switchFlag)
958 {
959     std::string name = "scrollSwitch";
960     if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
961         MMI_HILOGE("Failed to set scroll switch flag to mem, name:%s, switchFlag:%{public}d", name.c_str(), switchFlag);
962         return RET_ERR;
963     }
964     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_SCROLL_SETTING,
965         switchFlag);
966 
967     return RET_OK;
968 }
969 
GetTouchpadScrollSwitch(bool & switchFlag)970 void MouseTransformProcessor::GetTouchpadScrollSwitch(bool &switchFlag)
971 {
972     std::string name = "scrollSwitch";
973     GetConfigDataFromDatabase(name, switchFlag);
974 }
975 
SetTouchpadScrollDirection(bool state)976 int32_t MouseTransformProcessor::SetTouchpadScrollDirection(bool state)
977 {
978     std::string name = "scrollDirection";
979     if (PutConfigDataToDatabase(name, state) != RET_OK) {
980         MMI_HILOGE("Failed to set scroll direct switch flag to mem");
981         return RET_ERR;
982     }
983 
984     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_SCROLL_DIR_SETTING,
985         state);
986 
987     return RET_OK;
988 }
989 
GetTouchpadScrollDirection(bool & state)990 void MouseTransformProcessor::GetTouchpadScrollDirection(bool &state)
991 {
992     std::string name = "scrollDirection";
993     GetConfigDataFromDatabase(name, state);
994 }
995 
SetTouchpadTapSwitch(bool switchFlag)996 int32_t MouseTransformProcessor::SetTouchpadTapSwitch(bool switchFlag)
997 {
998     std::string name = "touchpadTap";
999     if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
1000         MMI_HILOGE("Failed to set scroll direct switch flag to mem");
1001         return RET_ERR;
1002     }
1003 
1004     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_TAP_SETTING,
1005         switchFlag);
1006 
1007     return RET_OK;
1008 }
1009 
GetTouchpadTapSwitch(bool & switchFlag)1010 void MouseTransformProcessor::GetTouchpadTapSwitch(bool &switchFlag)
1011 {
1012     std::string name = "touchpadTap";
1013     GetConfigDataFromDatabase(name, switchFlag);
1014 }
1015 
SetTouchpadPointerSpeed(int32_t speed)1016 int32_t MouseTransformProcessor::SetTouchpadPointerSpeed(int32_t speed)
1017 {
1018     std::string name = "touchPadPointerSpeed";
1019     if (PutConfigDataToDatabase(name, speed) != RET_OK) {
1020         MMI_HILOGE("Failed to set touch pad pointer speed to mem");
1021         return RET_ERR;
1022     }
1023 
1024     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_POINTER_SPEED_SETTING,
1025         speed);
1026 
1027     return RET_OK;
1028 }
1029 
GetTouchpadPointerSpeed(int32_t & speed)1030 void MouseTransformProcessor::GetTouchpadPointerSpeed(int32_t &speed)
1031 {
1032     std::string name = "touchPadPointerSpeed";
1033     GetConfigDataFromDatabase(name, speed);
1034     speed = speed == 0 ? DEFAULT_TOUCHPAD_SPEED : speed;
1035     speed = speed < MIN_SPEED ? MIN_SPEED : speed;
1036     speed = speed > MAX_SPEED ? MAX_SPEED : speed;
1037 }
1038 
SetTouchpadRightClickType(int32_t type)1039 int32_t MouseTransformProcessor::SetTouchpadRightClickType(int32_t type)
1040 {
1041     std::string name = "rightMenuSwitch";
1042     if (PutConfigDataToDatabase(name, type) != RET_OK) {
1043         MMI_HILOGE("Failed to set right click type to mem");
1044         return RET_ERR;
1045     }
1046     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_RIGHT_CLICK_SETTING,
1047         type);
1048     return RET_OK;
1049 }
1050 
GetTouchpadRightClickType(int32_t & type)1051 void MouseTransformProcessor::GetTouchpadRightClickType(int32_t &type)
1052 {
1053     std::string name = "rightMenuSwitch";
1054     GetConfigDataFromDatabase(name, type);
1055 
1056     if (type < RIGHT_CLICK_TYPE_MIN || type > RIGHT_CLICK_TYPE_MAX) {
1057         type = RIGHT_CLICK_TYPE_MIN;
1058     }
1059 }
1060 
PutConfigDataToDatabase(std::string & key,bool value)1061 int32_t MouseTransformProcessor::PutConfigDataToDatabase(std::string &key, bool value)
1062 {
1063     return PREFERENCES_MGR->SetBoolValue(key, MOUSE_FILE_NAME, value);
1064 }
1065 
GetConfigDataFromDatabase(std::string & key,bool & value)1066 void MouseTransformProcessor::GetConfigDataFromDatabase(std::string &key, bool &value)
1067 {
1068     value = PREFERENCES_MGR->GetBoolValue(key, true);
1069 }
1070 
PutConfigDataToDatabase(std::string & key,int32_t value)1071 int32_t MouseTransformProcessor::PutConfigDataToDatabase(std::string &key, int32_t value)
1072 {
1073     return PREFERENCES_MGR->SetIntValue(key, MOUSE_FILE_NAME, value);
1074 }
1075 
GetConfigDataFromDatabase(std::string & key,int32_t & value)1076 void MouseTransformProcessor::GetConfigDataFromDatabase(std::string &key, int32_t &value)
1077 {
1078     int32_t defaultValue = value;
1079     value = PREFERENCES_MGR->GetIntValue(key, defaultValue);
1080 }
1081 } // namespace MMI
1082 } // namespace OHOS
1083