diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2013-11-22 11:18:57 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2013-11-22 11:18:57 -0800 |
commit | dbccd44a638ae8705a5b14bff8b2dd74abc26045 (patch) | |
tree | 14bfabaf3f3c7be86dfc064e919e00433a0cf2bb /services/input | |
parent | ecfae4f899873f224e1aeed076dc8a41f8884487 (diff) | |
parent | b873a17ce7be0a9771c24999adca6964431728f6 (diff) | |
download | frameworks_base-dbccd44a638ae8705a5b14bff8b2dd74abc26045.zip frameworks_base-dbccd44a638ae8705a5b14bff8b2dd74abc26045.tar.gz frameworks_base-dbccd44a638ae8705a5b14bff8b2dd74abc26045.tar.bz2 |
Merge commit 'b873a17ce7be0a9771c24999adca6964431728f6' into HEAD
Change-Id: I938755073e70602cc8f51ce9bd420fdcf870cecd
Diffstat (limited to 'services/input')
-rw-r--r-- | services/input/Android.mk | 5 | ||||
-rw-r--r-- | services/input/EventHub.cpp | 45 | ||||
-rw-r--r-- | services/input/EventHub.h | 24 | ||||
-rw-r--r-- | services/input/InputApplication.h | 2 | ||||
-rw-r--r-- | services/input/InputDispatcher.cpp | 92 | ||||
-rw-r--r-- | services/input/InputDispatcher.h | 12 | ||||
-rw-r--r-- | services/input/InputListener.h | 2 | ||||
-rw-r--r-- | services/input/InputManager.h | 4 | ||||
-rw-r--r-- | services/input/InputReader.cpp | 38 | ||||
-rw-r--r-- | services/input/InputReader.h | 28 | ||||
-rw-r--r-- | services/input/InputWindow.h | 19 | ||||
-rw-r--r-- | services/input/PointerController.h | 2 | ||||
-rw-r--r-- | services/input/tests/Android.mk | 5 | ||||
-rw-r--r-- | services/input/tests/InputDispatcher_test.cpp | 3 | ||||
-rw-r--r-- | services/input/tests/InputReader_test.cpp | 36 |
15 files changed, 225 insertions, 92 deletions
diff --git a/services/input/Android.mk b/services/input/Android.mk index 5d913f3..6e944ef 100644 --- a/services/input/Android.mk +++ b/services/input/Android.mk @@ -36,12 +36,13 @@ LOCAL_SHARED_LIBRARIES := \ libhardware_legacy \ libskia \ libgui \ - libui + libui \ + libinput LOCAL_C_INCLUDES := \ external/skia/include/core -LOCAL_MODULE:= libinput +LOCAL_MODULE:= libinputservice LOCAL_MODULE_TAGS := optional diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp index 29e4eed..fc64656 100644 --- a/services/input/EventHub.cpp +++ b/services/input/EventHub.cpp @@ -36,9 +36,9 @@ #include <errno.h> #include <assert.h> -#include <androidfw/KeyLayoutMap.h> -#include <androidfw/KeyCharacterMap.h> -#include <androidfw/VirtualKeyMap.h> +#include <input/KeyLayoutMap.h> +#include <input/KeyCharacterMap.h> +#include <input/VirtualKeyMap.h> #include <string.h> #include <stdint.h> @@ -162,7 +162,7 @@ EventHub::Device::Device(int fd, int32_t id, const String8& path, next(NULL), fd(fd), id(id), path(path), identifier(identifier), classes(0), configuration(NULL), virtualKeyMap(NULL), - ffEffectPlaying(false), ffEffectId(-1), + ffEffectPlaying(false), ffEffectId(-1), controllerNumber(0), timestampOverrideSec(0), timestampOverrideUsec(0) { memset(keyBitmask, 0, sizeof(keyBitmask)); memset(absBitmask, 0, sizeof(absBitmask)); @@ -195,7 +195,7 @@ const int EventHub::EPOLL_SIZE_HINT; const int EventHub::EPOLL_MAX_EVENTS; EventHub::EventHub(void) : - mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), + mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(), mOpeningDevices(0), mClosingDevices(0), mNeedToSendFinishedDeviceScan(false), mNeedToReopenDevices(false), mNeedToScanDevices(true), @@ -269,6 +269,13 @@ uint32_t EventHub::getDeviceClasses(int32_t deviceId) const { return device->classes; } +int32_t EventHub::getDeviceControllerNumber(int32_t deviceId) const { + AutoMutex _l(mLock); + Device* device = getDeviceLocked(deviceId); + if (device == NULL) return 0; + return device->controllerNumber; +} + void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); @@ -1230,6 +1237,10 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { device->classes |= INPUT_DEVICE_CLASS_EXTERNAL; } + if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_GAMEPAD)) { + device->controllerNumber = getNextControllerNumberLocked(device); + } + // Register with epoll. struct epoll_event eventItem; memset(&eventItem, 0, sizeof(eventItem)); @@ -1347,6 +1358,27 @@ bool EventHub::isExternalDeviceLocked(Device* device) { return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH; } +int32_t EventHub::getNextControllerNumberLocked(Device* device) { + if (mControllerNumbers.isFull()) { + ALOGI("Maximum number of controllers reached, assigning controller number 0 to device %s", + device->identifier.name.string()); + return 0; + } + // Since the controller number 0 is reserved for non-controllers, translate all numbers up by + // one + return static_cast<int32_t>(mControllerNumbers.markFirstUnmarkedBit() + 1); +} + +void EventHub::releaseControllerNumberLocked(Device* device) { + int32_t num = device->controllerNumber; + device->controllerNumber= 0; + if (num == 0) { + return; + } + mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1)); +} + + bool EventHub::hasKeycodeLocked(Device* device, int keycode) const { if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) { return false; @@ -1398,6 +1430,8 @@ void EventHub::closeDeviceLocked(Device* device) { } } + releaseControllerNumberLocked(device); + mDevices.removeItem(device->id); device->close(); @@ -1527,6 +1561,7 @@ void EventHub::dump(String8& dump) { dump.appendFormat(INDENT3 "Path: %s\n", device->path.string()); dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string()); dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string()); + dump.appendFormat(INDENT3 "ControllerNumber: %d\n", device->controllerNumber); dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string()); dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, " "product=0x%04x, version=0x%04x\n", diff --git a/services/input/EventHub.h b/services/input/EventHub.h index c93fc7a..ae28f01 100644 --- a/services/input/EventHub.h +++ b/services/input/EventHub.h @@ -18,12 +18,12 @@ #ifndef _RUNTIME_EVENT_HUB_H #define _RUNTIME_EVENT_HUB_H -#include <androidfw/Input.h> -#include <androidfw/InputDevice.h> -#include <androidfw/Keyboard.h> -#include <androidfw/KeyLayoutMap.h> -#include <androidfw/KeyCharacterMap.h> -#include <androidfw/VirtualKeyMap.h> +#include <input/Input.h> +#include <input/InputDevice.h> +#include <input/Keyboard.h> +#include <input/KeyLayoutMap.h> +#include <input/KeyCharacterMap.h> +#include <input/VirtualKeyMap.h> #include <utils/String8.h> #include <utils/threads.h> #include <utils/Log.h> @@ -33,6 +33,7 @@ #include <utils/PropertyMap.h> #include <utils/Vector.h> #include <utils/KeyedVector.h> +#include <utils/BitSet.h> #include <linux/input.h> #include <sys/epoll.h> @@ -179,6 +180,8 @@ public: virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const = 0; + virtual int32_t getDeviceControllerNumber(int32_t deviceId) const = 0; + virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0; virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, @@ -263,6 +266,8 @@ public: virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const; + virtual int32_t getDeviceControllerNumber(int32_t deviceId) const; + virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const; virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, @@ -343,6 +348,8 @@ private: bool ffEffectPlaying; int16_t ffEffectId; // initially -1 + int32_t controllerNumber; + int32_t timestampOverrideSec; int32_t timestampOverrideUsec; @@ -384,6 +391,9 @@ private: bool isExternalDeviceLocked(Device* device); + int32_t getNextControllerNumberLocked(Device* device); + void releaseControllerNumberLocked(Device* device); + // Protect all internal state. mutable Mutex mLock; @@ -398,6 +408,8 @@ private: int32_t mNextDeviceId; + BitSet32 mControllerNumbers; + KeyedVector<int32_t, Device*> mDevices; Device *mOpeningDevices; diff --git a/services/input/InputApplication.h b/services/input/InputApplication.h index c04a935..1f5504c 100644 --- a/services/input/InputApplication.h +++ b/services/input/InputApplication.h @@ -17,7 +17,7 @@ #ifndef _UI_INPUT_APPLICATION_H #define _UI_INPUT_APPLICATION_H -#include <androidfw/Input.h> +#include <input/Input.h> #include <utils/RefBase.h> #include <utils/Timers.h> diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index 23a846b..274009f 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -84,6 +84,8 @@ const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec // Log a warning when an event takes longer than this to process, even if an ANR does not occur. const nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec +// Number of recent events to keep for debugging purposes. +const size_t RECENT_QUEUE_MAX_SIZE = 10; static inline nsecs_t now() { return systemTime(SYSTEM_TIME_MONOTONIC); @@ -455,6 +457,14 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) { return needWake; } +void InputDispatcher::addRecentEventLocked(EventEntry* entry) { + entry->refCount += 1; + mRecentQueue.enqueueAtTail(entry); + if (mRecentQueue.count() > RECENT_QUEUE_MAX_SIZE) { + mRecentQueue.dequeueAtHead()->release(); + } +} + sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y) { // Traverse windows from front to back to find touched window. @@ -464,6 +474,7 @@ sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t display const InputWindowInfo* windowInfo = windowHandle->getInfo(); if (windowInfo->displayId == displayId) { int32_t flags = windowInfo->layoutParamsFlags; + int32_t privateFlags = windowInfo->layoutParamsPrivateFlags; if (windowInfo->visible) { if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) { @@ -476,7 +487,7 @@ sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t display } } - if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) { + if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) { // Error window is on top but not visible, so touch is dropped. return NULL; } @@ -624,6 +635,7 @@ void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) { if (entry == mNextUnblockedEvent) { mNextUnblockedEvent = NULL; } + addRecentEventLocked(entry); entry->release(); } @@ -1204,13 +1216,14 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, continue; // wrong display } - int32_t flags = windowInfo->layoutParamsFlags; - if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) { + int32_t privateFlags = windowInfo->layoutParamsPrivateFlags; + if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) { if (topErrorWindowHandle == NULL) { topErrorWindowHandle = windowHandle; } } + int32_t flags = windowInfo->layoutParamsFlags; if (windowInfo->visible) { if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) { isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE @@ -1264,21 +1277,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, // Try to assign the pointer to the first foreground window we find, if there is one. newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle(); if (newTouchedWindowHandle == NULL) { - // There is no touched window. If this is an initial down event - // then wait for a window to appear that will handle the touch. This is - // to ensure that we report an ANR in the case where an application has started - // but not yet put up a window and the user is starting to get impatient. - if (maskedAction == AMOTION_EVENT_ACTION_DOWN - && mFocusedApplicationHandle != NULL) { - injectionResult = handleTargetsNotReadyLocked(currentTime, entry, - mFocusedApplicationHandle, NULL, nextWakeupTime, - "Waiting because there is no touchable window that can " - "handle the event but there is focused application that may " - "eventually add a new window when it finishes starting up."); - goto Unresponsive; - } - - ALOGI("Dropping event because there is no touched window."); + ALOGI("Dropping event because there is no touchable window at (%d, %d).", x, y); injectionResult = INPUT_EVENT_INJECTION_FAILED; goto Failed; } @@ -3161,6 +3160,31 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { nsecs_t currentTime = now(); + // Dump recently dispatched or dropped events from oldest to newest. + if (!mRecentQueue.isEmpty()) { + dump.appendFormat(INDENT "RecentQueue: length=%u\n", mRecentQueue.count()); + for (EventEntry* entry = mRecentQueue.head; entry; entry = entry->next) { + dump.append(INDENT2); + entry->appendDescription(dump); + dump.appendFormat(", age=%0.1fms\n", + (currentTime - entry->eventTime) * 0.000001f); + } + } else { + dump.append(INDENT "RecentQueue: <empty>\n"); + } + + // Dump event currently being dispatched. + if (mPendingEvent) { + dump.append(INDENT "PendingEvent:\n"); + dump.append(INDENT2); + mPendingEvent->appendDescription(dump); + dump.appendFormat(", age=%0.1fms\n", + (currentTime - mPendingEvent->eventTime) * 0.000001f); + } else { + dump.append(INDENT "PendingEvent: <none>\n"); + } + + // Dump inbound events from oldest to newest. if (!mInboundQueue.isEmpty()) { dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count()); for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) { @@ -3383,6 +3407,7 @@ void InputDispatcher::onANRLocked( & InputDispatcher::doNotifyANRLockedInterruptible); commandEntry->inputApplicationHandle = applicationHandle; commandEntry->inputWindowHandle = windowHandle; + commandEntry->reason = reason; } void InputDispatcher::doNotifyConfigurationChangedInterruptible( @@ -3412,7 +3437,8 @@ void InputDispatcher::doNotifyANRLockedInterruptible( mLock.unlock(); nsecs_t newTimeout = mPolicy->notifyANR( - commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle); + commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle, + commandEntry->reason); mLock.lock(); @@ -3809,7 +3835,8 @@ InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() { } void InputDispatcher::ConfigurationChangedEntry::appendDescription(String8& msg) const { - msg.append("ConfigurationChangedEvent()"); + msg.append("ConfigurationChangedEvent(), policyFlags=0x%08x", + policyFlags); } @@ -3824,7 +3851,8 @@ InputDispatcher::DeviceResetEntry::~DeviceResetEntry() { } void InputDispatcher::DeviceResetEntry::appendDescription(String8& msg) const { - msg.appendFormat("DeviceResetEvent(deviceId=%d)", deviceId); + msg.appendFormat("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", + deviceId, policyFlags); } @@ -3846,8 +3874,11 @@ InputDispatcher::KeyEntry::~KeyEntry() { } void InputDispatcher::KeyEntry::appendDescription(String8& msg) const { - msg.appendFormat("KeyEvent(action=%d, deviceId=%d, source=0x%08x)", - action, deviceId, source); + msg.appendFormat("KeyEvent(deviceId=%d, source=0x%08x, action=%d, " + "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, " + "repeatCount=%d), policyFlags=0x%08x", + deviceId, source, action, flags, keyCode, scanCode, metaState, + repeatCount, policyFlags); } void InputDispatcher::KeyEntry::recycle() { @@ -3884,8 +3915,19 @@ InputDispatcher::MotionEntry::~MotionEntry() { } void InputDispatcher::MotionEntry::appendDescription(String8& msg) const { - msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x, displayId=%d)", - action, deviceId, source, displayId); + msg.appendFormat("MotionEvent(deviceId=%d, source=0x%08x, action=%d, " + "flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, edgeFlags=0x%08x, " + "xPrecision=%.1f, yPrecision=%.1f, displayId=%d, pointers=[", + deviceId, source, action, flags, metaState, buttonState, edgeFlags, + xPrecision, yPrecision, displayId); + for (uint32_t i = 0; i < pointerCount; i++) { + if (i) { + msg.append(", "); + } + msg.appendFormat("%d: (%.1f, %.1f)", pointerProperties[i].id, + pointerCoords[i].getX(), pointerCoords[i].getY()); + } + msg.appendFormat("]), policyFlags=0x%08x", policyFlags); } diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h index 430721e..190e7b2 100644 --- a/services/input/InputDispatcher.h +++ b/services/input/InputDispatcher.h @@ -17,8 +17,8 @@ #ifndef _UI_INPUT_DISPATCHER_H #define _UI_INPUT_DISPATCHER_H -#include <androidfw/Input.h> -#include <androidfw/InputTransport.h> +#include <input/Input.h> +#include <input/InputTransport.h> #include <utils/KeyedVector.h> #include <utils/Vector.h> #include <utils/threads.h> @@ -202,7 +202,8 @@ public: /* Notifies the system that an application is not responding. * Returns a new timeout to continue waiting, or 0 to abort dispatch. */ virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, - const sp<InputWindowHandle>& inputWindowHandle) = 0; + const sp<InputWindowHandle>& inputWindowHandle, + const String8& reason) = 0; /* Notifies the system that an input channel is unrecoverably broken. */ virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0; @@ -596,6 +597,7 @@ private: KeyEntry* keyEntry; sp<InputApplicationHandle> inputApplicationHandle; sp<InputWindowHandle> inputWindowHandle; + String8 reason; int32_t userActivityEventType; uint32_t seq; bool handled; @@ -846,6 +848,7 @@ private: EventEntry* mPendingEvent; Queue<EventEntry> mInboundQueue; + Queue<EventEntry> mRecentQueue; Queue<CommandEntry> mCommandQueue; void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime); @@ -856,6 +859,9 @@ private: // Cleans up input state when dropping an inbound event. void dropInboundEventLocked(EventEntry* entry, DropReason dropReason); + // Adds an event to a queue of recent events for debugging purposes. + void addRecentEventLocked(EventEntry* entry); + // App switch latency optimization. bool mAppSwitchSawKeyDown; nsecs_t mAppSwitchDueTime; diff --git a/services/input/InputListener.h b/services/input/InputListener.h index cd7c25a..78ae10f 100644 --- a/services/input/InputListener.h +++ b/services/input/InputListener.h @@ -17,7 +17,7 @@ #ifndef _UI_INPUT_LISTENER_H #define _UI_INPUT_LISTENER_H -#include <androidfw/Input.h> +#include <input/Input.h> #include <utils/RefBase.h> #include <utils/Vector.h> diff --git a/services/input/InputManager.h b/services/input/InputManager.h index 29584c9..a213b2d 100644 --- a/services/input/InputManager.h +++ b/services/input/InputManager.h @@ -25,8 +25,8 @@ #include "InputReader.h" #include "InputDispatcher.h" -#include <androidfw/Input.h> -#include <androidfw/InputTransport.h> +#include <input/Input.h> +#include <input/InputTransport.h> #include <utils/Errors.h> #include <utils/Vector.h> #include <utils/Timers.h> diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index 1a61f20..03852a5 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -42,8 +42,8 @@ #include "InputReader.h" #include <cutils/log.h> -#include <androidfw/Keyboard.h> -#include <androidfw/VirtualKeyMap.h> +#include <input/Keyboard.h> +#include <input/VirtualKeyMap.h> #include <stddef.h> #include <stdlib.h> @@ -354,8 +354,9 @@ void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) { InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId); uint32_t classes = mEventHub->getDeviceClasses(deviceId); + int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId); - InputDevice* device = createDeviceLocked(deviceId, identifier, classes); + InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes); device->configure(when, &mConfig, 0); device->reset(when); @@ -395,10 +396,10 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) { delete device; } -InputDevice* InputReader::createDeviceLocked(int32_t deviceId, +InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) { InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(), - identifier, classes); + controllerNumber, identifier, classes); // External devices. if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { @@ -843,8 +844,8 @@ bool InputReaderThread::threadLoop() { // --- InputDevice --- InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation, - const InputDeviceIdentifier& identifier, uint32_t classes) : - mContext(context), mId(id), mGeneration(generation), + int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) : + mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber), mIdentifier(identifier), mClasses(classes), mSources(0), mIsExternal(false), mDropUntilNextSync(false) { } @@ -995,7 +996,8 @@ void InputDevice::timeoutExpired(nsecs_t when) { } void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { - outDeviceInfo->initialize(mId, mGeneration, mIdentifier, mAlias, mIsExternal); + outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, + mIsExternal); size_t numMappers = mMappers.size(); for (size_t i = 0; i < numMappers; i++) { @@ -2630,6 +2632,7 @@ void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) { info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat, y.fuzz, y.resolution); } + info->setButtonUnderPad(mParameters.hasButtonUnderPad); } } @@ -2795,6 +2798,9 @@ void TouchInputMapper::configureParameters() { mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER; } + mParameters.hasButtonUnderPad= + getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD); + String8 deviceTypeString; if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"), deviceTypeString)) { @@ -4647,6 +4653,14 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mCurrentFingerIdBits, positions); } + // If the gesture ever enters a mode other than TAP, HOVER or TAP_DRAG, without first returning + // to NEUTRAL, then we should not generate tap event. + if (mPointerGesture.lastGestureMode != PointerGesture::HOVER + && mPointerGesture.lastGestureMode != PointerGesture::TAP + && mPointerGesture.lastGestureMode != PointerGesture::TAP_DRAG) { + mPointerGesture.resetTap(); + } + // Pick a new active touch id if needed. // Choose an arbitrary pointer that just went down, if there is one. // Otherwise choose an arbitrary remaining pointer. @@ -4855,8 +4869,12 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, } } else { #if DEBUG_GESTURES - ALOGD("Gestures: Not a TAP, %0.3fms since down", - (when - mPointerGesture.tapDownTime) * 0.000001f); + if (mPointerGesture.tapDownTime != LLONG_MIN) { + ALOGD("Gestures: Not a TAP, %0.3fms since down", + (when - mPointerGesture.tapDownTime) * 0.000001f); + } else { + ALOGD("Gestures: Not a TAP, incompatible mode transitions"); + } #endif } } diff --git a/services/input/InputReader.h b/services/input/InputReader.h index 0189ba7..a8bb636 100644 --- a/services/input/InputReader.h +++ b/services/input/InputReader.h @@ -21,9 +21,9 @@ #include "PointerController.h" #include "InputListener.h" -#include <androidfw/Input.h> -#include <androidfw/VelocityControl.h> -#include <androidfw/VelocityTracker.h> +#include <input/Input.h> +#include <input/VelocityControl.h> +#include <input/VelocityTracker.h> #include <utils/KeyedVector.h> #include <utils/threads.h> #include <utils/Timers.h> @@ -409,7 +409,7 @@ public: protected: // These members are protected so they can be instrumented by test cases. - virtual InputDevice* createDeviceLocked(int32_t deviceId, + virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes); class ContextImpl : public InputReaderContext { @@ -507,16 +507,17 @@ private: /* Represents the state of a single input device. */ class InputDevice { public: - InputDevice(InputReaderContext* context, int32_t id, int32_t generation, - const InputDeviceIdentifier& identifier, uint32_t classes); + InputDevice(InputReaderContext* context, int32_t id, int32_t generation, int32_t + controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes); ~InputDevice(); inline InputReaderContext* getContext() { return mContext; } - inline int32_t getId() { return mId; } - inline int32_t getGeneration() { return mGeneration; } - inline const String8& getName() { return mIdentifier.name; } - inline uint32_t getClasses() { return mClasses; } - inline uint32_t getSources() { return mSources; } + inline int32_t getId() const { return mId; } + inline int32_t getControllerNumber() const { return mControllerNumber; } + inline int32_t getGeneration() const { return mGeneration; } + inline const String8& getName() const { return mIdentifier.name; } + inline uint32_t getClasses() const { return mClasses; } + inline uint32_t getSources() const { return mSources; } inline bool isExternal() { return mIsExternal; } inline void setExternal(bool external) { mIsExternal = external; } @@ -573,6 +574,7 @@ public: private: InputReaderContext* mContext; int32_t mId; + int32_t mControllerNumber; int32_t mGeneration; InputDeviceIdentifier mIdentifier; String8 mAlias; @@ -1205,6 +1207,7 @@ protected: bool hasAssociatedDisplay; bool associatedDisplayIsExternal; bool orientationAware; + bool hasButtonUnderPad; enum GestureMode { GESTURE_MODE_POINTER, @@ -1282,6 +1285,9 @@ protected: if (haveSizeBias) { *outSize += sizeBias; } + if (*outSize < 0) { + *outSize = 0; + } } } mCalibration; diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h index 7bd3af7..28fa7ab 100644 --- a/services/input/InputWindow.h +++ b/services/input/InputWindow.h @@ -17,8 +17,8 @@ #ifndef _UI_INPUT_WINDOW_H #define _UI_INPUT_WINDOW_H -#include <androidfw/Input.h> -#include <androidfw/InputTransport.h> +#include <input/Input.h> +#include <input/InputTransport.h> #include <utils/RefBase.h> #include <utils/Timers.h> #include <utils/String8.h> @@ -59,13 +59,13 @@ struct InputWindowInfo { FLAG_TURN_SCREEN_ON = 0x00200000, FLAG_DISMISS_KEYGUARD = 0x00400000, FLAG_SPLIT_TOUCH = 0x00800000, - FLAG_HARDWARE_ACCELERATED = 0x01000000, - FLAG_HARDWARE_ACCELERATED_SYSTEM = 0x02000000, - FLAG_SLIPPERY = 0x04000000, - FLAG_NEEDS_MENU_KEY = 0x08000000, - FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000, - FLAG_COMPATIBLE_WINDOW = 0x20000000, - FLAG_SYSTEM_ERROR = 0x40000000, + FLAG_SLIPPERY = 0x20000000, + FLAG_NEEDS_MENU_KEY = 0x40000000, + }; + + // Private Window flags from WindowManager.LayoutParams + enum { + PRIVATE_FLAG_SYSTEM_ERROR = 0x00000100, }; // Window types from WindowManager.LayoutParams @@ -117,6 +117,7 @@ struct InputWindowInfo { sp<InputChannel> inputChannel; String8 name; int32_t layoutParamsFlags; + int32_t layoutParamsPrivateFlags; int32_t layoutParamsType; nsecs_t dispatchingTimeout; int32_t frameLeft; diff --git a/services/input/PointerController.h b/services/input/PointerController.h index fd68b61..790c0bb 100644 --- a/services/input/PointerController.h +++ b/services/input/PointerController.h @@ -20,7 +20,7 @@ #include "SpriteController.h" #include <ui/DisplayInfo.h> -#include <androidfw/Input.h> +#include <input/Input.h> #include <utils/BitSet.h> #include <utils/RefBase.h> #include <utils/Looper.h> diff --git a/services/input/tests/Android.mk b/services/input/tests/Android.mk index 211e64b..9278f41 100644 --- a/services/input/tests/Android.mk +++ b/services/input/tests/Android.mk @@ -17,7 +17,8 @@ shared_libraries := \ libui \ libskia \ libstlport \ - libinput + libinput \ + libinputservice static_libraries := \ libgtest \ @@ -40,7 +41,7 @@ $(foreach file,$(test_src_files), \ $(eval LOCAL_SRC_FILES := $(file)) \ $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \ - $(eval include $(BUILD_EXECUTABLE)) \ + $(eval include $(BUILD_NATIVE_TEST)) \ ) # Build the manual test programs. diff --git a/services/input/tests/InputDispatcher_test.cpp b/services/input/tests/InputDispatcher_test.cpp index ed2b4a5..26b4fab 100644 --- a/services/input/tests/InputDispatcher_test.cpp +++ b/services/input/tests/InputDispatcher_test.cpp @@ -50,7 +50,8 @@ private: } virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, - const sp<InputWindowHandle>& inputWindowHandle) { + const sp<InputWindowHandle>& inputWindowHandle, + const String8& reason) { return 0; } diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index 14065d2..f068732 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -472,6 +472,10 @@ private: return device ? device->identifier : InputDeviceIdentifier(); } + virtual int32_t getDeviceControllerNumber(int32_t deviceId) const { + return 0; + } + virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { Device* device = getDevice(deviceId); if (device) { @@ -928,22 +932,24 @@ public: mNextDevice = device; } - InputDevice* newDevice(int32_t deviceId, const String8& name, uint32_t classes) { + InputDevice* newDevice(int32_t deviceId, int32_t controllerNumber, const String8& name, + uint32_t classes) { InputDeviceIdentifier identifier; identifier.name = name; int32_t generation = deviceId + 1; - return new InputDevice(&mContext, deviceId, generation, identifier, classes); + return new InputDevice(&mContext, deviceId, generation, controllerNumber, identifier, + classes); } protected: - virtual InputDevice* createDeviceLocked(int32_t deviceId, + virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) { if (mNextDevice) { InputDevice* device = mNextDevice; mNextDevice = NULL; return device; } - return InputReader::createDeviceLocked(deviceId, identifier, classes); + return InputReader::createDeviceLocked(deviceId, controllerNumber, identifier, classes); } friend class InputReaderTest; @@ -988,10 +994,10 @@ protected: mFakeEventHub->assertQueueIsEmpty(); } - FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, + FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber, const String8& name, uint32_t classes, uint32_t sources, const PropertyMap* configuration) { - InputDevice* device = mReader->newDevice(deviceId, name, classes); + InputDevice* device = mReader->newDevice(deviceId, controllerNumber, name, classes); FakeInputMapper* mapper = new FakeInputMapper(device, sources); device->addMapper(mapper); mReader->setNextDevice(device); @@ -1028,7 +1034,7 @@ TEST_F(InputReaderTest, GetInputDevices) { TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) { FakeInputMapper* mapper = NULL; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), + ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"), INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN); @@ -1055,7 +1061,7 @@ TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) { TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) { FakeInputMapper* mapper = NULL; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), + ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"), INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN); @@ -1082,7 +1088,7 @@ TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) { TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) { FakeInputMapper* mapper = NULL; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), + ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"), INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN); @@ -1109,7 +1115,7 @@ TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) { TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) { FakeInputMapper* mapper = NULL; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), + ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"), INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); mapper->addSupportedKeyCode(AKEYCODE_A); mapper->addSupportedKeyCode(AKEYCODE_B); @@ -1153,7 +1159,7 @@ TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChange TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) { FakeInputMapper* mapper = NULL; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), + ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"), INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, 1); @@ -1177,6 +1183,7 @@ protected: static const char* DEVICE_NAME; static const int32_t DEVICE_ID; static const int32_t DEVICE_GENERATION; + static const int32_t DEVICE_CONTROLLER_NUMBER; static const uint32_t DEVICE_CLASSES; sp<FakeEventHub> mFakeEventHub; @@ -1196,7 +1203,7 @@ protected: InputDeviceIdentifier identifier; identifier.name = DEVICE_NAME; mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION, - identifier, DEVICE_CLASSES); + DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES); } virtual void TearDown() { @@ -1212,6 +1219,7 @@ protected: const char* InputDeviceTest::DEVICE_NAME = "device"; const int32_t InputDeviceTest::DEVICE_ID = 1; const int32_t InputDeviceTest::DEVICE_GENERATION = 2; +const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0; const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK; @@ -1365,6 +1373,7 @@ protected: static const char* DEVICE_NAME; static const int32_t DEVICE_ID; static const int32_t DEVICE_GENERATION; + static const int32_t DEVICE_CONTROLLER_NUMBER; static const uint32_t DEVICE_CLASSES; sp<FakeEventHub> mFakeEventHub; @@ -1381,7 +1390,7 @@ protected: InputDeviceIdentifier identifier; identifier.name = DEVICE_NAME; mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION, - identifier, DEVICE_CLASSES); + DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES); mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0); } @@ -1461,6 +1470,7 @@ protected: const char* InputMapperTest::DEVICE_NAME = "device"; const int32_t InputMapperTest::DEVICE_ID = 1; const int32_t InputMapperTest::DEVICE_GENERATION = 2; +const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0; const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests |