Merge "Support zero-length paths for a11y gestures." into nyc-dev

am: d803d73

* commit 'd803d73331ee295444cc244415b00b985a2d89ea':
  Support zero-length paths for a11y gestures.

Change-Id: I5397937fb736a66fff2344e636939f503898d64a
This commit is contained in:
Phil Weaver
2016-04-27 22:07:01 +00:00
committed by android-build-merger

View File

@@ -18,7 +18,6 @@ package android.accessibilityservice;
import android.annotation.IntRange; import android.annotation.IntRange;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.graphics.Matrix;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PathMeasure; import android.graphics.PathMeasure;
import android.graphics.RectF; import android.graphics.RectF;
@@ -26,10 +25,8 @@ import android.view.InputDevice;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties; import android.view.MotionEvent.PointerProperties;
import android.view.ViewConfiguration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -160,9 +157,10 @@ public final class GestureDescription {
private final List<StrokeDescription> mStrokes = new ArrayList<>(); private final List<StrokeDescription> mStrokes = new ArrayList<>();
/** /**
* Add a stroke to the gesture description. Up to {@code MAX_STROKE_COUNT} paths may be * Add a stroke to the gesture description. Up to
* added to a gesture, and the total gesture duration (earliest path start time to latest path * {@link GestureDescription#getMaxStrokeCount()} paths may be
* end time) may not exceed {@code MAX_GESTURE_DURATION_MS}. * added to a gesture, and the total gesture duration (earliest path start time to latest
* path end time) may not exceed {@link GestureDescription#getMaxGestureDuration()}.
* *
* @param strokeDescription the stroke to add. * @param strokeDescription the stroke to add.
* *
@@ -201,10 +199,13 @@ public final class GestureDescription {
long mEndTime; long mEndTime;
private float mTimeToLengthConversion; private float mTimeToLengthConversion;
private PathMeasure mPathMeasure; private PathMeasure mPathMeasure;
// The tap location is only set for zero-length paths
float[] mTapLocation;
/** /**
* @param path The path to follow. Must have exactly one contour, and that contour must * @param path The path to follow. Must have exactly one contour. The bounds of the path
* have nonzero length. The bounds of the path must not be negative. * must not be negative. The path must not be empty. If the path has zero length
* (for example, a single {@code moveTo()}), the stroke is a touch that doesn't move.
* @param startTime The time, in milliseconds, from the time the gesture starts to the * @param startTime The time, in milliseconds, from the time the gesture starts to the
* time the stroke should start. Must not be negative. * time the stroke should start. Must not be negative.
* @param duration The duration, in milliseconds, the stroke takes to traverse the path. * @param duration The duration, in milliseconds, the stroke takes to traverse the path.
@@ -225,10 +226,18 @@ public final class GestureDescription {
|| (bounds.left < 0)) { || (bounds.left < 0)) {
throw new IllegalArgumentException("Path bounds must not be negative"); throw new IllegalArgumentException("Path bounds must not be negative");
} }
if (path.isEmpty()) {
throw new IllegalArgumentException("Path is empty");
}
mPath = new Path(path); mPath = new Path(path);
mPathMeasure = new PathMeasure(path, false); mPathMeasure = new PathMeasure(path, false);
if (mPathMeasure.getLength() == 0) { if (mPathMeasure.getLength() == 0) {
throw new IllegalArgumentException("Path has zero length"); // Treat zero-length paths as taps
Path tempPath = new Path(path);
tempPath.lineTo(-1, -1);
mTapLocation = new float[2];
PathMeasure pathMeasure = new PathMeasure(tempPath, false);
pathMeasure.getPosTan(0, mTapLocation, null);
} }
if (mPathMeasure.nextContour()) { if (mPathMeasure.nextContour()) {
throw new IllegalArgumentException("Path has more than one contour"); throw new IllegalArgumentException("Path has more than one contour");
@@ -237,12 +246,10 @@ public final class GestureDescription {
* Calling nextContour has moved mPathMeasure off the first contour, which is the only * Calling nextContour has moved mPathMeasure off the first contour, which is the only
* one we care about. Set the path again to go back to the first contour. * one we care about. Set the path again to go back to the first contour.
*/ */
mPathMeasure.setPath(path, false); mPathMeasure.setPath(mPath, false);
mStartTime = startTime; mStartTime = startTime;
mEndTime = startTime + duration; mEndTime = startTime + duration;
if (duration > 0) { mTimeToLengthConversion = getLength() / duration;
mTimeToLengthConversion = getLength() / duration;
}
} }
/** /**
@@ -278,6 +285,11 @@ public final class GestureDescription {
/* Assumes hasPointForTime returns true */ /* Assumes hasPointForTime returns true */
boolean getPosForTime(long time, float[] pos) { boolean getPosForTime(long time, float[] pos) {
if (mTapLocation != null) {
pos[0] = mTapLocation[0];
pos[1] = mTapLocation[1];
return true;
}
if (time == mEndTime) { if (time == mEndTime) {
// Close to the end time, roundoff can be a problem // Close to the end time, roundoff can be a problem
return mPathMeasure.getPosTan(getLength(), pos, null); return mPathMeasure.getPosTan(getLength(), pos, null);