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