• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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