1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gonk/libui/EventHub.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,435 @@ 1.4 +/* 1.5 + * Copyright (C) 2005 The Android Open Source Project 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * Unless required by applicable law or agreed to in writing, software 1.14 + * distributed under the License is distributed on an "AS IS" BASIS, 1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.16 + * See the License for the specific language governing permissions and 1.17 + * limitations under the License. 1.18 + */ 1.19 + 1.20 +// 1.21 +#ifndef _RUNTIME_EVENT_HUB_H 1.22 +#define _RUNTIME_EVENT_HUB_H 1.23 + 1.24 +#include "Input.h" 1.25 +#include "InputDevice.h" 1.26 +#include "Keyboard.h" 1.27 +#include "KeyLayoutMap.h" 1.28 +#include "KeyCharacterMap.h" 1.29 +#include "VirtualKeyMap.h" 1.30 +#include <utils/String8.h> 1.31 +#include <utils/threads.h> 1.32 +#include "cutils_log.h" 1.33 +#include <utils/threads.h> 1.34 +#include <utils/List.h> 1.35 +#include <utils/Errors.h> 1.36 +#include <utils/PropertyMap.h> 1.37 +#include <utils/Vector.h> 1.38 +#include <utils/KeyedVector.h> 1.39 + 1.40 +#include "linux_input.h" 1.41 +#include <sys/epoll.h> 1.42 + 1.43 +/* Convenience constants. */ 1.44 + 1.45 +#define BTN_FIRST 0x100 // first button code 1.46 +#define BTN_LAST 0x15f // last button code 1.47 + 1.48 +/* 1.49 + * These constants are used privately in Android to pass raw timestamps 1.50 + * through evdev from uinput device drivers because there is currently no 1.51 + * other way to transfer this information. The evdev driver automatically 1.52 + * timestamps all input events with the time they were posted and clobbers 1.53 + * whatever information was passed in. 1.54 + * 1.55 + * For the purposes of this hack, the timestamp is specified in the 1.56 + * CLOCK_MONOTONIC timebase and is split into two EV_MSC events specifying 1.57 + * seconds and microseconds. 1.58 + */ 1.59 +#define MSC_ANDROID_TIME_SEC 0x6 1.60 +#define MSC_ANDROID_TIME_USEC 0x7 1.61 + 1.62 +namespace android { 1.63 + 1.64 +enum { 1.65 + // Device id of a special "virtual" keyboard that is always present. 1.66 + VIRTUAL_KEYBOARD_ID = -1, 1.67 + // Device id of the "built-in" keyboard if there is one. 1.68 + BUILT_IN_KEYBOARD_ID = 0, 1.69 +}; 1.70 + 1.71 +/* 1.72 + * A raw event as retrieved from the EventHub. 1.73 + */ 1.74 +struct RawEvent { 1.75 + nsecs_t when; 1.76 + int32_t deviceId; 1.77 + int32_t type; 1.78 + int32_t code; 1.79 + int32_t value; 1.80 +}; 1.81 + 1.82 +/* Describes an absolute axis. */ 1.83 +struct RawAbsoluteAxisInfo { 1.84 + bool valid; // true if the information is valid, false otherwise 1.85 + 1.86 + int32_t minValue; // minimum value 1.87 + int32_t maxValue; // maximum value 1.88 + int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8 1.89 + int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise 1.90 + int32_t resolution; // resolution in units per mm or radians per mm 1.91 + 1.92 + inline void clear() { 1.93 + valid = false; 1.94 + minValue = 0; 1.95 + maxValue = 0; 1.96 + flat = 0; 1.97 + fuzz = 0; 1.98 + resolution = 0; 1.99 + } 1.100 +}; 1.101 + 1.102 +/* 1.103 + * Input device classes. 1.104 + */ 1.105 +enum { 1.106 + /* The input device is a keyboard or has buttons. */ 1.107 + INPUT_DEVICE_CLASS_KEYBOARD = 0x00000001, 1.108 + 1.109 + /* The input device is an alpha-numeric keyboard (not just a dial pad). */ 1.110 + INPUT_DEVICE_CLASS_ALPHAKEY = 0x00000002, 1.111 + 1.112 + /* The input device is a touchscreen or a touchpad (either single-touch or multi-touch). */ 1.113 + INPUT_DEVICE_CLASS_TOUCH = 0x00000004, 1.114 + 1.115 + /* The input device is a cursor device such as a trackball or mouse. */ 1.116 + INPUT_DEVICE_CLASS_CURSOR = 0x00000008, 1.117 + 1.118 + /* The input device is a multi-touch touchscreen. */ 1.119 + INPUT_DEVICE_CLASS_TOUCH_MT = 0x00000010, 1.120 + 1.121 + /* The input device is a directional pad (implies keyboard, has DPAD keys). */ 1.122 + INPUT_DEVICE_CLASS_DPAD = 0x00000020, 1.123 + 1.124 + /* The input device is a gamepad (implies keyboard, has BUTTON keys). */ 1.125 + INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040, 1.126 + 1.127 + /* The input device has switches. */ 1.128 + INPUT_DEVICE_CLASS_SWITCH = 0x00000080, 1.129 + 1.130 + /* The input device is a joystick (implies gamepad, has joystick absolute axes). */ 1.131 + INPUT_DEVICE_CLASS_JOYSTICK = 0x00000100, 1.132 + 1.133 + /* The input device has a vibrator (supports FF_RUMBLE). */ 1.134 + INPUT_DEVICE_CLASS_VIBRATOR = 0x00000200, 1.135 + 1.136 + /* The input device is virtual (not a real device, not part of UI configuration). */ 1.137 + INPUT_DEVICE_CLASS_VIRTUAL = 0x40000000, 1.138 + 1.139 + /* The input device is external (not built-in). */ 1.140 + INPUT_DEVICE_CLASS_EXTERNAL = 0x80000000, 1.141 +}; 1.142 + 1.143 +/* 1.144 + * Gets the class that owns an axis, in cases where multiple classes might claim 1.145 + * the same axis for different purposes. 1.146 + */ 1.147 +extern uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses); 1.148 + 1.149 +/* 1.150 + * Grand Central Station for events. 1.151 + * 1.152 + * The event hub aggregates input events received across all known input 1.153 + * devices on the system, including devices that may be emulated by the simulator 1.154 + * environment. In addition, the event hub generates fake input events to indicate 1.155 + * when devices are added or removed. 1.156 + * 1.157 + * The event hub provides a stream of input events (via the getEvent function). 1.158 + * It also supports querying the current actual state of input devices such as identifying 1.159 + * which keys are currently down. Finally, the event hub keeps track of the capabilities of 1.160 + * individual input devices, such as their class and the set of key codes that they support. 1.161 + */ 1.162 +class EventHubInterface : public virtual RefBase { 1.163 +protected: 1.164 + EventHubInterface() { } 1.165 + virtual ~EventHubInterface() { } 1.166 + 1.167 +public: 1.168 + // Synthetic raw event type codes produced when devices are added or removed. 1.169 + enum { 1.170 + // Sent when a device is added. 1.171 + DEVICE_ADDED = 0x10000000, 1.172 + // Sent when a device is removed. 1.173 + DEVICE_REMOVED = 0x20000000, 1.174 + // Sent when all added/removed devices from the most recent scan have been reported. 1.175 + // This event is always sent at least once. 1.176 + FINISHED_DEVICE_SCAN = 0x30000000, 1.177 + 1.178 + FIRST_SYNTHETIC_EVENT = DEVICE_ADDED, 1.179 + }; 1.180 + 1.181 + virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0; 1.182 + 1.183 + virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const = 0; 1.184 + 1.185 + virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0; 1.186 + 1.187 + virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, 1.188 + RawAbsoluteAxisInfo* outAxisInfo) const = 0; 1.189 + 1.190 + virtual bool hasRelativeAxis(int32_t deviceId, int axis) const = 0; 1.191 + 1.192 + virtual bool hasInputProperty(int32_t deviceId, int property) const = 0; 1.193 + 1.194 + virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, 1.195 + int32_t* outKeycode, uint32_t* outFlags) const = 0; 1.196 + 1.197 + virtual status_t mapAxis(int32_t deviceId, int32_t scanCode, 1.198 + AxisInfo* outAxisInfo) const = 0; 1.199 + 1.200 + // Sets devices that are excluded from opening. 1.201 + // This can be used to ignore input devices for sensors. 1.202 + virtual void setExcludedDevices(const Vector<String8>& devices) = 0; 1.203 + 1.204 + /* 1.205 + * Wait for events to become available and returns them. 1.206 + * After returning, the EventHub holds onto a wake lock until the next call to getEvent. 1.207 + * This ensures that the device will not go to sleep while the event is being processed. 1.208 + * If the device needs to remain awake longer than that, then the caller is responsible 1.209 + * for taking care of it (say, by poking the power manager user activity timer). 1.210 + * 1.211 + * The timeout is advisory only. If the device is asleep, it will not wake just to 1.212 + * service the timeout. 1.213 + * 1.214 + * Returns the number of events obtained, or 0 if the timeout expired. 1.215 + */ 1.216 + virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) = 0; 1.217 + 1.218 + /* 1.219 + * Query current input state. 1.220 + */ 1.221 + virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0; 1.222 + virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0; 1.223 + virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0; 1.224 + virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, 1.225 + int32_t* outValue) const = 0; 1.226 + 1.227 + /* 1.228 + * Examine key input devices for specific framework keycode support 1.229 + */ 1.230 + virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, 1.231 + uint8_t* outFlags) const = 0; 1.232 + 1.233 + virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const = 0; 1.234 + virtual bool hasLed(int32_t deviceId, int32_t led) const = 0; 1.235 + virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0; 1.236 + 1.237 + virtual void getVirtualKeyDefinitions(int32_t deviceId, 1.238 + Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0; 1.239 + 1.240 + virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0; 1.241 + virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) = 0; 1.242 + 1.243 + /* Control the vibrator. */ 1.244 + virtual void vibrate(int32_t deviceId, nsecs_t duration) = 0; 1.245 + virtual void cancelVibrate(int32_t deviceId) = 0; 1.246 + 1.247 + /* Requests the EventHub to reopen all input devices on the next call to getEvents(). */ 1.248 + virtual void requestReopenDevices() = 0; 1.249 + 1.250 + /* Wakes up getEvents() if it is blocked on a read. */ 1.251 + virtual void wake() = 0; 1.252 + 1.253 + /* Dump EventHub state to a string. */ 1.254 + virtual void dump(String8& dump) = 0; 1.255 + 1.256 + /* Called by the heatbeat to ensures that the reader has not deadlocked. */ 1.257 + virtual void monitor() = 0; 1.258 +}; 1.259 + 1.260 +class EventHub : public EventHubInterface 1.261 +{ 1.262 +public: 1.263 + EventHub(); 1.264 + 1.265 + virtual uint32_t getDeviceClasses(int32_t deviceId) const; 1.266 + 1.267 + virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const; 1.268 + 1.269 + virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const; 1.270 + 1.271 + virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, 1.272 + RawAbsoluteAxisInfo* outAxisInfo) const; 1.273 + 1.274 + virtual bool hasRelativeAxis(int32_t deviceId, int axis) const; 1.275 + 1.276 + virtual bool hasInputProperty(int32_t deviceId, int property) const; 1.277 + 1.278 + virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, 1.279 + int32_t* outKeycode, uint32_t* outFlags) const; 1.280 + 1.281 + virtual status_t mapAxis(int32_t deviceId, int32_t scanCode, 1.282 + AxisInfo* outAxisInfo) const; 1.283 + 1.284 + virtual void setExcludedDevices(const Vector<String8>& devices); 1.285 + 1.286 + virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const; 1.287 + virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const; 1.288 + virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const; 1.289 + virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const; 1.290 + 1.291 + virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, 1.292 + const int32_t* keyCodes, uint8_t* outFlags) const; 1.293 + 1.294 + virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize); 1.295 + 1.296 + virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const; 1.297 + virtual bool hasLed(int32_t deviceId, int32_t led) const; 1.298 + virtual void setLedState(int32_t deviceId, int32_t led, bool on); 1.299 + 1.300 + virtual void getVirtualKeyDefinitions(int32_t deviceId, 1.301 + Vector<VirtualKeyDefinition>& outVirtualKeys) const; 1.302 + 1.303 + virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const; 1.304 + virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map); 1.305 + 1.306 + virtual void vibrate(int32_t deviceId, nsecs_t duration); 1.307 + virtual void cancelVibrate(int32_t deviceId); 1.308 + 1.309 + virtual void requestReopenDevices(); 1.310 + 1.311 + virtual void wake(); 1.312 + 1.313 + virtual void dump(String8& dump); 1.314 + virtual void monitor(); 1.315 + 1.316 +protected: 1.317 + virtual ~EventHub(); 1.318 + 1.319 +private: 1.320 + struct Device { 1.321 + Device* next; 1.322 + 1.323 + int fd; // may be -1 if device is virtual 1.324 + const int32_t id; 1.325 + const String8 path; 1.326 + const InputDeviceIdentifier identifier; 1.327 + 1.328 + uint32_t classes; 1.329 + 1.330 + uint8_t keyBitmask[(KEY_MAX + 1) / 8]; 1.331 + uint8_t absBitmask[(ABS_MAX + 1) / 8]; 1.332 + uint8_t relBitmask[(REL_MAX + 1) / 8]; 1.333 + uint8_t swBitmask[(SW_MAX + 1) / 8]; 1.334 + uint8_t ledBitmask[(LED_MAX + 1) / 8]; 1.335 + uint8_t ffBitmask[(FF_MAX + 1) / 8]; 1.336 + uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8]; 1.337 + 1.338 + String8 configurationFile; 1.339 + PropertyMap* configuration; 1.340 + VirtualKeyMap* virtualKeyMap; 1.341 + KeyMap keyMap; 1.342 + 1.343 + sp<KeyCharacterMap> overlayKeyMap; 1.344 + sp<KeyCharacterMap> combinedKeyMap; 1.345 + 1.346 + bool ffEffectPlaying; 1.347 + int16_t ffEffectId; // initially -1 1.348 + 1.349 + int32_t timestampOverrideSec; 1.350 + int32_t timestampOverrideUsec; 1.351 + 1.352 + Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier); 1.353 + ~Device(); 1.354 + 1.355 + void close(); 1.356 + 1.357 + inline bool isVirtual() const { return fd < 0; } 1.358 + 1.359 + const sp<KeyCharacterMap>& getKeyCharacterMap() const { 1.360 + if (combinedKeyMap != NULL) { 1.361 + return combinedKeyMap; 1.362 + } 1.363 + return keyMap.keyCharacterMap; 1.364 + } 1.365 + }; 1.366 + 1.367 + status_t openDeviceLocked(const char *devicePath); 1.368 + void createVirtualKeyboardLocked(); 1.369 + void addDeviceLocked(Device* device); 1.370 + 1.371 + status_t closeDeviceByPathLocked(const char *devicePath); 1.372 + void closeDeviceLocked(Device* device); 1.373 + void closeAllDevicesLocked(); 1.374 + 1.375 + status_t scanDirLocked(const char *dirname); 1.376 + void scanDevicesLocked(); 1.377 + status_t readNotifyLocked(); 1.378 + 1.379 + Device* getDeviceLocked(int32_t deviceId) const; 1.380 + Device* getDeviceByPathLocked(const char* devicePath) const; 1.381 + 1.382 + bool hasKeycodeLocked(Device* device, int keycode) const; 1.383 + 1.384 + void loadConfigurationLocked(Device* device); 1.385 + status_t loadVirtualKeyMapLocked(Device* device); 1.386 + status_t loadKeyMapLocked(Device* device); 1.387 + 1.388 + bool isExternalDeviceLocked(Device* device); 1.389 + 1.390 + // Protect all internal state. 1.391 + mutable Mutex mLock; 1.392 + 1.393 + // The actual id of the built-in keyboard, or NO_BUILT_IN_KEYBOARD if none. 1.394 + // EventHub remaps the built-in keyboard to id 0 externally as required by the API. 1.395 + enum { 1.396 + // Must not conflict with any other assigned device ids, including 1.397 + // the virtual keyboard id (-1). 1.398 + NO_BUILT_IN_KEYBOARD = -2, 1.399 + }; 1.400 + int32_t mBuiltInKeyboardId; 1.401 + 1.402 + int32_t mNextDeviceId; 1.403 + 1.404 + KeyedVector<int32_t, Device*> mDevices; 1.405 + 1.406 + Device *mOpeningDevices; 1.407 + Device *mClosingDevices; 1.408 + 1.409 + bool mNeedToSendFinishedDeviceScan; 1.410 + bool mNeedToReopenDevices; 1.411 + bool mNeedToScanDevices; 1.412 + Vector<String8> mExcludedDevices; 1.413 + 1.414 + int mEpollFd; 1.415 + int mINotifyFd; 1.416 + int mWakeReadPipeFd; 1.417 + int mWakeWritePipeFd; 1.418 + 1.419 + // Ids used for epoll notifications not associated with devices. 1.420 + static const uint32_t EPOLL_ID_INOTIFY = 0x80000001; 1.421 + static const uint32_t EPOLL_ID_WAKE = 0x80000002; 1.422 + 1.423 + // Epoll FD list size hint. 1.424 + static const int EPOLL_SIZE_HINT = 8; 1.425 + 1.426 + // Maximum number of signalled FDs to handle at a time. 1.427 + static const int EPOLL_MAX_EVENTS = 16; 1.428 + 1.429 + // The array of pending epoll events and the index of the next event to be handled. 1.430 + struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS]; 1.431 + size_t mPendingEventCount; 1.432 + size_t mPendingEventIndex; 1.433 + bool mPendingINotify; 1.434 +}; 1.435 + 1.436 +}; // namespace android 1.437 + 1.438 +#endif // _RUNTIME_EVENT_HUB_H