Merge "Update a11y gesture and magnification APIs." into nyc-dev

This commit is contained in:
Phil Weaver
2016-03-18 15:52:27 +00:00
committed by Android (Google) Code Review
5 changed files with 33 additions and 143 deletions

View File

@@ -2756,14 +2756,10 @@ package android.accessibilityservice {
} }
public final class GestureDescription { public final class GestureDescription {
method public static android.accessibilityservice.GestureDescription createClick(int, int); method public static long getMaxGestureDuration();
method public static android.accessibilityservice.GestureDescription createLongClick(int, int); method public static int getMaxStrokeCount();
method public static android.accessibilityservice.GestureDescription createPinch(int, int, int, int, float, long);
method public static android.accessibilityservice.GestureDescription createSwipe(int, int, int, int, long);
method public android.accessibilityservice.GestureDescription.StrokeDescription getStroke(int); method public android.accessibilityservice.GestureDescription.StrokeDescription getStroke(int);
method public int getStrokeCount(); method public int getStrokeCount();
field public static final long MAX_GESTURE_DURATION_MS = 60000L; // 0xea60L
field public static final int MAX_STROKE_COUNT = 10; // 0xa
} }
public static class GestureDescription.Builder { public static class GestureDescription.Builder {

View File

@@ -2858,14 +2858,10 @@ package android.accessibilityservice {
} }
public final class GestureDescription { public final class GestureDescription {
method public static android.accessibilityservice.GestureDescription createClick(int, int); method public static long getMaxGestureDuration();
method public static android.accessibilityservice.GestureDescription createLongClick(int, int); method public static int getMaxStrokeCount();
method public static android.accessibilityservice.GestureDescription createPinch(int, int, int, int, float, long);
method public static android.accessibilityservice.GestureDescription createSwipe(int, int, int, int, long);
method public android.accessibilityservice.GestureDescription.StrokeDescription getStroke(int); method public android.accessibilityservice.GestureDescription.StrokeDescription getStroke(int);
method public int getStrokeCount(); method public int getStrokeCount();
field public static final long MAX_GESTURE_DURATION_MS = 60000L; // 0xea60L
field public static final int MAX_STROKE_COUNT = 10; // 0xa
} }
public static class GestureDescription.Builder { public static class GestureDescription.Builder {

View File

@@ -2756,14 +2756,10 @@ package android.accessibilityservice {
} }
public final class GestureDescription { public final class GestureDescription {
method public static android.accessibilityservice.GestureDescription createClick(int, int); method public static long getMaxGestureDuration();
method public static android.accessibilityservice.GestureDescription createLongClick(int, int); method public static int getMaxStrokeCount();
method public static android.accessibilityservice.GestureDescription createPinch(int, int, int, int, float, long);
method public static android.accessibilityservice.GestureDescription createSwipe(int, int, int, int, long);
method public android.accessibilityservice.GestureDescription.StrokeDescription getStroke(int); method public android.accessibilityservice.GestureDescription.StrokeDescription getStroke(int);
method public int getStrokeCount(); method public int getStrokeCount();
field public static final long MAX_GESTURE_DURATION_MS = 60000L; // 0xea60L
field public static final int MAX_STROKE_COUNT = 10; // 0xa
} }
public static class GestureDescription.Builder { public static class GestureDescription.Builder {

View File

@@ -851,6 +851,7 @@ public abstract class AccessibilityService extends Service {
return connection.getMagnificationScale(); return connection.getMagnificationScale();
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Failed to obtain scale", re); Log.w(LOG_TAG, "Failed to obtain scale", re);
re.rethrowFromSystemServer();
} }
} }
return 1.0f; return 1.0f;
@@ -879,6 +880,7 @@ public abstract class AccessibilityService extends Service {
return connection.getMagnificationCenterX(); return connection.getMagnificationCenterX();
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Failed to obtain center X", re); Log.w(LOG_TAG, "Failed to obtain center X", re);
re.rethrowFromSystemServer();
} }
} }
return 0.0f; return 0.0f;
@@ -907,6 +909,7 @@ public abstract class AccessibilityService extends Service {
return connection.getMagnificationCenterY(); return connection.getMagnificationCenterY();
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Failed to obtain center Y", re); Log.w(LOG_TAG, "Failed to obtain center Y", re);
re.rethrowFromSystemServer();
} }
} }
return 0.0f; return 0.0f;
@@ -933,6 +936,7 @@ public abstract class AccessibilityService extends Service {
return connection.getMagnifiedRegion(); return connection.getMagnifiedRegion();
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Failed to obtain magnified region", re); Log.w(LOG_TAG, "Failed to obtain magnified region", re);
re.rethrowFromSystemServer();
} }
} }
return Region.obtain(); return Region.obtain();
@@ -961,6 +965,7 @@ public abstract class AccessibilityService extends Service {
return connection.resetMagnification(animate); return connection.resetMagnification(animate);
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Failed to reset", re); Log.w(LOG_TAG, "Failed to reset", re);
re.rethrowFromSystemServer();
} }
} }
return false; return false;
@@ -989,6 +994,7 @@ public abstract class AccessibilityService extends Service {
scale, Float.NaN, Float.NaN, animate); scale, Float.NaN, Float.NaN, animate);
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Failed to set scale", re); Log.w(LOG_TAG, "Failed to set scale", re);
re.rethrowFromSystemServer();
} }
} }
return false; return false;
@@ -1020,6 +1026,7 @@ public abstract class AccessibilityService extends Service {
Float.NaN, centerX, centerY, animate); Float.NaN, centerX, centerY, animate);
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Failed to set center", re); Log.w(LOG_TAG, "Failed to set center", re);
re.rethrowFromSystemServer();
} }
} }
return false; return false;
@@ -1254,10 +1261,7 @@ public abstract class AccessibilityService extends Service {
Log.w(LOG_TAG, "Failed to set soft keyboard behavior", re); Log.w(LOG_TAG, "Failed to set soft keyboard behavior", re);
re.rethrowFromSystemServer(); re.rethrowFromSystemServer();
} }
} else {
throw new RuntimeException("AccessibilityServiceConnection is null");
} }
return false; return false;
} }
@@ -1301,6 +1305,7 @@ public abstract class AccessibilityService extends Service {
return connection.performGlobalAction(action); return connection.performGlobalAction(action);
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Error while calling performGlobalAction", re); Log.w(LOG_TAG, "Error while calling performGlobalAction", re);
re.rethrowFromSystemServer();
} }
} }
return false; return false;
@@ -1349,6 +1354,7 @@ public abstract class AccessibilityService extends Service {
return connection.getServiceInfo(); return connection.getServiceInfo();
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Error while getting AccessibilityServiceInfo", re); Log.w(LOG_TAG, "Error while getting AccessibilityServiceInfo", re);
re.rethrowFromSystemServer();
} }
} }
return null; return null;
@@ -1382,6 +1388,7 @@ public abstract class AccessibilityService extends Service {
AccessibilityInteractionClient.getInstance().clearCache(); AccessibilityInteractionClient.getInstance().clearCache();
} catch (RemoteException re) { } catch (RemoteException re) {
Log.w(LOG_TAG, "Error while setting AccessibilityServiceInfo", re); Log.w(LOG_TAG, "Error while setting AccessibilityServiceInfo", re);
re.rethrowFromSystemServer();
} }
} }
} }

