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