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