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 #ifndef ANDROID_INPUT_HUB_H_ 18 #define ANDROID_INPUT_HUB_H_ 19 20 #include <memory> 21 #include <string> 22 #include <unordered_map> 23 24 #include <utils/String8.h> 25 #include <utils/Timers.h> 26 27 namespace android { 28 29 /** 30 * InputEvent represents an event from the kernel. The fields largely mirror 31 * those found in linux/input.h. 32 */ 33 struct InputEvent { 34 nsecs_t when; 35 36 int32_t type; 37 int32_t code; 38 int32_t value; 39 }; 40 41 /** Describes an absolute axis. */ 42 struct AbsoluteAxisInfo { 43 int32_t minValue = 0; // minimum value 44 int32_t maxValue = 0; // maximum value 45 int32_t flat = 0; // center flat position, e.g. flat == 8 means center is between -8 and 8 46 int32_t fuzz = 0; // error tolerance, e.g. fuzz == 4 means value is +/- 4 due to noise 47 int32_t resolution = 0; // resolution in units per mm or radians per mm 48 }; 49 50 /** 51 * An InputDeviceNode represents a device node in the Linux system. It can be 52 * used to interact with the device, setting and getting property values. 53 * 54 * An InputDeviceNode should only be used on the same thread that is polling for 55 * input events. 56 */ 57 class InputDeviceNode { 58 public: 59 /** Get the Linux device path for the node. */ 60 virtual const std::string& getPath() const = 0; 61 62 /** Get the name of the device returned by the driver. */ 63 virtual const std::string& getName() const = 0; 64 /** Get the location of the device returned by the driver. */ 65 virtual const std::string& getLocation() const = 0; 66 /** Get the unique id of the device returned by the driver. */ 67 virtual const std::string& getUniqueId() const = 0; 68 69 /** Get the bus type of the device returned by the driver. */ 70 virtual uint16_t getBusType() const = 0; 71 /** Get the vendor id of the device returned by the driver. */ 72 virtual uint16_t getVendorId() const = 0; 73 /** Get the product id of the device returned by the driver. */ 74 virtual uint16_t getProductId() const = 0; 75 /** Get the version of the device driver. */ 76 virtual uint16_t getVersion() const = 0; 77 78 /** Returns true if the device has the key. */ 79 virtual bool hasKey(int32_t key) const = 0; 80 /** Returns true if the device has a key in the range [startKey, endKey). */ 81 virtual bool hasKeyInRange(int32_t startKey, int32_t endKey) const = 0; 82 /** Returns true if the device has the relative axis. */ 83 virtual bool hasRelativeAxis(int32_t axis) const = 0; 84 /** Returns true if the device has the absolute axis. */ 85 virtual bool hasAbsoluteAxis(int32_t axis) const = 0; 86 /** Returns true if the device has the switch. */ 87 virtual bool hasSwitch(int32_t sw) const = 0; 88 /** Returns true if the device has the force feedback method. */ 89 virtual bool hasForceFeedback(int32_t ff) const = 0; 90 /** Returns true if the device has the input property. */ 91 virtual bool hasInputProperty(int property) const = 0; 92 93 /** Returns the state of the key. */ 94 virtual int32_t getKeyState(int32_t key) const = 0; 95 /** Returns the state of the switch. */ 96 virtual int32_t getSwitchState(int32_t sw) const = 0; 97 /** Returns information about the absolute axis. */ 98 virtual const AbsoluteAxisInfo* getAbsoluteAxisInfo(int32_t axis) const = 0; 99 /** Returns the value of the absolute axis. */ 100 virtual status_t getAbsoluteAxisValue(int32_t axis, int32_t* outValue) const = 0; 101 102 /** Vibrate the device for duration ns. */ 103 virtual void vibrate(nsecs_t duration) = 0; 104 /** Stop vibration on the device. */ 105 virtual void cancelVibrate() = 0; 106 107 /** Disable key repeat for the device in the driver. */ 108 virtual void disableDriverKeyRepeat() = 0; 109 110 protected: 111 InputDeviceNode() = default; 112 virtual ~InputDeviceNode() = default; 113 }; 114 115 /** Callback interface for receiving input events, including device changes. */ 116 class InputCallbackInterface { 117 public: 118 virtual void onInputEvent(const std::shared_ptr<InputDeviceNode>& node, InputEvent& event, 119 nsecs_t event_time) = 0; 120 virtual void onDeviceAdded(const std::shared_ptr<InputDeviceNode>& node) = 0; 121 virtual void onDeviceRemoved(const std::shared_ptr<InputDeviceNode>& node) = 0; 122 123 protected: 124 InputCallbackInterface() = default; 125 virtual ~InputCallbackInterface() = default; 126 }; 127 128 /** 129 * InputHubInterface is responsible for monitoring a set of device paths and 130 * executing callbacks when events occur. Before calling poll(), you should set 131 * the device and input callbacks, and register your device path(s). 132 */ 133 class InputHubInterface { 134 public: 135 virtual status_t registerDevicePath(const std::string& path) = 0; 136 virtual status_t unregisterDevicePath(const std::string& path) = 0; 137 138 virtual status_t poll() = 0; 139 virtual status_t wake() = 0; 140 141 virtual void dump(String8& dump) = 0; 142 143 protected: 144 InputHubInterface() = default; 145 virtual ~InputHubInterface() = default; 146 }; 147 148 /** 149 * An implementation of InputHubInterface that uses epoll to wait for events. 150 * 151 * This class is not threadsafe. Any functions called on the InputHub should be 152 * called on the same thread that is used to call poll(). The only exception is 153 * wake(), which may be used to return from poll() before an input or device 154 * event occurs. 155 */ 156 class InputHub : public InputHubInterface { 157 public: 158 explicit InputHub(const std::shared_ptr<InputCallbackInterface>& cb); 159 virtual ~InputHub() override; 160 161 virtual status_t registerDevicePath(const std::string& path) override; 162 virtual status_t unregisterDevicePath(const std::string& path) override; 163 164 virtual status_t poll() override; 165 virtual status_t wake() override; 166 167 virtual void dump(String8& dump) override; 168 169 private: 170 status_t readNotify(); 171 status_t scanDir(const std::string& path); 172 std::shared_ptr<InputDeviceNode> openNode(const std::string& path); 173 status_t closeNode(const InputDeviceNode* node); 174 status_t closeNodeByFd(int fd); 175 std::shared_ptr<InputDeviceNode> findNodeByPath(const std::string& path); 176 177 enum class WakeMechanism { 178 /** 179 * The kernel supports the EPOLLWAKEUP flag for epoll_ctl. 180 * 181 * When using this mechanism, epoll_wait will internally acquire a wake 182 * lock whenever one of the FDs it is monitoring becomes ready. The wake 183 * lock is held automatically by the kernel until the next call to 184 * epoll_wait. 185 * 186 * This mechanism only exists in Linux kernel 3.5+. 187 */ 188 EPOLL_WAKEUP, 189 /** 190 * The kernel evdev driver supports the EVIOCSSUSPENDBLOCK ioctl. 191 * 192 * When using this mechanism, the InputHub asks evdev to acquire and 193 * hold a wake lock whenever its buffer is non-empty. We must take care 194 * to acquire our own userspace wake lock before draining the buffer to 195 * prevent actually going back into suspend before we have fully 196 * processed all of the events. 197 * 198 * This mechanism only exists in older Android Linux kernels. 199 */ 200 LEGACY_EVDEV_SUSPENDBLOCK_IOCTL, 201 /** 202 * The kernel doesn't seem to support any special wake mechanism. 203 * 204 * We explicitly acquire and release wake locks when processing input 205 * events. 206 */ 207 LEGACY_EVDEV_EXPLICIT_WAKE_LOCKS, 208 }; 209 WakeMechanism mWakeupMechanism = WakeMechanism::LEGACY_EVDEV_EXPLICIT_WAKE_LOCKS; 210 bool manageWakeLocks() const; 211 bool mNeedToCheckSuspendBlockIoctl = true; 212 213 int mEpollFd; 214 int mINotifyFd; 215 int mWakeEventFd; 216 217 // Callback for input events 218 std::shared_ptr<InputCallbackInterface> mInputCallback; 219 220 // Map from watch descriptors to watched paths 221 std::unordered_map<int, std::string> mWatchedPaths; 222 // Map from file descriptors to InputDeviceNodes 223 std::unordered_map<int, std::shared_ptr<InputDeviceNode>> mDeviceNodes; 224 }; 225 226 } // namespace android 227 228 #endif // ANDROID_INPUT_HUB_H_ 229