Loading include/input/Input.h +1 −0 Original line number Diff line number Diff line Loading @@ -212,6 +212,7 @@ struct PointerCoords { status_t setAxisValue(int32_t axis, float value); void scale(float scale); void applyOffset(float xOffset, float yOffset); inline float getX() const { return getAxisValue(AMOTION_EVENT_AXIS_X); Loading libs/input/Input.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,11 @@ void PointerCoords::scale(float scaleFactor) { scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor); } void PointerCoords::applyOffset(float xOffset, float yOffset) { setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset); setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset); } #ifdef HAVE_ANDROID_OS status_t PointerCoords::readFromParcel(Parcel* parcel) { bits = parcel->readInt64(); Loading services/inputflinger/InputDispatcher.cpp +115 −75 Original line number Diff line number Diff line Loading @@ -1023,7 +1023,14 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout sp<InputWindowHandle> windowHandle = connection->inputWindowHandle; if (windowHandle != NULL) { mTouchState.removeWindow(windowHandle); const InputWindowInfo* info = windowHandle->getInfo(); if (info) { ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(info->displayId); if (stateIndex >= 0) { mTouchStatesByDisplay.editValueAt(stateIndex).removeWindow( windowHandle); } } } if (connection->status == Connection::STATUS_NORMAL) { Loading Loading @@ -1164,11 +1171,21 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN; sp<InputWindowHandle> newHoverWindowHandle; bool isSplit = mTouchState.split; bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0 && (mTouchState.deviceId != entry->deviceId || mTouchState.source != entry->source || mTouchState.displayId != displayId); // Copy current touch state into mTempTouchState. // This state is always reset at the end of this function, so if we don't find state // for the specified display then our initial state will be empty. const TouchState* oldState = NULL; ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId); if (oldStateIndex >= 0) { oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex); mTempTouchState.copyFrom(*oldState); } bool isSplit = mTempTouchState.split; bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 && (mTempTouchState.deviceId != entry->deviceId || mTempTouchState.source != entry->source || mTempTouchState.displayId != displayId); bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT); Loading @@ -1178,11 +1195,10 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, bool wrongDevice = false; if (newGesture) { bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN; if (switchedDevice && mTouchState.down && !down) { if (switchedDevice && mTempTouchState.down && !down) { #if DEBUG_FOCUS ALOGD("Dropping event because a pointer for a different device is already down."); #endif mTempTouchState.copyFrom(mTouchState); injectionResult = INPUT_EVENT_INJECTION_FAILED; switchedDevice = false; wrongDevice = true; Loading @@ -1194,8 +1210,6 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, mTempTouchState.source = entry->source; mTempTouchState.displayId = displayId; isSplit = false; } else { mTempTouchState.copyFrom(mTouchState); } if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) { Loading Loading @@ -1518,32 +1532,31 @@ Failed: if (isHoverAction) { // Started hovering, therefore no longer down. if (mTouchState.down) { if (oldState && oldState->down) { #if DEBUG_FOCUS ALOGD("Conflicting pointer actions: Hover received while pointer was down."); #endif *outConflictingPointerActions = true; } mTouchState.reset(); mTempTouchState.reset(); if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) { mTouchState.deviceId = entry->deviceId; mTouchState.source = entry->source; mTouchState.displayId = displayId; mTempTouchState.deviceId = entry->deviceId; mTempTouchState.source = entry->source; mTempTouchState.displayId = displayId; } } else if (maskedAction == AMOTION_EVENT_ACTION_UP || maskedAction == AMOTION_EVENT_ACTION_CANCEL) { // All pointers up or canceled. mTouchState.reset(); mTempTouchState.reset(); } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) { // First pointer went down. if (mTouchState.down) { if (oldState && oldState->down) { #if DEBUG_FOCUS ALOGD("Conflicting pointer actions: Down received while already down."); #endif *outConflictingPointerActions = true; } mTouchState.copyFrom(mTempTouchState); } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) { // One pointer went up. if (isSplit) { Loading @@ -1562,12 +1575,20 @@ Failed: i += 1; } } mTouchState.copyFrom(mTempTouchState); } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) { // Discard temporary touch state since it was only valid for this action. } // Save changes unless the action was scroll in which case the temporary touch // state was only valid for this one action. if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) { if (mTempTouchState.displayId >= 0) { if (oldStateIndex >= 0) { mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState); } else { // Save changes to touch state as-is for all other actions. mTouchState.copyFrom(mTempTouchState); mTouchStatesByDisplay.add(displayId, mTempTouchState); } } else if (oldStateIndex >= 0) { mTouchStatesByDisplay.removeItemsAt(oldStateIndex); } } // Update hover state. Loading Loading @@ -2319,7 +2340,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet originalMotionEntry->yPrecision, originalMotionEntry->downTime, originalMotionEntry->displayId, splitPointerCount, splitPointerProperties, splitPointerCoords); splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0); if (originalMotionEntry->injectionState) { splitMotionEntry->injectionState = originalMotionEntry->injectionState; Loading Loading @@ -2491,7 +2512,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) { args->action, args->flags, args->metaState, args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime, args->displayId, args->pointerCount, args->pointerProperties, args->pointerCoords); args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0); needWake = enqueueInboundEventLocked(newEntry); mLock.unlock(); Loading Loading @@ -2539,7 +2560,7 @@ void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) { } } int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t displayId, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags) { #if DEBUG_INBOUND_EVENT_DETAILS Loading Loading @@ -2590,7 +2611,6 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, case AINPUT_EVENT_TYPE_MOTION: { const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event); int32_t displayId = ADISPLAY_ID_DEFAULT; int32_t action = motionEvent->getAction(); size_t pointerCount = motionEvent->getPointerCount(); const PointerProperties* pointerProperties = motionEvent->getPointerProperties(); Loading @@ -2613,7 +2633,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, motionEvent->getEdgeFlags(), motionEvent->getXPrecision(), motionEvent->getYPrecision(), motionEvent->getDownTime(), displayId, uint32_t(pointerCount), pointerProperties, samplePointerCoords); uint32_t(pointerCount), pointerProperties, samplePointerCoords, motionEvent->getXOffset(), motionEvent->getYOffset()); lastInjectedEntry = firstInjectedEntry; for (size_t i = motionEvent->getHistorySize(); i > 0; i--) { sampleEventTimes += 1; Loading @@ -2625,7 +2646,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, motionEvent->getEdgeFlags(), motionEvent->getXPrecision(), motionEvent->getYPrecision(), motionEvent->getDownTime(), displayId, uint32_t(pointerCount), pointerProperties, samplePointerCoords); uint32_t(pointerCount), pointerProperties, samplePointerCoords, motionEvent->getXOffset(), motionEvent->getYOffset()); lastInjectedEntry->next = nextInjectedEntry; lastInjectedEntry = nextInjectedEntry; } Loading Loading @@ -2850,8 +2872,10 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu mFocusedWindowHandle = newFocusedWindowHandle; } for (size_t i = 0; i < mTouchState.windows.size(); i++) { TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i); for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) { TouchState& state = mTouchStatesByDisplay.editValueAt(d); for (size_t i = 0; i < state.windows.size(); i++) { TouchedWindow& touchedWindow = state.windows.editItemAt(i); if (!hasWindowHandleLocked(touchedWindow.windowHandle)) { #if DEBUG_FOCUS ALOGD("Touched window was removed: %s", Loading @@ -2865,7 +2889,8 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu synthesizeCancelationEventsForInputChannelLocked( touchedInputChannel, options); } mTouchState.windows.removeAt(i--); state.windows.removeAt(i--); } } } Loading Loading @@ -3006,23 +3031,27 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, } bool found = false; for (size_t i = 0; i < mTouchState.windows.size(); i++) { const TouchedWindow& touchedWindow = mTouchState.windows[i]; for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) { TouchState& state = mTouchStatesByDisplay.editValueAt(d); for (size_t i = 0; i < state.windows.size(); i++) { const TouchedWindow& touchedWindow = state.windows[i]; if (touchedWindow.windowHandle == fromWindowHandle) { int32_t oldTargetFlags = touchedWindow.targetFlags; BitSet32 pointerIds = touchedWindow.pointerIds; mTouchState.windows.removeAt(i); state.windows.removeAt(i); int32_t newTargetFlags = oldTargetFlags & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS); mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); found = true; break; goto Found; } } } Found: if (! found) { #if DEBUG_FOCUS Loading Loading @@ -3066,7 +3095,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { drainInboundQueueLocked(); resetANRTimeoutsLocked(); mTouchState.reset(); mTouchStatesByDisplay.clear(); mLastHoverWindowHandle.clear(); } Loading Loading @@ -3101,22 +3130,28 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { dump.appendFormat(INDENT "FocusedWindow: name='%s'\n", mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>"); 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); dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId); if (!mTouchState.windows.isEmpty()) { dump.append(INDENT "TouchedWindows:\n"); for (size_t i = 0; i < mTouchState.windows.size(); i++) { const TouchedWindow& touchedWindow = mTouchState.windows[i]; dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", if (!mTouchStatesByDisplay.isEmpty()) { dump.appendFormat(INDENT "TouchStatesByDisplay:\n"); for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) { const TouchState& state = mTouchStatesByDisplay.valueAt(i); dump.appendFormat(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n", state.displayId, toString(state.down), toString(state.split), state.deviceId, state.source); if (!state.windows.isEmpty()) { dump.append(INDENT3 "Windows:\n"); for (size_t i = 0; i < state.windows.size(); i++) { const TouchedWindow& touchedWindow = state.windows[i]; dump.appendFormat(INDENT4 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", i, touchedWindow.windowHandle->getName().string(), touchedWindow.pointerIds.value, touchedWindow.targetFlags); } } else { dump.append(INDENT "TouchedWindows: <none>\n"); dump.append(INDENT3 "Windows: <none>\n"); } } } else { dump.append(INDENT "TouchStates: <no displays touched>\n"); } if (!mWindowHandles.isEmpty()) { Loading Loading @@ -3901,7 +3936,8 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime, int32_t metaState, int32_t buttonState, int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime, int32_t displayId, uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) : const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, float xOffset, float yOffset) : EventEntry(TYPE_MOTION, eventTime, policyFlags), eventTime(eventTime), deviceId(deviceId), source(source), action(action), flags(flags), Loading @@ -3911,6 +3947,9 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime, for (uint32_t i = 0; i < pointerCount; i++) { this->pointerProperties[i].copyFrom(pointerProperties[i]); this->pointerCoords[i].copyFrom(pointerCoords[i]); if (xOffset || yOffset) { this->pointerCoords[i].applyOffset(xOffset, yOffset); } } } Loading Loading @@ -4204,7 +4243,8 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim memento.flags, 0, 0, 0, memento.xPrecision, memento.yPrecision, memento.downTime, memento.displayId, memento.pointerCount, memento.pointerProperties, memento.pointerCoords)); memento.pointerCount, memento.pointerProperties, memento.pointerCoords, 0, 0)); } } } Loading services/inputflinger/InputDispatcher.h +5 −4 Original line number Diff line number Diff line Loading @@ -297,7 +297,7 @@ public: * * This method may be called on any thread (usually by the input manager). */ virtual int32_t injectInputEvent(const InputEvent* event, virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags) = 0; Loading Loading @@ -381,7 +381,7 @@ public: virtual void notifySwitch(const NotifySwitchArgs* args); virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args); virtual int32_t injectInputEvent(const InputEvent* event, virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags); Loading Loading @@ -525,7 +525,8 @@ private: int32_t metaState, int32_t buttonState, int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime, int32_t displayId, uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords); const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, float xOffset, float yOffset); virtual void appendDescription(String8& msg) const; protected: Loading Loading @@ -959,7 +960,7 @@ private: bool isSlippery() const; }; TouchState mTouchState; KeyedVector<int32_t, TouchState> mTouchStatesByDisplay; TouchState mTempTouchState; // Focused application. Loading services/inputflinger/tests/InputDispatcher_test.cpp +27 −12 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ static const nsecs_t ARBITRARY_TIME = 1234; // An arbitrary device id. static const int32_t DEVICE_ID = 1; // An arbitrary display id. static const int32_t DISPLAY_ID = 0; // An arbitrary injector pid / uid pair that has permission to inject events. static const int32_t INJECTOR_PID = 999; static const int32_t INJECTOR_UID = 1001; Loading Loading @@ -126,7 +129,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) { event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject key events with undefined action."; Loading @@ -134,7 +138,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) { event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject key events with ACTION_MULTIPLE."; } Loading @@ -154,7 +159,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with undefined action."; Loading @@ -164,7 +170,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer down index too large."; Loading @@ -173,7 +180,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer down index too small."; Loading @@ -183,7 +191,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer up index too large."; Loading @@ -192,7 +201,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer up index too small."; Loading @@ -201,7 +211,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 0, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with 0 pointers."; Loading @@ -209,7 +220,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with more than MAX_POINTERS pointers."; Loading @@ -219,7 +231,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer ids less than 0."; Loading @@ -228,7 +241,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer ids greater than MAX_POINTER_ID."; Loading @@ -239,7 +253,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 2, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with duplicate pointer ids."; } Loading Loading
include/input/Input.h +1 −0 Original line number Diff line number Diff line Loading @@ -212,6 +212,7 @@ struct PointerCoords { status_t setAxisValue(int32_t axis, float value); void scale(float scale); void applyOffset(float xOffset, float yOffset); inline float getX() const { return getAxisValue(AMOTION_EVENT_AXIS_X); Loading
libs/input/Input.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -213,6 +213,11 @@ void PointerCoords::scale(float scaleFactor) { scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor); } void PointerCoords::applyOffset(float xOffset, float yOffset) { setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset); setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset); } #ifdef HAVE_ANDROID_OS status_t PointerCoords::readFromParcel(Parcel* parcel) { bits = parcel->readInt64(); Loading
services/inputflinger/InputDispatcher.cpp +115 −75 Original line number Diff line number Diff line Loading @@ -1023,7 +1023,14 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout sp<InputWindowHandle> windowHandle = connection->inputWindowHandle; if (windowHandle != NULL) { mTouchState.removeWindow(windowHandle); const InputWindowInfo* info = windowHandle->getInfo(); if (info) { ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(info->displayId); if (stateIndex >= 0) { mTouchStatesByDisplay.editValueAt(stateIndex).removeWindow( windowHandle); } } } if (connection->status == Connection::STATUS_NORMAL) { Loading Loading @@ -1164,11 +1171,21 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN; sp<InputWindowHandle> newHoverWindowHandle; bool isSplit = mTouchState.split; bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0 && (mTouchState.deviceId != entry->deviceId || mTouchState.source != entry->source || mTouchState.displayId != displayId); // Copy current touch state into mTempTouchState. // This state is always reset at the end of this function, so if we don't find state // for the specified display then our initial state will be empty. const TouchState* oldState = NULL; ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId); if (oldStateIndex >= 0) { oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex); mTempTouchState.copyFrom(*oldState); } bool isSplit = mTempTouchState.split; bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0 && (mTempTouchState.deviceId != entry->deviceId || mTempTouchState.source != entry->source || mTempTouchState.displayId != displayId); bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT); Loading @@ -1178,11 +1195,10 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, bool wrongDevice = false; if (newGesture) { bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN; if (switchedDevice && mTouchState.down && !down) { if (switchedDevice && mTempTouchState.down && !down) { #if DEBUG_FOCUS ALOGD("Dropping event because a pointer for a different device is already down."); #endif mTempTouchState.copyFrom(mTouchState); injectionResult = INPUT_EVENT_INJECTION_FAILED; switchedDevice = false; wrongDevice = true; Loading @@ -1194,8 +1210,6 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, mTempTouchState.source = entry->source; mTempTouchState.displayId = displayId; isSplit = false; } else { mTempTouchState.copyFrom(mTouchState); } if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) { Loading Loading @@ -1518,32 +1532,31 @@ Failed: if (isHoverAction) { // Started hovering, therefore no longer down. if (mTouchState.down) { if (oldState && oldState->down) { #if DEBUG_FOCUS ALOGD("Conflicting pointer actions: Hover received while pointer was down."); #endif *outConflictingPointerActions = true; } mTouchState.reset(); mTempTouchState.reset(); if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) { mTouchState.deviceId = entry->deviceId; mTouchState.source = entry->source; mTouchState.displayId = displayId; mTempTouchState.deviceId = entry->deviceId; mTempTouchState.source = entry->source; mTempTouchState.displayId = displayId; } } else if (maskedAction == AMOTION_EVENT_ACTION_UP || maskedAction == AMOTION_EVENT_ACTION_CANCEL) { // All pointers up or canceled. mTouchState.reset(); mTempTouchState.reset(); } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) { // First pointer went down. if (mTouchState.down) { if (oldState && oldState->down) { #if DEBUG_FOCUS ALOGD("Conflicting pointer actions: Down received while already down."); #endif *outConflictingPointerActions = true; } mTouchState.copyFrom(mTempTouchState); } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) { // One pointer went up. if (isSplit) { Loading @@ -1562,12 +1575,20 @@ Failed: i += 1; } } mTouchState.copyFrom(mTempTouchState); } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) { // Discard temporary touch state since it was only valid for this action. } // Save changes unless the action was scroll in which case the temporary touch // state was only valid for this one action. if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) { if (mTempTouchState.displayId >= 0) { if (oldStateIndex >= 0) { mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState); } else { // Save changes to touch state as-is for all other actions. mTouchState.copyFrom(mTempTouchState); mTouchStatesByDisplay.add(displayId, mTempTouchState); } } else if (oldStateIndex >= 0) { mTouchStatesByDisplay.removeItemsAt(oldStateIndex); } } // Update hover state. Loading Loading @@ -2319,7 +2340,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet originalMotionEntry->yPrecision, originalMotionEntry->downTime, originalMotionEntry->displayId, splitPointerCount, splitPointerProperties, splitPointerCoords); splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0); if (originalMotionEntry->injectionState) { splitMotionEntry->injectionState = originalMotionEntry->injectionState; Loading Loading @@ -2491,7 +2512,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) { args->action, args->flags, args->metaState, args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime, args->displayId, args->pointerCount, args->pointerProperties, args->pointerCoords); args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0); needWake = enqueueInboundEventLocked(newEntry); mLock.unlock(); Loading Loading @@ -2539,7 +2560,7 @@ void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) { } } int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t displayId, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags) { #if DEBUG_INBOUND_EVENT_DETAILS Loading Loading @@ -2590,7 +2611,6 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, case AINPUT_EVENT_TYPE_MOTION: { const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event); int32_t displayId = ADISPLAY_ID_DEFAULT; int32_t action = motionEvent->getAction(); size_t pointerCount = motionEvent->getPointerCount(); const PointerProperties* pointerProperties = motionEvent->getPointerProperties(); Loading @@ -2613,7 +2633,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, motionEvent->getEdgeFlags(), motionEvent->getXPrecision(), motionEvent->getYPrecision(), motionEvent->getDownTime(), displayId, uint32_t(pointerCount), pointerProperties, samplePointerCoords); uint32_t(pointerCount), pointerProperties, samplePointerCoords, motionEvent->getXOffset(), motionEvent->getYOffset()); lastInjectedEntry = firstInjectedEntry; for (size_t i = motionEvent->getHistorySize(); i > 0; i--) { sampleEventTimes += 1; Loading @@ -2625,7 +2646,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, motionEvent->getEdgeFlags(), motionEvent->getXPrecision(), motionEvent->getYPrecision(), motionEvent->getDownTime(), displayId, uint32_t(pointerCount), pointerProperties, samplePointerCoords); uint32_t(pointerCount), pointerProperties, samplePointerCoords, motionEvent->getXOffset(), motionEvent->getYOffset()); lastInjectedEntry->next = nextInjectedEntry; lastInjectedEntry = nextInjectedEntry; } Loading Loading @@ -2850,8 +2872,10 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu mFocusedWindowHandle = newFocusedWindowHandle; } for (size_t i = 0; i < mTouchState.windows.size(); i++) { TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i); for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) { TouchState& state = mTouchStatesByDisplay.editValueAt(d); for (size_t i = 0; i < state.windows.size(); i++) { TouchedWindow& touchedWindow = state.windows.editItemAt(i); if (!hasWindowHandleLocked(touchedWindow.windowHandle)) { #if DEBUG_FOCUS ALOGD("Touched window was removed: %s", Loading @@ -2865,7 +2889,8 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu synthesizeCancelationEventsForInputChannelLocked( touchedInputChannel, options); } mTouchState.windows.removeAt(i--); state.windows.removeAt(i--); } } } Loading Loading @@ -3006,23 +3031,27 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, } bool found = false; for (size_t i = 0; i < mTouchState.windows.size(); i++) { const TouchedWindow& touchedWindow = mTouchState.windows[i]; for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) { TouchState& state = mTouchStatesByDisplay.editValueAt(d); for (size_t i = 0; i < state.windows.size(); i++) { const TouchedWindow& touchedWindow = state.windows[i]; if (touchedWindow.windowHandle == fromWindowHandle) { int32_t oldTargetFlags = touchedWindow.targetFlags; BitSet32 pointerIds = touchedWindow.pointerIds; mTouchState.windows.removeAt(i); state.windows.removeAt(i); int32_t newTargetFlags = oldTargetFlags & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS); mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); found = true; break; goto Found; } } } Found: if (! found) { #if DEBUG_FOCUS Loading Loading @@ -3066,7 +3095,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { drainInboundQueueLocked(); resetANRTimeoutsLocked(); mTouchState.reset(); mTouchStatesByDisplay.clear(); mLastHoverWindowHandle.clear(); } Loading Loading @@ -3101,22 +3130,28 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { dump.appendFormat(INDENT "FocusedWindow: name='%s'\n", mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>"); 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); dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId); if (!mTouchState.windows.isEmpty()) { dump.append(INDENT "TouchedWindows:\n"); for (size_t i = 0; i < mTouchState.windows.size(); i++) { const TouchedWindow& touchedWindow = mTouchState.windows[i]; dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", if (!mTouchStatesByDisplay.isEmpty()) { dump.appendFormat(INDENT "TouchStatesByDisplay:\n"); for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) { const TouchState& state = mTouchStatesByDisplay.valueAt(i); dump.appendFormat(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n", state.displayId, toString(state.down), toString(state.split), state.deviceId, state.source); if (!state.windows.isEmpty()) { dump.append(INDENT3 "Windows:\n"); for (size_t i = 0; i < state.windows.size(); i++) { const TouchedWindow& touchedWindow = state.windows[i]; dump.appendFormat(INDENT4 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", i, touchedWindow.windowHandle->getName().string(), touchedWindow.pointerIds.value, touchedWindow.targetFlags); } } else { dump.append(INDENT "TouchedWindows: <none>\n"); dump.append(INDENT3 "Windows: <none>\n"); } } } else { dump.append(INDENT "TouchStates: <no displays touched>\n"); } if (!mWindowHandles.isEmpty()) { Loading Loading @@ -3901,7 +3936,8 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime, int32_t metaState, int32_t buttonState, int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime, int32_t displayId, uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) : const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, float xOffset, float yOffset) : EventEntry(TYPE_MOTION, eventTime, policyFlags), eventTime(eventTime), deviceId(deviceId), source(source), action(action), flags(flags), Loading @@ -3911,6 +3947,9 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime, for (uint32_t i = 0; i < pointerCount; i++) { this->pointerProperties[i].copyFrom(pointerProperties[i]); this->pointerCoords[i].copyFrom(pointerCoords[i]); if (xOffset || yOffset) { this->pointerCoords[i].applyOffset(xOffset, yOffset); } } } Loading Loading @@ -4204,7 +4243,8 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim memento.flags, 0, 0, 0, memento.xPrecision, memento.yPrecision, memento.downTime, memento.displayId, memento.pointerCount, memento.pointerProperties, memento.pointerCoords)); memento.pointerCount, memento.pointerProperties, memento.pointerCoords, 0, 0)); } } } Loading
services/inputflinger/InputDispatcher.h +5 −4 Original line number Diff line number Diff line Loading @@ -297,7 +297,7 @@ public: * * This method may be called on any thread (usually by the input manager). */ virtual int32_t injectInputEvent(const InputEvent* event, virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags) = 0; Loading Loading @@ -381,7 +381,7 @@ public: virtual void notifySwitch(const NotifySwitchArgs* args); virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args); virtual int32_t injectInputEvent(const InputEvent* event, virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId, int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags); Loading Loading @@ -525,7 +525,8 @@ private: int32_t metaState, int32_t buttonState, int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime, int32_t displayId, uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords); const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, float xOffset, float yOffset); virtual void appendDescription(String8& msg) const; protected: Loading Loading @@ -959,7 +960,7 @@ private: bool isSlippery() const; }; TouchState mTouchState; KeyedVector<int32_t, TouchState> mTouchStatesByDisplay; TouchState mTempTouchState; // Focused application. Loading
services/inputflinger/tests/InputDispatcher_test.cpp +27 −12 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ static const nsecs_t ARBITRARY_TIME = 1234; // An arbitrary device id. static const int32_t DEVICE_ID = 1; // An arbitrary display id. static const int32_t DISPLAY_ID = 0; // An arbitrary injector pid / uid pair that has permission to inject events. static const int32_t INJECTOR_PID = 999; static const int32_t INJECTOR_UID = 1001; Loading Loading @@ -126,7 +129,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) { event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject key events with undefined action."; Loading @@ -134,7 +138,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) { event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject key events with ACTION_MULTIPLE."; } Loading @@ -154,7 +159,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with undefined action."; Loading @@ -164,7 +170,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer down index too large."; Loading @@ -173,7 +180,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer down index too small."; Loading @@ -183,7 +191,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer up index too large."; Loading @@ -192,7 +201,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer up index too small."; Loading @@ -201,7 +211,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 0, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with 0 pointers."; Loading @@ -209,7 +220,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with more than MAX_POINTERS pointers."; Loading @@ -219,7 +231,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer ids less than 0."; Loading @@ -228,7 +241,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with pointer ids greater than MAX_POINTER_ID."; Loading @@ -239,7 +253,8 @@ TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) { AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0, ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 2, pointerProperties, pointerCoords); ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event, ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent( &event, DISPLAY_ID, INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0)) << "Should reject motion events with duplicate pointer ids."; } Loading