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