View File

@@ -43,135 +43,32 @@ import java.util.List;
*/ */
public final class GestureDescription { public final class GestureDescription {
/** Gestures may contain no more than this many strokes */ /** Gestures may contain no more than this many strokes */
public static final int MAX_STROKE_COUNT = 10; private static final int MAX_STROKE_COUNT = 10;
/** /**
* Upper bound on total gesture duration. Nearly all gestures will be much shorter. * Upper bound on total gesture duration. Nearly all gestures will be much shorter.
*/ */
public static final long MAX_GESTURE_DURATION_MS = 60 * 1000; private static final long MAX_GESTURE_DURATION_MS = 60 * 1000;
private final List<StrokeDescription> mStrokes = new ArrayList<>(); private final List<StrokeDescription> mStrokes = new ArrayList<>();
private final float[] mTempPos = new float[2]; private final float[] mTempPos = new float[2];
/** /**
* Create a description of a click gesture * Get the upper limit for the number of strokes a gesture may contain.
* *
* @param x The x coordinate to click. Must not be negative. * @return The maximum number of strokes.
* @param y The y coordinate to click. Must not be negative.
*
* @return A description of a click at (x, y)
*/ */
public static GestureDescription createClick(@IntRange(from = 0) int x, public static int getMaxStrokeCount() {
@IntRange(from = 0) int y) { return MAX_STROKE_COUNT;
Path clickPath = new Path();
clickPath.moveTo(x, y);
clickPath.lineTo(x + 1, y);
return new GestureDescription(
new StrokeDescription(clickPath, 0, ViewConfiguration.getTapTimeout()));
} }
/** /**
* Create a description of a long click gesture * Get the upper limit on a gesture's duration.
* *
* @param x The x coordinate to click. Must not be negative. * @return The maximum duration in milliseconds.
* @param y The y coordinate to click. Must not be negative.
*
* @return A description of a click at (x, y)
*/ */
public static GestureDescription createLongClick(@IntRange(from = 0) int x, public static long getMaxGestureDuration() {
@IntRange(from = 0) int y) { return MAX_GESTURE_DURATION_MS;
Path clickPath = new Path();
clickPath.moveTo(x, y);
clickPath.lineTo(x + 1, y);
int longPressTime = ViewConfiguration.getLongPressTimeout();
return new GestureDescription(
new StrokeDescription(clickPath, 0, longPressTime + (longPressTime / 2)));
}
/**
* Create a description of a swipe gesture
*
* @param startX The x coordinate of the starting point. Must not be negative.
* @param startY The y coordinate of the starting point. Must not be negative.
* @param endX The x coordinate of the ending point. Must not be negative.
* @param endY The y coordinate of the ending point. Must not be negative.
* @param duration The time, in milliseconds, to complete the gesture. Must not be negative.
*
* @return A description of a swipe from ({@code startX}, {@code startY}) to
* ({@code endX}, {@code endY}) that takes {@code duration} milliseconds. Returns {@code null}
* if the path specified for the swipe is invalid.
*/
public static GestureDescription createSwipe(@IntRange(from = 0) int startX,
@IntRange(from = 0) int startY,
@IntRange(from = 0) int endX,
@IntRange(from = 0) int endY,
@IntRange(from = 0, to = MAX_GESTURE_DURATION_MS) long duration) {
Path swipePath = new Path();
swipePath.moveTo(startX, startY);
swipePath.lineTo(endX, endY);
return new GestureDescription(new StrokeDescription(swipePath, 0, duration));
}
/**
* Create a description for a pinch (or zoom) gesture.
*
* @param centerX The x coordinate of the center of the pinch. Must not be negative.
* @param centerY The y coordinate of the center of the pinch. Must not be negative.
* @param startSpacing The spacing of the touch points at the beginning of the gesture. Must not
* be negative.
* @param endSpacing The spacing of the touch points at the end of the gesture. Must not be
* negative.
* @param orientation The angle, in degrees, of the gesture. 0 represents a horizontal pinch
* @param duration The time, in milliseconds, to complete the gesture. Must not be negative.
*
* @return A description of a pinch centered at ({code centerX}, {@code centerY}) that starts
* with the touch points spaced by {@code startSpacing} and ends with them spaced by
* {@code endSpacing} that lasts {@code duration} ms. Returns {@code null} if either path
* specified for the pinch is invalid.
*/
public static GestureDescription createPinch(@IntRange(from = 0) int centerX,
@IntRange(from = 0) int centerY,
@IntRange(from = 0) int startSpacing,
@IntRange(from = 0) int endSpacing,
float orientation,
@IntRange(from = 0, to = MAX_GESTURE_DURATION_MS) long duration) {
if ((startSpacing < 0) || (endSpacing < 0)) {
throw new IllegalArgumentException("Pinch spacing cannot be negative");
}
float[] startPoint1 = new float[2];
float[] endPoint1 = new float[2];
float[] startPoint2 = new float[2];
float[] endPoint2 = new float[2];
/* Build points for a horizontal gesture centered at the origin */
startPoint1[0] = startSpacing / 2;
startPoint1[1] = 0;
endPoint1[0] = endSpacing / 2;
endPoint1[1] = 0;
startPoint2[0] = -startSpacing / 2;
startPoint2[1] = 0;
endPoint2[0] = -endSpacing / 2;
endPoint2[1] = 0;
/* Rotate and translate the points */
Matrix matrix = new Matrix();
matrix.setRotate(orientation);
matrix.postTranslate(centerX, centerY);
matrix.mapPoints(startPoint1);
matrix.mapPoints(endPoint1);
matrix.mapPoints(startPoint2);
matrix.mapPoints(endPoint2);
Path path1 = new Path();
path1.moveTo(startPoint1[0], startPoint1[1]);
path1.lineTo(endPoint1[0], endPoint1[1]);
Path path2 = new Path();
path2.moveTo(startPoint2[0], startPoint2[1]);
path2.lineTo(endPoint2[0], endPoint2[1]);
return new GestureDescription(Arrays.asList(
new StrokeDescription(path1, 0, duration),
new StrokeDescription(path2, 0, duration)));
} }
private GestureDescription() {} private GestureDescription() {}
@@ -180,10 +77,6 @@ public final class GestureDescription {
mStrokes.addAll(strokes); mStrokes.addAll(strokes);
} }
private GestureDescription(StrokeDescription stroke) {
mStrokes.add(stroke);
}
/** /**
* Get the number of stroke in the gesture. * Get the number of stroke in the gesture.
* *
@@ -278,21 +171,23 @@ public final class GestureDescription {
*/ */
public Builder addStroke(@NonNull StrokeDescription strokeDescription) { public Builder addStroke(@NonNull StrokeDescription strokeDescription) {
if (mStrokes.size() >= MAX_STROKE_COUNT) { if (mStrokes.size() >= MAX_STROKE_COUNT) {
throw new RuntimeException("Attempting to add too many strokes to a gesture"); throw new IllegalStateException(
"Attempting to add too many strokes to a gesture");
} }
mStrokes.add(strokeDescription); mStrokes.add(strokeDescription);
if (getTotalDuration(mStrokes) > MAX_GESTURE_DURATION_MS) { if (getTotalDuration(mStrokes) > MAX_GESTURE_DURATION_MS) {
mStrokes.remove(strokeDescription); mStrokes.remove(strokeDescription);
throw new RuntimeException("Gesture would exceed maximum duration with new stroke"); throw new IllegalStateException(
"Gesture would exceed maximum duration with new stroke");
} }
return this; return this;
} }
public GestureDescription build() { public GestureDescription build() {
if (mStrokes.size() == 0) { if (mStrokes.size() == 0) {
throw new RuntimeException("Gestures must have at least one stroke"); throw new IllegalStateException("Gestures must have at least one stroke");
} }
return new GestureDescription(mStrokes); return new GestureDescription(mStrokes);
} }
@@ -317,8 +212,8 @@ public final class GestureDescription {
* Must not be negative. * Must not be negative.
*/ */
public StrokeDescription(@NonNull Path path, public StrokeDescription(@NonNull Path path,
@IntRange(from = 0, to = MAX_GESTURE_DURATION_MS) long startTime, @IntRange(from = 0) long startTime,
@IntRange(from = 0, to = MAX_GESTURE_DURATION_MS) long duration) { @IntRange(from = 0) long duration) {
if (duration <= 0) { if (duration <= 0) {
throw new IllegalArgumentException("Duration must be positive"); throw new IllegalArgumentException("Duration must be positive");
} }