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 static bool getBooleanProperty(const InputProperty& prop) { 99 const char* propValue = prop.getValue(); 100 if (propValue == nullptr) return false; 101 102 char* end; 103 int value = std::strtol(propValue, &end, 10); 104 if (*end != '\0') { 105 ALOGW("Expected boolean for property %s; value=%s", prop.getKey(), propValue); 106 return false; 107 } 108 return value; 109 } 110 111 EvdevDevice::EvdevDevice(InputHostInterface* host, const std::shared_ptr<InputDeviceNode>& node) : 112 mHost(host), mDeviceNode(node), mDeviceDefinition(mHost->createDeviceDefinition()) { 113 114 InputBus bus = getInputBus(node); 115 mInputId = mHost->createDeviceIdentifier( 116 node->getName().c_str(), 117 node->getProductId(), 118 node->getVendorId(), 119 bus, 120 node->getUniqueId().c_str()); 121 122 createMappers(); 123 configureDevice(); 124 125 // If we found a need for at least one mapper, register the device with the 126 // host. If there were no mappers, this device is effectively ignored, as 127 // the host won't know about it. 128 if (mMappers.size() > 0) { 129 mDeviceHandle = mHost->registerDevice(mInputId, mDeviceDefinition); 130 for (const auto& mapper : mMappers) { 131 mapper->setDeviceHandle(mDeviceHandle); 132 } 133 } 134 } 135 136 void EvdevDevice::createMappers() { 137 // See if this is a cursor device such as a trackball or mouse. 138 if (mDeviceNode->hasKey(BTN_MOUSE) 139 && mDeviceNode->hasRelativeAxis(REL_X) 140 && mDeviceNode->hasRelativeAxis(REL_Y)) { 141 mClasses |= INPUT_DEVICE_CLASS_CURSOR; 142 mMappers.push_back(std::make_unique<MouseInputMapper>()); 143 } 144 145 bool isStylus = false; 146 bool haveGamepadButtons = mDeviceNode->hasKeyInRange(BTN_MISC, BTN_MOUSE) || 147 mDeviceNode->hasKeyInRange(BTN_JOYSTICK, BTN_DIGI); 148 149 // See if this is a touch pad or stylus. 150 // Is this a new modern multi-touch driver? 151 if (mDeviceNode->hasAbsoluteAxis(ABS_MT_POSITION_X) 152 && mDeviceNode->hasAbsoluteAxis(ABS_MT_POSITION_Y)) { 153 // Some joysticks such as the PS3 controller report axes that conflict 154 // with the ABS_MT range. Try to confirm that the device really is a 155 // touch screen. 156 if (mDeviceNode->hasKey(BTN_TOUCH) || !haveGamepadButtons) { 157 mClasses |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT; 158 //mMappers.push_back(std::make_unique<MultiTouchInputMapper>()); 159 } 160 // Is this an old style single-touch driver? 161 } else if (mDeviceNode->hasKey(BTN_TOUCH) 162 && mDeviceNode->hasAbsoluteAxis(ABS_X) 163 && mDeviceNode->hasAbsoluteAxis(ABS_Y)) { 164 mClasses |= INPUT_DEVICE_CLASS_TOUCH; 165 //mMappers.push_back(std::make_unique<SingleTouchInputMapper>()); 166 // Is this a BT stylus? 167 } else if ((mDeviceNode->hasAbsoluteAxis(ABS_PRESSURE) || mDeviceNode->hasKey(BTN_TOUCH)) 168 && !mDeviceNode->hasAbsoluteAxis(ABS_X) && !mDeviceNode->hasAbsoluteAxis(ABS_Y)) { 169 mClasses |= INPUT_DEVICE_CLASS_EXTERNAL_STYLUS; 170 //mMappers.push_back(std::make_unique<ExternalStylusInputMapper>()); 171 isStylus = true; 172 mClasses &= ~INPUT_DEVICE_CLASS_KEYBOARD; 173 } 174 175 // See if this is a keyboard. Ignore everything in the button range except 176 // for joystick and gamepad buttons which are handled like keyboards for the 177 // most part. 178 // Keyboard will try to claim some of the stylus buttons but we really want 179 // to reserve those so we can fuse it with the touch screen data. Note this 180 // means an external stylus cannot also be a keyboard device. 181 if (!isStylus) { 182 bool haveKeyboardKeys = mDeviceNode->hasKeyInRange(0, BTN_MISC) || 183 mDeviceNode->hasKeyInRange(KEY_OK, KEY_CNT); 184 if (haveKeyboardKeys || haveGamepadButtons) { 185 mClasses |= INPUT_DEVICE_CLASS_KEYBOARD; 186 //mMappers.push_back(std::make_unique<KeyboardInputMapper>()); 187 } 188 } 189 190 // See if this device is a joystick. 191 // Assumes that joysticks always have gamepad buttons in order to 192 // distinguish them from other devices such as accelerometers that also have 193 // absolute axes. 194 if (haveGamepadButtons) { 195 uint32_t assumedClasses = mClasses | INPUT_DEVICE_CLASS_JOYSTICK; 196 for (int i = 0; i < ABS_CNT; ++i) { 197 if (mDeviceNode->hasAbsoluteAxis(i) 198 && getAbsAxisUsage(i, assumedClasses) == INPUT_DEVICE_CLASS_JOYSTICK) { 199 mClasses = assumedClasses; 200 //mMappers.push_back(std::make_unique<JoystickInputMapper>()); 201 break; 202 } 203 } 204 } 205 206 // Check whether this device has switches. 207 for (int i = 0; i < SW_CNT; ++i) { 208 if (mDeviceNode->hasSwitch(i)) { 209 mClasses |= INPUT_DEVICE_CLASS_SWITCH; 210 mMappers.push_back(std::make_unique<SwitchInputMapper>()); 211 break; 212 } 213 } 214 215 // Check whether this device supports the vibrator. 216 // TODO: decide if this is necessary. 217 if (mDeviceNode->hasForceFeedback(FF_RUMBLE)) { 218 mClasses |= INPUT_DEVICE_CLASS_VIBRATOR; 219 //mMappers.push_back(std::make_unique<VibratorInputMapper>()); 220 } 221 222 ALOGD("device %s classes=0x%x %zu mappers", mDeviceNode->getPath().c_str(), mClasses, 223 mMappers.size()); 224 } 225 226 void EvdevDevice::configureDevice() { 227 for (const auto& mapper : mMappers) { 228 auto reportDef = mHost->createInputReportDefinition(); 229 if (mapper->configureInputReport(mDeviceNode.get(), reportDef)) { 230 mDeviceDefinition->addReport(reportDef); 231 } else { 232 mHost->freeReportDefinition(reportDef); 233 } 234 235 reportDef = mHost->createOutputReportDefinition(); 236 if (mapper->configureOutputReport(mDeviceNode.get(), reportDef)) { 237 mDeviceDefinition->addReport(reportDef); 238 } else { 239 mHost->freeReportDefinition(reportDef); 240 } 241 } 242 } 243 244 void EvdevDevice::processInput(InputEvent& event, nsecs_t currentTime) { 245 #if DEBUG_INPUT_EVENTS 246 std::string log; 247 log.append("---InputEvent for device %s---\n"); 248 log.append(" when: %" PRId64 "\n"); 249 log.append(" type: %d\n"); 250 log.append(" code: %d\n"); 251 log.append(" value: %d\n"); 252 ALOGD(log.c_str(), mDeviceNode->getPath().c_str(), event.when, event.type, event.code, 253 event.value); 254 #endif 255 256 if (event.type == EV_MSC) { 257 if (event.code == MSC_ANDROID_TIME_SEC) { 258 mOverrideSec = event.value; 259 } else if (event.code == MSC_ANDROID_TIME_USEC) { 260 mOverrideUsec = event.value; 261 } 262 return; 263 } 264 265 if (mOverrideSec || mOverrideUsec) { 266 event.when = s2ns(mOverrideSec) + us2ns(mOverrideUsec); 267 ALOGV("applied override time %d.%06d", mOverrideSec, mOverrideUsec); 268 269 if (event.type == EV_SYN && event.code == SYN_REPORT) { 270 mOverrideSec = 0; 271 mOverrideUsec = 0; 272 } 273 } 274 275 // Bug 7291243: Add a guard in case the kernel generates timestamps 276 // that appear to be far into the future because they were generated 277 // using the wrong clock source. 278 // 279 // This can happen because when the input device is initially opened 280 // it has a default clock source of CLOCK_REALTIME. Any input events 281 // enqueued right after the device is opened will have timestamps 282 // generated using CLOCK_REALTIME. We later set the clock source 283 // to CLOCK_MONOTONIC but it is already too late. 284 // 285 // Invalid input event timestamps can result in ANRs, crashes and 286 // and other issues that are hard to track down. We must not let them 287 // propagate through the system. 288 // 289 // Log a warning so that we notice the problem and recover gracefully. 290 if (event.when >= currentTime + s2ns(10)) { 291 // Double-check. Time may have moved on. 292 auto time = systemTime(SYSTEM_TIME_MONOTONIC); 293 if (event.when > time) { 294 ALOGW("An input event from %s has a timestamp that appears to have " 295 "been generated using the wrong clock source (expected " 296 "CLOCK_MONOTONIC): event time %" PRId64 ", current time %" PRId64 297 ", call time %" PRId64 ". Using current time instead.", 298 mDeviceNode->getPath().c_str(), event.when, time, currentTime); 299 event.when = time; 300 } else { 301 ALOGV("Event time is ok but failed the fast path and required an extra " 302 "call to systemTime: event time %" PRId64 ", current time %" PRId64 303 ", call time %" PRId64 ".", event.when, time, currentTime); 304 } 305 } 306 307 for (size_t i = 0; i < mMappers.size(); ++i) { 308 mMappers[i]->process(event); 309 } 310 } 311 312 } // namespace android 313