diff options
author | Adam Powell <adamp@google.com> | 2010-03-03 17:22:15 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-03-03 17:22:15 -0800 |
commit | 37f700a83cf885447e67053a87d4e30b2f44ae44 (patch) | |
tree | 0742bf3c0de1ffe41432811e44018cc41788b033 /services | |
parent | e58aa0d964f91597cf3eecf16ff72988e6c5f5a3 (diff) | |
parent | f5bcc6addd9c1f8f6bb8b8626540d003b3f964fa (diff) | |
download | frameworks_base-37f700a83cf885447e67053a87d4e30b2f44ae44.zip frameworks_base-37f700a83cf885447e67053a87d4e30b2f44ae44.tar.gz frameworks_base-37f700a83cf885447e67053a87d4e30b2f44ae44.tar.bz2 |
Merge "InputDevice filtering for jumpy screens. Updated ScaleGestureDetector for framework deprecations."
Diffstat (limited to 'services')
-rw-r--r-- | services/java/com/android/server/InputDevice.java | 165 | ||||
-rw-r--r-- | services/java/com/android/server/KeyInputQueue.java | 16 |
2 files changed, 179 insertions, 2 deletions
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java index d5e94ec..ed7eed0 100644 --- a/services/java/com/android/server/InputDevice.java +++ b/services/java/com/android/server/InputDevice.java @@ -34,6 +34,16 @@ public class InputDevice { /** Maximum number of pointers we will track and report. */ static final int MAX_POINTERS = 10; + /** + * Slop distance for jumpy pointer detection. + * This is in touchscreen coordinates, not pixels or dips. + */ + private static final int JUMPY_EPSILON = 30; + + /** Number of jumpy points to drop for touchscreens that need it. */ + private static final int JUMPY_TRANSITION_DROPS = 3; + private static final int JUMPY_DROP_LIMIT = 3; + final int id; final int classes; final String name; @@ -84,6 +94,9 @@ public class InputDevice { // Used to determine whether we dropped bad data, to avoid doing // it repeatedly. final boolean[] mDroppedBadPoint = new boolean[MAX_POINTERS]; + + // Used to count the number of jumpy points dropped. + private int mJumpyPointsDropped = 0; // Used to perform averaging of reported coordinates, to smooth // the data and filter out transients during a release. @@ -232,6 +245,158 @@ public class InputDevice { } } + void dropJumpyPoint(InputDevice dev) { + final int nextNumPointers = mNextNumPointers; + final int lastNumPointers = mLastNumPointers; + final int[] nextData = mNextData; + final int[] lastData = mLastData; + + if (nextNumPointers != mLastNumPointers) { + if (DEBUG_HACKS) { + Slog.d("InputDevice", "Different pointer count " + lastNumPointers + + " -> " + nextNumPointers); + for (int i = 0; i < nextNumPointers; i++) { + int ioff = i * MotionEvent.NUM_SAMPLE_DATA; + Slog.d("InputDevice", "Pointer " + i + " (" + + mNextData[ioff + MotionEvent.SAMPLE_X] + ", " + + mNextData[ioff + MotionEvent.SAMPLE_Y] + ")"); + } + } + + // Just drop the first few events going from 1 to 2 pointers. + // They're bad often enough that they're not worth considering. + if (lastNumPointers == 1 && nextNumPointers == 2 + && mJumpyPointsDropped < JUMPY_TRANSITION_DROPS) { + mNextNumPointers = 1; + mJumpyPointsDropped++; + } else if (lastNumPointers == 2 && nextNumPointers == 1 + && mJumpyPointsDropped < JUMPY_TRANSITION_DROPS) { + // The event when we go from 2 -> 1 tends to be messed up too + System.arraycopy(lastData, 0, nextData, 0, + lastNumPointers * MotionEvent.NUM_SAMPLE_DATA); + mNextNumPointers = lastNumPointers; + mJumpyPointsDropped++; + + if (DEBUG_HACKS) { + for (int i = 0; i < mNextNumPointers; i++) { + int ioff = i * MotionEvent.NUM_SAMPLE_DATA; + Slog.d("InputDevice", "Pointer " + i + " replaced (" + + mNextData[ioff + MotionEvent.SAMPLE_X] + ", " + + mNextData[ioff + MotionEvent.SAMPLE_Y] + ")"); + } + } + } else { + mJumpyPointsDropped = 0; + + if (DEBUG_HACKS) { + Slog.d("InputDevice", "Transition - drop limit reset"); + } + } + return; + } + + // 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 (nextNumPointers < 2) { + return; + } + + int badPointerIndex = -1; + int badPointerReplaceXWith = 0; + int badPointerReplaceYWith = 0; + int badPointerDistance = Integer.MIN_VALUE; + for (int i = nextNumPointers - 1; i >= 0; i--) { + boolean dropx = false; + boolean dropy = false; + + // Limit how many times a jumpy point can get dropped. + if (mJumpyPointsDropped < JUMPY_DROP_LIMIT) { + final int ioff = i * MotionEvent.NUM_SAMPLE_DATA; + final int x = nextData[ioff + MotionEvent.SAMPLE_X]; + final int y = nextData[ioff + MotionEvent.SAMPLE_Y]; + + if (DEBUG_HACKS) { + Slog.d("InputDevice", "Point " + i + " (" + x + ", " + y + ")"); + } + + // Check if a touch point is too close to another's coordinates + for (int j = 0; j < nextNumPointers && !dropx && !dropy; j++) { + if (j == i) { + continue; + } + + final int joff = j * MotionEvent.NUM_SAMPLE_DATA; + final int xOther = nextData[joff + MotionEvent.SAMPLE_X]; + final int yOther = nextData[joff + MotionEvent.SAMPLE_Y]; + + dropx = Math.abs(x - xOther) <= JUMPY_EPSILON; + dropy = Math.abs(y - yOther) <= JUMPY_EPSILON; + } + + if (dropx) { + int xreplace = lastData[MotionEvent.SAMPLE_X]; + int yreplace = lastData[MotionEvent.SAMPLE_Y]; + int distance = Math.abs(yreplace - y); + for (int j = 1; j < lastNumPointers; j++) { + final int joff = j * MotionEvent.NUM_SAMPLE_DATA; + int lasty = lastData[joff + MotionEvent.SAMPLE_Y]; + int currDist = Math.abs(lasty - y); + if (currDist < distance) { + xreplace = lastData[joff + MotionEvent.SAMPLE_X]; + yreplace = lasty; + distance = currDist; + } + } + + int badXDelta = Math.abs(xreplace - x); + if (badXDelta > badPointerDistance) { + badPointerDistance = badXDelta; + badPointerIndex = i; + badPointerReplaceXWith = xreplace; + badPointerReplaceYWith = yreplace; + } + } else if (dropy) { + int xreplace = lastData[MotionEvent.SAMPLE_X]; + int yreplace = lastData[MotionEvent.SAMPLE_Y]; + int distance = Math.abs(xreplace - x); + for (int j = 1; j < lastNumPointers; j++) { + final int joff = j * MotionEvent.NUM_SAMPLE_DATA; + int lastx = lastData[joff + MotionEvent.SAMPLE_X]; + int currDist = Math.abs(lastx - x); + if (currDist < distance) { + xreplace = lastx; + yreplace = lastData[joff + MotionEvent.SAMPLE_Y]; + distance = currDist; + } + } + + int badYDelta = Math.abs(yreplace - y); + if (badYDelta > badPointerDistance) { + badPointerDistance = badYDelta; + badPointerIndex = i; + badPointerReplaceXWith = xreplace; + badPointerReplaceYWith = yreplace; + } + } + } + } + if (badPointerIndex >= 0) { + if (DEBUG_HACKS) { + Slog.d("InputDevice", "Replacing bad pointer " + badPointerIndex + + " with (" + badPointerReplaceXWith + ", " + badPointerReplaceYWith + + ")"); + } + + final int offset = badPointerIndex * MotionEvent.NUM_SAMPLE_DATA; + nextData[offset + MotionEvent.SAMPLE_X] = badPointerReplaceXWith; + nextData[offset + MotionEvent.SAMPLE_Y] = badPointerReplaceYWith; + mJumpyPointsDropped++; + } else { + mJumpyPointsDropped = 0; + } + } + /** * Special hack for devices that have bad screen data: aggregate and * compute averages of the coordinate data, to reduce the amount of diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java index a08258a..8cd9578 100644 --- a/services/java/com/android/server/KeyInputQueue.java +++ b/services/java/com/android/server/KeyInputQueue.java @@ -18,6 +18,7 @@ package com.android.server; import android.content.Context; import android.content.res.Configuration; +import android.content.res.Resources; import android.os.Environment; import android.os.LatencyTimer; import android.os.PowerManager; @@ -60,6 +61,12 @@ public abstract class KeyInputQueue { */ static boolean BAD_TOUCH_HACK = false; + /** + * Turn on some hacks to improve touch interaction with another device + * where touch coordinate data can get corrupted. + */ + static boolean JUMPY_TOUCH_HACK = false; + private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml"; final SparseArray<InputDevice> mDevices = new SparseArray<InputDevice>(); @@ -284,8 +291,10 @@ public abstract class KeyInputQueue { lt = new LatencyTimer(100, 1000); } - BAD_TOUCH_HACK = context.getResources().getBoolean( - com.android.internal.R.bool.config_filterTouchEvents); + Resources r = context.getResources(); + BAD_TOUCH_HACK = r.getBoolean(com.android.internal.R.bool.config_filterTouchEvents); + + JUMPY_TOUCH_HACK = r.getBoolean(com.android.internal.R.bool.config_filterJumpyTouchEvents); mHapticFeedbackCallback = hapticFeedbackCallback; @@ -758,6 +767,9 @@ public abstract class KeyInputQueue { if (BAD_TOUCH_HACK) { ms.dropBadPoint(di); } + if (JUMPY_TOUCH_HACK) { + ms.dropJumpyPoint(di); + } boolean doMotion = !monitorVirtualKey(di, ev, curTime, curTimeNano); |