• 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 "touch_transform_processor.h"
17 
18 #include <linux/input.h>
19 
20 #include "event_log_helper.h"
21 #include "input_windows_manager.h"
22 #include "fingersense_wrapper.h"
23 #include "mmi_log.h"
24 
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MMI_LOG_DOMAIN, "TouchTransformProcessor" };
29 constexpr int32_t MT_TOOL_NONE { -1 };
30 constexpr int32_t BTN_DOWN { 1 };
31 } // namespace
32 
TouchTransformProcessor(int32_t deviceId)33 TouchTransformProcessor::TouchTransformProcessor(int32_t deviceId)
34     : deviceId_(deviceId)
35 {
36     InitToolTypes();
37 }
38 
OnEventTouchDown(struct libinput_event * event)39 bool TouchTransformProcessor::OnEventTouchDown(struct libinput_event *event)
40 {
41     CALL_DEBUG_ENTER;
42     CHKPF(event);
43     auto touch = libinput_event_get_touch_event(event);
44     CHKPF(touch);
45     auto device = libinput_event_get_device(event);
46     CHKPF(device);
47     EventTouch touchInfo;
48     int32_t logicalDisplayId = -1;
49     if (!WinMgr->TouchPointToDisplayPoint(deviceId_, touch, touchInfo, logicalDisplayId)) {
50         MMI_HILOGE("TouchDownPointToDisplayPoint failed");
51         return false;
52     }
53     auto pointIds = pointerEvent_->GetPointerIds();
54     uint64_t time = libinput_event_touch_get_time_usec(touch);
55     if (pointIds.empty()) {
56         pointerEvent_->SetActionStartTime(time);
57         pointerEvent_->SetTargetDisplayId(logicalDisplayId);
58     }
59     pointerEvent_->SetActionTime(time);
60     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_DOWN);
61     PointerEvent::PointerItem item;
62     double pressure = libinput_event_touch_get_pressure(touch);
63     int32_t seatSlot = libinput_event_touch_get_seat_slot(touch);
64     int32_t longAxis = libinput_event_get_touch_contact_long_axis(touch);
65     int32_t shortAxis = libinput_event_get_touch_contact_short_axis(touch);
66     item.SetPressure(pressure);
67     item.SetLongAxis(longAxis);
68     item.SetShortAxis(shortAxis);
69     item.SetPointerId(seatSlot);
70     item.SetDownTime(time);
71     item.SetPressed(true);
72     UpdatePointerItemProperties(item, touchInfo);
73     item.SetDeviceId(deviceId_);
74     int32_t toolType = GetTouchToolType(touch, device);
75 #ifdef OHOS_BUILD_ENABLE_FINGERSENSE_WRAPPER
76     NotifyFingersenseProcess(item, toolType);
77 #endif // OHOS_BUILD_ENABLE_FINGERSENSE_WRAPPER
78     item.SetToolType(toolType);
79     pointerEvent_->SetDeviceId(deviceId_);
80     pointerEvent_->AddPointerItem(item);
81     pointerEvent_->SetPointerId(seatSlot);
82     EventLogHelper::PrintEventData(pointerEvent_, pointerEvent_->GetPointerAction(),
83         pointerEvent_->GetPointerIds().size());
84     return true;
85 }
86 
UpdatePointerItemProperties(PointerEvent::PointerItem & item,EventTouch & touchInfo)87 void TouchTransformProcessor::UpdatePointerItemProperties(PointerEvent::PointerItem &item, EventTouch &touchInfo)
88 {
89     CALL_DEBUG_ENTER;
90     item.SetDisplayX(touchInfo.point.x);
91     item.SetDisplayY(touchInfo.point.y);
92     item.SetToolDisplayX(touchInfo.toolRect.point.x);
93     item.SetToolDisplayY(touchInfo.toolRect.point.y);
94     item.SetToolWidth(touchInfo.toolRect.width);
95     item.SetToolHeight(touchInfo.toolRect.height);
96 }
97 
98 #ifdef OHOS_BUILD_ENABLE_FINGERSENSE_WRAPPER
NotifyFingersenseProcess(PointerEvent::PointerItem & pointerItem,int32_t & toolType)99 void TouchTransformProcessor::NotifyFingersenseProcess(PointerEvent::PointerItem &pointerItem, int32_t &toolType)
100 {
101     CALL_DEBUG_ENTER;
102     TransformTouchProperties(rawTouch_, pointerItem);
103     if (FINGERSENSE_WRAPPER->setCurrentToolType_) {
104         MMI_HILOGD("fingersense start classify touch down event");
105         FINGERSENSE_WRAPPER->setCurrentToolType_(rawTouch_, toolType);
106     }
107 }
TransformTouchProperties(TouchType & rawTouch,PointerEvent::PointerItem & pointerItem)108 void TouchTransformProcessor::TransformTouchProperties(TouchType &rawTouch, PointerEvent::PointerItem &pointerItem)
109 {
110     CALL_DEBUG_ENTER;
111     rawTouch.id = pointerItem.GetPointerId();
112     rawTouch.pressure = pointerItem.GetPressure();
113     rawTouch.x = pointerItem.GetDisplayX();
114     rawTouch.y = pointerItem.GetDisplayY();
115 }
116 #endif // OHOS_BUILD_ENABLE_FINGERSENSE_WRAPPER
117 
OnEventTouchMotion(struct libinput_event * event)118 bool TouchTransformProcessor::OnEventTouchMotion(struct libinput_event *event)
119 {
120     CALL_DEBUG_ENTER;
121     CHKPF(event);
122     auto touch = libinput_event_get_touch_event(event);
123     CHKPF(touch);
124     uint64_t time = libinput_event_touch_get_time_usec(touch);
125     pointerEvent_->SetActionTime(time);
126     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE);
127     EventTouch touchInfo;
128     int32_t logicalDisplayId = pointerEvent_->GetTargetDisplayId();
129     if (!WinMgr->TouchPointToDisplayPoint(deviceId_, touch, touchInfo, logicalDisplayId)) {
130         MMI_HILOGE("Get TouchMotionPointToDisplayPoint failed");
131         return false;
132     }
133     PointerEvent::PointerItem item;
134     int32_t seatSlot = libinput_event_touch_get_seat_slot(touch);
135     if (!(pointerEvent_->GetPointerItem(seatSlot, item))) {
136         MMI_HILOGE("Get pointer parameter failed");
137         return false;
138     }
139     double pressure = libinput_event_touch_get_pressure(touch);
140     int32_t longAxis = libinput_event_get_touch_contact_long_axis(touch);
141     int32_t shortAxis = libinput_event_get_touch_contact_short_axis(touch);
142     item.SetPressure(pressure);
143     item.SetLongAxis(longAxis);
144     item.SetShortAxis(shortAxis);
145     item.SetDisplayX(touchInfo.point.x);
146     item.SetDisplayY(touchInfo.point.y);
147     item.SetToolDisplayX(touchInfo.toolRect.point.x);
148     item.SetToolDisplayY(touchInfo.toolRect.point.y);
149     item.SetToolWidth(touchInfo.toolRect.width);
150     item.SetToolHeight(touchInfo.toolRect.height);
151     pointerEvent_->UpdatePointerItem(seatSlot, item);
152     pointerEvent_->SetPointerId(seatSlot);
153     EventLogHelper::PrintEventData(pointerEvent_, pointerEvent_->GetPointerAction(),
154         pointerEvent_->GetPointerIds().size());
155     return true;
156 }
157 
OnEventTouchUp(struct libinput_event * event)158 bool TouchTransformProcessor::OnEventTouchUp(struct libinput_event *event)
159 {
160     CALL_DEBUG_ENTER;
161     CHKPF(event);
162     auto touch = libinput_event_get_touch_event(event);
163     CHKPF(touch);
164     uint64_t time = libinput_event_touch_get_time_usec(touch);
165     pointerEvent_->SetActionTime(time);
166     pointerEvent_->SetPointerAction(PointerEvent::POINTER_ACTION_UP);
167 
168     PointerEvent::PointerItem item;
169     int32_t seatSlot = libinput_event_touch_get_seat_slot(touch);
170     if (!(pointerEvent_->GetPointerItem(seatSlot, item))) {
171         MMI_HILOGE("Get pointer parameter failed");
172         return false;
173     }
174     item.SetPressed(false);
175 #ifdef OHOS_BUILD_ENABLE_FINGERSENSE_WRAPPER
176     TransformTouchProperties(rawTouch_, item);
177     if (FINGERSENSE_WRAPPER->notifyTouchUp_) {
178         MMI_HILOGD("notify fingersense touch up event");
179         FINGERSENSE_WRAPPER->notifyTouchUp_(&rawTouch_);
180     }
181 #endif // OHOS_BUILD_ENABLE_FINGERSENSE_WRAPPER
182     pointerEvent_->UpdatePointerItem(seatSlot, item);
183     pointerEvent_->SetPointerId(seatSlot);
184     return true;
185 }
186 
OnEvent(struct libinput_event * event)187 std::shared_ptr<PointerEvent> TouchTransformProcessor::OnEvent(struct libinput_event *event)
188 {
189     CALL_DEBUG_ENTER;
190     CHKPP(event);
191     if (pointerEvent_ == nullptr) {
192         pointerEvent_ = PointerEvent::Create();
193         CHKPP(pointerEvent_);
194     }
195     auto type = libinput_event_get_type(event);
196     uint64_t sensorTime = libinput_event_get_sensortime(event);
197     pointerEvent_->SetSensorInputTime(sensorTime);
198     switch (type) {
199         case LIBINPUT_EVENT_TOUCH_DOWN: {
200             if (!OnEventTouchDown(event)) {
201                 MMI_HILOGE("Get OnEventTouchDown failed");
202                 return nullptr;
203             }
204             break;
205         }
206         case LIBINPUT_EVENT_TOUCH_UP: {
207             if (!OnEventTouchUp(event)) {
208                 MMI_HILOGE("Get OnEventTouchUp failed");
209                 return nullptr;
210             }
211             break;
212         }
213         case LIBINPUT_EVENT_TOUCH_MOTION: {
214             if (!OnEventTouchMotion(event)) {
215                 MMI_HILOGE("Get OnEventTouchMotion failed");
216                 return nullptr;
217             }
218             break;
219         }
220         default: {
221             MMI_HILOGE("Unknown event type, touchType:%{public}d", type);
222             return nullptr;
223         }
224     }
225     pointerEvent_->SetSourceType(PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
226     pointerEvent_->UpdateId();
227     WinMgr->UpdateTargetPointer(pointerEvent_);
228     return pointerEvent_;
229 }
230 
GetTouchToolType(struct libinput_event_touch * data,struct libinput_device * device)231 int32_t TouchTransformProcessor::GetTouchToolType(struct libinput_event_touch *data,
232     struct libinput_device *device)
233 {
234     int32_t toolType = libinput_event_touch_get_tool_type(data);
235     switch (toolType) {
236         case MT_TOOL_NONE: {
237             return GetTouchToolType(device);
238         }
239         case MT_TOOL_FINGER: {
240             return PointerEvent::TOOL_TYPE_FINGER;
241         }
242         case MT_TOOL_PEN: {
243             return PointerEvent::TOOL_TYPE_PEN;
244         }
245         default : {
246             MMI_HILOGW("Unknown tool type, identified as finger, toolType:%{public}d", toolType);
247             return PointerEvent::TOOL_TYPE_FINGER;
248         }
249     }
250 }
251 
GetTouchToolType(struct libinput_device * device)252 int32_t TouchTransformProcessor::GetTouchToolType(struct libinput_device *device)
253 {
254     for (const auto &item : vecToolType_) {
255         if (libinput_device_touch_btn_tool_type_down(device, item.first) == BTN_DOWN) {
256             return item.second;
257         }
258     }
259     MMI_HILOGW("Unknown Btn tool type, identified as finger");
260     return PointerEvent::TOOL_TYPE_FINGER;
261 }
262 
InitToolTypes()263 void TouchTransformProcessor::InitToolTypes()
264 {
265     vecToolType_.emplace_back(std::make_pair(BTN_TOOL_PEN, PointerEvent::TOOL_TYPE_PEN));
266     vecToolType_.emplace_back(std::make_pair(BTN_TOOL_RUBBER, PointerEvent::TOOL_TYPE_RUBBER));
267     vecToolType_.emplace_back(std::make_pair(BTN_TOOL_BRUSH, PointerEvent::TOOL_TYPE_BRUSH));
268     vecToolType_.emplace_back(std::make_pair(BTN_TOOL_PENCIL, PointerEvent::TOOL_TYPE_PENCIL));
269     vecToolType_.emplace_back(std::make_pair(BTN_TOOL_AIRBRUSH, PointerEvent::TOOL_TYPE_AIRBRUSH));
270     vecToolType_.emplace_back(std::make_pair(BTN_TOOL_FINGER, PointerEvent::TOOL_TYPE_FINGER));
271     vecToolType_.emplace_back(std::make_pair(BTN_TOOL_MOUSE, PointerEvent::TOOL_TYPE_MOUSE));
272     vecToolType_.emplace_back(std::make_pair(BTN_TOOL_LENS, PointerEvent::TOOL_TYPE_LENS));
273 }
274 } // namespace MMI
275 } // namespace OHOS
276