1 /*
2 * Copyright (c) 2020-2021 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 "dfx/event_injector.h"
17 #if ENABLE_DEBUG
18 #include "common/input_device_manager.h"
19 #include "dfx/key_event_injector.h"
20 #include "dfx/point_event_injector.h"
21 #include "gfx_utils/graphic_log.h"
22
23 namespace OHOS {
~EventInjector()24 EventInjector::~EventInjector()
25 {
26 if (pointEventInjector_ != nullptr) {
27 InputDeviceManager::GetInstance()->Remove(pointEventInjector_);
28 delete pointEventInjector_;
29 pointEventInjector_ = nullptr;
30 }
31 if (keyEventInjector_ != nullptr) {
32 InputDeviceManager::GetInstance()->Remove(keyEventInjector_);
33 delete keyEventInjector_;
34 keyEventInjector_ = nullptr;
35 }
36 }
37
GetInstance()38 EventInjector* EventInjector::GetInstance()
39 {
40 static EventInjector instance;
41 return &instance;
42 }
43
RegisterEventInjector(EventDataType type)44 bool EventInjector::RegisterEventInjector(EventDataType type)
45 {
46 switch (type) {
47 case EventDataType::POINT_TYPE:
48 if (pointEventInjector_ == nullptr) {
49 pointEventInjector_ = new PointEventInjector();
50 if (pointEventInjector_ == nullptr) {
51 GRAPHIC_LOGE("EventInjector::RegisterEventInjector register pointEventInjector failed Err!\n");
52 return false;
53 }
54 InputDeviceManager::GetInstance()->Add(pointEventInjector_);
55 }
56 return true;
57 case EventDataType::KEY_TYPE:
58 if (keyEventInjector_ == nullptr) {
59 keyEventInjector_ = new KeyEventInjector();
60 if (keyEventInjector_ == nullptr) {
61 GRAPHIC_LOGE("EventInjector::RegisterEventInjector register keyEventInjector failed Err!\n");
62 return false;
63 }
64 InputDeviceManager::GetInstance()->Add(keyEventInjector_);
65 }
66 return true;
67 default:
68 break;
69 }
70 return false;
71 }
72
UnregisterEventInjector(EventDataType type)73 void EventInjector::UnregisterEventInjector(EventDataType type)
74 {
75 switch (type) {
76 case EventDataType::POINT_TYPE:
77 if (pointEventInjector_ != nullptr) {
78 InputDeviceManager::GetInstance()->Remove(pointEventInjector_);
79 delete pointEventInjector_;
80 pointEventInjector_ = nullptr;
81 }
82 break;
83 case EventDataType::KEY_TYPE:
84 if (keyEventInjector_ != nullptr) {
85 InputDeviceManager::GetInstance()->Remove(keyEventInjector_);
86 delete keyEventInjector_;
87 keyEventInjector_ = nullptr;
88 }
89 break;
90 default:
91 break;
92 }
93 }
94
IsEventInjectorRegistered(EventDataType type) const95 bool EventInjector::IsEventInjectorRegistered(EventDataType type) const
96 {
97 switch (type) {
98 case EventDataType::POINT_TYPE:
99 if (pointEventInjector_ != nullptr) {
100 return true;
101 }
102 break;
103 case EventDataType::KEY_TYPE:
104 if (keyEventInjector_ != nullptr) {
105 return true;
106 }
107 break;
108 default:
109 break;
110 }
111 return false;
112 }
113
SetInjectEvent(const DeviceData * dataArray,uint16_t arrayLength,EventDataType type)114 bool EventInjector::SetInjectEvent(const DeviceData* dataArray, uint16_t arrayLength, EventDataType type)
115 {
116 if (dataArray == nullptr) {
117 return false;
118 }
119 switch (type) {
120 case EventDataType::POINT_TYPE:
121 if (pointEventInjector_ == nullptr) {
122 return false;
123 }
124 for (uint16_t i = 0; i < arrayLength; i++) {
125 if (!pointEventInjector_->SetPointEvent(dataArray[i])) {
126 return false;
127 }
128 }
129 break;
130 case EventDataType::KEY_TYPE:
131 if (keyEventInjector_ == nullptr) {
132 return false;
133 }
134 for (uint16_t i = 0; i < arrayLength; i++) {
135 if (!keyEventInjector_->SetKey(dataArray[i])) {
136 return false;
137 }
138 }
139 break;
140 default:
141 return false;
142 }
143 return true;
144 }
145
SetClickEvent(const Point & clickPoint)146 bool EventInjector::SetClickEvent(const Point& clickPoint)
147 {
148 uint16_t clickArrayLen = 2; /* 2:click event point */
149 if (clickArrayLen > pointEventInjector_->GetLeftSize()) {
150 GRAPHIC_LOGE("front points need to be read.(left size in pointer queue is not enough)");
151 return false;
152 }
153 bool setResult = true;
154 DeviceData* dataArray = new DeviceData[clickArrayLen];
155 if (dataArray == nullptr) {
156 return false;
157 }
158 dataArray[0].point = clickPoint;
159 dataArray[0].state = InputDevice::STATE_PRESS;
160 dataArray[1].point = clickPoint;
161 dataArray[1].state = InputDevice::STATE_RELEASE;
162 if (!SetInjectEvent(dataArray, clickArrayLen, EventDataType::POINT_TYPE)) {
163 setResult = false;
164 }
165 delete[] dataArray;
166 return setResult;
167 }
168
SetLongPressEvent(const Point & longPressPoint)169 bool EventInjector::SetLongPressEvent(const Point& longPressPoint)
170 {
171 uint16_t pointCount = INDEV_LONG_PRESS_TIME / INDEV_READ_PERIOD + 1;
172 if (pointCount > pointEventInjector_->GetLeftSize()) {
173 GRAPHIC_LOGE("front points need to be read.(left size in pointer queue is not enough)");
174 return false;
175 }
176 bool setResult = true;
177 DeviceData* dataArray = new DeviceData[pointCount];
178 if (dataArray == nullptr) {
179 return false;
180 }
181 for (uint16_t i = 0; i < pointCount; i++) {
182 dataArray[i].point = longPressPoint;
183 dataArray[i].state = InputDevice::STATE_PRESS;
184 }
185 dataArray[pointCount - 1].state = InputDevice::STATE_RELEASE;
186 if (!SetInjectEvent(dataArray, pointCount, EventDataType::POINT_TYPE)) {
187 setResult = false;
188 }
189 delete[] dataArray;
190 return setResult;
191 }
192
SetDragEvent(const Point & startPoint,const Point & endPoint,uint32_t dragTime)193 bool EventInjector::SetDragEvent(const Point& startPoint, const Point& endPoint, uint32_t dragTime)
194 {
195 uint16_t pointCount = (dragTime / INDEV_READ_PERIOD) + 1;
196 /* 3: at least 3 points in drag event */
197 if (pointCount < 3) {
198 GRAPHIC_LOGE("dragTime is too short.(drag event needs at least 3 points)");
199 return false;
200 }
201 if (pointCount > pointEventInjector_->GetLeftSize()) {
202 GRAPHIC_LOGE("dragTime is too long or front points need to be read.(left size in pointer queue is not enough)");
203 return false;
204 }
205 bool setResult = true;
206 int16_t negativeFlag = 1; /* 1:represent the coordinate (x, y) of endPoint is larger than startPoint. */
207 DeviceData* dataArray = new DeviceData[pointCount];
208 if (dataArray == nullptr) {
209 return false;
210 }
211 if (startPoint.x == endPoint.x) {
212 float pointStep = static_cast<float>(MATH_ABS(endPoint.y - startPoint.y)) / (pointCount - 1);
213 if (endPoint.y < startPoint.y) {
214 negativeFlag = -1; /* -1:represent the coordinate y of endPoint is smaller than startPoint. */
215 }
216 for (uint16_t i = 0; i < pointCount; i++) {
217 dataArray[i].point.x = startPoint.x;
218 dataArray[i].point.y = startPoint.y + static_cast<int16_t>(i * negativeFlag * pointStep);
219 dataArray[i].state = InputDevice::STATE_PRESS;
220 }
221 } else {
222 float slope = static_cast<float>(endPoint.y - startPoint.y) / (endPoint.x - startPoint.x);
223 int16_t constPara = startPoint.y - static_cast<int16_t>(slope * startPoint.x);
224 float pointStep = static_cast<float>(MATH_ABS(endPoint.x - startPoint.x)) / (pointCount - 1);
225 if (endPoint.x < startPoint.x) {
226 negativeFlag = -1; /* -1:represent the coordinate x of endPoint is smaller than startPoint. */
227 }
228 for (uint16_t i = 0; i < pointCount; i++) {
229 dataArray[i].point.x = startPoint.x + static_cast<int16_t>(i * negativeFlag * pointStep);
230 dataArray[i].point.y = static_cast<int16_t>(slope * (dataArray[i].point.x)) + constPara;
231 dataArray[i].state = InputDevice::STATE_PRESS;
232 }
233 }
234 dataArray[pointCount - 1].point = endPoint;
235 dataArray[pointCount - 1].state = InputDevice::STATE_RELEASE;
236 if (!SetInjectEvent(dataArray, pointCount, EventDataType::POINT_TYPE)) {
237 setResult = false;
238 }
239 delete[] dataArray;
240 return setResult;
241 }
242
SetKeyEvent(uint16_t keyId,uint16_t state)243 bool EventInjector::SetKeyEvent(uint16_t keyId, uint16_t state)
244 {
245 uint16_t kevArrayLen = 1;
246 if (kevArrayLen > keyEventInjector_->GetLeftSize()) {
247 GRAPHIC_LOGE("front key event need to be read.(left size in key event queue is not enough)");
248 return false;
249 }
250 bool setResult = true;
251 DeviceData* dataArray = new DeviceData[kevArrayLen];
252 if (dataArray == nullptr) {
253 return false;
254 }
255 for (uint16_t i = 0; i < kevArrayLen; i++) {
256 dataArray[i].keyId = keyId;
257 dataArray[i].state = state;
258 }
259 if (!SetInjectEvent(dataArray, kevArrayLen, EventDataType::KEY_TYPE)) {
260 setResult = false;
261 }
262 delete[] dataArray;
263 return setResult;
264 }
265
266 #if ENABLE_WINDOW
SetWindowId(uint8_t windowId)267 void EventInjector::SetWindowId(uint8_t windowId)
268 {
269 if (pointEventInjector_ != nullptr) {
270 pointEventInjector_->SetWindowId(windowId);
271 }
272 }
273 #endif
274 } // namespace OHOS
275 #endif // ENABLE_DEBUG