OSDN Git Service

Fix crashes caused by some input devices.
authorJeff Brown <jeffbrown@google.com>
Wed, 26 Jan 2011 00:02:22 +0000 (16:02 -0800)
committerJeff Brown <jeffbrown@google.com>
Wed, 26 Jan 2011 00:02:22 +0000 (16:02 -0800)
The touch screen sometimes reports more than 10 pointers even though that's
all we asked for.  When this happens, we start dropping events with more
than 10 pointers.  This confuses applications and causes them to crash.
Raised the limit to 16 pointers.
Bug: 3331247

The default behavior was to identify all touch devices as touch screens.
External devices that are plugged in are more likely to be touch pads
not attached to a screen.  Changed the default to be a touch pad
and renamed some internal constants to avoid confusion.

A certain mouse happens to also behave like a touch pad.  That caused
problems because we would see multiple concurrent traces of motion events
coming from the same input device so we would batch them up.
Added code to ensure that we don't batch events unless they come from
the same *source* in addition to coming from the same *device*.

Due to batching or misbehaving drivers, it's possible for the set of
pointer ids to be different from what we expect when it comes time to
split motion events across windows.  As a result, we can generate motion
events with 0 pointers.  When we try to deliver those events, we cause
an error in the InputTransport so we tear down the InputChannel and kill
the application.
Added code to check out assumption about pointer ids and drop the
event gracefully instead.

Patched up the tests to take into account the change in default behavior
for identifying touch screens and touch pads.

Change-Id: Ic364bd4cb4cc6335d4a1213a26d6bdadc7e33505

include/ui/Input.h
services/input/EventHub.cpp
services/input/EventHub.h
services/input/InputDispatcher.cpp
services/input/InputDispatcher.h
services/input/InputReader.cpp
services/input/tests/InputReader_test.cpp

index 30b45f7..2012fcc 100644 (file)
@@ -50,8 +50,10 @@ enum {
 /*
  * Maximum number of pointers supported per motion event.
  * Smallest number of pointers is 1.
+ * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers
+ * will occasionally emit 11.  There is not much harm making this constant bigger.)
  */
-#define MAX_POINTERS 10
+#define MAX_POINTERS 16
 
 /*
  * Maximum pointer id value supported in a motion event.
index 487e73f..41dbe2f 100644 (file)
@@ -778,12 +778,12 @@ int EventHub::openDevice(const char *devicePath) {
         // Is this a new modern multi-touch driver?
         if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
                 && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
-            device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT;
+            device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
 
         // Is this an old style single-touch driver?
         } else if (test_bit(BTN_TOUCH, key_bitmask)
                 && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
-            device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN;
+            device->classes |= INPUT_DEVICE_CLASS_TOUCH;
         }
     }
 
@@ -808,7 +808,7 @@ int EventHub::openDevice(const char *devicePath) {
     }
 #endif
 
-    if ((device->classes & INPUT_DEVICE_CLASS_TOUCHSCREEN)) {
+    if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
         // Load the virtual keys for the touch screen, if any.
         // We do this now so that we can make sure to load the keymap if necessary.
         status_t status = loadVirtualKeyMap(device);
index 74b7ec5..0ee0b9b 100644 (file)
@@ -106,14 +106,14 @@ enum {
     /* The input device is an alpha-numeric keyboard (not just a dial pad). */
     INPUT_DEVICE_CLASS_ALPHAKEY      = 0x00000002,
 
-    /* The input device is a touchscreen (either single-touch or multi-touch). */
-    INPUT_DEVICE_CLASS_TOUCHSCREEN   = 0x00000004,
+    /* The input device is a touchscreen or a touchpad (either single-touch or multi-touch). */
+    INPUT_DEVICE_CLASS_TOUCH         = 0x00000004,
 
     /* The input device is a cursor device such as a trackball or mouse. */
     INPUT_DEVICE_CLASS_CURSOR        = 0x00000008,
 
     /* The input device is a multi-touch touchscreen. */
-    INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010,
+    INPUT_DEVICE_CLASS_TOUCH_MT      = 0x00000010,
 
     /* The input device is a directional pad (implies keyboard, has DPAD keys). */
     INPUT_DEVICE_CLASS_DPAD          = 0x00000020,
index e314145..cbfdd75 100644 (file)
@@ -1165,12 +1165,15 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
         mTempTouchState.reset();
         mTempTouchState.down = true;
         mTempTouchState.deviceId = entry->deviceId;
+        mTempTouchState.source = entry->source;
         isSplit = false;
         wrongDevice = false;
     } else {
         mTempTouchState.copyFrom(mTouchState);
         isSplit = mTempTouchState.split;
-        wrongDevice = mTempTouchState.down && mTempTouchState.deviceId != entry->deviceId;
+        wrongDevice = mTempTouchState.down
+                && (mTempTouchState.deviceId != entry->deviceId
+                        || mTempTouchState.source != entry->source);
         if (wrongDevice) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
             LOGD("Dropping event because a pointer for a different device is already down.");
@@ -1599,6 +1602,9 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
         if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
             MotionEntry* splitMotionEntry = splitMotionEvent(
                     originalMotionEntry, inputTarget->pointerIds);
+            if (!splitMotionEntry) {
+                return; // split event was dropped
+            }
 #if DEBUG_FOCUS
             LOGD("channel '%s' ~ Split motion event.",
                     connection->getInputChannelName());
@@ -2120,7 +2126,19 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet
             splitPointerCount += 1;
         }
     }
