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