diff --git a/core/api/current.txt b/core/api/current.txt index 87ede5955410e..fe4f6bb4001e5 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -52459,7 +52459,9 @@ package android.view { method public int getScaledHoverSlop(); method public int getScaledMaximumDrawingCacheSize(); method public int getScaledMaximumFlingVelocity(); + method public int getScaledMaximumFlingVelocity(int, int, int); method public int getScaledMinimumFlingVelocity(); + method public int getScaledMinimumFlingVelocity(int, int, int); method public int getScaledMinimumScalingSpan(); method public int getScaledOverflingDistance(); method public int getScaledOverscrollDistance(); diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index f51d9bacc0a58..c96d298f9382b 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; +import android.hardware.input.InputManager; import android.os.Build; import android.os.Bundle; import android.os.RemoteException; @@ -232,6 +233,12 @@ public class ViewConfiguration { */ private static final int MAXIMUM_FLING_VELOCITY = 8000; + /** Value used as a minimum fling velocity, when fling is not supported. */ + private static final int NO_FLING_MIN_VELOCITY = Integer.MAX_VALUE; + + /** Value used as a maximum fling velocity, when fling is not supported. */ + private static final int NO_FLING_MAX_VELOCITY = Integer.MIN_VALUE; + /** * Delay before dispatching a recurring accessibility event in milliseconds. * This delay guarantees that a recurring event will be send at most once @@ -333,6 +340,8 @@ public class ViewConfiguration { private final int mFadingEdgeLength; private final int mMinimumFlingVelocity; private final int mMaximumFlingVelocity; + private final int mMinimumRotaryEncoderFlingVelocity; + private final int mMaximumRotaryEncoderFlingVelocity; private final int mScrollbarSize; private final int mTouchSlop; private final int mHandwritingSlop; @@ -378,6 +387,8 @@ public class ViewConfiguration { mFadingEdgeLength = FADING_EDGE_LENGTH; mMinimumFlingVelocity = MINIMUM_FLING_VELOCITY; mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY; + mMinimumRotaryEncoderFlingVelocity = MINIMUM_FLING_VELOCITY; + mMaximumRotaryEncoderFlingVelocity = MAXIMUM_FLING_VELOCITY; mScrollbarSize = SCROLL_BAR_SIZE; mTouchSlop = TOUCH_SLOP; mHandwritingSlop = HANDWRITING_SLOP; @@ -504,6 +515,19 @@ public class ViewConfiguration { com.android.internal.R.dimen.config_viewMinFlingVelocity); mMaximumFlingVelocity = res.getDimensionPixelSize( com.android.internal.R.dimen.config_viewMaxFlingVelocity); + + int configMinRotaryEncoderFlingVelocity = res.getDimensionPixelSize( + com.android.internal.R.dimen.config_viewMinRotaryEncoderFlingVelocity); + int configMaxRotaryEncoderFlingVelocity = res.getDimensionPixelSize( + com.android.internal.R.dimen.config_viewMaxRotaryEncoderFlingVelocity); + if (configMinRotaryEncoderFlingVelocity < 0 || configMaxRotaryEncoderFlingVelocity < 0) { + mMinimumRotaryEncoderFlingVelocity = NO_FLING_MIN_VELOCITY; + mMaximumRotaryEncoderFlingVelocity = NO_FLING_MAX_VELOCITY; + } else { + mMinimumRotaryEncoderFlingVelocity = configMinRotaryEncoderFlingVelocity; + mMaximumRotaryEncoderFlingVelocity = configMaxRotaryEncoderFlingVelocity; + } + mGlobalActionsKeyTimeout = res.getInteger( com.android.internal.R.integer.config_globalActionsKeyTimeout); @@ -1076,6 +1100,98 @@ public class ViewConfiguration { return sHasPermanentMenuKey; } + /** + * Minimum absolute value of velocity to initiate a fling for a motion generated by an + * {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and on + * a given motion event {@code axis}. + * + *

Before utilizing this method to get a minimum fling velocity for a motion generated by the + * input device, scale the velocity of the motion events generated by the input device to pixels + * per second. + * + *

For instance, if you tracked {@link MotionEvent#AXIS_SCROLL} vertical velocities generated + * from a {@link InputDevice#SOURCE_ROTARY_ENCODER}, the velocity returned from + * {@link VelocityTracker} will be in the units with which the axis values were reported in the + * motion event. Before comparing that velocity against the minimum fling velocity specified + * here, make sure that the {@link MotionEvent#AXIS_SCROLL} velocity from the tracker is + * calculated in "units per second" (see {@link VelocityTracker#computeCurrentVelocity(int)}, + * {@link VelocityTracker#computeCurrentVelocity(int, float)} to adjust your velocity + * computations to "per second"), and use {@link #getScaledVerticalScrollFactor} to change this + * velocity value to "pixels/second". + * + *

If the provided {@code inputDeviceId} is not valid, or if the input device whose ID is + * provided does not support the given motion event source and/or axis, this method will return + * {@code Integer.MAX_VALUE}. + * + *

Obtaining the correct arguments for this method call

+ *

inputDeviceId: if calling this method in response to a {@link MotionEvent}, use + * the device ID that is reported by the event, which can be obtained using + * {@link MotionEvent#getDeviceId()}. Otherwise, use a valid ID that is obtained from + * {@link InputDevice#getId()}, or from an {@link InputManager} instance + * ({@link InputManager#getInputDeviceIds()} gives all the valid input device IDs). + * + *

axis: a {@link MotionEvent} may report data for multiple axes, and each axis may + * have multiple data points for different pointers. Use the axis for which you obtained the + * velocity for ({@link VelocityTracker} lets you calculate velocities for a specific axis. Use + * the axis for which you calculated velocity). You can use + * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the + * {@link InputDevice}, from which you can derive all the valid axes for the device. + * + *

source: use {@link MotionEvent#getSource()} if calling this method in response to a + * {@link MotionEvent}. Otherwise, use a valid source for the {@link InputDevice}. You can use + * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the + * {@link InputDevice}, from which you can derive all the valid sources for the device. + * + * + *

This method optimizes calls over multiple input device IDs, so caching the return value of + * the method is not necessary if you are handling multiple input devices. + * + * @param inputDeviceId the ID of the {@link InputDevice} that generated the motion triggering + * fling. + * @param axis the axis on which the motion triggering the fling happened. This axis should be + * a valid axis that can be reported by the provided input device from the provided + * input device source. + * @param source the input source of the motion causing fling. This source should be a valid + * source for the {@link InputDevice} whose ID is {@code inputDeviceId}. + * + * @return the minimum velocity, in pixels/second, to trigger fling. + * + * @see InputDevice#getMotionRange(int, int) + * @see InputDevice#getMotionRanges() + * @see VelocityTracker#getAxisVelocity(int, int) + * @see VelocityTracker#getAxisVelocity(int) + */ + public int getScaledMinimumFlingVelocity(int inputDeviceId, int axis, int source) { + if (!isInputDeviceInfoValid(inputDeviceId, axis, source)) return NO_FLING_MIN_VELOCITY; + + if (source == InputDevice.SOURCE_ROTARY_ENCODER) return mMinimumRotaryEncoderFlingVelocity; + + return mMinimumFlingVelocity; + } + + /** + * Maximum absolute value of velocity to initiate a fling for a motion generated by an + * {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and on + * a given motion event {@code axis}. + * + *

Similar to {@link #getScaledMinimumFlingVelocity(int, int, int)}, but for maximum fling + * velocity, instead of minimum. Also, unlike that method which returns + * {@code Integer.MAX_VALUE} for bad input device ID, source and/or motion event axis inputs, + * this method returns {@code Integer.MIN_VALUE} for such bad inputs. + */ + public int getScaledMaximumFlingVelocity(int inputDeviceId, int axis, int source) { + if (!isInputDeviceInfoValid(inputDeviceId, axis, source)) return NO_FLING_MAX_VELOCITY; + + if (source == InputDevice.SOURCE_ROTARY_ENCODER) return mMaximumRotaryEncoderFlingVelocity; + + return mMaximumFlingVelocity; + } + + private static boolean isInputDeviceInfoValid(int id, int axis, int source) { + InputDevice device = InputManager.getInstance().getInputDevice(id); + return device != null && device.getMotionRange(axis, source) != null; + } + /** * Check if shortcuts should be displayed in menus. * diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 37d5b84d242bf..1e3074c505e45 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2674,6 +2674,14 @@ 8000dp + + -1dp + + + -1dp + 500 diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 2af91e1adaa5d..d91e463ea62aa 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -515,6 +515,8 @@ + +