1/* 2 * Copyright (c) 2021-2022 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 "virtual_device.h" 17 18#include <fcntl.h> 19#include <securec.h> 20#include <unistd.h> 21 22#include "mmi_log.h" 23 24#undef MMI_LOG_TAG 25#define MMI_LOG_TAG "VirtualDevice" 26 27namespace OHOS { 28namespace MMI { 29namespace { 30using namespace OHOS::HiviewDFX; 31constexpr uint32_t MAX_NAME_LENGTH { 80 }; 32 33bool DoIoctl(int32_t fd, int32_t request, const uint32_t value) 34{ 35 int32_t rc = ioctl(fd, request, value); 36 if (rc < 0) { 37 MMI_HILOGE("Failed to ioctl"); 38 return false; 39 } 40 return true; 41} 42} // namespace 43 44VirtualDevice::VirtualDevice(const char *deviceName, uint16_t productId) 45 : deviceName_(deviceName), 46 busType_(BUS_USB), 47 vendorId_(0x6006), 48 productId_(productId), 49 version_(1) {} 50 51VirtualDevice::~VirtualDevice() 52{ 53 if (fd_ >= 0) { 54 ioctl(fd_, UI_DEV_DESTROY); 55 close(fd_); 56 fd_ = -1; 57 } 58} 59 60bool VirtualDevice::SetUp() 61{ 62 fd_ = open("/dev/uinput", O_WRONLY | O_NONBLOCK); 63 if (fd_ < 0) { 64 MMI_HILOGE("Failed to open uinput"); 65 return false; 66 } 67 for (const auto &item : GetEventTypes()) { 68 if (!DoIoctl(fd_, UI_SET_EVBIT, item)) { 69 MMI_HILOGE("Error setting event type:%{public}u", item); 70 return false; 71 } 72 } 73 for (const auto &item : GetKeys()) { 74 if (!DoIoctl(fd_, UI_SET_KEYBIT, item)) { 75 MMI_HILOGE("Error setting key:%{public}u", item); 76 return false; 77 } 78 } 79 for (const auto &item : GetProperties()) { 80 if (!DoIoctl(fd_, UI_SET_PROPBIT, item)) { 81 MMI_HILOGE("Error setting property:%{public}u", item); 82 return false; 83 } 84 } 85 for (const auto &item : GetAbs()) { 86 if (!DoIoctl(fd_, UI_SET_ABSBIT, item)) { 87 MMI_HILOGE("Error setting property:%{public}u", item); 88 return false; 89 } 90 } 91 for (const auto &item : GetRelBits()) { 92 if (!DoIoctl(fd_, UI_SET_RELBIT, item)) { 93 MMI_HILOGE("Error setting rel:%{public}u", item); 94 return false; 95 } 96 } 97 98 return SetUpExt(); 99} 100 101bool VirtualDevice::SetUpExt() 102{ 103 errno_t ret = strncpy_s(dev_.name, MAX_NAME_LENGTH, deviceName_, sizeof(dev_.name)); 104 if (ret != EOK) { 105 MMI_HILOGE("Failed to copy deviceName"); 106 return false; 107 } 108 dev_.id.bustype = busType_; 109 dev_.id.vendor = vendorId_; 110 dev_.id.product = productId_; 111 dev_.id.version = version_; 112 if (write(fd_, &dev_, sizeof(dev_)) < 0) { 113 MMI_HILOGE("Unable to set input device info"); 114 return false; 115 } 116 if (ioctl(fd_, UI_DEV_CREATE) < 0) { 117 MMI_HILOGE("Unable to create input device"); 118 return false; 119 } 120 return true; 121} 122 123bool VirtualDevice::EmitEvent(uint16_t type, uint16_t code, uint32_t value) const 124{ 125 struct input_event event {}; 126 event.type = type; 127 event.code = code; 128 event.value = value; 129#ifndef __MUSL__ 130 gettimeofday(&event.time, nullptr); 131#endif 132 if (write(fd_, &event, sizeof(event)) < static_cast<ssize_t>(sizeof(event))) { 133 MMI_HILOGE("Event write failed"); 134 return false; 135 } 136 return true; 137} 138 139const std::vector<uint32_t> &VirtualDevice::GetEventTypes() const 140{ 141 static const std::vector<uint32_t> evtTypes {}; 142 return evtTypes; 143} 144 145const std::vector<uint32_t> &VirtualDevice::GetKeys() const 146{ 147 static const std::vector<uint32_t> keys {}; 148 return keys; 149} 150 151const std::vector<uint32_t> &VirtualDevice::GetProperties() const 152{ 153 static const std::vector<uint32_t> properties {}; 154 return properties; 155} 156 157const std::vector<uint32_t> &VirtualDevice::GetAbs() const 158{ 159 static const std::vector<uint32_t> abs {}; 160 return abs; 161} 162 163const std::vector<uint32_t> &VirtualDevice::GetRelBits() const 164{ 165 static const std::vector<uint32_t> relBits {}; 166 return relBits; 167} 168} 169} 170