summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorAdam Powell <adamp@google.com>2012-10-02 19:32:59 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-10-02 19:33:00 -0700
commitd27f1cd30b140f042e11032e4aa4381756e2998f (patch)
treec5f072ce93f5c9e0e895a7acef37829b65b26f46 /core/java
parent75b694f1d6038edee8b071df1e339b81d7960e97 (diff)
parent5b5c414e31c4a8433a3290b931687a05dadc97b6 (diff)
downloadframeworks_base-d27f1cd30b140f042e11032e4aa4381756e2998f.zip
frameworks_base-d27f1cd30b140f042e11032e4aa4381756e2998f.tar.gz
frameworks_base-d27f1cd30b140f042e11032e4aa4381756e2998f.tar.bz2
Merge "Further refine touchMajor processing in ScaleGestureDetector" into jb-mr1-dev
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/ScaleGestureDetector.java157
1 files changed, 49 insertions, 108 deletions
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 4873860..a74e438 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -19,9 +19,6 @@ package android.view;
import android.content.Context;
import android.os.SystemClock;
import android.util.FloatMath;
-import android.util.Log;
-
-import java.util.Arrays;
/**
* Detects scaling transformation gestures using the supplied {@link MotionEvent}s.
@@ -143,11 +140,16 @@ public class ScaleGestureDetector {
private int mSpanSlop;
private int mMinSpan;
- private float[] mTouchHistoryLastAccepted;
- private int[] mTouchHistoryDirection;
- private long[] mTouchHistoryLastAcceptedTime;
+ // Bounds for recently seen values
+ private float mTouchUpper;
+ private float mTouchLower;
+ private float mTouchHistoryLastAccepted;
+ private int mTouchHistoryDirection;
+ private long mTouchHistoryLastAcceptedTime;
+ private int mTouchMinMajor;
private static final long TOUCH_STABILIZE_TIME = 128; // ms
+ private static final int TOUCH_MIN_MAJOR = 48; // dp
/**
* Consistency verifier for debugging purposes.
@@ -160,6 +162,8 @@ public class ScaleGestureDetector {
mContext = context;
mListener = listener;
mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2;
+ mTouchMinMajor =
+ (int) (context.getResources().getDisplayMetrics().density * TOUCH_MIN_MAJOR + 0.5f);
mMinSpan = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.config_minScalingSpan);
}
@@ -172,81 +176,55 @@ public class ScaleGestureDetector {
private void addTouchHistory(MotionEvent ev) {
final long currentTime = SystemClock.uptimeMillis();
final int count = ev.getPointerCount();
+ boolean accept = currentTime - mTouchHistoryLastAcceptedTime >= TOUCH_STABILIZE_TIME;
+ float total = 0;
+ int sampleCount = 0;
for (int i = 0; i < count; i++) {
- final int id = ev.getPointerId(i);
- ensureTouchHistorySize(id);
-
- final boolean hasLastAccepted = !Float.isNaN(mTouchHistoryLastAccepted[id]);
- boolean accept = true;
+ final boolean hasLastAccepted = !Float.isNaN(mTouchHistoryLastAccepted);
final int historySize = ev.getHistorySize();
- for (int h = 0; h < historySize + 1; h++) {
- final float major;
- final float minor;
+ final int pointerSampleCount = historySize + 1;
+ for (int h = 0; h < pointerSampleCount; h++) {
+ float major;
if (h < historySize) {
major = ev.getHistoricalTouchMajor(i, h);
- minor = ev.getHistoricalTouchMinor(i, h);
} else {
major = ev.getTouchMajor(i);
- minor = ev.getTouchMinor(i);
}
- final float avg = (major + minor) / 2;
+ if (major < mTouchMinMajor) major = mTouchMinMajor;
+ total += major;
+
+ if (Float.isNaN(mTouchUpper) || major > mTouchUpper) {
+ mTouchUpper = major;
+ }
+ if (Float.isNaN(mTouchLower) || major < mTouchLower) {
+ mTouchLower = major;
+ }
if (hasLastAccepted) {
- final int directionSig = (int) Math.signum(avg - mTouchHistoryLastAccepted[id]);
- if (directionSig != mTouchHistoryDirection[id] ||
- (directionSig == 0 && mTouchHistoryDirection[id] == 0)) {
- mTouchHistoryDirection[id] = directionSig;
+ final int directionSig = (int) Math.signum(major - mTouchHistoryLastAccepted);
+ if (directionSig != mTouchHistoryDirection ||
+ (directionSig == 0 && mTouchHistoryDirection == 0)) {
+ mTouchHistoryDirection = directionSig;
final long time = h < historySize ? ev.getHistoricalEventTime(h)
: ev.getEventTime();
- mTouchHistoryLastAcceptedTime[id] = time;
- accept = false;
- }
- if (currentTime - mTouchHistoryLastAcceptedTime[id] < TOUCH_STABILIZE_TIME) {
+ mTouchHistoryLastAcceptedTime = time;
accept = false;
}
}
}
-
- if (accept) {
- float newAccepted = (ev.getTouchMajor(i) + ev.getTouchMinor(i)) / 2;
- if (hasLastAccepted) {
- newAccepted = (mTouchHistoryLastAccepted[id] + newAccepted) / 2;
- }
- mTouchHistoryLastAccepted[id] = newAccepted;
- mTouchHistoryDirection[id] = 0;
- mTouchHistoryLastAcceptedTime[id] = ev.getEventTime();
- }
+ sampleCount += pointerSampleCount;
}
- }
- /**
- * Clear out the touch history for a given pointer id.
- * @param id pointer id to clear
- * @see #addTouchHistory(MotionEvent)
- */
- private boolean removeTouchHistoryForId(int id) {
- if (id >= mTouchHistoryLastAccepted.length) {
- return false;
- }
- mTouchHistoryLastAccepted[id] = Float.NaN;
- mTouchHistoryDirection[id] = 0;
- mTouchHistoryLastAcceptedTime[id] = 0;
- return true;
- }
+ final float avg = total / sampleCount;
- /**
- * Get the adjusted combined touchMajor/touchMinor value for a given pointer id
- * @param id the pointer id of the data to obtain
- * @return the adjusted major/minor value for the point at id
- * @see #addTouchHistory(MotionEvent)
- */
- private float getAdjustedTouchHistory(int id) {
- if (id >= mTouchHistoryLastAccepted.length) {
- Log.e(TAG, "Error retrieving adjusted touch history for id=" + id +
- " - incomplete event stream?");
- return 0;
+ if (accept) {
+ float newAccepted = (mTouchUpper + mTouchLower + avg) / 3;
+ mTouchUpper = (mTouchUpper + newAccepted) / 2;
+ mTouchLower = (mTouchLower + newAccepted) / 2;
+ mTouchHistoryLastAccepted = newAccepted;
+ mTouchHistoryDirection = 0;
+ mTouchHistoryLastAcceptedTime = ev.getEventTime();
}
- return mTouchHistoryLastAccepted[id];
}
/**
@@ -254,41 +232,11 @@ public class ScaleGestureDetector {
* @see #addTouchHistory(MotionEvent)
*/
private void clearTouchHistory() {
- if (mTouchHistoryLastAccepted == null) {
- // All three arrays will be null if this is the case; nothing to do.
- return;
- }
- Arrays.fill(mTouchHistoryLastAccepted, Float.NaN);
- Arrays.fill(mTouchHistoryDirection, 0);
- Arrays.fill(mTouchHistoryLastAcceptedTime, 0);
- }
-
- private void ensureTouchHistorySize(int id) {
- final int requiredSize = id + 1;
- if (mTouchHistoryLastAccepted == null || mTouchHistoryLastAccepted.length < requiredSize) {
- final float[] newLastAccepted = new float[requiredSize];
- final int[] newDirection = new int[requiredSize];
- final long[] newLastAcceptedTime = new long[requiredSize];
-
- int oldLength = 0;
- if (mTouchHistoryLastAccepted != null) {
- System.arraycopy(mTouchHistoryLastAccepted, 0, newLastAccepted, 0,
- mTouchHistoryLastAccepted.length);
- System.arraycopy(mTouchHistoryDirection, 0, newDirection, 0,
- mTouchHistoryDirection.length);
- System.arraycopy(mTouchHistoryLastAcceptedTime, 0, newLastAcceptedTime, 0,
- mTouchHistoryLastAcceptedTime.length);
- oldLength = mTouchHistoryLastAccepted.length;
- }
-
- Arrays.fill(newLastAccepted, oldLength, newLastAccepted.length, Float.NaN);
- Arrays.fill(newDirection, oldLength, newDirection.length, 0);
- Arrays.fill(newLastAcceptedTime, oldLength, newLastAcceptedTime.length, 0);
-
- mTouchHistoryLastAccepted = newLastAccepted;
- mTouchHistoryDirection = newDirection;
- mTouchHistoryLastAcceptedTime = newLastAcceptedTime;
- }
+ mTouchUpper = Float.NaN;
+ mTouchLower = Float.NaN;
+ mTouchHistoryLastAccepted = Float.NaN;
+ mTouchHistoryDirection = 0;
+ mTouchHistoryLastAcceptedTime = 0;
}
/**
@@ -346,23 +294,16 @@ public class ScaleGestureDetector {
final float focusX = sumX / div;
final float focusY = sumY / div;
- if (pointerUp) {
- final int id = event.getPointerId(event.getActionIndex());
- if (!removeTouchHistoryForId(id)) {
- Log.e(TAG, "Got ACTION_POINTER_UP for previously unknown id=" + id +
- " - incomplete event stream?");
- }
- } else {
- addTouchHistory(event);
- }
+
+ addTouchHistory(event);
// Determine average deviation from focal point
float devSumX = 0, devSumY = 0;
for (int i = 0; i < count; i++) {
if (skipIndex == i) continue;
- // Average touch major and touch minor and convert the resulting diameter into a radius.
- final float touchSize = getAdjustedTouchHistory(event.getPointerId(i)) / 2;
+ // Convert the resulting diameter into a radius.
+ final float touchSize = mTouchHistoryLastAccepted / 2;
devSumX += Math.abs(event.getX(i) - focusX) + touchSize;
devSumY += Math.abs(event.getY(i) - focusY) + touchSize;
}