1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "touchpad_transform_processor.h"
17
18 #include <linux/input.h>
19
20 #include "dfx_hisysevent.h"
21 #include "event_log_helper.h"
22 #include "i_input_windows_manager.h"
23 #include "i_preference_manager.h"
24 #include "mouse_device_state.h"
25
26 #undef MMI_LOG_DOMAIN
27 #define MMI_LOG_DOMAIN MMI_LOG_DISPATCH
28 #undef MMI_LOG_TAG
29 #define MMI_LOG_TAG "TouchPadTransformProcessor"
30
31 namespace OHOS {
32 namespace MMI {
33 namespace {
34 constexpr int32_t MT_TOOL_NONE { -1 };
35 constexpr int32_t BTN_DOWN { 1 };
36 constexpr int32_t FINGER_COUNT_MAX { 5 };
37 constexpr int32_t FINGER_TAP_MIN { 3 };
38 constexpr int32_t FINGER_TAP_THREE { 3 };
39 constexpr int32_t TP_SYSTEM_PINCH_FINGER_CNT { 2 };
40 constexpr int32_t DEFAULT_POINTER_ID { 0 };
41 constexpr int32_t MIN_ROWS { 1 };
42 constexpr int32_t MAX_ROWS { 100 };
43 constexpr int32_t DEFAULT_ROWS { 3 };
44 constexpr int32_t MAX_N_POINTER_ITEMS { 10 };
45
46 const char* TOUCHPAD_FILE_NAME = "touchpad_settings.xml";
47 std::string g_threeFingerTapKey = "touchpadThreeFingerTap";
48 } // namespace
49
TouchPadTransformProcessor(int32_t deviceId)50 TouchPadTransformProcessor::TouchPadTransformProcessor(int32_t deviceId)
51 : deviceId_(deviceId)
52 {
53 InitToolType();
54 }
55
OnEventTouchPadDown(struct libinput_event * event)56 int32_t TouchPadTransformProcessor::OnEventTouchPadDown(struct libinput_event *event)
57 {
58 CALL_INFO_TRACE;
59 CHKPR(event, RET_ERR);
60 auto touchpad = libinput_event_get_touchpad_event(event);
61 CHKPR(touchpad, RET_ERR);
62 auto device = libinput_event_get_device(event);
63 CHKPR(device, RET_ERR);
64
65 uint64_t time = libinput_event_touchpad_get_time_usec(touchpad);
66 auto pointIds = pointerEvent_->GetPointerIds();
67 if (pointIds.empty()) {
68 pointerEvent_->SetActionStartTime(time);
69 }
70 pointerEvent_->SetActionTime(time);
71 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
72 PointerEvent::PointerItem item;
73 int32_t longAxis = libinput_event_touchpad_get_touch_contact_long_axis(touchpad);
74 int32_t shortAxis = libinput_event_touchpad_get_touch_contact_short_axis(touchpad);
75 double pressure = libinput_event_touchpad_get_pressure(touchpad);
76 int32_t seatSlot = libinput_event_touchpad_get_seat_slot(touchpad);
77 double logicalX = libinput_event_touchpad_get_x(touchpad);
78 double logicalY = libinput_event_touchpad_get_y(touchpad);
79 double toolPhysicalX = libinput_event_touchpad_get_tool_x(touchpad);
80 double toolPhysicalY = libinput_event_touchpad_get_tool_y(touchpad);
81 double toolWidth = libinput_event_touchpad_get_tool_width(touchpad);
82 double toolHeight = libinput_event_touchpad_get_tool_height(touchpad);
83 int32_t toolType = GetTouchPadToolType(touchpad, device);
84 if (toolType == PointerEvent::TOOL_TYPE_PALM) {
85 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
86 }
87
88 item.SetLongAxis(longAxis);
89 item.SetShortAxis(shortAxis);
90 item.SetPressure(pressure);
91 item.SetToolType(toolType);
92 item.SetPointerId(seatSlot);
93 item.SetDownTime(time);
94 item.SetPressed(true);
95 item.SetDisplayX(static_cast<int32_t>(logicalX));
96 item.SetDisplayY(static_cast<int32_t>(logicalY));
97 item.SetDisplayXPos(logicalX);
98 item.SetDisplayYPos(logicalY);
99 item.SetToolDisplayX(static_cast<int32_t>(toolPhysicalX));
100 item.SetToolDisplayY(static_cast<int32_t>(toolPhysicalY));
101 item.SetToolWidth(static_cast<int32_t>(toolWidth));
102 item.SetToolHeight(static_cast<int32_t>(toolHeight));
103 item.SetDeviceId(deviceId_);
104 pointerEvent_->SetDeviceId(deviceId_);
105 RemoveSurplusPointerItem();
106 pointerEvent_->AddPointerItem(item);
107 pointerEvent_->SetPointerId(seatSlot);
108
109 return RET_OK;
110 }
111
OnEventTouchPadMotion(struct libinput_event * event)112 int32_t TouchPadTransformProcessor::OnEventTouchPadMotion(struct libinput_event *event)
113 {
114 CALL_DEBUG_ENTER;
115 CHKPR(event, RET_ERR);
116 auto touchpad = libinput_event_get_touchpad_event(event);
117 CHKPR(touchpad, RET_ERR);
118 int32_t seatSlot = libinput_event_touchpad_get_seat_slot(touchpad);
119 auto device = libinput_event_get_device(event);
120 CHKPR(device, RET_ERR);
121
122 uint64_t time = libinput_event_touchpad_get_time_usec(touchpad);
123 pointerEvent_->SetActionTime(time);
124 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
125 PointerEvent::PointerItem item;
126 if (!pointerEvent_->GetPointerItem(seatSlot, item)) {
127 MMI_HILOGD("Can't find the pointer item data, seatSlot:%{public}d, errCode:%{public}d",
128 seatSlot, PARAM_INPUT_FAIL);
129 return RET_ERR;
130 }
131 int32_t longAxis = libinput_event_touchpad_get_touch_contact_long_axis(touchpad);
132 int32_t shortAxis = libinput_event_touchpad_get_touch_contact_short_axis(touchpad);
133 double pressure = libinput_event_touchpad_get_pressure(touchpad);
134 double logicalX = libinput_event_touchpad_get_x(touchpad);
135 double logicalY = libinput_event_touchpad_get_y(touchpad);
136 double toolPhysicalX = libinput_event_touchpad_get_tool_x(touchpad);
137 double toolPhysicalY = libinput_event_touchpad_get_tool_y(touchpad);
138 double toolWidth = libinput_event_touchpad_get_tool_width(touchpad);
139 double toolHeight = libinput_event_touchpad_get_tool_height(touchpad);
140 int32_t toolType = GetTouchPadToolType(touchpad, device);
141 if (toolType == PointerEvent::TOOL_TYPE_PALM) {
142 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_CANCEL);
143 }
144
145 item.SetLongAxis(longAxis);
146 item.SetShortAxis(shortAxis);
147 item.SetPressure(pressure);
148 item.SetDisplayX(static_cast<int32_t>(logicalX));
149 item.SetDisplayY(static_cast<int32_t>(logicalY));
150 item.SetDisplayXPos(logicalX);
151 item.SetDisplayYPos(logicalY);
152 item.SetToolDisplayX(static_cast<int32_t>(toolPhysicalX));
153 item.SetToolDisplayY(static_cast<int32_t>(toolPhysicalY));
154 item.SetToolWidth(static_cast<int32_t>(toolWidth));
155 item.SetToolHeight(static_cast<int32_t>(toolHeight));
156 pointerEvent_->UpdatePointerItem(seatSlot, item);
157 pointerEvent_->SetPointerId(seatSlot);
158
159 return RET_OK;
160 }
161
OnEventTouchPadUp(struct libinput_event * event)162 int32_t TouchPadTransformProcessor::OnEventTouchPadUp(struct libinput_event *event)
163 {
164 CALL_DEBUG_ENTER;
165 CHKPR(event, RET_ERR);
166 auto touchpad = libinput_event_get_touchpad_event(event);
167 CHKPR(touchpad, RET_ERR);
168 int32_t seatSlot = libinput_event_touchpad_get_seat_slot(touchpad);
169
170 uint64_t time = libinput_event_touchpad_get_time_usec(touchpad);
171 pointerEvent_->SetActionTime(time);
172 if (MULTI_FINGERTAP_HDR->GetMultiFingersState() == MulFingersTap::TRIPLE_TAP) {
173 SetTouchPadMultiTapData();
174 } else {
175 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
176 }
177 PointerEvent::PointerItem item;
178 if (!pointerEvent_->GetPointerItem(seatSlot, item)) {
179 MMI_HILOGE("Can't find the pointer item data, seatSlot:%{public}d, errCode:%{public}d",
180 seatSlot, PARAM_INPUT_FAIL);
181 return RET_ERR;
182 }
183 item.SetPressed(false);
184 pointerEvent_->UpdatePointerItem(seatSlot, item);
185 pointerEvent_->SetPointerId(seatSlot);
186
187 return RET_OK;
188 }
189
OnEvent(struct libinput_event * event)190 std::shared_ptr<PointerEvent> TouchPadTransformProcessor::OnEvent(struct libinput_event *event)
191 {
192 CALL_DEBUG_ENTER;
193 CHKPP(event);
194 if (pointerEvent_ == nullptr) {
195 pointerEvent_ = PointerEvent::Create();
196 CHKPP(pointerEvent_);
197 }
198
199 int32_t ret = RET_OK;
200 int32_t type = libinput_event_get_type(event);
201 switch (type) {
202 case LIBINPUT_EVENT_TOUCHPAD_DOWN: {
203 ret = OnEventTouchPadDown(event);
204 break;
205 }
206 case LIBINPUT_EVENT_TOUCHPAD_UP: {
207 ret = OnEventTouchPadUp(event);
208 break;
209 }
210 case LIBINPUT_EVENT_TOUCHPAD_MOTION: {
211 ret = OnEventTouchPadMotion(event);
212 break;
213 }
214 case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: {
215 ret = OnEventTouchPadSwipeBegin(event);
216 break;
217 }
218 case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: {
219 ret = OnEventTouchPadSwipeUpdate(event);
220 break;
221 }
222 case LIBINPUT_EVENT_GESTURE_SWIPE_END: {
223 ret = OnEventTouchPadSwipeEnd(event);
224 break;
225 }
226 case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
227 case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
228 case LIBINPUT_EVENT_GESTURE_PINCH_END:
229 OnEventTouchPadPinchGesture(event);
230 break;
231 default: {
232 MMI_HILOGW("Touch pad action is not found");
233 return nullptr;
234 }
235 }
236
237 if (ret != RET_OK) {
238 return nullptr;
239 }
240
241 pointerEvent_->UpdateId();
242 StartLogTraceId(pointerEvent_->GetId(), pointerEvent_->GetEventType(), pointerEvent_->GetPointerAction());
243 MMI_HILOGD("Pointer event dispatcher of server:");
244 EventLogHelper::PrintEventData(pointerEvent_, pointerEvent_->GetPointerAction(),
245 pointerEvent_->GetPointerIds().size(), MMI_LOG_FREEZE);
246 auto device = INPUT_DEV_MGR->GetInputDevice(pointerEvent_->GetDeviceId());
247 CHKPP(device);
248 if (pointerEvent_->GetPointerAction() != PointerEvent::POINTER_ACTION_MOVE &&
249 pointerEvent_->GetPointerAction() != PointerEvent::POINTER_ACTION_SWIPE_UPDATE) {
250 aggregator_.Record(MMI_LOG_FREEZE, device->GetName() + ", TW: " +
251 std::to_string(pointerEvent_->GetTargetWindowId()), std::to_string(pointerEvent_->GetId()));
252 }
253
254 return pointerEvent_;
255 }
256
GetTouchPadToolType(struct libinput_event_touch * touchpad,struct libinput_device * device)257 int32_t TouchPadTransformProcessor::GetTouchPadToolType(
258 struct libinput_event_touch *touchpad, struct libinput_device *device)
259 {
260 int32_t toolType = libinput_event_touchpad_get_tool_type(touchpad);
261 switch (toolType) {
262 case MT_TOOL_NONE: {
263 return GetTouchPadToolType(device);
264 }
265 case MT_TOOL_FINGER: {
266 return PointerEvent::TOOL_TYPE_FINGER;
267 }
268 case MT_TOOL_PEN: {
269 return PointerEvent::TOOL_TYPE_PEN;
270 }
271 case MT_TOOL_PALM: {
272 MMI_HILOGD("toolType is MT_TOOL_PALM");
273 return PointerEvent::TOOL_TYPE_PALM;
274 }
275 default : {
276 MMI_HILOGW("Unknown tool type, identified as finger, toolType:%{public}d", toolType);
277 return PointerEvent::TOOL_TYPE_FINGER;
278 }
279 }
280 }
281
GetTouchPadToolType(struct libinput_device * device)282 int32_t TouchPadTransformProcessor::GetTouchPadToolType(struct libinput_device *device)
283 {
284 for (const auto &item : vecToolType_) {
285 if (libinput_device_touchpad_btn_tool_type_down(device, item.first) == BTN_DOWN) {
286 return item.second;
287 }
288 }
289 MMI_HILOGD("Unknown Btn tool type, identified as finger");
290 return PointerEvent::TOOL_TYPE_FINGER;
291 }
292
SetTouchPadSwipeData(struct libinput_event * event,int32_t action)293 int32_t TouchPadTransformProcessor::SetTouchPadSwipeData(struct libinput_event *event, int32_t action)
294 {
295 CALL_DEBUG_ENTER;
296
297 bool tpSwipeSwitch = true;
298 GetTouchpadSwipeSwitch(tpSwipeSwitch);
299
300 if (!tpSwipeSwitch) {
301 MMI_HILOGD("Touchpad swipe switch is false");
302 return RET_ERR;
303 }
304
305 CHKPR(event, RET_ERR);
306 struct libinput_event_gesture *gesture = libinput_event_get_gesture_event(event);
307 CHKPR(gesture, RET_ERR);
308
309 int64_t time = static_cast<int64_t>(libinput_event_gesture_get_time(gesture));
310 pointerEvent_->SetActionTime(GetSysClockTime());
311 pointerEvent_->SetActionStartTime(time);
312 pointerEvent_->SetPointerAction(action);
313 pointerEvent_->SetDeviceId(deviceId_);
314
315 int32_t fingerCount = libinput_event_gesture_get_finger_count(gesture);
316 if (fingerCount < 0 || fingerCount > FINGER_COUNT_MAX) {
317 MMI_HILOGE("Finger count is invalid");
318 return RET_ERR;
319 }
320 if (fingerCount == FINGER_TAP_THREE) {
321 GetTouchpadThreeFingersTapSwitch(tpSwipeSwitch);
322 if (!tpSwipeSwitch) {
323 return RET_OK;
324 }
325 }
326 pointerEvent_->SetFingerCount(fingerCount);
327
328 if (fingerCount == 0) {
329 MMI_HILOGD("There is no finger in swipe action:%{public}d", action);
330 return RET_ERR;
331 }
332
333 AddItemForEventWhileSetSwipeData(time, gesture, fingerCount);
334
335 if (action == PointerEvent::POINTER_ACTION_SWIPE_BEGIN) {
336 MMI_HILOGE("Start report for POINTER_ACTION_SWIPE_BEGIN");
337 swipeHistory_.clear();
338 DfxHisysevent::StatisticTouchpadGesture(pointerEvent_);
339 }
340
341 return RET_OK;
342 }
343
AddItemForEventWhileSetSwipeData(int64_t time,libinput_event_gesture * gesture,int32_t fingerCount)344 int32_t TouchPadTransformProcessor::AddItemForEventWhileSetSwipeData(int64_t time, libinput_event_gesture *gesture,
345 int32_t fingerCount)
346 {
347 if (fingerCount == 0 || fingerCount > FINGER_COUNT_MAX) {
348 MMI_HILOGD("There are wrong finger counts in swipe action");
349 return RET_ERR;
350 }
351 Coords avgCoord {0, 0};
352 std::vector<Coords> fingerCoords(FINGER_COUNT_MAX, avgCoord);
353 int32_t action = pointerEvent_->GetPointerAction();
354 for (int32_t i = 0; i < fingerCount; ++i) {
355 fingerCoords[i].x = libinput_event_gesture_get_device_coords_x(gesture, i);
356 fingerCoords[i].y = libinput_event_gesture_get_device_coords_y(gesture, i);
357 }
358 if (action == PointerEvent::POINTER_ACTION_SWIPE_UPDATE) {
359 SmoothMultifingerSwipeData(fingerCoords, fingerCount);
360 }
361 for (int32_t i = 0; i < fingerCount; ++i) {
362 avgCoord += fingerCoords[i];
363 }
364 avgCoord /= fingerCount;
365 PointerEvent::PointerItem pointerItem;
366 pointerEvent_->GetPointerItem(DEFAULT_POINTER_ID, pointerItem);
367 pointerItem.SetPressed(MouseState->IsLeftBtnPressed());
368 pointerItem.SetDownTime(time);
369 pointerItem.SetDisplayX(avgCoord.x);
370 pointerItem.SetDisplayY(avgCoord.y);
371 pointerItem.SetDisplayXPos(avgCoord.x);
372 pointerItem.SetDisplayYPos(avgCoord.y);
373 pointerItem.SetDeviceId(deviceId_);
374 pointerItem.SetPointerId(DEFAULT_POINTER_ID);
375 pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
376 RemoveSurplusPointerItem();
377 pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, pointerItem);
378 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_TOUCHPAD);
379 if ((pointerEvent_->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_BEGIN ||
380 pointerEvent_->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_UPDATE ||
381 pointerEvent_->GetPointerAction() == PointerEvent::POINTER_ACTION_SWIPE_END) &&
382 (pointerEvent_->GetTargetWindowId() > 0)) {
383 pointerEvent_->SetTargetWindowId(-1);
384 pointerEvent_->SetAgentWindowId(-1);
385 pointerItem.SetTargetWindowId(-1);
386 }
387 return RET_OK;
388 }
389
SmoothMultifingerSwipeData(std::vector<Coords> & fingerCoords,const int32_t fingerCount)390 void TouchPadTransformProcessor::SmoothMultifingerSwipeData(std::vector<Coords>& fingerCoords,
391 const int32_t fingerCount)
392 {
393 bool isMissing = false;
394 Coords coordDelta {0, 0};
395 int32_t historyFingerCount = 0;
396 for (int32_t i = 0; i < fingerCount; ++i) {
397 if (static_cast<int32_t>(swipeHistory_.size()) <= i) {
398 swipeHistory_.emplace_back(std::deque<Coords>());
399 }
400 if (fingerCoords[i].x == 0 && fingerCoords[i].y == 0) {
401 isMissing = true;
402 continue;
403 }
404 swipeHistory_[i].push_back(fingerCoords[i]);
405 if (static_cast<int32_t>(swipeHistory_[i].size()) > fingerCount) {
406 swipeHistory_[i].pop_front();
407 }
408 }
409 if (!isMissing) {
410 return;
411 }
412 for (int32_t i = 0; i < fingerCount; ++i) {
413 int32_t historySize = static_cast<int32_t>(swipeHistory_[i].size()) - 1;
414 if (historySize > 0) {
415 coordDelta += swipeHistory_[i][historySize] - swipeHistory_[i][0];
416 historyFingerCount += historySize;
417 }
418 }
419 if (historyFingerCount > 0) {
420 coordDelta /= historyFingerCount;
421 }
422 for (int32_t i = 0; i < fingerCount; ++i) {
423 if (fingerCoords[i].x == 0 && fingerCoords[i].y == 0) {
424 fingerCoords[i] = swipeHistory_[i].back() + coordDelta;
425 swipeHistory_[i].push_back(fingerCoords[i]);
426 }
427 if (static_cast<int32_t>(swipeHistory_[i].size()) > fingerCount) {
428 swipeHistory_[i].pop_front();
429 }
430 }
431 }
432
OnEventTouchPadSwipeBegin(struct libinput_event * event)433 int32_t TouchPadTransformProcessor::OnEventTouchPadSwipeBegin(struct libinput_event *event)
434 {
435 CALL_DEBUG_ENTER;
436 return SetTouchPadSwipeData(event, PointerEvent::POINTER_ACTION_SWIPE_BEGIN);
437 }
438
OnEventTouchPadSwipeUpdate(struct libinput_event * event)439 int32_t TouchPadTransformProcessor::OnEventTouchPadSwipeUpdate(struct libinput_event *event)
440 {
441 CALL_DEBUG_ENTER;
442 return SetTouchPadSwipeData(event, PointerEvent::POINTER_ACTION_SWIPE_UPDATE);
443 }
444
OnEventTouchPadSwipeEnd(struct libinput_event * event)445 int32_t TouchPadTransformProcessor::OnEventTouchPadSwipeEnd(struct libinput_event *event)
446 {
447 CALL_DEBUG_ENTER;
448 return SetTouchPadSwipeData(event, PointerEvent::POINTER_ACTION_SWIPE_END);
449 }
450
SetTouchPadMultiTapData()451 void TouchPadTransformProcessor::SetTouchPadMultiTapData()
452 {
453 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_TOUCHPAD);
454 pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_TRIPTAP);
455 auto state = MULTI_FINGERTAP_HDR->GetMultiFingersState();
456 pointerEvent_->SetFingerCount(static_cast<int32_t>(state));
457 }
458
SetPinchPointerItem(int64_t time)459 void TouchPadTransformProcessor::SetPinchPointerItem(int64_t time)
460 {
461 PointerEvent::PointerItem pointerItem;
462 pointerItem.SetDownTime(time);
463 pointerItem.SetPressed(MouseState->IsLeftBtnPressed());
464 pointerItem.SetDeviceId(deviceId_);
465 pointerItem.SetPointerId(DEFAULT_POINTER_ID);
466 pointerItem.SetWindowX(0);
467 pointerItem.SetWindowY(0);
468 pointerItem.SetWindowXPos(0.0);
469 pointerItem.SetWindowYPos(0.0);
470 auto mouseInfo = WIN_MGR->GetMouseInfo();
471 pointerItem.SetDisplayX(mouseInfo.physicalX);
472 pointerItem.SetDisplayY(mouseInfo.physicalY);
473 pointerItem.SetDisplayXPos(mouseInfo.physicalX);
474 pointerItem.SetDisplayYPos(mouseInfo.physicalY);
475 pointerItem.SetToolType(PointerEvent::TOOL_TYPE_TOUCHPAD);
476 RemoveSurplusPointerItem();
477 pointerEvent_->UpdatePointerItem(DEFAULT_POINTER_ID, pointerItem);
478 }
479
ProcessTouchPadPinchDataEvent(int32_t fingerCount,int32_t action,double scale,double angle)480 void TouchPadTransformProcessor::ProcessTouchPadPinchDataEvent
481 (int32_t fingerCount, int32_t action, double scale, double angle)
482 {
483 CALL_DEBUG_ENTER;
484 pointerEvent_->ClearButtonPressed();
485 std::vector<int32_t> pressedButtons;
486 MouseState->GetPressedButtons(pressedButtons);
487 for (const auto &item : pressedButtons) {
488 pointerEvent_->SetButtonPressed(item);
489 }
490
491 pointerEvent_->SetFingerCount(fingerCount);
492 pointerEvent_->SetDeviceId(deviceId_);
493 auto mouseInfo = WIN_MGR->GetMouseInfo();
494 pointerEvent_->SetTargetDisplayId(mouseInfo.displayId);
495 pointerEvent_->SetTargetWindowId(-1);
496 pointerEvent_->SetPointerId(DEFAULT_POINTER_ID);
497 pointerEvent_->SetPointerAction(action);
498 if (!MMI_EQ(scale, 0.0)) {
499 pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_PINCH, scale);
500 }
501 if (!MMI_EQ(angle, 0.0)) {
502 rotateAngle_ += angle;
503 MMI_HILOGD("The rotate angle is %{public}f", rotateAngle_);
504 pointerEvent_->SetAxisValue(PointerEvent::AXIS_TYPE_ROTATE, rotateAngle_);
505 }
506
507 if (fingerCount == TP_SYSTEM_PINCH_FINGER_CNT) {
508 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_MOUSE);
509 pointerEvent_->SetAxisEventType(PointerEvent::AXIS_EVENT_TYPE_PINCH);
510 } else {
511 pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_TOUCHPAD);
512 }
513
514 if (pointerEvent_->GetFingerCount() == TP_SYSTEM_PINCH_FINGER_CNT) {
515 WIN_MGR->UpdateTargetPointer(pointerEvent_);
516 }
517
518 // only three or four finger pinch need to statistic
519 if (action == PointerEvent::POINTER_ACTION_AXIS_BEGIN && fingerCount > TP_SYSTEM_PINCH_FINGER_CNT) {
520 DfxHisysevent::StatisticTouchpadGesture(pointerEvent_);
521 }
522 }
523
OnEventTouchPadPinchGesture(libinput_event * event)524 int32_t TouchPadTransformProcessor::OnEventTouchPadPinchGesture(libinput_event *event)
525 {
526 CALL_DEBUG_ENTER;
527 CHKPR(event, RET_ERR);
528 auto type = libinput_event_get_type(event);
529 auto gesture = libinput_event_get_gesture_event(event);
530 CHKPR(gesture, RET_ERR);
531 double scale = libinput_event_gesture_get_scale(gesture);
532 double angle = libinput_event_gesture_get_angle_delta(gesture);
533 auto action = GetPinchGestureType(type, angle);
534 MMI_HILOGD("The action is %{public}d, scale is %{public}f, angle is %{public}f", action, scale, angle);
535 int32_t fingerCount = libinput_event_gesture_get_finger_count(gesture);
536 MMI_HILOGD("The finger count is %{public}d", fingerCount);
537 if (fingerCount <= 0 || fingerCount > FINGER_COUNT_MAX) {
538 MMI_HILOGE("Finger count is invalid");
539 return RET_ERR;
540 }
541 bool tpPinchSwitch = false;
542 GetTouchpadPinchSwitch(tpPinchSwitch);
543 if (!tpPinchSwitch && fingerCount == TP_SYSTEM_PINCH_FINGER_CNT &&
544 (action == PointerEvent::POINTER_ACTION_AXIS_BEGIN ||
545 action == PointerEvent::POINTER_ACTION_AXIS_UPDATE ||
546 action == PointerEvent::POINTER_ACTION_AXIS_END)) {
547 MMI_HILOGD("Touchpad pinch switch is false");
548 return RET_ERR;
549 }
550 bool tpRotateSwitch = false;
551 GetTouchpadPinchSwitch(tpRotateSwitch);
552 if (!tpRotateSwitch && fingerCount == TP_SYSTEM_PINCH_FINGER_CNT &&
553 (action == PointerEvent::POINTER_ACTION_ROTATE_BEGIN ||
554 action == PointerEvent::POINTER_ACTION_ROTATE_UPDATE ||
555 action == PointerEvent::POINTER_ACTION_ROTATE_END)) {
556 MMI_HILOGD("Touchpad rotate switch is false");
557 return RET_ERR;
558 }
559 int64_t time = static_cast<int64_t>(libinput_event_gesture_get_time(gesture));
560 pointerEvent_->SetActionTime(GetSysClockTime());
561 pointerEvent_->SetActionStartTime(time);
562 SetPinchPointerItem(time);
563 ProcessTouchPadPinchDataEvent(fingerCount, action, scale, angle);
564 return RET_OK;
565 }
566
GetPinchGestureType(int32_t type,double angle)567 int32_t TouchPadTransformProcessor::GetPinchGestureType(int32_t type, double angle)
568 {
569 switch (type) {
570 case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: {
571 rotateAngle_ = 0.0;
572 isRotateGesture_ = MMI_EQ(angle, 0.0) ? false : true;
573 return MMI_EQ(angle, 0.0) ? PointerEvent::POINTER_ACTION_AXIS_BEGIN :
574 PointerEvent::POINTER_ACTION_ROTATE_BEGIN;
575 }
576 case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: {
577 return isRotateGesture_ ? PointerEvent::POINTER_ACTION_ROTATE_UPDATE :
578 PointerEvent::POINTER_ACTION_AXIS_UPDATE;
579 }
580 case LIBINPUT_EVENT_GESTURE_PINCH_END: {
581 return isRotateGesture_ ? PointerEvent::POINTER_ACTION_ROTATE_END :
582 PointerEvent::POINTER_ACTION_AXIS_END;
583 }
584 default:
585 break;
586 }
587 MMI_HILOGE("Check pinch gesture failed. type:%{public}d", type);
588 return RET_ERR;
589 }
590
InitToolType()591 void TouchPadTransformProcessor::InitToolType()
592 {
593 vecToolType_.push_back(std::make_pair(BTN_TOOL_PEN, PointerEvent::TOOL_TYPE_PEN));
594 vecToolType_.push_back(std::make_pair(BTN_TOOL_RUBBER, PointerEvent::TOOL_TYPE_RUBBER));
595 vecToolType_.push_back(std::make_pair(BTN_TOOL_BRUSH, PointerEvent::TOOL_TYPE_BRUSH));
596 vecToolType_.push_back(std::make_pair(BTN_TOOL_PENCIL, PointerEvent::TOOL_TYPE_PENCIL));
597 vecToolType_.push_back(std::make_pair(BTN_TOOL_AIRBRUSH, PointerEvent::TOOL_TYPE_AIRBRUSH));
598 vecToolType_.push_back(std::make_pair(BTN_TOOL_FINGER, PointerEvent::TOOL_TYPE_FINGER));
599 vecToolType_.push_back(std::make_pair(BTN_TOOL_MOUSE, PointerEvent::TOOL_TYPE_MOUSE));
600 vecToolType_.push_back(std::make_pair(BTN_TOOL_LENS, PointerEvent::TOOL_TYPE_LENS));
601 }
602
SetTouchpadSwipeSwitch(bool switchFlag)603 int32_t TouchPadTransformProcessor::SetTouchpadSwipeSwitch(bool switchFlag)
604 {
605 std::string name = "touchpadSwipe";
606 if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
607 MMI_HILOGE("Failed to set touchpad swpie switch flag to mem");
608 return RET_ERR;
609 }
610
611 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_SWIPE_SETTING,
612 switchFlag);
613 return RET_OK;
614 }
615
GetTouchpadSwipeSwitch(bool & switchFlag)616 void TouchPadTransformProcessor::GetTouchpadSwipeSwitch(bool &switchFlag)
617 {
618 std::string name = "touchpadSwipe";
619 GetConfigDataFromDatabase(name, switchFlag);
620 }
621
SetTouchpadPinchSwitch(bool switchFlag)622 int32_t TouchPadTransformProcessor::SetTouchpadPinchSwitch(bool switchFlag)
623 {
624 std::string name = "touchpadPinch";
625 if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
626 MMI_HILOGE("Failed to set touchpad pinch switch flag to mem");
627 return RET_ERR;
628 }
629
630 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_PINCH_SETTING,
631 switchFlag);
632 return RET_OK;
633 }
634
GetTouchpadPinchSwitch(bool & switchFlag)635 void TouchPadTransformProcessor::GetTouchpadPinchSwitch(bool &switchFlag)
636 {
637 std::string name = "touchpadPinch";
638 GetConfigDataFromDatabase(name, switchFlag);
639 }
640
SetTouchpadRotateSwitch(bool rotateSwitch)641 int32_t TouchPadTransformProcessor::SetTouchpadRotateSwitch(bool rotateSwitch)
642 {
643 std::string name = "touchpadRotate";
644 if (PutConfigDataToDatabase(name, rotateSwitch) != RET_OK) {
645 MMI_HILOGE("PutConfigDataToDatabase failed");
646 return RET_ERR;
647 }
648
649 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_ROTATE_SETTING,
650 rotateSwitch);
651 return RET_OK;
652 }
653
GetTouchpadRotateSwitch(bool & rotateSwitch)654 void TouchPadTransformProcessor::GetTouchpadRotateSwitch(bool &rotateSwitch)
655 {
656 std::string name = "touchpadRotate";
657 GetConfigDataFromDatabase(name, rotateSwitch);
658 }
659
SetTouchpadDoubleTapAndDragState(bool switchFlag)660 int32_t TouchPadTransformProcessor::SetTouchpadDoubleTapAndDragState(bool switchFlag)
661 {
662 std::string name = "touchpadDoubleTapAndDrag";
663 if (!PREFERENCES_MGR->IsInitPreference()) {
664 MMI_HILOGE("Preference is not init");
665 return RET_ERR;
666 }
667 if (PutConfigDataToDatabase(name, switchFlag) != RET_OK) {
668 MMI_HILOGE("PutConfigDataToDatabase failed");
669 return RET_ERR;
670 }
671
672 auto originDevices = INPUT_DEV_MGR->GetTouchPadDeviceOrigins();
673 if (originDevices.empty()) {
674 return RET_OK;
675 }
676
677 auto state = LIBINPUT_CONFIG_DRAG_DISABLED;
678 if (switchFlag) {
679 state = LIBINPUT_CONFIG_DRAG_ENABLED;
680 }
681 for (const auto &originDevice : originDevices) {
682 if (originDevice == nullptr) {
683 continue;
684 }
685 auto ret = libinput_device_config_tap_set_drag_enabled(originDevice, state);
686 MMI_HILOGI("Touchpad set double tap and drag state successfully, "
687 "state:%{public}d, ret:%{public}d", state, ret);
688 }
689
690 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_DOUBLE_TAP_DRAG_SETTING,
691 switchFlag);
692 return RET_OK;
693 }
694
GetTouchpadDoubleTapAndDragState(bool & switchFlag)695 void TouchPadTransformProcessor::GetTouchpadDoubleTapAndDragState(bool &switchFlag)
696 {
697 std::string name = "touchpadDoubleTapAndDrag";
698 GetConfigDataFromDatabase(name, switchFlag);
699 }
700
SetTouchpadScrollRows(int32_t rows)701 int32_t TouchPadTransformProcessor::SetTouchpadScrollRows(int32_t rows)
702 {
703 CALL_DEBUG_ENTER;
704 int32_t newRows = std::clamp(rows, MIN_ROWS, MAX_ROWS);
705 std::string name = "touchpadScrollRows";
706 int32_t ret = PREFERENCES_MGR->SetIntValue(name, TOUCHPAD_FILE_NAME, newRows);
707 MMI_HILOGD("Set touchpad scroll rows successfully, rows:%{public}d", newRows);
708 return ret;
709 }
710
GetTouchpadScrollRows()711 int32_t TouchPadTransformProcessor::GetTouchpadScrollRows()
712 {
713 CALL_DEBUG_ENTER;
714 std::string name = "touchpadScrollRows";
715 int32_t rows = PREFERENCES_MGR->GetIntValue(name, DEFAULT_ROWS);
716 MMI_HILOGD("Get touchpad scroll rows successfully, rows:%{public}d", rows);
717 return rows;
718 }
719
PutConfigDataToDatabase(std::string & key,bool value)720 int32_t TouchPadTransformProcessor::PutConfigDataToDatabase(std::string &key, bool value)
721 {
722 return PREFERENCES_MGR->SetBoolValue(key, TOUCHPAD_FILE_NAME, value);
723 }
724
GetConfigDataFromDatabase(std::string & key,bool & value)725 void TouchPadTransformProcessor::GetConfigDataFromDatabase(std::string &key, bool &value)
726 {
727 value = PREFERENCES_MGR->GetBoolValue(key, true);
728 }
729
GetPointerEvent()730 std::shared_ptr<PointerEvent> TouchPadTransformProcessor::GetPointerEvent()
731 {
732 return pointerEvent_;
733 }
734
RemoveSurplusPointerItem()735 void TouchPadTransformProcessor::RemoveSurplusPointerItem()
736 {
737 std::list<PointerEvent::PointerItem> pointerItems = pointerEvent_->GetAllPointerItems();
738 if (pointerItems.size() >= MAX_N_POINTER_ITEMS) {
739 MMI_HILOGW("Exceed maximum allowed number of pointer items");
740 pointerEvent_->RemovePointerItem(pointerItems.begin()->GetPointerId());
741 }
742 }
743
MultiFingersTapHandler()744 MultiFingersTapHandler::MultiFingersTapHandler() {}
745
~MultiFingersTapHandler()746 MultiFingersTapHandler::~MultiFingersTapHandler() {}
747
HandleMulFingersTap(struct libinput_event_touch * event,int32_t type)748 int32_t MultiFingersTapHandler::HandleMulFingersTap(struct libinput_event_touch *event, int32_t type)
749 {
750 CALL_DEBUG_ENTER;
751 CHKPR(event, RET_ERR);
752 // if is not multifigners tap, return.
753 if (tapTrends_ == TapTrends::NO_MULTAP) {
754 return RET_OK;
755 }
756 // calculator delta time, if is larger than threshold, return.
757 auto time = libinput_event_touchpad_get_time_usec(event);
758 uint64_t deltaTime = 0;
759 if (tapTrends_ != TapTrends::BEGIN) {
760 deltaTime = time - lastTime;
761 } else {
762 beginTime = time;
763 }
764 lastTime = time;
765 if ((deltaTime > perTimeThreshold) || ((lastTime - beginTime) > totalTimeThreshold)) {
766 MMI_HILOGD("Not multitap, single time interval or total time interval is out of range."
767 "single:%{public}" PRId64 ", total:%{public}" PRId64, deltaTime, (lastTime - beginTime));
768 SetMultiFingersTapHdrDefault();
769 return RET_OK;
770 }
771 if (type == LIBINPUT_EVENT_TOUCHPAD_DOWN) {
772 // if trends is up, is not multifigners tap, return.
773 if ((tapTrends_ == TapTrends::UPING) || !CanAddToPointerMaps(event)) {
774 MMI_HILOGD("The trends is up, is not a multifigners tap event");
775 SetMultiFingersTapHdrDefault();
776 return RET_OK;
777 } else {
778 downCnt++;
779 tapTrends_ = TapTrends::DOWNING;
780 }
781 } else if ((type == LIBINPUT_EVENT_TOUCHPAD_UP) && !CanUnsetPointerItem(event)) {
782 upCnt++;
783 tapTrends_ = TapTrends::UPING;
784 }
785
786 if ((upCnt == downCnt) && (upCnt >= FINGER_TAP_MIN) && (upCnt <= FINGER_COUNT_MAX)) {
787 multiFingersState_ = static_cast<MulFingersTap>(upCnt);
788 MMI_HILOGD("This is multifinger tap event, finger count:%{public}d", upCnt);
789 }
790 return RET_OK;
791 }
792
SetMultiFingersTapHdrDefault(bool isAllDefault)793 void MultiFingersTapHandler::SetMultiFingersTapHdrDefault(bool isAllDefault)
794 {
795 downCnt = 0;
796 upCnt = 0;
797 tapTrends_ = TapTrends::BEGIN;
798 beginTime = 0;
799 lastTime = 0;
800 if (isAllDefault) {
801 multiFingersState_ = MulFingersTap::NO_TAP;
802 }
803 pointerMaps.clear();
804 }
805
ClearPointerItems(std::shared_ptr<PointerEvent> pointer)806 bool MultiFingersTapHandler::ClearPointerItems(std::shared_ptr<PointerEvent> pointer)
807 {
808 CHKPF(pointer);
809 auto ids_ = pointer->GetPointerIds();
810 for (const auto &id : ids_) {
811 pointer->RemovePointerItem(id);
812 }
813 return true;
814 }
815
GetMultiFingersState()816 MulFingersTap MultiFingersTapHandler::GetMultiFingersState()
817 {
818 return multiFingersState_;
819 }
820
CanAddToPointerMaps(struct libinput_event_touch * event)821 bool MultiFingersTapHandler::CanAddToPointerMaps(struct libinput_event_touch *event)
822 {
823 CHKPF(event);
824 int32_t seatSlot = libinput_event_touchpad_get_seat_slot(event);
825 if (pointerMaps.find(seatSlot) != pointerMaps.end()) {
826 return false;
827 }
828 auto currentX = libinput_event_touchpad_get_x(event);
829 auto currentY = libinput_event_touchpad_get_y(event);
830 pointerMaps[seatSlot] = {currentX, currentY};
831 return true;
832 }
833
CanUnsetPointerItem(struct libinput_event_touch * event)834 bool MultiFingersTapHandler::CanUnsetPointerItem(struct libinput_event_touch *event)
835 {
836 CHKPF(event);
837 int32_t seatSlot = libinput_event_touchpad_get_seat_slot(event);
838 if (pointerMaps.find(seatSlot) != pointerMaps.end()) {
839 return false;
840 } else {
841 pointerMaps[seatSlot] = {-1.0F, -1.0F};
842 return true;
843 }
844 }
845
SetTouchpadThreeFingersTapSwitch(bool switchFlag)846 int32_t TouchPadTransformProcessor::SetTouchpadThreeFingersTapSwitch(bool switchFlag)
847 {
848 if (PutConfigDataToDatabase(g_threeFingerTapKey, switchFlag) != RET_OK) {
849 MMI_HILOGE("Failed to set touchpad three fingers switch flag to mem");
850 return RET_ERR;
851 }
852 DfxHisysevent::ReportTouchpadSettingState(DfxHisysevent::TOUCHPAD_SETTING_CODE::TOUCHPAD_PINCH_SETTING,
853 switchFlag);
854 return RET_OK;
855 }
856
GetTouchpadThreeFingersTapSwitch(bool & switchFlag)857 int32_t TouchPadTransformProcessor::GetTouchpadThreeFingersTapSwitch(bool &switchFlag)
858 {
859 GetConfigDataFromDatabase(g_threeFingerTapKey, switchFlag);
860 return RET_OK;
861 }
862 } // namespace MMI
863 } // namespace OHOS
864