summaryrefslogtreecommitdiffstats
path: root/services/input
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2013-11-22 11:18:57 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2013-11-22 11:18:57 -0800
commitdbccd44a638ae8705a5b14bff8b2dd74abc26045 (patch)
tree14bfabaf3f3c7be86dfc064e919e00433a0cf2bb /services/input
parentecfae4f899873f224e1aeed076dc8a41f8884487 (diff)
parentb873a17ce7be0a9771c24999adca6964431728f6 (diff)
downloadframeworks_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.mk5
-rw-r--r--services/input/EventHub.cpp45
-rw-r--r--services/input/EventHub.h24
-rw-r--r--services/input/InputApplication.h2
-rw-r--r--services/input/InputDispatcher.cpp92
-rw-r--r--services/input/InputDispatcher.h12
-rw-r--r--services/input/InputListener.h2
-rw-r--r--services/input/InputManager.h4
-rw-r--r--services/input/InputReader.cpp38
-rw-r--r--services/input/InputReader.h28
-rw-r--r--services/input/InputWindow.h19
-rw-r--r--services/input/PointerController.h2
-rw-r--r--services/input/tests/Android.mk5
-rw-r--r--services/input/tests/InputDispatcher_test.cpp3
-rw-r--r--services/input/tests/InputReader_test.cpp36
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