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 23namespace OHOS { 24EventInjector::~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 39EventInjector* EventInjector::GetInstance() 40{ 41 static EventInjector instance; 42 return &instance; 43} 44 45bool 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 74void 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 96bool 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 115bool 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 147bool 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 170bool 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 194bool 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 244bool 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 268void 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