-    assert(splitPointerCount == pointerIds.count());
+
+    if (splitPointerCount != pointerIds.count()) {
+        // This is bad.  We are missing some of the pointers that we expected to deliver.
+        // Most likely this indicates that we received an ACTION_MOVE events that has
+        // different pointer ids than we expected based on the previous ACTION_DOWN
+        // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
+        // in this way.
+        LOGW("Dropping split motion event because the pointer count is %d but "
+                "we expected there to be %d pointers.  This probably means we received "
+                "a broken sequence of pointer ids from the input device.",
+                splitPointerCount, pointerIds.count());
+        return NULL;
+    }
 
     int32_t action = originalMotionEntry->action;
     int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
@@ -2196,7 +2214,7 @@ void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
     }
 }
 
-void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
+void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
         uint32_t policyFlags, int32_t action, int32_t flags,
         int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
 #if DEBUG_INBOUND_EVENT_DETAILS
@@ -2243,7 +2261,7 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t sou
     }
 }
 
-void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
+void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
         uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
         uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
         float xPrecision, float yPrecision, nsecs_t downTime) {
@@ -2296,6 +2314,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t
                 }
 
                 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
+                        || motionEntry->source != source
                         || motionEntry->pointerCount != pointerCount
                         || motionEntry->isInjected()) {
                     // Last motion event in the queue for this device is not compatible for
@@ -2355,6 +2374,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t
                             dispatchEntry->eventEntry);
                     if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
                             || motionEntry->deviceId != deviceId
