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