1 /*
2  * Copyright (c) 2021-2024 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 "processing_pen_device.h"
17 
18 #undef MMI_LOG_TAG
19 #define MMI_LOG_TAG "ProcessingPenDevice"
20 
21 namespace OHOS {
22 namespace MMI {
23 namespace {
24 constexpr int32_t EV_ABS_Z_DEFAULT_VALUE { 450 };
25 constexpr int32_t EV_ABS_MISC_DEFAULT_VALUE { 2114 };
26 } // namespace
27 
TransformJsonDataToInputData(const DeviceItem & penEventArrays,InputEventArray & inputEventArray)28 int32_t ProcessingPenDevice::TransformJsonDataToInputData(const DeviceItem& penEventArrays,
29     InputEventArray& inputEventArray)
30 {
31     CALL_DEBUG_ENTER;
32     if (penEventArrays.events.empty()) {
33         MMI_HILOGE("Manage pen array failed, inputData is empty");
34         return RET_ERR;
35     }
36     std::vector<PenEvent> penEventArray;
37     if (AnalysisPenPadEvent(penEventArrays.events, penEventArray) == RET_ERR) {
38         MMI_HILOGE("AnalysisPenPadEvent error");
39         return RET_ERR;
40     }
41     TransformPenEventToInputEvent(penEventArray, inputEventArray);
42     return RET_OK;
43 }
44 
TransformPenEventToInputEvent(const std::vector<PenEvent> & penEvents,InputEventArray & inputEventArray)45 void ProcessingPenDevice::TransformPenEventToInputEvent(const std::vector<PenEvent>& penEvents,
46                                                         InputEventArray& inputEventArray)
47 {
48     if (penEvents.empty()) {
49         MMI_HILOGE("penEvents is empty");
50         return;
51     }
52     SetPenApproachPadEvent(penEvents.front(), inputEventArray);
53     for (const auto &item : penEvents) {
54         SetPenSlidePadEvent(item, inputEventArray);
55     }
56     SetPenLeavePadEvent(penEvents[penEvents.back()], inputEventArray);
57 }
58 
SetPenApproachPadEvent(const PenEvent & penEvent,InputEventArray & inputEventArray)59 void ProcessingPenDevice::SetPenApproachPadEvent(const PenEvent& penEvent, InputEventArray& inputEventArray)
60 {
61     SetEvAbsX(inputEventArray, 0, penEvent.xPos);
62     SetEvAbsY(inputEventArray, 0, penEvent.yPos);
63     SetAbsTiltX(inputEventArray, 0, penEvent.tiltX);
64     SetAbsTiltY(inputEventArray, 0, penEvent.tiltY);
65     SetEvAbsZ(inputEventArray, 0, EV_ABS_Z_DEFAULT_VALUE);
66     SetAbsDistance(inputEventArray, 0, penEvent.distance);
67     if (penEvent.eventType == "PEN_TOUCH") {
68         SetBtnPen(inputEventArray, 0, 1);
69     } else if (penEvent.eventType == "RUBBER_TOUCH") {
70         SetBtnRubber(inputEventArray, 0, 1);
71     } else {
72         MMI_HILOGW("Unknown eventType type");
73     }
74 
75     SetMscSerial(inputEventArray, 0);
76     SetAbsMisc(inputEventArray, 0, EV_ABS_MISC_DEFAULT_VALUE);
77     SetSynReport(inputEventArray);
78 }
79 
SetPenSlidePadEvent(const PenEvent & penEvent,InputEventArray & inputEventArray)80 void ProcessingPenDevice::SetPenSlidePadEvent(const PenEvent& penEvent, InputEventArray& inputEventArray)
81 {
82     if (penEvent.eventType == "PEN_KEY") {
83         SetBtnStylus(inputEventArray, 0, static_cast<uint16_t>(penEvent.keyValue), penEvent.keyStatus);
84         return;
85     }
86     if (penEvent.distance == 0) {
87         SetMscSerial(inputEventArray, 0);
88         SetSynReport(inputEventArray, 0);
89         return;
90     }
91     SetEvAbsX(inputEventArray, 0, penEvent.xPos);
92     SetEvAbsY(inputEventArray, 0, penEvent.yPos);
93     static int32_t previousPressure = 0;
94     if (penEvent.pressure > 0) {
95         if (previousPressure == 0) {
96             SetAbsPressure(inputEventArray, 0, penEvent.pressure);
97             SetBtnTouch(inputEventArray, 0, 1);
98         } else if (previousPressure > 0) {
99             SetAbsPressure(inputEventArray, 0, penEvent.pressure);
100         } else {
101             MMI_HILOGW("Unknown previousPressure type");
102         }
103     } else if ((penEvent.pressure == 0) && (previousPressure > 0)) {
104         SetAbsPressure(inputEventArray, 0, penEvent.pressure);
105         SetBtnTouch(inputEventArray, 0, 0);
106     } else {
107         MMI_HILOGW("Unknown pressure type");
108     }
109     previousPressure = penEvent.pressure;
110     SetAbsDistance(inputEventArray, 0, penEvent.distance);
111     SetAbsTiltX(inputEventArray, 0, penEvent.tiltX);
112     SetAbsTiltY(inputEventArray, 0, penEvent.tiltY);
113     SetMscSerial(inputEventArray, 0);
114     SetSynReport(inputEventArray);
115 }
116 
SetPenLeavePadEvent(const PenEvent & penEvent,InputEventArray & inputEventArray)117 void ProcessingPenDevice::SetPenLeavePadEvent(const PenEvent& penEvent, InputEventArray& inputEventArray)
118 {
119     SetEvAbsX(inputEventArray, 0);
120     SetEvAbsY(inputEventArray, 0);
121     SetAbsTiltX(inputEventArray, 0);
122     SetAbsTiltY(inputEventArray, 0);
123     SetEvAbsZ(inputEventArray, 0);
124     SetAbsDistance(inputEventArray, 0, 0);
125     if (penEvent.eventType == "PEN_TOUCH") {
126         SetBtnPen(inputEventArray, 0, 0);
127     } else if (penEvent.eventType == "RUBBER_TOUCH") {
128         SetBtnRubber(inputEventArray, 0, 0);
129     } else {
130         MMI_HILOGW("Unknown eventType type");
131     }
132 
133     SetMscSerial(inputEventArray, 0);
134     SetAbsMisc(inputEventArray, 0, 0);
135     SetSynReport(inputEventArray);
136 }
137 
AnalysisPenPadEvent(const std::vector<DeviceEvent> & inputData,std::vector<PenEvent> & penEventArray)138 int32_t ProcessingPenDevice::AnalysisPenPadEvent(const std::vector<DeviceEvent>& inputData,
139     std::vector<PenEvent>& penEventArray)
140 {
141     if (AnalysisPenApproachPadEvent(inputData[0], penEventArray) == RET_ERR) {
142         return RET_ERR;
143     }
144 
145     uint64_t endEventIndex = inputData.size() - 1;
146     for (uint64_t i = 1; i < endEventIndex; i++) {
147         if (AnalysisPenSlidePadEvent(inputData[i], penEventArray) == RET_ERR) {
148             return RET_ERR;
149         }
150     }
151     if (AnalysisPenLeavePadEvent(inputData[endEventIndex], penEventArray) == RET_ERR) {
152         return RET_ERR;
153     }
154 
155     return RET_OK;
156 }
157 
AnalysisPenApproachPadEvent(const DeviceEvent & event,std::vector<PenEvent> & penEventArray)158 int32_t ProcessingPenDevice::AnalysisPenApproachPadEvent(const DeviceEvent& event, std::vector<PenEvent>& penEventArray)
159 {
160     if ((event.eventType != "RUBBER_TOUCH") && (event.eventType != "PEN_TOUCH")) {
161         MMI_HILOGE("Enter the correct event type in the configuration file.");
162         return RET_ERR;
163     }
164 
165     PenEvent penEvent;
166     penEvent.eventType = event.eventType;
167     penEvent.distance = event.distance;
168     penEvent.yPos = event.yPos;
169     penEvent.tiltX = event.tiltX;
170     penEvent.tiltY = event.tiltY;
171     penEvent.pressure = event.pressure;
172     penEvent.xPos = event.xPos;
173     penEventArray.push_back(penEvent);
174 
175     return RET_OK;
176 }
177 
AnalysisPenSlidePadEvent(const DeviceEvent & event,std::vector<PenEvent> & penEventArray)178 int32_t ProcessingPenDevice::AnalysisPenSlidePadEvent(const DeviceEvent& event, std::vector<PenEvent>& penEventArray)
179 {
180     PenEvent penEvent;
181     penEvent.eventType = event.eventType;
182     if (penEvent.eventType == "PEN_KEY") {
183         penEvent.keyValue = event.keyValue;
184         penEvent.keyStatus = event.keyStatus;
185     } else if ((penEvent.eventType == "PEN_TOUCH") || (penEvent.eventType == "RUBBER_TOUCH")) {
186         penEvent.yPos = event.yPos;
187         penEvent.xPos = event.xPos;
188         penEvent.tiltY = event.tiltY;
189         penEvent.tiltX = event.tiltX;
190         penEvent.distance = event.distance;
191         penEvent.pressure = event.pressure;
192     } else {
193         MMI_HILOGW("Unknown eventType type");
194     }
195     penEventArray.push_back(penEvent);
196 
197     return RET_OK;
198 }
199 
AnalysisPenLeavePadEvent(const DeviceEvent & event,std::vector<PenEvent> & penEventArray)200 int32_t ProcessingPenDevice::AnalysisPenLeavePadEvent(const DeviceEvent& event, std::vector<PenEvent>& penEventArray)
201 {
202     if ((event.eventType != "RUBBER_TOUCH") && (event.eventType != "PEN_TOUCH")) {
203         MMI_HILOGE("Enter the correct event type in the configuration file.");
204         return RET_ERR;
205     }
206 
207     PenEvent penEvent;
208     penEvent.eventType = event.eventType;
209     penEvent.yPos = event.yPos;
210     penEvent.tiltY = event.tiltY;
211     penEvent.xPos = event.xPos;
212     penEvent.tiltX = event.tiltX;
213     penEvent.distance = event.distance;
214     penEvent.pressure = event.pressure;
215     penEventArray.push_back(penEvent);
216 
217     return RET_OK;
218 }
219 } // namespace MMI
220 } // namespace OHOS