+                            || motionEntry->source != source
                             || motionEntry->pointerCount != pointerCount
                             || motionEntry->isInjected()) {
                         // The motion event is not compatible with this move.
@@ -2883,6 +2903,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
     dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
     dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
     dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
+    dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
     if (!mTouchState.windows.isEmpty()) {
         dump.append(INDENT "TouchedWindows:\n");
         for (size_t i = 0; i < mTouchState.windows.size(); i++) {
@@ -3308,7 +3329,7 @@ InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
 }
 
 InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
-        int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
+        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
         int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
         int32_t repeatCount, nsecs_t downTime) {
     KeyEntry* entry = mKeyEntryPool.alloc();
@@ -3329,7 +3350,7 @@ InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t ev
 }
 
 InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
-        int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
+        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
         int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
         nsecs_t downTime, uint32_t pointerCount,
         const int32_t* pointerIds, const PointerCoords* pointerCoords) {
@@ -3757,7 +3778,7 @@ InputDispatcher::CommandEntry::~CommandEntry() {
 // --- InputDispatcher::TouchState ---
 
 InputDispatcher::TouchState::TouchState() :
-    down(false), split(false), deviceId(-1) {
+    down(false), split(false), deviceId(-1), source(0) {
 }
 
 InputDispatcher::TouchState::~TouchState() {
@@ -3767,6 +3788,7 @@ void InputDispatcher::TouchState::reset() {
     down = false;
     split = false;
     deviceId = -1;
+    source = 0;
     windows.clear();
 }
 
@@ -3774,6 +3796,7 @@ void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
     down = other.down;
     split = other.split;
     deviceId = other.deviceId;
+    source = other.source;
     windows.clear();
     windows.appendVector(other.windows);
 }
index 11e5117..006c6b8 100644 (file)
@@ -227,10 +227,10 @@ public:
      * These methods should only be called on the input reader thread.
      */
     virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
-    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
+    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
             uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
             int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
-    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
+    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
             uint32_t policyFlags, int32_t action, int32_t flags,
             int32_t metaState, int32_t edgeFlags,
             uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
@@ -313,10 +313,10 @@ public:
     virtual void dispatchOnce();
 
     virtual void notifyConfigurationChanged(nsecs_t eventTime);
-    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
+    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
             uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
             int32_t scanCode, int32_t metaState, nsecs_t downTime);
-    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
+    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
             uint32_t policyFlags, int32_t action, int32_t flags,
             int32_t metaState, int32_t edgeFlags,
             uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
@@ -379,7 +379,7 @@ private:
 
     struct KeyEntry : EventEntry {
         int32_t deviceId;
-        int32_t source;
+        uint32_t source;
         int32_t action;
         int32_t flags;
         int32_t keyCode;
@@ -407,7 +407,7 @@ private:
 
     struct MotionEntry : EventEntry {
         int32_t deviceId;
-        int32_t source;
+        uint32_t source;
         int32_t action;
         int32_t flags;
         int32_t metaState;
@@ -549,11 +549,11 @@ private:
         InjectionState* obtainInjectionState(int32_t injectorPid, int32_t injectorUid);
         ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
         KeyEntry* obtainKeyEntry(nsecs_t eventTime,
-                int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
+                int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
                 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
                 int32_t repeatCount, nsecs_t downTime);
         MotionEntry* obtainMotionEntry(nsecs_t eventTime,
-                int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
+                int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
                 int32_t flags, int32_t metaState, int32_t edgeFlags,
                 float xPrecision, float yPrecision,
                 nsecs_t downTime, uint32_t pointerCount,
@@ -645,7 +645,7 @@ private:
     private:
         struct KeyMemento {
             int32_t deviceId;
-            int32_t source;
+            uint32_t source;
             int32_t keyCode;
             int32_t scanCode;
             int32_t flags;
@@ -654,7 +654,7 @@ private:
 
         struct MotionMemento {
             int32_t deviceId;
-            int32_t source;
+            uint32_t source;
             float xPrecision;
             float yPrecision;
             nsecs_t downTime;
@@ -846,6 +846,7 @@ private:
         bool down;
         bool split;
         int32_t deviceId; // id of the device that is currently down, others are rejected
+        uint32_t source;  // source of the device that is current down, others are rejected
         Vector<TouchedWindow> windows;
 
         TouchState();
index 2e83256..680b64b 100644 (file)
@@ -260,10 +260,10 @@ InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, ui
         device->addMapper(new CursorInputMapper(device));
     }
 
-    // Touchscreen-like devices.
-    if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT) {
+    // Touchscreens and touchpad devices.
+    if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
         device->addMapper(new MultiTouchInputMapper(device));
-    } else if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN) {
+    } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
         device->addMapper(new SingleTouchInputMapper(device));
     }
 
@@ -1455,12 +1455,12 @@ void TouchInputMapper::configureParameters() {
     mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
 
     String8 deviceTypeString;
-    mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
+    mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
     if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
             deviceTypeString)) {
-        if (deviceTypeString == "touchPad") {
-            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
-        } else if (deviceTypeString != "touchScreen") {
+        if (deviceTypeString == "touchScreen") {
+            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
+        } else if (deviceTypeString != "touchPad") {
             LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
         }
     }
index 98d627d..25030d8 100644 (file)
@@ -188,7 +188,7 @@ public:
     struct NotifyKeyArgs {
         nsecs_t eventTime;
         int32_t deviceId;
-        int32_t source;
+        uint32_t source;
         uint32_t policyFlags;
         int32_t action;
         int32_t flags;
@@ -201,7 +201,7 @@ public:
     struct NotifyMotionArgs {
         nsecs_t eventTime;
         int32_t deviceId;
-        int32_t source;
+        uint32_t source;
         uint32_t policyFlags;
         int32_t action;
         int32_t flags;
@@ -288,7 +288,7 @@ private:
         mNotifyConfigurationChangedArgs.push_back(args);
     }
 
-    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
+    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
             uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
             int32_t scanCode, int32_t metaState, nsecs_t downTime) {
         NotifyKeyArgs args;
@@ -305,7 +305,7 @@ private:
         mNotifyKeyArgs.push_back(args);
     }
 
-    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
+    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
             uint32_t policyFlags, int32_t action, int32_t flags,
             int32_t metaState, int32_t edgeFlags,
             uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
@@ -976,8 +976,10 @@ TEST_F(InputReaderTest, GetInputConfiguration_WhenAlphabeticKeyboardPresent_Retu
 }
 
 TEST_F(InputReaderTest, GetInputConfiguration_WhenTouchScreenPresent_ReturnsFingerTouchScreen) {
+    PropertyMap configuration;
+    configuration.addProperty(String8("touch.deviceType"), String8("touchScreen"));
     ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("touchscreen"),
-            INPUT_DEVICE_CLASS_TOUCHSCREEN, NULL));
+            INPUT_DEVICE_CLASS_TOUCH, &configuration));
 
     InputConfiguration config;
     mReader->getInputConfiguration(&config);
