1 /* 2 * Copyright (C) 2015 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 #define LOG_TAG "InputDevice" 18 //#define LOG_NDEBUG 0 19 20 // Enables debug output for processing input events 21 #define DEBUG_INPUT_EVENTS 0 22 23 #include "InputDevice.h" 24 25 #include <linux/input.h> 26 27 #define __STDC_FORMAT_MACROS 28 #include <cinttypes> 29 #include <cstdlib> 30 #include <string> 31 32 #include <utils/Log.h> 33 #include <utils/Timers.h> 34 35 #include "InputHost.h" 36 #include "InputHub.h" 37 #include "MouseInputMapper.h" 38 #include "SwitchInputMapper.h" 39 40 #define MSC_ANDROID_TIME_SEC 0x6 41 #define MSC_ANDROID_TIME_USEC 0x7 42 43 namespace android { 44 45 static InputBus getInputBus(const std::shared_ptr<InputDeviceNode>& node) { 46 switch (node->getBusType()) { 47 case BUS_USB: 48 return INPUT_BUS_USB; 49 case BUS_BLUETOOTH: 50 return INPUT_BUS_BT; 51 case BUS_RS232: 52 return INPUT_BUS_SERIAL; 53 default: 54 // TODO: check for other linux bus types that might not be built-in 55 return INPUT_BUS_BUILTIN; 56 } 57 } 58 59 static uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) { 60 // Touch devices get dibs on touch-related axes. 61 if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) { 62 switch (axis) { 63 case ABS_X: 64 case ABS_Y: 65 case ABS_PRESSURE: 66 case ABS_TOOL_WIDTH: 67 case ABS_DISTANCE: 68 case ABS_TILT_X: 69 case ABS_TILT_Y: 70 case ABS_MT_SLOT: 71 case ABS_MT_TOUCH_MAJOR: 72 case ABS_MT_TOUCH_MINOR: 73 case ABS_MT_WIDTH_MAJOR: 74 case ABS_MT_WIDTH_MINOR: 75 case ABS_MT_ORIENTATION: 76 case ABS_MT_POSITION_X: 77 case ABS_MT_POSITION_Y: 78 case ABS_MT_TOOL_TYPE: 79 case ABS_MT_BLOB_ID: 80 case ABS_MT_TRACKING_ID: 81 case ABS_MT_PRESSURE: 82 case ABS_MT_DISTANCE: 83 return INPUT_DEVICE_CLASS_TOUCH; 84 } 85 } 86 87 // External stylus gets the pressure axis 88 if (deviceClasses & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) { 89 if (axis == ABS_PRESSURE) { 90 return INPUT_DEVICE_CLASS_EXTERNAL_STYLUS; 91 } 92 } 93 94 // Joystick devices get the rest. 95 return INPUT_DEVICE_CLASS_JOYSTICK; 96 } 97 98 EvdevDevice::EvdevDevice(InputHostInterface* host, const std::shared_ptr<InputDeviceNode>& node) : 99 mHost(host), mDeviceNode(node), mDeviceDefinition(mHost->createDeviceDefinition()) { 100 101 InputBus bus = getInputBus(node); 102 mInputId = mHost->createDeviceIdentifier( 103 node->getName().c_str(), 104 node->getProductId(), 105 node->getVendorId(), 106 bus, 107 node->getUniqueId().c_str()); 108 109 createMappers(); 110 configureDevice(); 111 112 // If we found a need for at least one mapper, register the device with the 113 // host. If there were no mappers, this device is effectively ignored, as 114 // the host won't know about it. 115 if (mMappers.size() > 0) { 116 mDeviceHandle = mHost->registerDevice(mInputId, mDeviceDefinition); 117 for (const auto& mapper : mMappers) { 118 mapper->setDeviceHandle(mDeviceHandle); 119 } 120 } 121 } 122 123 void EvdevDevice::createMappers() { 124 // See if this is a cursor device such as a trackball or mouse. 125 if (mDeviceNode->hasKey(BTN_MOUSE) 126 && mDeviceNode->hasRelativeAxis(REL_X) 127 && mDeviceNode->hasRelativeAxis(REL_Y)) { 128 mClasses |= INPUT_DEVICE_CLASS_CURSOR; 129 mMappers.push_back(std::make_unique<MouseInputMapper>()); 130 } 131 132 bool isStylus = false; 133 bool haveGamepadButtons = mDeviceNode->hasKeyInRange(BTN_MISC, BTN_MOUSE) || 134 mDeviceNode->hasKeyInRange(BTN_JOYSTICK, BTN_DIGI); 135 136 // See if this is a touch pad or stylus. 137 // Is this a new modern multi-touch driver? 138 if (mDeviceNode->hasAbsoluteAxis(ABS_MT_POSITION_X) 139 && mDeviceNode->hasAbsoluteAxis(ABS_MT_POSITION_Y)) { 140 // Some joysticks such as the PS3 controller report axes that conflict 141 // with the ABS_MT range. Try to confirm that the device really is a 142 // touch screen. 143 if (mDeviceNode->hasKey(BTN_TOUCH) || !haveGamepadButtons) { 144 mClasses |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT; 145 //mMappers.push_back(std::make_unique<MultiTouchInputMapper>()); 146 } 147 // Is this an old style single-touch driver? 148 } else if (mDeviceNode->hasKey(BTN_TOUCH) 149 && mDeviceNode->hasAbsoluteAxis(ABS_X) 150 && mDeviceNode->hasAbsoluteAxis(ABS_Y)) { 151 mClasses |= INPUT_DEVICE_CLASS_TOUCH; 152 //mMappers.push_back(std::make_unique<SingleTouchInputMapper>()); 153 // Is this a BT stylus? 154 } else if ((mDeviceNode->hasAbsoluteAxis(ABS_PRESSURE) || mDeviceNode->hasKey(BTN_TOUCH)) 155 && !mDeviceNode->hasAbsoluteAxis(ABS_X) && !mDeviceNode->hasAbsoluteAxis(ABS_Y)) { 156 mClasses |= INPUT_DEVICE_CLASS_EXTERNAL_STYLUS; 157 //mMappers.push_back(std::make_unique<ExternalStylusInputMapper>()); 158 isStylus = true; 159 mClasses &= ~INPUT_DEVICE_CLASS_KEYBOARD; 160 } 161 162 // See if this is a keyboard. Ignore everything in the button range except 163 // for joystick and gamepad buttons which are handled like keyboards for the 164 // most part. 165 // Keyboard will try to claim some of the stylus buttons but we really want 166 // to reserve those so we can fuse it with the touch screen data. Note this 167 // means an external stylus cannot also be a keyboard device. 168 if (!isStylus) { 169 bool haveKeyboardKeys = mDeviceNode->hasKeyInRange(0, BTN_MISC) || 170 mDeviceNode->hasKeyInRange(KEY_OK, KEY_CNT); 171 if (haveKeyboardKeys || haveGamepadButtons) { 172 mClasses |= INPUT_DEVICE_CLASS_KEYBOARD; 173 //mMappers.push_back(std::make_unique<KeyboardInputMapper>()); 174 } 175 } 176 177 // See if this device is a joystick. 178 // Assumes that joysticks always have gamepad buttons in order to 179 // distinguish them from other devices such as accelerometers that also have 180 // absolute axes. 181 if (haveGamepadButtons) { 182 uint32_t assumedClasses = mClasses | INPUT_DEVICE_CLASS_JOYSTICK; 183 for (int i = 0; i < ABS_CNT; ++i) { 184 if (mDeviceNode->hasAbsoluteAxis(i) 185 && getAbsAxisUsage(i, assumedClasses) == INPUT_DEVICE_CLASS_JOYSTICK) { 186 mClasses = assumedClasses; 187 //mMappers.push_back(std::make_unique<JoystickInputMapper>()); 188 break; 189 } 190 } 191 } 192 193 // Check whether this device has switches. 194 for (int i = 0; i < SW_CNT; ++i) { 195 if (mDeviceNode->hasSwitch(i)) { 196 mClasses |= INPUT_DEVICE_CLASS_SWITCH; 197 mMappers.push_back(std::make_unique<SwitchInputMapper>()); 198 break; 199 } 200 } 201 202 // Check whether this device supports the vibrator. 203 // TODO: decide if this is necessary. 204 if (mDeviceNode->hasForceFeedback(FF_RUMBLE)) { 205 mClasses |= INPUT_DEVICE_CLASS_VIBRATOR; 206 //mMappers.push_back(std::make_unique<VibratorInputMapper>()); 207 } 208 209 ALOGD("device %s classes=0x%x %zu mappers", mDeviceNode->getPath().c_str(), mClasses, 210 mMappers.size()); 211 } 212 213 void EvdevDevice::configureDevice() { 214 for (const auto& mapper : mMappers) { 215 auto reportDef = mHost->createInputReportDefinition(); 216 if (mapper->configureInputReport(mDeviceNode.get(), reportDef)) { 217 mDeviceDefinition->addReport(reportDef); 218 } else { 219 mHost->freeReportDefinition(reportDef); 220 } 221 222 reportDef = mHost->createOutputReportDefinition(); 223 if (mapper->configureOutputReport(mDeviceNode.get(), reportDef)) { 224 mDeviceDefinition->addReport(reportDef); 225 } else { 226 mHost->freeReportDefinition(reportDef); 227 } 228 } 229 } 230 231 void EvdevDevice::processInput(InputEvent& event, nsecs_t currentTime) { 232 #if DEBUG_INPUT_EVENTS 233 std::string log; 234 log.append("---InputEvent for device %s---\n"); 235 log.append(" when: %" PRId64 "\n"); 236 log.append(" type: %d\n"); 237 log.append(" code: %d\n"); 238 log.append(" value: %d\n"); 239 ALOGD(log.c_str(), mDeviceNode->getPath().c_str(), event.when, event.type, event.code, 240 event.value); 241 #endif 242 243 if (event.type == EV_MSC) { 244 if (event.code == MSC_ANDROID_TIME_SEC) { 245 mOverrideSec = event.value; 246 } else if (event.code == MSC_ANDROID_TIME_USEC) { 247 mOverrideUsec = event.value; 248 } 249 return; 250 } 251 252 if (mOverrideSec || mOverrideUsec) { 253 event.when = s2ns(mOverrideSec) + us2ns(mOverrideUsec); 254 ALOGV("applied override time %d.%06d", mOverrideSec, mOverrideUsec); 255 256 if (event.type == EV_SYN && event.code == SYN_REPORT) { 257 mOverrideSec = 0; 258 mOverrideUsec = 0; 259 } 260 } 261 262 // Bug 7291243: Add a guard in case the kernel generates timestamps 263 // that appear to be far into the future because they were generated 264 // using the wrong clock source. 265 // 266 // This can happen because when the input device is initially opened 267 // it has a default clock source of CLOCK_REALTIME. Any input events 268 // enqueued right after the device is opened will have timestamps 269 // generated using CLOCK_REALTIME. We later set the clock source 270 // to CLOCK_MONOTONIC but it is already too late. 271 // 272 // Invalid input event timestamps can result in ANRs, crashes and 273 // and other issues that are hard to track down. We must not let them 274 // propagate through the system. 275 // 276 // Log a warning so that we notice the problem and recover gracefully. 277 if (event.when >= currentTime + s2ns(10)) { 278 // Double-check. Time may have moved on. 279 auto time = systemTime(SYSTEM_TIME_MONOTONIC); 280 if (event.when > time) { 281 ALOGW("An input event from %s has a timestamp that appears to have " 282 "been generated using the wrong clock source (expected " 283 "CLOCK_MONOTONIC): event time %" PRId64 ", current time %" PRId64 284 ", call time %" PRId64 ". Using current time instead.", 285 mDeviceNode->getPath().c_str(), event.when, time, currentTime); 286 event.when = time; 287 } else { 288 ALOGV("Event time is ok but failed the fast path and required an extra " 289 "call to systemTime: event time %" PRId64 ", current time %" PRId64 290 ", call time %" PRId64 ".", event.when, time, currentTime); 291 } 292 } 293 294 for (size_t i = 0; i < mMappers.size(); ++i) { 295 mMappers[i]->process(event); 296 } 297 } 298 299 } // namespace android 300