Loading core/res/res/values/config.xml +0 −12 Original line number Diff line number Diff line Loading @@ -441,18 +441,6 @@ <!-- Enables swipe versus poly-finger touch disambiguation in the KeyboardView --> <bool name="config_swipeDisambiguation">true</bool> <!-- Enables special filtering code in the framework for raw touch events from the touch driver. This code exists for one particular device, and should not be enabled for any others. Hopefully in the future it will be removed when the lower-level touch driver generates better data. --> <bool name="config_filterTouchEvents">false</bool> <!-- Enables special filtering code in the framework for raw touch events from the touch driver. This code exists for one particular device, and should not be enabled for any others. --> <bool name="config_filterJumpyTouchEvents">false</bool> <!-- Specifies the amount of time to disable virtual keys after the screen is touched in order to filter out accidental virtual key presses due to swiping gestures or taps near the edge of the display. May be 0 to disable the feature. Loading services/input/InputReader.cpp +2 −400 Original line number Diff line number Diff line Loading @@ -768,10 +768,6 @@ void InputReader::dump(String8& dump) { dump.append(mConfig.excludedDeviceNames.itemAt(i).string()); } dump.append("]\n"); dump.appendFormat(INDENT2 "FilterTouchEvents: %s\n", toString(mConfig.filterTouchEvents)); dump.appendFormat(INDENT2 "FilterJumpyTouchEvents: %s\n", toString(mConfig.filterJumpyTouchEvents)); dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n", mConfig.virtualKeyQuietTime * 0.000001f); Loading Loading @@ -1955,13 +1951,6 @@ void TouchInputMapper::initializeLocked() { mLastTouch.clear(); mDownTime = 0; for (uint32_t i = 0; i < MAX_POINTERS; i++) { mAveragingTouchFilter.historyStart[i] = 0; mAveragingTouchFilter.historyEnd[i] = 0; } mJumpyTouchFilter.jumpyPointsDropped = 0; mLocked.currentVirtualKey.down = false; mLocked.orientedRanges.havePressure = false; Loading Loading @@ -2028,10 +2017,6 @@ void TouchInputMapper::configure(const InputReaderConfiguration* config, uint32_ } void TouchInputMapper::configureParameters() { mParameters.useBadTouchFilter = mConfig.filterTouchEvents; mParameters.useAveragingTouchFilter = mConfig.filterTouchEvents; mParameters.useJumpyTouchFilter = mConfig.filterJumpyTouchEvents; // Use the pointer presentation mode for devices that do not support distinct // multitouch. The spot-based presentation relies on being able to accurately // locate two or more fingers on the touch pad. Loading Loading @@ -2122,13 +2107,6 @@ void TouchInputMapper::dumpParameters(String8& dump) { mParameters.associatedDisplayId); dump.appendFormat(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware)); dump.appendFormat(INDENT4 "UseBadTouchFilter: %s\n", toString(mParameters.useBadTouchFilter)); dump.appendFormat(INDENT4 "UseAveragingTouchFilter: %s\n", toString(mParameters.useAveragingTouchFilter)); dump.appendFormat(INDENT4 "UseJumpyTouchFilter: %s\n", toString(mParameters.useJumpyTouchFilter)); } void TouchInputMapper::configureRawAxes() { Loading Loading @@ -2985,33 +2963,10 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { #endif // Preprocess pointer data. if (mParameters.useBadTouchFilter) { if (applyBadTouchFilter()) { havePointerIds = false; } } if (mParameters.useJumpyTouchFilter) { if (applyJumpyTouchFilter()) { havePointerIds = false; } } if (!havePointerIds) { calculatePointerIds(); } TouchData temp; TouchData* savedTouch; if (mParameters.useAveragingTouchFilter) { temp.copyFrom(mCurrentTouch); savedTouch = & temp; applyAveragingTouchFilter(); } else { savedTouch = & mCurrentTouch; } uint32_t policyFlags = 0; if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) { if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) { Loading Loading @@ -3058,9 +3013,9 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { // Keep the button state so we can track edge-triggered button state changes. if (touchResult == DROP_STROKE) { mLastTouch.clear(); mLastTouch.buttonState = savedTouch->buttonState; mLastTouch.buttonState = mCurrentTouch.buttonState; } else { mLastTouch.copyFrom(*savedTouch); mLastTouch.copyFrom(mCurrentTouch); } } Loading Loading @@ -4826,359 +4781,6 @@ void TouchInputMapper::calculatePointerIds() { } } /* Special hack for devices that have bad screen data: if one of the * points has moved more than a screen height from the last position, * then drop it. */ bool TouchInputMapper::applyBadTouchFilter() { uint32_t pointerCount = mCurrentTouch.pointerCount; // Nothing to do if there are no points. if (pointerCount == 0) { return false; } // Don't do anything if a finger is going down or up. We run // here before assigning pointer IDs, so there isn't a good // way to do per-finger matching. if (pointerCount != mLastTouch.pointerCount) { return false; } // We consider a single movement across more than a 7/16 of // the long size of the screen to be bad. This was a magic value // determined by looking at the maximum distance it is feasible // to actually move in one sample. int32_t maxDeltaY = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) * 7 / 16; // XXX The original code in InputDevice.java included commented out // code for testing the X axis. Note that when we drop a point // we don't actually restore the old X either. Strange. // The old code also tries to track when bad points were previously // detected but it turns out that due to the placement of a "break" // at the end of the loop, we never set mDroppedBadPoint to true // so it is effectively dead code. // Need to figure out if the old code is busted or just overcomplicated // but working as intended. // Look through all new points and see if any are farther than // acceptable from all previous points. for (uint32_t i = pointerCount; i-- > 0; ) { int32_t y = mCurrentTouch.pointers[i].y; int32_t closestY = INT_MAX; int32_t closestDeltaY = 0; #if DEBUG_HACKS LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y); #endif for (uint32_t j = pointerCount; j-- > 0; ) { int32_t lastY = mLastTouch.pointers[j].y; int32_t deltaY = abs(y - lastY); #if DEBUG_HACKS LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d", j, lastY, deltaY); #endif if (deltaY < maxDeltaY) { goto SkipSufficientlyClosePoint; } if (deltaY < closestDeltaY) { closestDeltaY = deltaY; closestY = lastY; } } // Must not have found a close enough match. #if DEBUG_HACKS LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d", i, y, closestY, closestDeltaY, maxDeltaY); #endif mCurrentTouch.pointers[i].y = closestY; return true; // XXX original code only corrects one point SkipSufficientlyClosePoint: ; } // No change. return false; } /* Special hack for devices that have bad screen data: drop points where * the coordinate value for one axis has jumped to the other pointer's location. */ bool TouchInputMapper::applyJumpyTouchFilter() { uint32_t pointerCount = mCurrentTouch.pointerCount; if (mLastTouch.pointerCount != pointerCount) { #if DEBUG_HACKS LOGD("JumpyTouchFilter: Different pointer count %d -> %d", mLastTouch.pointerCount, pointerCount); for (uint32_t i = 0; i < pointerCount; i++) { LOGD(" Pointer %d (%d, %d)", i, mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); } #endif if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) { if (mLastTouch.pointerCount == 1 && pointerCount == 2) { // Just drop the first few events going from 1 to 2 pointers. // They're bad often enough that they're not worth considering. mCurrentTouch.pointerCount = 1; mJumpyTouchFilter.jumpyPointsDropped += 1; #if DEBUG_HACKS LOGD("JumpyTouchFilter: Pointer 2 dropped"); #endif return true; } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) { // The event when we go from 2 -> 1 tends to be messed up too mCurrentTouch.pointerCount = 2; mCurrentTouch.pointers[0] = mLastTouch.pointers[0]; mCurrentTouch.pointers[1] = mLastTouch.pointers[1]; mJumpyTouchFilter.jumpyPointsDropped += 1; #if DEBUG_HACKS for (int32_t i = 0; i < 2; i++) { LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i, mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); } #endif return true; } } // Reset jumpy points dropped on other transitions or if limit exceeded. mJumpyTouchFilter.jumpyPointsDropped = 0; #if DEBUG_HACKS LOGD("JumpyTouchFilter: Transition - drop limit reset"); #endif return false; } // We have the same number of pointers as last time. // A 'jumpy' point is one where the coordinate value for one axis // has jumped to the other pointer's location. No need to do anything // else if we only have one pointer. if (pointerCount < 2) { return false; } if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) { int jumpyEpsilon = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) / JUMPY_EPSILON_DIVISOR; // We only replace the single worst jumpy point as characterized by pointer distance // in a single axis. int32_t badPointerIndex = -1; int32_t badPointerReplacementIndex = -1; int32_t badPointerDistance = INT_MIN; // distance to be corrected for (uint32_t i = pointerCount; i-- > 0; ) { int32_t x = mCurrentTouch.pointers[i].x; int32_t y = mCurrentTouch.pointers[i].y; #if DEBUG_HACKS LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y); #endif // Check if a touch point is too close to another's coordinates bool dropX = false, dropY = false; for (uint32_t j = 0; j < pointerCount; j++) { if (i == j) { continue; } if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) { dropX = true; break; } if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) { dropY = true; break; } } if (! dropX && ! dropY) { continue; // not jumpy } // Find a replacement candidate by comparing with older points on the // complementary (non-jumpy) axis. int32_t distance = INT_MIN; // distance to be corrected int32_t replacementIndex = -1; if (dropX) { // X looks too close. Find an older replacement point with a close Y. int32_t smallestDeltaY = INT_MAX; for (uint32_t j = 0; j < pointerCount; j++) { int32_t deltaY = abs(y - mLastTouch.pointers[j].y); if (deltaY < smallestDeltaY) { smallestDeltaY = deltaY; replacementIndex = j; } } distance = abs(x - mLastTouch.pointers[replacementIndex].x); } else { // Y looks too close. Find an older replacement point with a close X. int32_t smallestDeltaX = INT_MAX; for (uint32_t j = 0; j < pointerCount; j++) { int32_t deltaX = abs(x - mLastTouch.pointers[j].x); if (deltaX < smallestDeltaX) { smallestDeltaX = deltaX; replacementIndex = j; } } distance = abs(y - mLastTouch.pointers[replacementIndex].y); } // If replacing this pointer would correct a worse error than the previous ones // considered, then use this replacement instead. if (distance > badPointerDistance) { badPointerIndex = i; badPointerReplacementIndex = replacementIndex; badPointerDistance = distance; } } // Correct the jumpy pointer if one was found. if (badPointerIndex >= 0) { #if DEBUG_HACKS LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)", badPointerIndex, mLastTouch.pointers[badPointerReplacementIndex].x, mLastTouch.pointers[badPointerReplacementIndex].y); #endif mCurrentTouch.pointers[badPointerIndex].x = mLastTouch.pointers[badPointerReplacementIndex].x; mCurrentTouch.pointers[badPointerIndex].y = mLastTouch.pointers[badPointerReplacementIndex].y; mJumpyTouchFilter.jumpyPointsDropped += 1; return true; } } mJumpyTouchFilter.jumpyPointsDropped = 0; return false; } /* Special hack for devices that have bad screen data: aggregate and * compute averages of the coordinate data, to reduce the amount of * jitter seen by applications. */ void TouchInputMapper::applyAveragingTouchFilter() { for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) { uint32_t id = mCurrentTouch.pointers[currentIndex].id; int32_t x = mCurrentTouch.pointers[currentIndex].x; int32_t y = mCurrentTouch.pointers[currentIndex].y; int32_t pressure; switch (mCalibration.pressureSource) { case Calibration::PRESSURE_SOURCE_PRESSURE: pressure = mCurrentTouch.pointers[currentIndex].pressure; break; case Calibration::PRESSURE_SOURCE_TOUCH: pressure = mCurrentTouch.pointers[currentIndex].touchMajor; break; default: pressure = 1; break; } if (mLastTouch.idBits.hasBit(id)) { // Pointer was down before and is still down now. // Compute average over history trace. uint32_t start = mAveragingTouchFilter.historyStart[id]; uint32_t end = mAveragingTouchFilter.historyEnd[id]; int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x; int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y; uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); #if DEBUG_HACKS LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld", id, distance); #endif if (distance < AVERAGING_DISTANCE_LIMIT) { // Increment end index in preparation for recording new historical data. end += 1; if (end > AVERAGING_HISTORY_SIZE) { end = 0; } // If the end index has looped back to the start index then we have filled // the historical trace up to the desired size so we drop the historical // data at the start of the trace. if (end == start) { start += 1; if (start > AVERAGING_HISTORY_SIZE) { start = 0; } } // Add the raw data to the historical trace. mAveragingTouchFilter.historyStart[id] = start; mAveragingTouchFilter.historyEnd[id] = end; mAveragingTouchFilter.historyData[end].pointers[id].x = x; mAveragingTouchFilter.historyData[end].pointers[id].y = y; mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure; // Average over all historical positions in the trace by total pressure. int32_t averagedX = 0; int32_t averagedY = 0; int32_t totalPressure = 0; for (;;) { int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x; int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y; int32_t historicalPressure = mAveragingTouchFilter.historyData[start] .pointers[id].pressure; averagedX += historicalX * historicalPressure; averagedY += historicalY * historicalPressure; totalPressure += historicalPressure; if (start == end) { break; } start += 1; if (start > AVERAGING_HISTORY_SIZE) { start = 0; } } if (totalPressure != 0) { averagedX /= totalPressure; averagedY /= totalPressure; #if DEBUG_HACKS LOGD("AveragingTouchFilter: Pointer id %d - " "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure, averagedX, averagedY); #endif mCurrentTouch.pointers[currentIndex].x = averagedX; mCurrentTouch.pointers[currentIndex].y = averagedY; } } else { #if DEBUG_HACKS LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id); #endif } } else { #if DEBUG_HACKS LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id); #endif } // Reset pointer history. mAveragingTouchFilter.historyStart[id] = 0; mAveragingTouchFilter.historyEnd[id] = 0; mAveragingTouchFilter.historyData[0].pointers[id].x = x; mAveragingTouchFilter.historyData[0].pointers[id].y = y; mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure; } } int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { { // acquire lock AutoMutex _l(mLock); Loading services/input/InputReader.h +0 −49 Original line number Diff line number Diff line Loading @@ -57,14 +57,6 @@ struct InputReaderConfiguration { CHANGE_MUST_REOPEN = 1 << 31, }; // Determines whether to turn on some hacks we have to improve the touch interaction with a // certain device whose screen currently is not all that good. bool filterTouchEvents; // Determines whether to turn on some hacks to improve touch interaction with another device // where touch coordinate data can get corrupted. bool filterJumpyTouchEvents; // Gets the amount of time to disable virtual keys after the screen is touched // in order to filter out accidental virtual key presses due to swiping gestures // or taps near the edge of the display. May be 0 to disable the feature. Loading Loading @@ -146,8 +138,6 @@ struct InputReaderConfiguration { float pointerGestureZoomSpeedRatio; InputReaderConfiguration() : filterTouchEvents(false), filterJumpyTouchEvents(false), virtualKeyQuietTime(0), pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f), wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f), Loading Loading @@ -812,10 +802,6 @@ protected: int32_t associatedDisplayId; bool orientationAware; bool useBadTouchFilter; bool useJumpyTouchFilter; bool useAveragingTouchFilter; enum GestureMode { GESTURE_MODE_POINTER, GESTURE_MODE_SPOTS, Loading Loading @@ -1042,38 +1028,6 @@ protected: void syncTouch(nsecs_t when, bool havePointerIds); private: /* Maximum number of historical samples to average. */ static const uint32_t AVERAGING_HISTORY_SIZE = 5; /* Slop distance for jumpy pointer detection. * The vertical range of the screen divided by this is our epsilon value. */ static const uint32_t JUMPY_EPSILON_DIVISOR = 212; /* Number of jumpy points to drop for touchscreens that need it. */ static const uint32_t JUMPY_TRANSITION_DROPS = 3; static const uint32_t JUMPY_DROP_LIMIT = 3; /* Maximum squared distance for averaging. * If moving farther than this, turn of averaging to avoid lag in response. */ static const uint64_t AVERAGING_DISTANCE_LIMIT = 75 * 75; struct AveragingTouchFilterState { // Individual history tracks are stored by pointer id uint32_t historyStart[MAX_POINTERS]; uint32_t historyEnd[MAX_POINTERS]; struct { struct { int32_t x; int32_t y; int32_t pressure; } pointers[MAX_POINTERS]; } historyData[AVERAGING_HISTORY_SIZE]; } mAveragingTouchFilter; struct JumpyTouchFilterState { uint32_t jumpyPointsDropped; } mJumpyTouchFilter; struct PointerDistanceHeapElement { uint32_t currentPointerIndex : 8; uint32_t lastPointerIndex : 8; Loading Loading @@ -1251,9 +1205,6 @@ private: bool isPointInsideSurfaceLocked(int32_t x, int32_t y); const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y); bool applyBadTouchFilter(); bool applyJumpyTouchFilter(); void applyAveragingTouchFilter(); void calculatePointerIds(); }; Loading services/input/tests/InputReader_test.cpp +0 −8 Original line number Diff line number Diff line Loading @@ -144,14 +144,6 @@ public: mDisplayInfos.add(displayId, info); } void setFilterTouchEvents(bool enabled) { mConfig.filterTouchEvents = enabled; } void setFilterJumpyTouchEvents(bool enabled) { mConfig.filterJumpyTouchEvents = enabled; } virtual nsecs_t getVirtualKeyQuietTime() { return 0; } Loading services/java/com/android/server/wm/InputManager.java +0 −12 Original line number Diff line number Diff line Loading @@ -552,18 +552,6 @@ public class InputManager { == PackageManager.PERMISSION_GRANTED; } @SuppressWarnings("unused") public boolean filterTouchEvents() { return mContext.getResources().getBoolean( com.android.internal.R.bool.config_filterTouchEvents); } @SuppressWarnings("unused") public boolean filterJumpyTouchEvents() { return mContext.getResources().getBoolean( com.android.internal.R.bool.config_filterJumpyTouchEvents); } @SuppressWarnings("unused") public int getVirtualKeyQuietTimeMillis() { return mContext.getResources().getInteger( Loading Loading
core/res/res/values/config.xml +0 −12 Original line number Diff line number Diff line Loading @@ -441,18 +441,6 @@ <!-- Enables swipe versus poly-finger touch disambiguation in the KeyboardView --> <bool name="config_swipeDisambiguation">true</bool> <!-- Enables special filtering code in the framework for raw touch events from the touch driver. This code exists for one particular device, and should not be enabled for any others. Hopefully in the future it will be removed when the lower-level touch driver generates better data. --> <bool name="config_filterTouchEvents">false</bool> <!-- Enables special filtering code in the framework for raw touch events from the touch driver. This code exists for one particular device, and should not be enabled for any others. --> <bool name="config_filterJumpyTouchEvents">false</bool> <!-- Specifies the amount of time to disable virtual keys after the screen is touched in order to filter out accidental virtual key presses due to swiping gestures or taps near the edge of the display. May be 0 to disable the feature. Loading
services/input/InputReader.cpp +2 −400 Original line number Diff line number Diff line Loading @@ -768,10 +768,6 @@ void InputReader::dump(String8& dump) { dump.append(mConfig.excludedDeviceNames.itemAt(i).string()); } dump.append("]\n"); dump.appendFormat(INDENT2 "FilterTouchEvents: %s\n", toString(mConfig.filterTouchEvents)); dump.appendFormat(INDENT2 "FilterJumpyTouchEvents: %s\n", toString(mConfig.filterJumpyTouchEvents)); dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n", mConfig.virtualKeyQuietTime * 0.000001f); Loading Loading @@ -1955,13 +1951,6 @@ void TouchInputMapper::initializeLocked() { mLastTouch.clear(); mDownTime = 0; for (uint32_t i = 0; i < MAX_POINTERS; i++) { mAveragingTouchFilter.historyStart[i] = 0; mAveragingTouchFilter.historyEnd[i] = 0; } mJumpyTouchFilter.jumpyPointsDropped = 0; mLocked.currentVirtualKey.down = false; mLocked.orientedRanges.havePressure = false; Loading Loading @@ -2028,10 +2017,6 @@ void TouchInputMapper::configure(const InputReaderConfiguration* config, uint32_ } void TouchInputMapper::configureParameters() { mParameters.useBadTouchFilter = mConfig.filterTouchEvents; mParameters.useAveragingTouchFilter = mConfig.filterTouchEvents; mParameters.useJumpyTouchFilter = mConfig.filterJumpyTouchEvents; // Use the pointer presentation mode for devices that do not support distinct // multitouch. The spot-based presentation relies on being able to accurately // locate two or more fingers on the touch pad. Loading Loading @@ -2122,13 +2107,6 @@ void TouchInputMapper::dumpParameters(String8& dump) { mParameters.associatedDisplayId); dump.appendFormat(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware)); dump.appendFormat(INDENT4 "UseBadTouchFilter: %s\n", toString(mParameters.useBadTouchFilter)); dump.appendFormat(INDENT4 "UseAveragingTouchFilter: %s\n", toString(mParameters.useAveragingTouchFilter)); dump.appendFormat(INDENT4 "UseJumpyTouchFilter: %s\n", toString(mParameters.useJumpyTouchFilter)); } void TouchInputMapper::configureRawAxes() { Loading Loading @@ -2985,33 +2963,10 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { #endif // Preprocess pointer data. if (mParameters.useBadTouchFilter) { if (applyBadTouchFilter()) { havePointerIds = false; } } if (mParameters.useJumpyTouchFilter) { if (applyJumpyTouchFilter()) { havePointerIds = false; } } if (!havePointerIds) { calculatePointerIds(); } TouchData temp; TouchData* savedTouch; if (mParameters.useAveragingTouchFilter) { temp.copyFrom(mCurrentTouch); savedTouch = & temp; applyAveragingTouchFilter(); } else { savedTouch = & mCurrentTouch; } uint32_t policyFlags = 0; if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) { if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) { Loading Loading @@ -3058,9 +3013,9 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { // Keep the button state so we can track edge-triggered button state changes. if (touchResult == DROP_STROKE) { mLastTouch.clear(); mLastTouch.buttonState = savedTouch->buttonState; mLastTouch.buttonState = mCurrentTouch.buttonState; } else { mLastTouch.copyFrom(*savedTouch); mLastTouch.copyFrom(mCurrentTouch); } } Loading Loading @@ -4826,359 +4781,6 @@ void TouchInputMapper::calculatePointerIds() { } } /* Special hack for devices that have bad screen data: if one of the * points has moved more than a screen height from the last position, * then drop it. */ bool TouchInputMapper::applyBadTouchFilter() { uint32_t pointerCount = mCurrentTouch.pointerCount; // Nothing to do if there are no points. if (pointerCount == 0) { return false; } // Don't do anything if a finger is going down or up. We run // here before assigning pointer IDs, so there isn't a good // way to do per-finger matching. if (pointerCount != mLastTouch.pointerCount) { return false; } // We consider a single movement across more than a 7/16 of // the long size of the screen to be bad. This was a magic value // determined by looking at the maximum distance it is feasible // to actually move in one sample. int32_t maxDeltaY = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) * 7 / 16; // XXX The original code in InputDevice.java included commented out // code for testing the X axis. Note that when we drop a point // we don't actually restore the old X either. Strange. // The old code also tries to track when bad points were previously // detected but it turns out that due to the placement of a "break" // at the end of the loop, we never set mDroppedBadPoint to true // so it is effectively dead code. // Need to figure out if the old code is busted or just overcomplicated // but working as intended. // Look through all new points and see if any are farther than // acceptable from all previous points. for (uint32_t i = pointerCount; i-- > 0; ) { int32_t y = mCurrentTouch.pointers[i].y; int32_t closestY = INT_MAX; int32_t closestDeltaY = 0; #if DEBUG_HACKS LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y); #endif for (uint32_t j = pointerCount; j-- > 0; ) { int32_t lastY = mLastTouch.pointers[j].y; int32_t deltaY = abs(y - lastY); #if DEBUG_HACKS LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d", j, lastY, deltaY); #endif if (deltaY < maxDeltaY) { goto SkipSufficientlyClosePoint; } if (deltaY < closestDeltaY) { closestDeltaY = deltaY; closestY = lastY; } } // Must not have found a close enough match. #if DEBUG_HACKS LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d", i, y, closestY, closestDeltaY, maxDeltaY); #endif mCurrentTouch.pointers[i].y = closestY; return true; // XXX original code only corrects one point SkipSufficientlyClosePoint: ; } // No change. return false; } /* Special hack for devices that have bad screen data: drop points where * the coordinate value for one axis has jumped to the other pointer's location. */ bool TouchInputMapper::applyJumpyTouchFilter() { uint32_t pointerCount = mCurrentTouch.pointerCount; if (mLastTouch.pointerCount != pointerCount) { #if DEBUG_HACKS LOGD("JumpyTouchFilter: Different pointer count %d -> %d", mLastTouch.pointerCount, pointerCount); for (uint32_t i = 0; i < pointerCount; i++) { LOGD(" Pointer %d (%d, %d)", i, mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); } #endif if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) { if (mLastTouch.pointerCount == 1 && pointerCount == 2) { // Just drop the first few events going from 1 to 2 pointers. // They're bad often enough that they're not worth considering. mCurrentTouch.pointerCount = 1; mJumpyTouchFilter.jumpyPointsDropped += 1; #if DEBUG_HACKS LOGD("JumpyTouchFilter: Pointer 2 dropped"); #endif return true; } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) { // The event when we go from 2 -> 1 tends to be messed up too mCurrentTouch.pointerCount = 2; mCurrentTouch.pointers[0] = mLastTouch.pointers[0]; mCurrentTouch.pointers[1] = mLastTouch.pointers[1]; mJumpyTouchFilter.jumpyPointsDropped += 1; #if DEBUG_HACKS for (int32_t i = 0; i < 2; i++) { LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i, mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); } #endif return true; } } // Reset jumpy points dropped on other transitions or if limit exceeded. mJumpyTouchFilter.jumpyPointsDropped = 0; #if DEBUG_HACKS LOGD("JumpyTouchFilter: Transition - drop limit reset"); #endif return false; } // We have the same number of pointers as last time. // A 'jumpy' point is one where the coordinate value for one axis // has jumped to the other pointer's location. No need to do anything // else if we only have one pointer. if (pointerCount < 2) { return false; } if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) { int jumpyEpsilon = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) / JUMPY_EPSILON_DIVISOR; // We only replace the single worst jumpy point as characterized by pointer distance // in a single axis. int32_t badPointerIndex = -1; int32_t badPointerReplacementIndex = -1; int32_t badPointerDistance = INT_MIN; // distance to be corrected for (uint32_t i = pointerCount; i-- > 0; ) { int32_t x = mCurrentTouch.pointers[i].x; int32_t y = mCurrentTouch.pointers[i].y; #if DEBUG_HACKS LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y); #endif // Check if a touch point is too close to another's coordinates bool dropX = false, dropY = false; for (uint32_t j = 0; j < pointerCount; j++) { if (i == j) { continue; } if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) { dropX = true; break; } if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) { dropY = true; break; } } if (! dropX && ! dropY) { continue; // not jumpy } // Find a replacement candidate by comparing with older points on the // complementary (non-jumpy) axis. int32_t distance = INT_MIN; // distance to be corrected int32_t replacementIndex = -1; if (dropX) { // X looks too close. Find an older replacement point with a close Y. int32_t smallestDeltaY = INT_MAX; for (uint32_t j = 0; j < pointerCount; j++) { int32_t deltaY = abs(y - mLastTouch.pointers[j].y); if (deltaY < smallestDeltaY) { smallestDeltaY = deltaY; replacementIndex = j; } } distance = abs(x - mLastTouch.pointers[replacementIndex].x); } else { // Y looks too close. Find an older replacement point with a close X. int32_t smallestDeltaX = INT_MAX; for (uint32_t j = 0; j < pointerCount; j++) { int32_t deltaX = abs(x - mLastTouch.pointers[j].x); if (deltaX < smallestDeltaX) { smallestDeltaX = deltaX; replacementIndex = j; } } distance = abs(y - mLastTouch.pointers[replacementIndex].y); } // If replacing this pointer would correct a worse error than the previous ones // considered, then use this replacement instead. if (distance > badPointerDistance) { badPointerIndex = i; badPointerReplacementIndex = replacementIndex; badPointerDistance = distance; } } // Correct the jumpy pointer if one was found. if (badPointerIndex >= 0) { #if DEBUG_HACKS LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)", badPointerIndex, mLastTouch.pointers[badPointerReplacementIndex].x, mLastTouch.pointers[badPointerReplacementIndex].y); #endif mCurrentTouch.pointers[badPointerIndex].x = mLastTouch.pointers[badPointerReplacementIndex].x; mCurrentTouch.pointers[badPointerIndex].y = mLastTouch.pointers[badPointerReplacementIndex].y; mJumpyTouchFilter.jumpyPointsDropped += 1; return true; } } mJumpyTouchFilter.jumpyPointsDropped = 0; return false; } /* Special hack for devices that have bad screen data: aggregate and * compute averages of the coordinate data, to reduce the amount of * jitter seen by applications. */ void TouchInputMapper::applyAveragingTouchFilter() { for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) { uint32_t id = mCurrentTouch.pointers[currentIndex].id; int32_t x = mCurrentTouch.pointers[currentIndex].x; int32_t y = mCurrentTouch.pointers[currentIndex].y; int32_t pressure; switch (mCalibration.pressureSource) { case Calibration::PRESSURE_SOURCE_PRESSURE: pressure = mCurrentTouch.pointers[currentIndex].pressure; break; case Calibration::PRESSURE_SOURCE_TOUCH: pressure = mCurrentTouch.pointers[currentIndex].touchMajor; break; default: pressure = 1; break; } if (mLastTouch.idBits.hasBit(id)) { // Pointer was down before and is still down now. // Compute average over history trace. uint32_t start = mAveragingTouchFilter.historyStart[id]; uint32_t end = mAveragingTouchFilter.historyEnd[id]; int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x; int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y; uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); #if DEBUG_HACKS LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld", id, distance); #endif if (distance < AVERAGING_DISTANCE_LIMIT) { // Increment end index in preparation for recording new historical data. end += 1; if (end > AVERAGING_HISTORY_SIZE) { end = 0; } // If the end index has looped back to the start index then we have filled // the historical trace up to the desired size so we drop the historical // data at the start of the trace. if (end == start) { start += 1; if (start > AVERAGING_HISTORY_SIZE) { start = 0; } } // Add the raw data to the historical trace. mAveragingTouchFilter.historyStart[id] = start; mAveragingTouchFilter.historyEnd[id] = end; mAveragingTouchFilter.historyData[end].pointers[id].x = x; mAveragingTouchFilter.historyData[end].pointers[id].y = y; mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure; // Average over all historical positions in the trace by total pressure. int32_t averagedX = 0; int32_t averagedY = 0; int32_t totalPressure = 0; for (;;) { int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x; int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y; int32_t historicalPressure = mAveragingTouchFilter.historyData[start] .pointers[id].pressure; averagedX += historicalX * historicalPressure; averagedY += historicalY * historicalPressure; totalPressure += historicalPressure; if (start == end) { break; } start += 1; if (start > AVERAGING_HISTORY_SIZE) { start = 0; } } if (totalPressure != 0) { averagedX /= totalPressure; averagedY /= totalPressure; #if DEBUG_HACKS LOGD("AveragingTouchFilter: Pointer id %d - " "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure, averagedX, averagedY); #endif mCurrentTouch.pointers[currentIndex].x = averagedX; mCurrentTouch.pointers[currentIndex].y = averagedY; } } else { #if DEBUG_HACKS LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id); #endif } } else { #if DEBUG_HACKS LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id); #endif } // Reset pointer history. mAveragingTouchFilter.historyStart[id] = 0; mAveragingTouchFilter.historyEnd[id] = 0; mAveragingTouchFilter.historyData[0].pointers[id].x = x; mAveragingTouchFilter.historyData[0].pointers[id].y = y; mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure; } } int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { { // acquire lock AutoMutex _l(mLock); Loading
services/input/InputReader.h +0 −49 Original line number Diff line number Diff line Loading @@ -57,14 +57,6 @@ struct InputReaderConfiguration { CHANGE_MUST_REOPEN = 1 << 31, }; // Determines whether to turn on some hacks we have to improve the touch interaction with a // certain device whose screen currently is not all that good. bool filterTouchEvents; // Determines whether to turn on some hacks to improve touch interaction with another device // where touch coordinate data can get corrupted. bool filterJumpyTouchEvents; // Gets the amount of time to disable virtual keys after the screen is touched // in order to filter out accidental virtual key presses due to swiping gestures // or taps near the edge of the display. May be 0 to disable the feature. Loading Loading @@ -146,8 +138,6 @@ struct InputReaderConfiguration { float pointerGestureZoomSpeedRatio; InputReaderConfiguration() : filterTouchEvents(false), filterJumpyTouchEvents(false), virtualKeyQuietTime(0), pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f), wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f), Loading Loading @@ -812,10 +802,6 @@ protected: int32_t associatedDisplayId; bool orientationAware; bool useBadTouchFilter; bool useJumpyTouchFilter; bool useAveragingTouchFilter; enum GestureMode { GESTURE_MODE_POINTER, GESTURE_MODE_SPOTS, Loading Loading @@ -1042,38 +1028,6 @@ protected: void syncTouch(nsecs_t when, bool havePointerIds); private: /* Maximum number of historical samples to average. */ static const uint32_t AVERAGING_HISTORY_SIZE = 5; /* Slop distance for jumpy pointer detection. * The vertical range of the screen divided by this is our epsilon value. */ static const uint32_t JUMPY_EPSILON_DIVISOR = 212; /* Number of jumpy points to drop for touchscreens that need it. */ static const uint32_t JUMPY_TRANSITION_DROPS = 3; static const uint32_t JUMPY_DROP_LIMIT = 3; /* Maximum squared distance for averaging. * If moving farther than this, turn of averaging to avoid lag in response. */ static const uint64_t AVERAGING_DISTANCE_LIMIT = 75 * 75; struct AveragingTouchFilterState { // Individual history tracks are stored by pointer id uint32_t historyStart[MAX_POINTERS]; uint32_t historyEnd[MAX_POINTERS]; struct { struct { int32_t x; int32_t y; int32_t pressure; } pointers[MAX_POINTERS]; } historyData[AVERAGING_HISTORY_SIZE]; } mAveragingTouchFilter; struct JumpyTouchFilterState { uint32_t jumpyPointsDropped; } mJumpyTouchFilter; struct PointerDistanceHeapElement { uint32_t currentPointerIndex : 8; uint32_t lastPointerIndex : 8; Loading Loading @@ -1251,9 +1205,6 @@ private: bool isPointInsideSurfaceLocked(int32_t x, int32_t y); const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y); bool applyBadTouchFilter(); bool applyJumpyTouchFilter(); void applyAveragingTouchFilter(); void calculatePointerIds(); }; Loading
services/input/tests/InputReader_test.cpp +0 −8 Original line number Diff line number Diff line Loading @@ -144,14 +144,6 @@ public: mDisplayInfos.add(displayId, info); } void setFilterTouchEvents(bool enabled) { mConfig.filterTouchEvents = enabled; } void setFilterJumpyTouchEvents(bool enabled) { mConfig.filterJumpyTouchEvents = enabled; } virtual nsecs_t getVirtualKeyQuietTime() { return 0; } Loading
services/java/com/android/server/wm/InputManager.java +0 −12 Original line number Diff line number Diff line Loading @@ -552,18 +552,6 @@ public class InputManager { == PackageManager.PERMISSION_GRANTED; } @SuppressWarnings("unused") public boolean filterTouchEvents() { return mContext.getResources().getBoolean( com.android.internal.R.bool.config_filterTouchEvents); } @SuppressWarnings("unused") public boolean filterJumpyTouchEvents() { return mContext.getResources().getBoolean( com.android.internal.R.bool.config_filterJumpyTouchEvents); } @SuppressWarnings("unused") public int getVirtualKeyQuietTimeMillis() { return mContext.getResources().getInteger( Loading