• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "mouse_transform_processor.h"
17 #include "dfx_hisysevent.h"
18 #include "event_log_helper.h"
19 #include "i_pointer_drawing_manager.h"
20 #include "i_preference_manager.h"
21 #include "input_event_handler.h"
22 #include "mouse_device_state.h"
23 #include "scene_board_judgement.h"
24 #include "touchpad_transform_processor.h"
25 #include "util_ex.h"
26 #include "linux/input.h"
27 
28 #undef MMI_LOG_DOMAIN
29 #define MMI_LOG_DOMAIN MMI_LOG_DISPATCH
30 #undef MMI_LOG_TAG
31 #define MMI_LOG_TAG "MouseTransformProcessor"
32 
33 namespace OHOS {
34 namespace MMI {
35 namespace {
36 constexpr int32_t MIN_SPEED { 1 };
37 constexpr int32_t MAX_SPEED { 20 };
38 constexpr int32_t DEFAULT_SPEED { 10 };
39 constexpr int32_t MAX_TOUCHPAD_SPEED { 11 };
40 constexpr int32_t DEFAULT_TOUCHPAD_SPEED { 6 };
41 constexpr int32_t DEFAULT_ROWS { 3 };
42 constexpr int32_t MIN_ROWS { 1 };
43 constexpr int32_t MAX_ROWS { 100 };
44 constexpr int32_t BTN_RIGHT_MENUE_CODE { 0x118 };
45 constexpr int32_t RIGHT_CLICK_TYPE_MIN { 1 };
46 constexpr int32_t RIGHT_CLICK_TYPE_MAX { 3 };
47 [[ maybe_unused ]] constexpr int32_t TP_CLICK_FINGER_ONE { 1 };
48 constexpr int32_t TP_RIGHT_CLICK_FINGER_CNT { 2 };
49 constexpr int32_t HARD_PC_PRO_DEVICE_WIDTH { 2880 };
50 constexpr int32_t HARD_PC_PRO_DEVICE_HEIGHT { 1920 };
51 constexpr int32_t SOFT_PC_PRO_DEVICE_WIDTH { 3120 };
52 constexpr int32_t SOFT_PC_PRO_DEVICE_HEIGHT { 2080 };
53 constexpr int32_t TABLET_DEVICE_WIDTH { 2880 };
54 constexpr int32_t TABLET_DEVICE_HEIGHT { 1920 };
55 constexpr int32_t FOLD_PC_WIDTH { 2472 };
56 constexpr int32_t FOLD_PC_HEIGHT { 3296 };
57 const char* DEVICE_TYPE_FOLD_PC { "FOLD_PC" };
58 const char* DEVICE_TYPE_TABLET { "TABLET"};
59 const char* DEVICE_TYPE_PC_PRO { "PC_PRO" };
60 const std::string PRODUCT_TYPE = OHOS::system::GetParameter("const.build.product", "HYM");
61 const std::string MOUSE_FILE_NAME { "mouse_settings.xml" };
62 constexpr int32_t WAIT_TIME_FOR_BUTTON_UP { 35 };
63 constexpr int32_t ANGLE_90 { 90 };
64 constexpr int32_t ANGLE_360 { 360 };
65 constexpr int32_t FINE_CALCULATE { 20 };
66 constexpr int32_t STEP_CALCULATE { 40 };
67 constexpr int32_t STOP_CALCULATE { 5000 };
68 constexpr int32_t CALCULATE_STEP { 5 };
69 constexpr float MM_TO_INCH { 25.4f };
70 constexpr int32_t SCREEN_DIAGONAL_0 { 0 };
71 constexpr int32_t SCREEN_DIAGONAL_8 { 8 };
72 constexpr int32_t SCREEN_DIAGONAL_18 { 18 };
73 constexpr int32_t SCREEN_DIAGONAL_27 { 27 };
74 constexpr int32_t SCREEN_DIAGONAL_55 { 55 };
75 constexpr float FACTOR_0 { 1.0f };
76 constexpr float FACTOR_8 { 0.7f };
77 constexpr float FACTOR_18 { 1.0f };
78 constexpr float FACTOR_27 { 1.2f };
79 constexpr float FACTOR_55 { 1.6f };
80 constexpr float FACTOR_MAX { 2.4f };
81 constexpr double CONST_HALF { 0.5 };
82 constexpr int32_t CONST_TWO { 2 };
83 constexpr double CONST_DOUBLE_ZERO { 0.0 };
84 constexpr double CONST_DOUBLE_ONE { 1.0 };
85 } // namespace
86 
87 int32_t MouseTransformProcessor::globalPointerSpeed_ = DEFAULT_SPEED;
88 int32_t MouseTransformProcessor::scrollSwitchPid_ = -1;
89 TouchpadCDG MouseTransformProcessor::touchpadOption_;
90 DeviceType MouseTransformProcessor::deviceTypeGlobal_ = DeviceType::DEVICE_UNKOWN;
91 
MouseTransformProcessor(int32_t deviceId)92 MouseTransformProcessor::MouseTransformProcessor(int32_t deviceId)
93     : pointerEvent_(PointerEvent::Create()), deviceId_(deviceId)
94 {
95     globalPointerSpeed_ = GetPointerSpeed();
96 }
97 
GetPointerEvent() const98 std::shared_ptr<PointerEvent> MouseTransformProcessor::GetPointerEvent() const
99 {
100     return pointerEvent_;
101 }
102 
103 #ifdef OHOS_BUILD_EMULATOR
CalculateCursorPosFromOffset(Offset offset,const DisplayInfo & displayInfo)104 static Coordinate2D CalculateCursorPosFromOffset(Offset offset, const DisplayInfo &displayInfo)
105 {
106     auto direction = displayInfo.displayDirection;
107     auto width = displayInfo.width;
108     auto height = displayInfo.height;
109     constexpr int evenNum = 2;
110     if ((displayInfo.displayDirection - displayInfo.direction) % evenNum != 0) {
111         std::swap(width, height);
112     }
113     offset.dx -= displayInfo.offsetX;
114     offset.dy -= displayInfo.offsetY;
115     if (direction == DIRECTION90) {
116         std::swap(offset.dx, offset.dy);
117         offset.dx = width - offset.dx;
118     } else if (direction == DIRECTION180) {
119         offset.dx = width - offset.dx;
120         offset.dy = height - offset.dy;
121     } else if (direction == DIRECTION270) {
122         std::swap(offset.dx, offset.dy);
123         offset.dy = height - offset.dy;
124     }
125     return {offset.dx, offset.dy};
126 }
127 #endif
128 
ScreenFactor(const int32_t diagonalInch)129 float ScreenFactor(const int32_t diagonalInch)
130 {
131     if (diagonalInch <= SCREEN_DIAGONAL_0) {
132         return FACTOR_0;
133     } else if (diagonalInch < SCREEN_DIAGONAL_8) {
134         return FACTOR_8;
135     } else if (diagonalInch < SCREEN_DIAGONAL_18) {
136         return FACTOR_18;
137     } else if (diagonalInch < SCREEN_DIAGONAL_27) {
138         return FACTOR_27;
139     } else if (diagonalInch < SCREEN_DIAGONAL_55) {
140         return FACTOR_55;
141     } else {
142         return FACTOR_MAX;
143     }
144 }
145 
HandleMotionInner(struct libinput_event_pointer * data,struct libinput_event * event)146 int32_t MouseTransformProcessor::HandleMotionInner(struct libinput_event_pointer* data, struct libinput_event* event)
147 {
148     CALL_DEBUG_ENTER;
149     CHKPR(data, ERROR_NULL_POINTER);
150     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
151 #ifndef OHOS_BUILD_ENABLE_WATCH
152     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
153     pointerEvent_->SetButtonId(buttonId_);
154 
155     CursorPosition cursorPos = WIN_MGR->GetCursorPos();
156     if (cursorPos.displayId < 0) {
157         MMI_HILOGE("No display");
158         return RET_ERR;
159     }
160     unaccelerated_.dx = libinput_event_pointer_get_dx_unaccelerated(data);
161     unaccelerated_.dy = libinput_event_pointer_get_dy_unaccelerated(data);
162 
163     Offset offset { unaccelerated_.dx, unaccelerated_.dy };
164     auto displayInfo = WIN_MGR->GetPhysicalDisplay(cursorPos.displayId);
165     CHKPR(displayInfo, ERROR_NULL_POINTER);
166     CalculateMouseResponseTimeProbability(event);
167     const int32_t type = libinput_event_get_type(event);
168     int32_t ret = RET_ERR;
169     DeviceType deviceType = CheckDeviceType(displayInfo->width, displayInfo->height);
170     deviceTypeGlobal_ = deviceType;
171     if (type == LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD) {
172         pointerEvent_->AddFlag(InputEvent::EVENT_FLAG_TOUCHPAD_POINTER);
173         ret = UpdateTouchpadMoveLocation(displayInfo, event, offset, cursorPos.cursorPos.x, cursorPos.cursorPos.y,
174             static_cast<int32_t>(deviceType));
175     } else {
176         pointerEvent_->ClearFlag(InputEvent::EVENT_FLAG_TOUCHPAD_POINTER);
177         pointerEvent_->ClearFlag(InputEvent::EVENT_FLAG_VIRTUAL_TOUCHPAD_POINTER);
178         ret = UpdateMouseMoveLocation(displayInfo, offset, cursorPos.cursorPos.x, cursorPos.cursorPos.y,
179             static_cast<int32_t>(deviceType));
180     }
181     if (ret != RET_OK) {
182         MMI_HILOGE("Failed to handle motion correction");
183         return ret;
184     }
185 #ifdef OHOS_BUILD_EMULATOR
186     cursorPos.cursorPos = CalculateCursorPosFromOffset(offset, *displayInfo);
187 #endif // OHOS_BUILD_EMULATOR
188     WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y);
189     pointerEvent_->SetTargetDisplayId(cursorPos.displayId);
190     MMI_HILOGD("Change coordinate: x:%.2f, y:%.2f, currentDisplayId:%d",
191         cursorPos.cursorPos.x, cursorPos.cursorPos.y, cursorPos.displayId);
192 #endif // OHOS_BUILD_ENABLE_WATCH
193     return RET_OK;
194 }
195 
UpdateMouseMoveLocation(const DisplayInfo * displayInfo,Offset & offset,double & abs_x,double & abs_y,int32_t deviceType)196 int32_t MouseTransformProcessor::UpdateMouseMoveLocation(const DisplayInfo* displayInfo, Offset &offset,
197     double &abs_x, double &abs_y, int32_t deviceType)
198 {
199     int32_t ret = RET_ERR;
200     uint64_t dalta_time = 0;
201 #ifdef OHOS_BUILD_MOUSE_REPORTING_RATE
202     dalta_time = filterInsertionPoint_.filterDeltaTime;
203     HandleFilterMouseEvent(&offset);
204     CalculateOffset(displayInfo, offset);
205 #endif // OHOS_BUILD_MOUSE_REPORTING_RATE
206     if (displayInfo->ppi > static_cast<float>(CONST_DOUBLE_ZERO)) {
207         double displaySize = sqrt(pow(displayInfo->width, CONST_TWO) + pow(displayInfo->height, CONST_TWO));
208         double diagonalMm = sqrt(pow(displayInfo->physicalWidth, CONST_TWO)
209             + pow(displayInfo->physicalHeight, CONST_TWO));
210         double displayPpi = static_cast<double>(displayInfo->ppi);
211         if (displayInfo->validWidth != static_cast<int32_t>(CONST_DOUBLE_ZERO) &&
212             displayInfo->validHeight != static_cast<int32_t>(CONST_DOUBLE_ZERO)  &&
213             (displayInfo->validWidth != displayInfo->width || displayInfo->validHeight != displayInfo->height)) {
214             displaySize = sqrt(pow(displayInfo->validWidth, CONST_TWO) + pow(displayInfo->validHeight, CONST_TWO));
215             diagonalMm = sqrt(pow(displayInfo->physicalWidth, CONST_TWO)
216                 + pow(displayInfo->physicalHeight * CONST_HALF, CONST_TWO));
217         }
218         if (diagonalMm > CONST_DOUBLE_ZERO) {
219             displayPpi = displaySize * MM_TO_INCH / diagonalMm;
220         }
221         int32_t diagonalInch = static_cast<int32_t>(diagonalMm / MM_TO_INCH);
222         float factor = ScreenFactor(diagonalInch);
223         ret = HandleMotionDynamicAccelerateMouse(&offset, WIN_MGR->GetMouseIsCaptureMode(),
224             &abs_x, &abs_y, globalPointerSpeed_, dalta_time, displayPpi, static_cast<double>(factor));
225         return ret;
226     } else {
227         ret = HandleMotionAccelerateMouse(&offset, WIN_MGR->GetMouseIsCaptureMode(),
228             &abs_x, &abs_y, globalPointerSpeed_, deviceType);
229         return ret;
230     }
231 }
232 
UpdateTouchpadMoveLocation(const DisplayInfo * displayInfo,struct libinput_event * event,Offset & offset,double & abs_x,double & abs_y,int32_t deviceType)233 int32_t MouseTransformProcessor::UpdateTouchpadMoveLocation(const DisplayInfo* displayInfo,
234     struct libinput_event* event, Offset &offset, double &abs_x, double &abs_y, int32_t deviceType)
235 {
236     int32_t ret = RET_ERR;
237     CalculateOffset(displayInfo, offset);
238     struct libinput_device *device = libinput_event_get_device(event);
239     CHKPR(device, ERROR_NULL_POINTER);
240     const std::string devName = libinput_device_get_name(device);
241     if (displayInfo->width == static_cast<int32_t>(CONST_DOUBLE_ZERO) ||
242         displayInfo->height == static_cast<int32_t>(CONST_DOUBLE_ZERO)) {
243         ret = HandleMotionAccelerateTouchpad(&offset, WIN_MGR->GetMouseIsCaptureMode(),
244             &abs_x, &abs_y, GetTouchpadSpeed(), deviceType);
245         return ret;
246     } else if (PRODUCT_TYPE == DEVICE_TYPE_FOLD_PC && devName == "input_mt_wrapper") {
247         deviceType = static_cast<int32_t>(DeviceType::DEVICE_FOLD_PC_VIRT);
248         deviceTypeGlobal_ = DeviceType::DEVICE_FOLD_PC_VIRT;
249         pointerEvent_->AddFlag(InputEvent::EVENT_FLAG_VIRTUAL_TOUCHPAD_POINTER);
250         ret = HandleMotionAccelerateTouchpad(&offset, WIN_MGR->GetMouseIsCaptureMode(),
251             &abs_x, &abs_y, GetTouchpadSpeed(), deviceType);
252         return ret;
253     } else {
254         pointerEvent_->AddFlag(InputEvent::EVENT_FLAG_TOUCHPAD_POINTER);
255         double displaySize = sqrt(pow(displayInfo->width, CONST_TWO) + pow(displayInfo->height, CONST_TWO));
256         if (displayInfo->validWidth != static_cast<int32_t>(CONST_DOUBLE_ZERO) &&
257             displayInfo->validHeight != static_cast<int32_t>(CONST_DOUBLE_ZERO) &&
258             (displayInfo->validWidth != displayInfo->width || displayInfo->validWidth != displayInfo->height)) {
259             displaySize = sqrt(pow(displayInfo->validWidth, CONST_TWO) + pow(displayInfo->validHeight, CONST_TWO));
260         }
261         double touchpadPPi = libinput_touchpad_device_get_ppi(device);
262         double touchpadSize = libinput_touchpad_device_get_hypot_size(device) * touchpadPPi;
263         int32_t frequency = libinput_touchpad_device_get_frequency(device);
264         if (touchpadPPi < CONST_DOUBLE_ONE || touchpadSize < CONST_DOUBLE_ONE || frequency < CONST_DOUBLE_ONE) {
265             return RET_ERR;
266         }
267         ret = HandleMotionDynamicAccelerateTouchpad(&offset, WIN_MGR->GetMouseIsCaptureMode(),
268             &abs_x, &abs_y, GetTouchpadSpeed(), displaySize, touchpadSize, touchpadPPi, frequency);
269         return ret;
270     }
271 }
272 
CalculateMouseResponseTimeProbability(struct libinput_event * event)273 void MouseTransformProcessor::CalculateMouseResponseTimeProbability(struct libinput_event *event)
274 {
275     struct libinput_device *dev = libinput_event_get_device(event);
276     const std::string mouseName = libinput_device_get_name(dev);
277     const int32_t devType = libinput_device_get_id_bustype(dev);
278     MMI_HILOGD("mouseName:%{public}s, devType:%{public}d", mouseName.c_str(), devType);
279     if (devType != BUS_USB && devType != BUS_BLUETOOTH) {
280         return;
281     }
282     std::string connectType = devType == BUS_USB ? "USB" : "BLUETOOTH";
283     MMI_HILOGD("connectType:%{public}s", connectType.c_str());
284     auto curMouseTimeMap = mouseMap.find(mouseName);
285     if (curMouseTimeMap == mouseMap.end()) {
286         MMI_HILOGD("start to collect");
287         mouseMap[mouseName] = std::chrono::steady_clock::now();
288         mouseResponseMap[mouseName] = {};
289     } else {
290         std::chrono::time_point<std::chrono::steady_clock> curTime = std::chrono::steady_clock::now();
291         long long gap =
292             std::chrono::duration_cast<std::chrono::milliseconds>(curTime - curMouseTimeMap->second).count();
293         mouseMap[mouseName] = curTime;
294         MMI_HILOGD("current time difference:%{public}lld", gap);
295         std::map<long long, int32_t> &curMap = mouseResponseMap.find(mouseName)->second;
296 
297         if (gap < FINE_CALCULATE) {
298             auto curMapIt = curMap.try_emplace(gap, 1);
299             if (!curMapIt.second) {
300                 curMapIt.first->second += 1;
301             }
302         } else if (gap >= FINE_CALCULATE && gap < STEP_CALCULATE) {
303             long long tempNum = gap - gap % CALCULATE_STEP;
304             auto curMapIt = curMap.try_emplace(tempNum, 1);
305             if (!curMapIt.second) {
306                 curMapIt.first->second += 1;
307             }
308         } else if (gap >= STEP_CALCULATE && gap < STOP_CALCULATE) {
309             auto curMapIt = curMap.try_emplace(STEP_CALCULATE, 1);
310             if (!curMapIt.second) {
311                 curMapIt.first->second += 1;
312             }
313         } else if (gap > STOP_CALCULATE) {
314             HandleReportMouseResponseTime(connectType, curMap);
315             mouseResponseMap.erase(mouseName);
316             mouseMap.erase(mouseName);
317         }
318     }
319 }
320 
HandleReportMouseResponseTime(std::string & connectType,std::map<long long,int32_t> & curMap)321 void MouseTransformProcessor::HandleReportMouseResponseTime(
322     std::string &connectType, std::map<long long, int32_t> &curMap)
323 {
324     MMI_HILOGD("Start to report");
325     long total = 0;
326     for (const auto &[key, value] : curMap) {
327         total += value;
328     }
329     MMI_HILOGD("Total mouse movements: %{public}ld", total);
330     int32_t ret = HiSysEventWrite(
331         OHOS::HiviewDFX::HiSysEvent::Domain::MULTI_MODAL_INPUT,
332         "COLLECT_MOUSE_RESPONSE_TIME",
333         OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC,
334         "MOUSE_CONNECT_TYPE", connectType,
335         "MOVING_TOTAL", total,
336         "1ms", curMap.find(1)->second / total,
337         "2ms", curMap.find(2)->second / total,
338         "3ms", curMap.find(3)->second / total,
339         "4ms", curMap.find(4)->second / total,
340         "5ms", curMap.find(5)->second / total,
341         "6ms", curMap.find(6)->second / total,
342         "7ms", curMap.find(7)->second / total,
343         "8ms", curMap.find(8)->second / total,
344         "9ms", curMap.find(9)->second / total,
345         "10ms", curMap.find(10)->second / total,
346         "11ms", curMap.find(11)->second / total,
347         "12ms", curMap.find(12)->second / total,
348         "13ms", curMap.find(13)->second / total,
349         "14ms", curMap.find(14)->second / total,
350         "15ms", curMap.find(15)->second / total,
351         "16ms", curMap.find(16)->second / total,
352         "17ms", curMap.find(17)->second / total,
353         "18ms", curMap.find(18)->second / total,
354         "19ms", curMap.find(19)->second / total,
355         "20ms", curMap.find(FINE_CALCULATE)->second / total,
356         "25ms", curMap.find(25)->second / total,
357         "30ms", curMap.find(30)->second / total,
358         "35ms", curMap.find(35)->second / total,
359         "40ms", curMap.find(STEP_CALCULATE)->second / total,
360         "MSG", "collectiong mouse response time probability");
361     if (ret != RET_OK) {
362         MMI_HILOGE("Mouse write failed , ret:%{public}d", ret);
363     }
364     MMI_HILOGD("Mouse write end , ret:%{public}d", ret);
365 }
366 
CalculateOffset(const DisplayInfo * displayInfo,Offset & offset)367 void MouseTransformProcessor::CalculateOffset(const DisplayInfo* displayInfo, Offset &offset)
368 {
369 #ifndef OHOS_BUILD_EMULATOR
370     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
371         Direction direction = static_cast<Direction>((
372             ((displayInfo->direction - displayInfo->displayDirection) * ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
373 #ifdef OHOS_BUILD_ENABLE_HARDWARE_CURSOR
374         if (WIN_MGR->IsSupported()) {
375             direction = displayInfo->direction;
376         }
377 #endif // OHOS_BUILD_ENABLE_HARDWARE_CURSOR
378         std::negate<double> neg;
379         if (direction == DIRECTION90) {
380             double tmp = offset.dx;
381             offset.dx = offset.dy;
382             offset.dy = neg(tmp);
383         } else if (direction == DIRECTION180) {
384             offset.dx = neg(offset.dx);
385             offset.dy = neg(offset.dy);
386         } else if (direction == DIRECTION270) {
387             double tmp = offset.dx;
388             offset.dx = neg(offset.dy);
389             offset.dy = tmp;
390         }
391     }
392 #endif // OHOS_BUILD_EMULATOR
393 }
394 
HandleButtonInner(struct libinput_event_pointer * data,struct libinput_event * event)395 int32_t MouseTransformProcessor::HandleButtonInner(struct libinput_event_pointer* data, struct libinput_event* event)
396 {
397     CALL_DEBUG_ENTER;
398     CHKPR(data, ERROR_NULL_POINTER);
399     CHKPR(event, ERROR_NULL_POINTER);
400     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
401 #ifndef OHOS_BUILD_ENABLE_WATCH
402     MMI_HILOGD("Current action:%{public}d", pointerEvent_->GetPointerAction());
403 
404     uint32_t button = libinput_event_pointer_get_button(data);
405     uint32_t originButton = button;
406     const int32_t type = libinput_event_get_type(event);
407     bool tpTapSwitch = true;
408     GetTouchpadTapSwitch(tpTapSwitch);
409 
410     // touch pad tap switch is disable
411     if (type == LIBINPUT_EVENT_POINTER_TAP && !tpTapSwitch) {
412         MMI_HILOGD("Touch pad is disable");
413         return RET_ERR;
414     }
415     PointerEvent::PointerItem pointerItem;
416     auto isItemExist = pointerEvent_->GetPointerItem(pointerEvent_->GetPointerId(), pointerItem);
417     if (isItemExist) {
418         pointerItem.SetCanceled(false);
419         pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
420     }
421     auto state = libinput_event_pointer_get_button_state(data);
422     HandleTouchPadButton(state, type);
423 
424     TransTouchpadRightButton(data, type, button);
425 
426     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_MIDDLE_BUTTON_CODE &&
427         type == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
428         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
429     }
430 
431     auto ret = HandleButtonValueInner(data, button, type);
432     if (ret != RET_OK) {
433         MMI_HILOGE("The button value does not exist");
434         return RET_ERR;
435     }
436 
437     if (state == LIBINPUT_BUTTON_STATE_RELEASED) {
438         int32_t switchTypeData = RIGHT_CLICK_TYPE_MIN;
439         GetTouchpadRightClickType(switchTypeData);
440         RightClickType switchType = RightClickType(switchTypeData);
441         if (type == LIBINPUT_EVENT_POINTER_TAP && switchType == RightClickType::TP_TWO_FINGER_TAP &&
442             button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE) {
443             MMI_HILOGI("Right click up, do sleep");
444             std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME_FOR_BUTTON_UP));
445         }
446         MouseState->MouseBtnStateCounts(button, BUTTON_STATE_RELEASED);
447         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP);
448         int32_t buttonId = MouseState->LibinputChangeToPointer(button);
449         pointerEvent_->DeleteReleaseButton(buttonId);
450         DeletePressedButton(originButton);
451         isPressed_ = false;
452         buttonId_ = PointerEvent::BUTTON_NONE;
453     } else if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
454         MouseState->MouseBtnStateCounts(button, BUTTON_STATE_PRESSED);
455         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN);
456         int32_t buttonId = MouseState->LibinputChangeToPointer(button);
457         pointerEvent_->SetButtonPressed(buttonId);
458         buttonMapping_[originButton] = buttonId;
459         isPressed_ = true;
460         buttonId_ = pointerEvent_->GetButtonId();
461         CursorPosition cursorPos = WIN_MGR->GetCursorPos();
462         if (cursorPos.displayId < 0) {
463             MMI_HILOGE("No display");
464             return RET_ERR;
465         }
466         auto displayInfo = WIN_MGR->GetPhysicalDisplay(cursorPos.displayId);
467         CHKPR(displayInfo, ERROR_NULL_POINTER);
468         if (cursorPos.direction != displayInfo->direction) {
469             WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y);
470         }
471     } else {
472         MMI_HILOGE("Unknown state, state:%{public}u", state);
473         return RET_ERR;
474     }
475 #endif // OHOS_BUILD_ENABLE_WATCH
476     return RET_OK;
477 }
478 
HandleTouchPadButton(enum libinput_button_state state,int32_t type)479 void MouseTransformProcessor::HandleTouchPadButton(enum libinput_button_state state, int32_t type)
480 {
481     if (state != LIBINPUT_BUTTON_STATE_PRESSED) {
482         return;
483     }
484     if (type != LIBINPUT_EVENT_POINTER_TAP && type != LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
485         return;
486     }
487     CHKPV(pointerEvent_);
488     auto pressedButtons = pointerEvent_->GetPressedButtons();
489     if (pressedButtons.empty()) {
490         return;
491     }
492     MMI_HILOGW("touchpad button residue size:%{public}zu", pressedButtons.size());
493     for (auto it = pressedButtons.begin(); it != pressedButtons.end(); it++) {
494         MMI_HILOGW("touchpad button residue id:%{public}d", *it);
495     }
496     std::shared_ptr<PointerEvent> cancelPointerEvent = std::make_shared<PointerEvent>(*pointerEvent_);
497     pointerEvent_->ClearButtonPressed();
498     CHKPV(cancelPointerEvent);
499     cancelPointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
500     WIN_MGR->UpdateTargetPointer(cancelPointerEvent);
501     auto eventDispatchHandler = InputHandler->GetEventDispatchHandler();
502     CHKPV(eventDispatchHandler);
503     eventDispatchHandler->HandlePointerEvent(cancelPointerEvent);
504 }
505 
DeletePressedButton(uint32_t originButton)506 void MouseTransformProcessor::DeletePressedButton(uint32_t originButton)
507 {
508     auto iter = buttonMapping_.find(originButton);
509     if (iter != buttonMapping_.end()) {
510         pointerEvent_->DeleteReleaseButton(iter->second);
511         buttonMapping_.erase(iter);
512     }
513 }
514 
HandleButtonValueInner(struct libinput_event_pointer * data,uint32_t & button,int32_t type)515 int32_t MouseTransformProcessor::HandleButtonValueInner(struct libinput_event_pointer *data, uint32_t& button,
516     int32_t type)
517 {
518     CALL_DEBUG_ENTER;
519     CHKPR(data, ERROR_NULL_POINTER);
520     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
521     int32_t buttonId = MouseState->LibinputChangeToPointer(button);
522     if (buttonId == PointerEvent::BUTTON_NONE) {
523         MMI_HILOGE("Unknown btn, btn:%{public}u", button);
524         return RET_ERR;
525     }
526 
527     std::string name = "primaryButton";
528     int32_t primaryButton = PREFERENCES_MGR->GetIntValue(name, 0);
529     MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
530     if (type == LIBINPUT_EVENT_POINTER_BUTTON && primaryButton == RIGHT_BUTTON) {
531         if (buttonId == PointerEvent::MOUSE_BUTTON_LEFT) {
532             buttonId = PointerEvent::MOUSE_BUTTON_RIGHT;
533             button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE;
534         } else if (buttonId == PointerEvent::MOUSE_BUTTON_RIGHT) {
535             buttonId = PointerEvent::MOUSE_BUTTON_LEFT;
536             button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
537         } else {
538             MMI_HILOGD("The buttonId does not switch");
539         }
540     }
541 
542     pointerEvent_->SetButtonId(buttonId);
543     return RET_OK;
544 }
545 
SetMouseScrollRows(int32_t rows)546 int32_t MouseTransformProcessor::SetMouseScrollRows(int32_t rows)
547 {
548     CALL_DEBUG_ENTER;
549     if (rows < MIN_ROWS) {
550         rows = MIN_ROWS;
551     } else if (rows > MAX_ROWS) {
552         rows = MAX_ROWS;
553     }
554     std::string name = "rows";
555     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, rows);
556     MMI_HILOGD("Set mouse scroll rows successfully, rows:%{public}d", rows);
557     return ret;
558 }
559 
GetMouseScrollRows()560 int32_t MouseTransformProcessor::GetMouseScrollRows()
561 {
562     CALL_DEBUG_ENTER;
563     std::string name = "rows";
564     int32_t rows = PREFERENCES_MGR->GetIntValue(name, DEFAULT_ROWS);
565     MMI_HILOGD("Get mouse scroll rows successfully, rows:%{public}d", rows);
566     return rows;
567 }
568 
HandleTouchPadAxisState(libinput_pointer_axis_source source,int32_t & direction,bool & tpScrollSwitch)569 void MouseTransformProcessor::HandleTouchPadAxisState(libinput_pointer_axis_source source,
570     int32_t& direction, bool& tpScrollSwitch)
571 {
572     bool scrollDirectionState = true;
573     GetTouchpadScrollSwitch(tpScrollSwitch);
574     GetTouchpadScrollDirection(scrollDirectionState);
575     if (scrollDirectionState == true && source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
576         direction = -1;
577     }
578 }
579 
HandleAxisInner(struct libinput_event_pointer * data)580 int32_t MouseTransformProcessor::HandleAxisInner(struct libinput_event_pointer* data)
581 {
582     CALL_DEBUG_ENTER;
583     CHKPR(data, ERROR_NULL_POINTER);
584     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
585 
586     bool tpScrollSwitch = true;
587     int32_t tpScrollDirection = 1;
588 
589     libinput_pointer_axis_source source = libinput_event_pointer_get_axis_source(data);
590     HandleTouchPadAxisState(source, tpScrollDirection, tpScrollSwitch);
591     if (!tpScrollSwitch && source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
592         MMI_HILOGE("TouchPad axis event is disable,pid:%{public}d Set false", scrollSwitchPid_);
593         return RET_ERR;
594     }
595 
596     if (buttonId_ == PointerEvent::BUTTON_NONE && pointerEvent_->GetButtonId() != PointerEvent::BUTTON_NONE) {
597         pointerEvent_->SetButtonId(PointerEvent::BUTTON_NONE);
598     }
599     if (libinput_event_pointer_get_axis_source(data) == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
600         MMI_HILOGD("Libinput event axis source type is finger");
601         MMI_HILOGD("Axis event type is update");
602         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_UPDATE);
603         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
604     } else {
605         if (TimerMgr->IsExist(timerId_)) {
606             pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_UPDATE);
607             pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
608             TimerMgr->ResetTimer(timerId_);
609             MMI_HILOGD("Axis update");
610         } else {
611             static constexpr int32_t timeout = 100;
612             std::weak_ptr<MouseTransformProcessor> weakPtr = shared_from_this();
613             timerId_ = TimerMgr->AddTimer(timeout, 1, [weakPtr]() {
614                 CALL_DEBUG_ENTER;
615                 auto sharedPtr = weakPtr.lock();
616                 CHKPV(sharedPtr);
617                 MMI_HILOGD("Timer:%{public}d", sharedPtr->timerId_);
618                 sharedPtr->timerId_ = -1;
619                 auto pointerEvent = sharedPtr->GetPointerEvent();
620                 CHKPV(pointerEvent);
621                 pointerEvent->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
622                 pointerEvent->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
623                 pointerEvent->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL, 0);
624                 pointerEvent->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL, 0);
625                 pointerEvent->UpdateId();
626                 LogTracer lt(pointerEvent->GetId(), pointerEvent->GetEventType(), pointerEvent->GetPointerAction());
627                 auto inputEventNormalizeHandler = InputHandler->GetEventNormalizeHandler();
628                 CHKPV(inputEventNormalizeHandler);
629                 inputEventNormalizeHandler->HandlePointerEvent(pointerEvent);
630             });
631 
632             pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_BEGIN);
633             pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
634             MMI_HILOGD("Axis begin");
635             CursorPosition cursorPos = WIN_MGR->GetCursorPos();
636             if (cursorPos.displayId < 0) {
637                 MMI_HILOGE("No display");
638                 return RET_ERR;
639             }
640             auto displayInfo = WIN_MGR->GetPhysicalDisplay(cursorPos.displayId);
641             CHKPR(displayInfo, ERROR_NULL_POINTER);
642             if (cursorPos.direction != displayInfo->direction) {
643                 WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId,
644                     cursorPos.cursorPos.x, cursorPos.cursorPos.y);
645             }
646         }
647     }
648 #ifndef OHOS_BUILD_ENABLE_WATCH
649     if (source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
650         pointerEvent_->SetScrollRows(TouchPadTransformProcessor::GetTouchpadScrollRows());
651     } else {
652         pointerEvent_->SetScrollRows(MouseTransformProcessor::GetMouseScrollRows());
653     }
654 #else
655     pointerEvent_->SetScrollRows(MouseTransformProcessor::GetMouseScrollRows());
656 #endif // OHOS_BUILD_ENABLE_WATCH
657     const int32_t initRows = 3;
658     if (libinput_event_pointer_has_axis(data, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
659         double axisValue = libinput_event_pointer_get_axis_value(data, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
660 #ifndef OHOS_BUILD_ENABLE_WATCH
661         if (source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
662             axisValue = TouchPadTransformProcessor::GetTouchpadScrollRows() * (axisValue / initRows);
663             axisValue = HandleAxisAccelateTouchPad(axisValue) * tpScrollDirection;
664         } else {
665             axisValue = GetMouseScrollRows() * axisValue * tpScrollDirection;
666         }
667 #else
668         axisValue = GetMouseScrollRows() * axisValue * tpScrollDirection;
669 #endif // OHOS_BUILD_ENABLE_WATCH
670         pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_VERTICAL, axisValue);
671     }
672     if (libinput_event_pointer_has_axis(data, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
673         double axisValue = libinput_event_pointer_get_axis_value(data, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
674 #ifndef OHOS_BUILD_ENABLE_WATCH
675         if (source == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
676             axisValue = TouchPadTransformProcessor::GetTouchpadScrollRows() * (axisValue / initRows);
677             axisValue = HandleAxisAccelateTouchPad(axisValue) * tpScrollDirection;
678         } else {
679             axisValue = GetMouseScrollRows() * axisValue * tpScrollDirection;
680         }
681 #else
682         axisValue = GetMouseScrollRows() * axisValue * tpScrollDirection;
683 #endif // OHOS_BUILD_ENABLE_WATCH
684         pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL, axisValue);
685     }
686     return RET_OK;
687 }
688 
689 #ifndef OHOS_BUILD_ENABLE_WATCH
HandleAxisAccelateTouchPad(double axisValue)690 double MouseTransformProcessor::HandleAxisAccelateTouchPad(double axisValue)
691 {
692     const int32_t initRows = 3;
693     DeviceType deviceType = DeviceType::DEVICE_PC;
694     if (deviceTypeGlobal_ == DeviceType::DEVICE_FOLD_PC_VIRT) {
695         deviceType = DeviceType::DEVICE_FOLD_PC_VIRT;
696         double speedAdjustCoef = 1.0;
697         axisValue = axisValue * speedAdjustCoef;
698     } else {
699         if (PRODUCT_TYPE == DEVICE_TYPE_PC_PRO) {
700             deviceType = DeviceType::DEVICE_SOFT_PC_PRO;
701         }
702         if (PRODUCT_TYPE == DEVICE_TYPE_TABLET) {
703             deviceType = DeviceType::DEVICE_TABLET;
704         }
705         if (PRODUCT_TYPE == DEVICE_TYPE_FOLD_PC) {
706             deviceType = DeviceType::DEVICE_FOLD_PC;
707         }
708     }
709     int32_t ret =
710         HandleAxisAccelerateTouchpad(WIN_MGR->GetMouseIsCaptureMode(), &axisValue, static_cast<int32_t>(deviceType));
711     if (ret != RET_OK) {
712         MMI_HILOGW("Fail accelerate axis");
713         axisValue = TouchPadTransformProcessor::GetTouchpadScrollRows() * (axisValue / initRows);
714     }
715     return axisValue;
716 }
717 #endif // OHOS_BUILD_ENABLE_WATCH
718 
HandleAxisBeginEndInner(struct libinput_event * event)719 int32_t MouseTransformProcessor::HandleAxisBeginEndInner(struct libinput_event *event)
720 {
721     CALL_DEBUG_ENTER;
722     CHKPR(event, ERROR_NULL_POINTER);
723     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
724     if (buttonId_ == PointerEvent::BUTTON_NONE && pointerEvent_->GetButtonId() != PointerEvent::BUTTON_NONE) {
725         pointerEvent_->SetButtonId(PointerEvent::BUTTON_NONE);
726     }
727     if (!isAxisBegin_ && isPressed_) {
728         MMI_HILOGE("Axis is invalid");
729         return RET_ERR;
730     }
731     if (isAxisBegin_ && isPressed_) {
732         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
733         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
734         isAxisBegin_ = false;
735         MMI_HILOGD("Axis end due to a pressed event");
736         return RET_OK;
737     }
738     if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCHPAD_DOWN && !isPressed_) {
739         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_BEGIN);
740         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
741         isAxisBegin_ = true;
742         MMI_HILOGD("Axis begin");
743         return RET_OK;
744     }
745     if (libinput_event_get_type(event) == LIBINPUT_EVENT_TOUCHPAD_UP && !isPressed_) {
746         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
747         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
748         isAxisBegin_ = false;
749         MMI_HILOGD("Axis end");
750         return RET_OK;
751     }
752     MMI_HILOGE("Axis is invalid");
753     return RET_ERR;
754 }
755 
HandleScrollFingerInner(struct libinput_event * event)756 int32_t MouseTransformProcessor::HandleScrollFingerInner(struct libinput_event *event)
757 {
758     CALL_DEBUG_ENTER;
759     CHKPR(event, ERROR_NULL_POINTER);
760     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
761     if (buttonId_ == PointerEvent::BUTTON_NONE && pointerEvent_->GetButtonId() != PointerEvent::BUTTON_NONE) {
762         pointerEvent_->SetButtonId(PointerEvent::BUTTON_NONE);
763     }
764     if (libinput_event_get_type(event) == LIBINPUT_EVENT_POINTER_SCROLL_FINGER_BEGIN) {
765         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_BEGIN);
766         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
767         MMI_HILOGD("Axis begin");
768     } else if (libinput_event_get_type(event) == LIBINPUT_EVENT_POINTER_SCROLL_FINGER_END) {
769         pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
770         pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_SCROLL);
771         MMI_HILOGD("Axis end");
772     } else {
773         MMI_HILOGE("Axis is invalid");
774         return RET_ERR;
775     }
776     return RET_OK;
777 }
778 
HandleAxisPostInner(PointerEvent::PointerItem & pointerItem)779 void MouseTransformProcessor::HandleAxisPostInner(PointerEvent::PointerItem &pointerItem)
780 {
781     CALL_DEBUG_ENTER;
782     CHKPV(pointerEvent_);
783     auto mouseInfo = WIN_MGR->GetMouseInfo();
784     MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
785     pointerItem.SetDisplayX(mouseInfo.physicalX);
786     pointerItem.SetDisplayY(mouseInfo.physicalY);
787     pointerItem.SetWindowX(0);
788     pointerItem.SetWindowY(0);
789     pointerItem.SetPointerId(0);
790     pointerItem.SetPressed(isPressed_);
791     int64_t time = GetSysClockTime();
792     pointerItem.SetDownTime(time);
793     pointerItem.SetWidth(0);
794     pointerItem.SetHeight(0);
795     pointerItem.SetPressure(0);
796     pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
797     pointerItem.SetDeviceId(deviceId_);
798     pointerItem.SetRawDx(0);
799     pointerItem.SetRawDy(0);
800     pointerEvent_->UpdateId();
801     StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
802     pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
803     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
804     pointerEvent_->SetActionTime(time);
805     pointerEvent_->SetActionStartTime(time);
806     pointerEvent_->SetPointerId(0);
807     pointerEvent_->SetDeviceId(deviceId_);
808     pointerEvent_->SetTargetDisplayId(mouseInfo.displayId);
809     pointerEvent_->SetTargetWindowId(-1);
810     pointerEvent_->SetAgentWindowId(-1);
811 }
812 
HandlePostInner(struct libinput_event_pointer * data,PointerEvent::PointerItem & pointerItem)813 bool MouseTransformProcessor::HandlePostInner(struct libinput_event_pointer* data,
814     PointerEvent::PointerItem &pointerItem)
815 {
816     CALL_DEBUG_ENTER;
817     CHKPF(pointerEvent_);
818     auto mouseInfo = WIN_MGR->GetMouseInfo();
819     MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
820     pointerItem.SetDisplayX(mouseInfo.physicalX);
821     pointerItem.SetDisplayY(mouseInfo.physicalY);
822     pointerItem.SetWindowX(0);
823     pointerItem.SetWindowY(0);
824     pointerItem.SetPointerId(0);
825     pointerItem.SetPressed(isPressed_);
826 
827     int64_t time = GetSysClockTime();
828     pointerItem.SetDownTime(time);
829     pointerItem.SetWidth(0);
830     pointerItem.SetHeight(0);
831     pointerItem.SetPressure(0);
832     pointerItem.SetDeviceId(deviceId_);
833     if (pointerEvent_->GetPointerAction() == PointerEvent::POINTER_ACTION_BUTTON_UP) {
834         pointerItem.SetRawDx(0);
835         pointerItem.SetRawDy(0);
836     } else {
837         pointerItem.SetRawDx(static_cast<int32_t>(unaccelerated_.dx));
838         pointerItem.SetRawDy(static_cast<int32_t>(unaccelerated_.dy));
839     }
840 
841     pointerEvent_->UpdateId();
842     StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
843     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
844     pointerEvent_->SetActionTime(time);
845     pointerEvent_->SetActionStartTime(time);
846     pointerEvent_->SetDeviceId(deviceId_);
847     pointerEvent_->SetPointerId(0);
848     pointerEvent_->SetTargetDisplayId(mouseInfo.displayId);
849     pointerEvent_->SetTargetWindowId(-1);
850     pointerEvent_->SetAgentWindowId(-1);
851     if (data == nullptr) {
852         pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
853         return false;
854     }
855     if (libinput_event_pointer_get_axis_source(data) == LIBINPUT_POINTER_AXIS_SOURCE_FINGER) {
856         pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
857         MMI_HILOGD("ToolType is touchpad");
858     } else {
859         pointerItem.SetToolType(PointerEvent::TOOL_TYPE_MOUSE);
860     }
861     pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
862     return true;
863 }
864 
CheckAndPackageAxisEvent()865 bool MouseTransformProcessor::CheckAndPackageAxisEvent()
866 {
867     CALL_INFO_TRACE;
868     if (!isAxisBegin_) {
869         return false;
870     }
871     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_AXIS_END);
872     isAxisBegin_ = false;
873     PointerEvent::PointerItem item;
874     HandleAxisPostInner(item);
875     WIN_MGR->UpdateTargetPointer(pointerEvent_);
876     return true;
877 }
878 
Normalize(struct libinput_event * event)879 int32_t MouseTransformProcessor::Normalize(struct libinput_event *event)
880 {
881     CALL_DEBUG_ENTER;
882     CHKPR(event, ERROR_NULL_POINTER);
883     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
884     const int32_t type = libinput_event_get_type(event);
885     auto data = libinput_event_get_pointer_event(event);
886     if (type != LIBINPUT_EVENT_TOUCHPAD_DOWN && type != LIBINPUT_EVENT_TOUCHPAD_UP) {
887         CHKPR(data, ERROR_NULL_POINTER);
888     }
889     pointerEvent_->ClearAxisValue();
890     int32_t result;
891     switch (type) {
892         case LIBINPUT_EVENT_POINTER_MOTION:
893         case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
894         case LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD:
895             result = HandleMotionInner(data, event);
896             break;
897         case LIBINPUT_EVENT_POINTER_TAP:
898         case LIBINPUT_EVENT_POINTER_BUTTON:
899         case LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD:
900             result = HandleButtonInner(data, event);
901             break;
902         case LIBINPUT_EVENT_POINTER_AXIS:
903             result = HandleAxisInner(data);
904             break;
905         case LIBINPUT_EVENT_POINTER_SCROLL_FINGER_BEGIN:
906         case LIBINPUT_EVENT_POINTER_SCROLL_FINGER_END:
907             result = HandleScrollFingerInner(event);
908             break;
909         default:
910             MMI_HILOGE("Unknown type:%{public}d", type);
911             return RET_ERR;
912     }
913     if (result == RET_ERR) {
914         return result;
915     }
916     PointerEvent::PointerItem pointerItem;
917     pointerEvent_->GetPointerItem(pointerEvent_->GetPointerId(), pointerItem);
918     if (type == LIBINPUT_EVENT_POINTER_MOTION_TOUCHPAD) {
919         pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
920     } else if (type == LIBINPUT_EVENT_POINTER_MOTION || type == LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE) {
921         pointerItem.SetToolType(PointerEvent::TOOL_TYPE_MOUSE);
922     }
923     if (type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER_BEGIN || type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER_END) {
924         HandleAxisPostInner(pointerItem);
925     } else if (!HandlePostInner(data, pointerItem)) {
926         CHKPL(pointerEvent_);
927         return RET_ERR;
928     }
929     WIN_MGR->UpdateTargetPointer(pointerEvent_);
930     DumpInner();
931     return result;
932 }
933 
NormalizeRotateEvent(struct libinput_event * event,int32_t type,double angle)934 int32_t MouseTransformProcessor::NormalizeRotateEvent(struct libinput_event *event, int32_t type, double angle)
935 {
936     CALL_DEBUG_ENTER;
937     CHKPR(event, ERROR_NULL_POINTER);
938     CHKPR(pointerEvent_, ERROR_NULL_POINTER);
939     auto data = libinput_event_get_pointer_event(event);
940     pointerEvent_->SetPointerAction(type);
941     pointerEvent_->ClearAxisValue();
942     pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_ROTATE, angle);
943     PointerEvent::PointerItem pointerItem;
944     pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
945     if (!HandlePostInner(data, pointerItem)) {
946         WIN_MGR->UpdateTargetPointer(pointerEvent_);
947         DumpInner();
948         return ERROR_NULL_POINTER;
949     }
950     WIN_MGR->UpdateTargetPointer(pointerEvent_);
951     DumpInner();
952     return RET_OK;
953 }
954 
955 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
HandleMotionMoveMouse(int32_t offsetX,int32_t offsetY)956 void MouseTransformProcessor::HandleMotionMoveMouse(int32_t offsetX, int32_t offsetY)
957 {
958     CALL_DEBUG_ENTER;
959     CHKPV(pointerEvent_);
960     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
961     CursorPosition cursorPos = WIN_MGR->GetCursorPos();
962     cursorPos.cursorPos.x += offsetX;
963     cursorPos.cursorPos.y += offsetY;
964     WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y);
965 }
966 
OnDisplayLost(int32_t displayId)967 void MouseTransformProcessor::OnDisplayLost(int32_t displayId)
968 {
969     CursorPosition cursorPos = WIN_MGR->GetCursorPos();
970     if (cursorPos.displayId != displayId) {
971         cursorPos = WIN_MGR->ResetCursorPos();
972         WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y);
973     }
974 }
975 
GetDisplayId()976 int32_t MouseTransformProcessor::GetDisplayId()
977 {
978     return WIN_MGR->GetCursorPos().displayId;
979 }
980 
HandlePostMoveMouse(PointerEvent::PointerItem & pointerItem)981 void MouseTransformProcessor::HandlePostMoveMouse(PointerEvent::PointerItem& pointerItem)
982 {
983     CALL_DEBUG_ENTER;
984     auto mouseInfo = WIN_MGR->GetMouseInfo();
985     CHKPV(pointerEvent_);
986     MouseState->SetMouseCoords(mouseInfo.physicalX, mouseInfo.physicalY);
987     pointerItem.SetDisplayX(mouseInfo.physicalX);
988     pointerItem.SetDisplayY(mouseInfo.physicalY);
989     pointerItem.SetWindowX(0);
990     pointerItem.SetWindowY(0);
991     pointerItem.SetPointerId(0);
992     pointerItem.SetPressed(isPressed_);
993 
994     int64_t time = GetSysClockTime();
995     pointerItem.SetDownTime(time);
996     pointerItem.SetWidth(0);
997     pointerItem.SetHeight(0);
998     pointerItem.SetPressure(0);
999 
1000     pointerEvent_->UpdateId();
1001     StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
1002     pointerEvent_->UpdatePointerItem(pointerEvent_->GetPointerId(), pointerItem);
1003     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
1004     pointerEvent_->SetActionTime(time);
1005     pointerEvent_->SetActionStartTime(time);
1006 
1007     pointerEvent_->SetPointerId(0);
1008     pointerEvent_->SetTargetDisplayId(-1);
1009     pointerEvent_->SetTargetWindowId(-1);
1010     pointerEvent_->SetAgentWindowId(-1);
1011 }
1012 
NormalizeMoveMouse(int32_t offsetX,int32_t offsetY)1013 bool MouseTransformProcessor::NormalizeMoveMouse(int32_t offsetX, int32_t offsetY)
1014 {
1015     CALL_DEBUG_ENTER;
1016     CHKPF(pointerEvent_);
1017     bool bHasPointerDevice = INPUT_DEV_MGR->HasPointerDevice();
1018     if (!bHasPointerDevice) {
1019         MMI_HILOGE("There hasn't any pointer device");
1020         return false;
1021     }
1022 
1023     PointerEvent::PointerItem pointerItem;
1024     HandleMotionMoveMouse(offsetX, offsetY);
1025     HandlePostMoveMouse(pointerItem);
1026     DumpInner();
1027     return bHasPointerDevice;
1028 }
1029 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
1030 
DumpInner()1031 void MouseTransformProcessor::DumpInner()
1032 {
1033     static int32_t lastDeviceId = -1;
1034     static std::string lastDeviceName("default");
1035     auto nowId = pointerEvent_->GetDeviceId();
1036     if (lastDeviceId != nowId) {
1037         auto device = INPUT_DEV_MGR->GetInputDevice(nowId);
1038         CHKPV(device);
1039         lastDeviceId = nowId;
1040         lastDeviceName = device->GetName();
1041     }
1042     EventLogHelper::PrintEventData(pointerEvent_, MMI_LOG_FREEZE);
1043     aggregator_.Record(MMI_LOG_FREEZE, lastDeviceName + ", TW: " +
1044         std::to_string(pointerEvent_->GetTargetWindowId()), std::to_string(pointerEvent_->GetId()));
1045 }
1046 
CheckDeviceType(int32_t width,int32_t height)1047 DeviceType MouseTransformProcessor::CheckDeviceType(int32_t width, int32_t height)
1048 {
1049     CALL_DEBUG_ENTER;
1050     DeviceType ret = DeviceType::DEVICE_PC;
1051     if (PRODUCT_TYPE == DEVICE_TYPE_PC_PRO) {
1052         if (width == HARD_PC_PRO_DEVICE_WIDTH && height == HARD_PC_PRO_DEVICE_HEIGHT) {
1053             ret = DeviceType::DEVICE_HARD_PC_PRO;
1054         } else if (width == SOFT_PC_PRO_DEVICE_WIDTH && height == SOFT_PC_PRO_DEVICE_HEIGHT) {
1055             ret = DeviceType::DEVICE_SOFT_PC_PRO;
1056         } else {
1057             MMI_HILOGD("Undefined width:%{public}d, height:%{public}d", width, height);
1058         }
1059         MMI_HILOGD("Device width:%{public}d, height:%{public}d", width, height);
1060     }
1061     if (PRODUCT_TYPE == DEVICE_TYPE_TABLET) {
1062         if (width == TABLET_DEVICE_WIDTH && height == TABLET_DEVICE_HEIGHT) {
1063             ret = DeviceType::DEVICE_TABLET;
1064         }
1065     }
1066     if (PRODUCT_TYPE == DEVICE_TYPE_FOLD_PC) {
1067         ret = DeviceType::DEVICE_FOLD_PC;
1068     }
1069     return ret;
1070 }
1071 
Dump(int32_t fd,const std::vector<std::string> & args)1072 void MouseTransformProcessor::Dump(int32_t fd, const std::vector<std::string> &args)
1073 {
1074     CALL_DEBUG_ENTER;
1075     PointerEvent::PointerItem item;
1076     CHKPV(pointerEvent_);
1077     pointerEvent_->GetPointerItem(pointerEvent_->GetPointerId(), item);
1078     mprintf(fd, "Mouse device state information:\t");
1079     mprintf(fd,
1080             "PointerId:%d | SourceType:%s | PointerAction:%s | WindowX:%d | WindowY:%d | ButtonId:%d "
1081             "| AgentWindowId:%d | TargetWindowId:%d | DownTime:%" PRId64 " | IsPressed:%s \t",
1082             pointerEvent_->GetPointerId(), pointerEvent_->DumpSourceType(), pointerEvent_->DumpPointerAction(),
1083             item.GetWindowX(), item.GetWindowY(), pointerEvent_->GetButtonId(), pointerEvent_->GetAgentWindowId(),
1084             pointerEvent_->GetTargetWindowId(), item.GetDownTime(), item.IsPressed() ? "true" : "false");
1085 }
1086 
SetMousePrimaryButton(int32_t primaryButton)1087 int32_t MouseTransformProcessor::SetMousePrimaryButton(int32_t primaryButton)
1088 {
1089     CALL_DEBUG_ENTER;
1090     MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
1091     std::string name = "primaryButton";
1092     PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, primaryButton);
1093     return RET_OK;
1094 }
1095 
GetMousePrimaryButton()1096 int32_t MouseTransformProcessor::GetMousePrimaryButton()
1097 {
1098     CALL_DEBUG_ENTER;
1099     std::string name = "primaryButton";
1100     int32_t primaryButton = PREFERENCES_MGR->GetIntValue(name, 0);
1101     MMI_HILOGD("Set mouse primary button:%{public}d", primaryButton);
1102     return primaryButton;
1103 }
1104 
SetPointerSpeed(int32_t speed)1105 int32_t MouseTransformProcessor::SetPointerSpeed(int32_t speed)
1106 {
1107     CALL_DEBUG_ENTER;
1108     if (speed < MIN_SPEED) {
1109         speed = MIN_SPEED;
1110     } else if (speed > MAX_SPEED) {
1111         speed = MAX_SPEED;
1112     }
1113     globalPointerSpeed_ = speed;
1114     std::string name = "speed";
1115     int32_t ret = PREFERENCES_MGR->SetIntValue(name, MOUSE_FILE_NAME, speed);
1116     MMI_HILOGD("Set pointer speed successfully, speed:%{public}d", speed);
1117     return ret;
1118 }
1119 
GetPointerSpeed()1120 int32_t MouseTransformProcessor::GetPointerSpeed()
1121 {
1122     std::string name = "speed";
1123     int32_t speed = PREFERENCES_MGR->GetIntValue(name, DEFAULT_SPEED);
1124     MMI_HILOGD("Pointer speed:%{public}d", speed);
1125     return speed;
1126 }
1127 
GetTouchpadSpeed()1128 int32_t MouseTransformProcessor::GetTouchpadSpeed()
1129 {
1130     int32_t speed = DEFAULT_TOUCHPAD_SPEED;
1131     GetTouchpadPointerSpeed(speed);
1132     MMI_HILOGD("TouchPad pointer speed:%{public}d", speed);
1133     return speed;
1134 }
1135 
SetPointerLocation(int32_t x,int32_t y,int32_t displayId)1136 int32_t MouseTransformProcessor::SetPointerLocation(int32_t x, int32_t y, int32_t displayId)
1137 {
1138     MMI_HILOGI("SetPointerLocation x:%d, y:%d, displayId:%d", x, y, displayId);
1139     CursorPosition cursorPos = WIN_MGR->GetCursorPos();
1140     if (cursorPos.displayId < 0) {
1141         MMI_HILOGE("No display");
1142         return RET_ERR;
1143     }
1144     cursorPos.cursorPos.x = x;
1145     cursorPos.cursorPos.y = y;
1146     if (displayId >= 0) {
1147         cursorPos.displayId = displayId;
1148     }
1149     WIN_MGR->UpdateAndAdjustMouseLocation(cursorPos.displayId, cursorPos.cursorPos.x, cursorPos.cursorPos.y, false);
1150     cursorPos = WIN_MGR->GetCursorPos();
1151     IPointerDrawingManager::GetInstance()->SetPointerLocation(cursorPos.cursorPos.x, cursorPos.cursorPos.y,
1152         cursorPos.displayId);
1153     MMI_HILOGI("CursorPosX:%f, cursorPosY:%f", cursorPos.cursorPos.x, cursorPos.cursorPos.y);
1154     return RET_OK;
1155 }
1156 
1157 #ifndef OHOS_BUILD_ENABLE_WATCH
HandleTouchpadRightButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)1158 void MouseTransformProcessor::HandleTouchpadRightButton(struct libinput_event_pointer *data, const int32_t evenType,
1159     uint32_t &button)
1160 {
1161     // touchpad left click 280 -> 272
1162     if (button == BTN_RIGHT_MENUE_CODE) {
1163         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
1164         return;
1165     }
1166 
1167     // touchpad two finger tap 273 -> 0
1168     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
1169         evenType == LIBINPUT_EVENT_POINTER_TAP) {
1170         button = 0;
1171         return;
1172     }
1173 
1174     // touchpad two finger button 272 -> 0
1175     uint32_t buttonArea = libinput_event_pointer_get_button_area(data);
1176     if (buttonArea == BTN_RIGHT) {
1177         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE;
1178     } else {
1179         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
1180     }
1181 }
1182 
HandleTouchpadLeftButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)1183 void MouseTransformProcessor::HandleTouchpadLeftButton(struct libinput_event_pointer *data, const int32_t evenType,
1184     uint32_t &button)
1185 {
1186     // touchpad left click 280 -> 273
1187     if (button == BTN_RIGHT_MENUE_CODE) {
1188         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE;
1189         return;
1190     }
1191 
1192     // touchpad right click 273 -> 272
1193     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
1194         evenType != LIBINPUT_EVENT_POINTER_TAP) {
1195         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
1196         return;
1197     }
1198 
1199     // touchpad two finger tap 273 -> 0
1200     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
1201         evenType == LIBINPUT_EVENT_POINTER_TAP) {
1202         button = 0;
1203         return;
1204     }
1205 
1206     // touchpad two finger button 272 -> 273
1207     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE &&
1208         evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
1209         uint32_t fingerCount = libinput_event_pointer_get_finger_count(data);
1210         uint32_t buttonArea = libinput_event_pointer_get_button_area(data);
1211         if (buttonArea == BTN_RIGHT_MENUE_CODE && fingerCount == TP_RIGHT_CLICK_FINGER_CNT) {
1212             button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE;
1213         }
1214         return;
1215     }
1216 }
1217 
HandleTouchpadTwoFingerButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)1218 void MouseTransformProcessor::HandleTouchpadTwoFingerButton(struct libinput_event_pointer *data, const int32_t evenType,
1219     uint32_t &button)
1220 {
1221     // touchpad two finger button -> 273
1222     uint32_t fingerCount = libinput_event_pointer_get_finger_count(data);
1223     if (fingerCount == TP_RIGHT_CLICK_FINGER_CNT) {
1224         if (button == BTN_RIGHT_MENUE_CODE) {
1225             button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
1226         }
1227         return;
1228     }
1229 
1230     // touchpad right click 273 -> 272
1231     if (button == MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_RIGHT_BUTTON_CODE &&
1232         evenType == LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
1233         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
1234         return;
1235     }
1236 
1237     // touchpad left click 280 -> 272
1238     if (button == BTN_RIGHT_MENUE_CODE) {
1239         button = MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE;
1240         return;
1241     }
1242 }
1243 
TransTouchpadRightButton(struct libinput_event_pointer * data,const int32_t evenType,uint32_t & button)1244 void MouseTransformProcessor::TransTouchpadRightButton(struct libinput_event_pointer *data, const int32_t evenType,
1245     uint32_t &button)
1246 {
1247     int32_t switchTypeData = RIGHT_CLICK_TYPE_MIN;
1248     GetTouchpadRightClickType(switchTypeData);
1249 
1250     RightClickType switchType = RightClickType(switchTypeData);
1251     if (evenType != LIBINPUT_EVENT_POINTER_TAP && evenType != LIBINPUT_EVENT_POINTER_BUTTON_TOUCHPAD) {
1252         MMI_HILOGD("Event not from touchpad");
1253         return;
1254     }
1255     MMI_HILOGD("Transform right button event, evenType:%d, switchType:%d, button:%d", evenType, switchType, button);
1256     uint32_t btn = button;
1257     auto state = libinput_event_pointer_get_button_state(data);
1258     if (state == LIBINPUT_BUTTON_STATE_RELEASED) {
1259         button = pressedButton_;
1260         if (button < MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE) {
1261             MMI_HILOGE("button release from:%{public}d to :%{public}d, evenType:%{public}d, switchType:%{public}d",
1262                 button, btn, evenType, switchType);
1263         }
1264         return;
1265     }
1266     switch (switchType) {
1267         case RightClickType::TP_RIGHT_BUTTON:
1268             HandleTouchpadRightButton(data, evenType, button);
1269             break;
1270 
1271         case RightClickType::TP_LEFT_BUTTON:
1272             HandleTouchpadLeftButton(data, evenType, button);
1273             break;
1274 
1275         case RightClickType::TP_TWO_FINGER_TAP:
1276             HandleTouchpadTwoFingerButton(data, evenType, button);
1277             break;
1278         default:
1279             MMI_HILOGD("Invalid type, switchType:%{public}d", switchType);
1280             break;
1281     }
1282     if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
1283         pressedButton_ = button;
1284         if (button < MouseDeviceState::LIBINPUT_BUTTON_CODE::LIBINPUT_LEFT_BUTTON_CODE) {
1285             MMI_HILOGE("button press from:%{public}d to :%{public}d, evenType:%{public}d, switchType:%{public}d",
1286                 button, btn, evenType, switchType);
1287         }
1288     }
1289 }
1290 #endif // OHOS_BUILD_ENABLE_WATCH
1291 
SetTouchpadScrollSwitch(int32_t pid,bool switchFlag)1292 int32_t MouseTransformProcessor::SetTouchpadScrollSwitch(int32_t pid, bool switchFlag)
1293 {
1294     std::string name = "scrollSwitch";
1295     if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
1296         MMI_HILOGE("Failed to set scroll switch flag to mem, name:%s, switchFlag:%{public}d", name.c_str(), switchFlag);
1297         return RET_ERR;
1298     }
1299     if (!switchFlag) {
1300         scrollSwitchPid_ = pid;
1301     }
1302     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_SCROLL_SETTING,
1303         switchFlag);
1304 
1305     return RET_OK;
1306 }
1307 
GetTouchpadScrollSwitch(bool & switchFlag)1308 void MouseTransformProcessor::GetTouchpadScrollSwitch(bool &switchFlag)
1309 {
1310     std::string name = "scrollSwitch";
1311     GetConfigDataFromDatabase(name, switchFlag);
1312 }
1313 
SetTouchpadScrollDirection(bool state)1314 int32_t MouseTransformProcessor::SetTouchpadScrollDirection(bool state)
1315 {
1316     std::string name = "scrollDirection";
1317     if (PutConfigDataToDatabase(name, state) != RET_OK) {
1318         MMI_HILOGE("Failed to set scroll direct switch flag to mem");
1319         return RET_ERR;
1320     }
1321 
1322     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_SCROLL_DIR_SETTING,
1323         state);
1324 
1325     return RET_OK;
1326 }
1327 
GetTouchpadScrollDirection(bool & state)1328 void MouseTransformProcessor::GetTouchpadScrollDirection(bool &state)
1329 {
1330     std::string name = "scrollDirection";
1331     GetConfigDataFromDatabase(name, state);
1332 }
1333 
SetTouchpadTapSwitch(bool switchFlag)1334 int32_t MouseTransformProcessor::SetTouchpadTapSwitch(bool switchFlag)
1335 {
1336     std::string name = "touchpadTap";
1337     if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
1338         MMI_HILOGE("Failed to set scroll direct switch flag to mem");
1339         return RET_ERR;
1340     }
1341 
1342     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_TAP_SETTING,
1343         switchFlag);
1344 
1345     return RET_OK;
1346 }
1347 
GetTouchpadTapSwitch(bool & switchFlag)1348 void MouseTransformProcessor::GetTouchpadTapSwitch(bool &switchFlag)
1349 {
1350     std::string name = "touchpadTap";
1351     GetConfigDataFromDatabase(name, switchFlag);
1352 }
1353 
SetTouchpadPointerSpeed(int32_t speed)1354 int32_t MouseTransformProcessor::SetTouchpadPointerSpeed(int32_t speed)
1355 {
1356     std::string name = "touchPadPointerSpeed";
1357     if (PutConfigDataToDatabase(name, speed) != RET_OK) {
1358         MMI_HILOGE("Failed to set touch pad pointer speed to mem");
1359         return RET_ERR;
1360     }
1361 
1362     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_POINTER_SPEED_SETTING,
1363         speed);
1364 
1365     return RET_OK;
1366 }
1367 
GetTouchpadPointerSpeed(int32_t & speed)1368 void MouseTransformProcessor::GetTouchpadPointerSpeed(int32_t &speed)
1369 {
1370     std::string name = "touchPadPointerSpeed";
1371     GetConfigDataFromDatabase(name, speed);
1372     speed = speed == 0 ? DEFAULT_TOUCHPAD_SPEED : speed;
1373     speed = speed < MIN_SPEED ? MIN_SPEED : speed;
1374     speed = speed > MAX_TOUCHPAD_SPEED ? MAX_TOUCHPAD_SPEED : speed;
1375 }
1376 
GetTouchpadCDG(TouchpadCDG & touchpadCDG)1377 void MouseTransformProcessor::GetTouchpadCDG(TouchpadCDG &touchpadCDG)
1378 {
1379     touchpadCDG = touchpadOption_;
1380 }
1381 
UpdateTouchpadCDG(double touchpadPPi,double touchpadSize)1382 void MouseTransformProcessor::UpdateTouchpadCDG(double touchpadPPi, double touchpadSize)
1383 {
1384     touchpadOption_.ppi = touchpadPPi;
1385     touchpadOption_.size = touchpadSize;
1386     touchpadOption_.speed = GetTouchpadSpeed();
1387 }
1388 
SetTouchpadRightClickType(int32_t type)1389 int32_t MouseTransformProcessor::SetTouchpadRightClickType(int32_t type)
1390 {
1391     std::string name = "rightMenuSwitch";
1392     if (PutConfigDataToDatabase(name, type) != RET_OK) {
1393         MMI_HILOGE("Failed to set right click type to mem");
1394         return RET_ERR;
1395     }
1396     DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_RIGHT_CLICK_SETTING,
1397         type);
1398     return RET_OK;
1399 }
1400 
GetTouchpadRightClickType(int32_t & type)1401 void MouseTransformProcessor::GetTouchpadRightClickType(int32_t &type)
1402 {
1403     std::string name = "rightMenuSwitch";
1404     GetConfigDataFromDatabase(name, type);
1405 
1406     if (type < RIGHT_CLICK_TYPE_MIN || type > RIGHT_CLICK_TYPE_MAX) {
1407         type = RIGHT_CLICK_TYPE_MIN;
1408     }
1409 }
1410 
PutConfigDataToDatabase(std::string & key,bool value)1411 int32_t MouseTransformProcessor::PutConfigDataToDatabase(std::string &key, bool value)
1412 {
1413     return PREFERENCES_MGR->SetBoolValue(key, MOUSE_FILE_NAME, value);
1414 }
1415 
GetConfigDataFromDatabase(std::string & key,bool & value)1416 void MouseTransformProcessor::GetConfigDataFromDatabase(std::string &key, bool &value)
1417 {
1418     value = PREFERENCES_MGR->GetBoolValue(key, true);
1419 }
1420 
PutConfigDataToDatabase(std::string & key,int32_t value)1421 int32_t MouseTransformProcessor::PutConfigDataToDatabase(std::string &key, int32_t value)
1422 {
1423     return PREFERENCES_MGR->SetIntValue(key, MOUSE_FILE_NAME, value);
1424 }
1425 
GetConfigDataFromDatabase(std::string & key,int32_t & value)1426 void MouseTransformProcessor::GetConfigDataFromDatabase(std::string &key, int32_t &value)
1427 {
1428     int32_t defaultValue = value;
1429     value = PREFERENCES_MGR->GetIntValue(key, defaultValue);
1430 }
1431 
1432 #ifdef OHOS_BUILD_MOUSE_REPORTING_RATE
HandleFilterMouseEvent(Offset * offset)1433 void MouseTransformProcessor::HandleFilterMouseEvent(Offset* offset)
1434 {
1435     if (filterInsertionPoint_.filterFlag) {
1436         offset->dx = filterInsertionPoint_.filterX;
1437         offset->dy = filterInsertionPoint_.filterY;
1438         filterInsertionPoint_.filterDeltaTime = 0;
1439         filterInsertionPoint_.filterX = 0.0;
1440         filterInsertionPoint_.filterY = 0.0;
1441         filterInsertionPoint_.filterFlag = false;
1442         MMI_HILOGD("x:%.2f, y:%.2f", offset->dx, offset->dy);
1443     }
1444 }
1445 
CheckFilterMouseEvent(struct libinput_event * event)1446 bool MouseTransformProcessor::CheckFilterMouseEvent(struct libinput_event *event)
1447 {
1448     CHKPF(event);
1449 
1450     if (libinput_event_get_type(event) != LIBINPUT_EVENT_POINTER_MOTION) {
1451         return false;
1452     }
1453 
1454     auto data = libinput_event_get_pointer_event(event);
1455     CHKPF(data);
1456     uint64_t currentTime = libinput_event_pointer_get_time_usec(data);
1457     if ((!filterInsertionPoint_.filterPrePointTime) ||
1458         (currentTime < filterInsertionPoint_.filterPrePointTime)) {
1459         filterInsertionPoint_.filterPrePointTime = currentTime;
1460     }
1461 
1462     double dx = libinput_event_pointer_get_dx_unaccelerated(data);
1463     double dy = libinput_event_pointer_get_dy_unaccelerated(data);
1464 
1465     filterInsertionPoint_.filterDeltaTime += currentTime - filterInsertionPoint_.filterPrePointTime;
1466     filterInsertionPoint_.filterX += dx;
1467     filterInsertionPoint_.filterY += dy;
1468 
1469     filterInsertionPoint_.filterPrePointTime = currentTime;
1470     struct libinput_device *device = libinput_event_get_device(event);
1471     CHKPF(device);
1472     if (filterInsertionPoint_.filterDeltaTime < FilterInsertionPoint::FILTER_THRESHOLD_US &&
1473         libinput_device_get_id_bustype(device) == BUS_USB) {
1474         MMI_HILOGD("Mouse motion event delta time is too short");
1475         return true;
1476     }
1477 
1478     filterInsertionPoint_.filterFlag = true;
1479     return false;
1480 }
1481 #endif // OHOS_BUILD_MOUSE_REPORTING_RATE
1482 } // namespace MMI
1483 } // namespace OHOS
1484