• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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