1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "virtual_device_base.h" 18 19 #include <errno.h> 20 #include <inttypes.h> 21 #include <string.h> 22 #include <unistd.h> 23 24 #include "log/log.h" 25 26 using vsoc_input_service::VirtualDeviceBase; 27 28 namespace { 29 30 bool DoIoctl(int fd, int request, const uint32_t value) { 31 int rc = ioctl(fd, request, value); 32 if (rc < 0) { 33 SLOGE("ioctl failed (%s)", strerror(errno)); 34 return false; 35 } 36 return true; 37 } 38 39 } // namespace 40 41 VirtualDeviceBase::VirtualDeviceBase(const char* device_name, 42 uint16_t product_id) 43 : device_name_(device_name), 44 bus_type_(BUS_USB), 45 vendor_id_(0x6006), 46 product_id_(product_id), 47 version_(1) {} 48 49 VirtualDeviceBase::~VirtualDeviceBase() { 50 if (fd_ >= 0) { 51 close(fd_); 52 fd_ = -1; 53 } 54 } 55 56 bool VirtualDeviceBase::SetUp() { 57 fd_ = open("/dev/uinput", O_WRONLY | O_NONBLOCK); 58 if (fd_ < 0) { 59 SLOGE("Failed to open /dev/uinput (%s)", strerror(errno)); 60 return false; 61 } 62 63 strncpy(dev_.name, device_name_, sizeof(dev_.name)); 64 dev_.id.bustype = bus_type_; 65 dev_.id.vendor = vendor_id_; 66 dev_.id.product = product_id_; 67 dev_.id.version = version_; 68 69 for (uint32_t evt_type : GetEventTypes()) { 70 if (!DoIoctl(fd_, UI_SET_EVBIT, evt_type)) { 71 SLOGE("Error setting event type: %" PRIu32, evt_type); 72 return false; 73 } 74 } 75 76 for (uint32_t key : GetKeys()) { 77 if (!DoIoctl(fd_, UI_SET_KEYBIT, key)) { 78 SLOGE("Error setting key: %" PRIu32, key); 79 return false; 80 } 81 } 82 83 for (uint32_t property : GetProperties()) { 84 if (!DoIoctl(fd_, UI_SET_PROPBIT, property)) { 85 SLOGE("Error setting property: %" PRIu32, property); 86 return false; 87 } 88 } 89 90 for (uint32_t abs : GetAbs()) { 91 if (!DoIoctl(fd_, UI_SET_ABSBIT, abs)) { 92 SLOGE("Error setting abs: %" PRIu32, abs); 93 return false; 94 } 95 } 96 97 if (write(fd_, &dev_, sizeof(dev_)) < 0) { 98 SLOGE("Unable to set input device info (%s)", strerror(errno)); 99 return false; 100 } 101 if (ioctl(fd_, UI_DEV_CREATE) < 0) { 102 SLOGE("Unable to create input device (%s)", strerror(errno)); 103 return false; 104 } 105 106 return true; 107 } 108 109 bool VirtualDeviceBase::EmitEvent(uint16_t type, 110 uint16_t code, 111 uint32_t value) { 112 struct input_event event {}; 113 event.type = type; 114 event.code = code; 115 event.value = value; 116 117 if (write(fd_, &event, sizeof(event)) < static_cast<ssize_t>(sizeof(event))) { 118 SLOGE("Event write failed (%s): aborting", strerror(errno)); 119 return false; 120 } 121 return true; 122 } 123 124 // By default devices have no event types, keys, properties or absolutes, 125 // subclasses can override this behavior if necessary. 126 const std::vector<const uint32_t>& VirtualDeviceBase::GetEventTypes() const { 127 static const std::vector<const uint32_t> evt_types{}; 128 return evt_types; 129 } 130 const std::vector<const uint32_t>& VirtualDeviceBase::GetKeys() const { 131 static const std::vector<const uint32_t> keys{}; 132 return keys; 133 } 134 const std::vector<const uint32_t>& VirtualDeviceBase::GetProperties() const { 135 static const std::vector<const uint32_t> properties{}; 136 return properties; 137 } 138 const std::vector<const uint32_t>& VirtualDeviceBase::GetAbs() const { 139 static const std::vector<const uint32_t> abs{}; 140 return abs; 141 } 142