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