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