xref: /aosp_15_r20/hardware/libhardware/modules/input/evdev/InputHub.h (revision e01b6f769022e40d0923dee176e8dc7cd1d52984)
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