@@ -987,6 +989,18 @@ TEST_F(InputReaderTest, GetInputConfiguration_WhenTouchScreenPresent_ReturnsFing
     ASSERT_EQ(InputConfiguration::TOUCHSCREEN_FINGER, config.touchScreen);
 }
 
+TEST_F(InputReaderTest, GetInputConfiguration_WhenTouchPadPresent_ReturnsFingerNoTouch) {
+    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("touchpad"),
+            INPUT_DEVICE_CLASS_TOUCH, NULL));
+
+    InputConfiguration config;
+    mReader->getInputConfiguration(&config);
+
+    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
+    ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation);
+    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
+}
+
 TEST_F(InputReaderTest, GetInputConfiguration_WhenMousePresent_ReturnsNoNavigation) {
     sp<FakePointerController> controller = new FakePointerController();
     mFakePolicy->setPointerController(0, controller);
@@ -2385,6 +2399,14 @@ void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
 }
 
 
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecified_ReturnsTouchPad) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
+}
+
 TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchPad_ReturnsTouchPad) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
     prepareAxes(POSITION);
@@ -2405,6 +2427,7 @@ TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_Return
 
 TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2432,6 +2455,7 @@ TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
 
 TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2459,6 +2483,7 @@ TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
 
 TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2475,6 +2500,7 @@ TEST_F(SingleTouchInputMapperTest, Reset_WhenVirtualKeysAreDown_SendsUp) {
     // Note: Ideally we should send cancels but the implementation is more straightforward
     // with up and this will only happen if a device is forcibly removed.
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2508,6 +2534,7 @@ TEST_F(SingleTouchInputMapperTest, Reset_WhenVirtualKeysAreDown_SendsUp) {
 
 TEST_F(SingleTouchInputMapperTest, Reset_WhenNothingIsPressed_NothingMuchHappens) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2534,6 +2561,7 @@ TEST_F(SingleTouchInputMapperTest, Reset_WhenNothingIsPressed_NothingMuchHappens
 
 TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2583,6 +2611,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNor
 
 TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2697,6 +2726,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
 
 TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2765,6 +2795,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves
 
 TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -2848,6 +2879,7 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
 
 TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareAxes(POSITION);
     addConfigurationProperty("touch.orientationAware", "0");
     addMapperAndConfigure(mapper);
@@ -2870,6 +2902,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotate
 
 TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareAxes(POSITION);
     addMapperAndConfigure(mapper);
 
@@ -2930,6 +2963,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
 
 TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
     SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION | PRESSURE | TOOL);
     addMapperAndConfigure(mapper);
@@ -3062,6 +3096,7 @@ void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) {
 
 TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
     MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION);
     prepareVirtualKeys();
@@ -3313,6 +3348,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
 
 TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
     MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION | ID);
     prepareVirtualKeys();
@@ -3473,6 +3509,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
 
 TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
     MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR);
     addMapperAndConfigure(mapper);
@@ -3518,6 +3555,7 @@ TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
 
 TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
     MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION | TOUCH | TOOL | MINOR);
     addConfigurationProperty("touch.touchSize.calibration", "geometric");
@@ -3559,6 +3597,7 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration)
 
 TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinearCalibration) {
     MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION | TOUCH | TOOL);
     addConfigurationProperty("touch.touchSize.calibration", "pressure");
@@ -3615,6 +3654,7 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinear
 
 TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibration) {
     MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(DISPLAY_ORIENTATION_0);
     prepareAxes(POSITION | TOUCH | TOOL);
     addConfigurationProperty("touch.touchSize.calibration", "pressure");