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