1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.view;
18 
19 import android.annotation.FloatRange;
20 import android.annotation.NonNull;
21 import android.annotation.TestApi;
22 import android.annotation.UiContext;
23 import android.app.Activity;
24 import android.app.AppGlobals;
25 import android.compat.annotation.UnsupportedAppUsage;
26 import android.content.Context;
27 import android.content.res.Configuration;
28 import android.content.res.Resources;
29 import android.graphics.Rect;
30 import android.hardware.input.InputManager;
31 import android.hardware.input.InputManagerGlobal;
32 import android.os.Build;
33 import android.os.Bundle;
34 import android.os.RemoteException;
35 import android.os.StrictMode;
36 import android.provider.Settings;
37 import android.util.DisplayMetrics;
38 import android.util.SparseArray;
39 import android.util.TypedValue;
40 
41 /**
42  * Contains methods to standard constants used in the UI for timeouts, sizes, and distances.
43  */
44 public class ViewConfiguration {
45     private static final String TAG = "ViewConfiguration";
46 
47     /**
48      * Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
49      * dips
50      */
51     private static final int SCROLL_BAR_SIZE = 4;
52 
53     /**
54      * Duration of the fade when scrollbars fade away in milliseconds
55      */
56     private static final int SCROLL_BAR_FADE_DURATION = 250;
57 
58     /**
59      * Default delay before the scrollbars fade in milliseconds
60      */
61     private static final int SCROLL_BAR_DEFAULT_DELAY = 300;
62 
63     /**
64      * Defines the length of the fading edges in dips
65      */
66     private static final int FADING_EDGE_LENGTH = 12;
67 
68     /**
69      * Defines the duration in milliseconds of the pressed state in child
70      * components.
71      */
72     private static final int PRESSED_STATE_DURATION = 64;
73 
74     /**
75      * Defines the default duration in milliseconds before a press turns into
76      * a long press
77      * @hide
78      */
79     public static final int DEFAULT_LONG_PRESS_TIMEOUT = 400;
80 
81     /**
82      * Defines the default duration in milliseconds between the first tap's up event and the second
83      * tap's down event for an interaction to be considered part of the same multi-press.
84      */
85     private static final int DEFAULT_MULTI_PRESS_TIMEOUT = 300;
86 
87     /**
88      * Defines the time between successive key repeats in milliseconds.
89      */
90     private static final int KEY_REPEAT_DELAY = 50;
91 
92     /**
93      * Defines the duration in milliseconds a user needs to hold down the
94      * appropriate button to bring up the global actions dialog (power off,
95      * lock screen, etc).
96      */
97     private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 500;
98 
99     /**
100      * Defines the duration in milliseconds a user needs to hold down the
101      * appropriate buttons (power + volume down) to trigger the screenshot chord.
102      */
103     private static final int SCREENSHOT_CHORD_KEY_TIMEOUT = 0;
104 
105     /**
106      * Defines the duration in milliseconds a user needs to hold down the
107      * appropriate button to bring up the accessibility shortcut for the first time
108      */
109     private static final int A11Y_SHORTCUT_KEY_TIMEOUT = 3000;
110 
111     /**
112      * Defines the duration in milliseconds a user needs to hold down the
113      * appropriate button to enable the accessibility shortcut once it's configured.
114      */
115     private static final int A11Y_SHORTCUT_KEY_TIMEOUT_AFTER_CONFIRMATION = 1000;
116 
117     /**
118      * Defines the duration in milliseconds we will wait to see if a touch event
119      * is a tap or a scroll. If the user does not move within this interval, it is
120      * considered to be a tap.
121      */
122     private static final int TAP_TIMEOUT = 100;
123 
124     /**
125      * Defines the duration in milliseconds we will wait to see if a touch event
126      * is a jump tap. If the user does not complete the jump tap within this interval, it is
127      * considered to be a tap.
128      */
129     private static final int JUMP_TAP_TIMEOUT = 500;
130 
131     /**
132      * Defines the duration in milliseconds between the first tap's up event and
133      * the second tap's down event for an interaction to be considered a
134      * double-tap.
135      */
136     private static final int DOUBLE_TAP_TIMEOUT = 300;
137 
138     /**
139      * Defines the minimum duration in milliseconds between the first tap's up event and
140      * the second tap's down event for an interaction to be considered a
141      * double-tap.
142      */
143     private static final int DOUBLE_TAP_MIN_TIME = 40;
144 
145     /**
146      * Defines the maximum duration in milliseconds between a touch pad
147      * touch and release for a given touch to be considered a tap (click) as
148      * opposed to a hover movement gesture.
149      */
150     private static final int HOVER_TAP_TIMEOUT = 150;
151 
152     /**
153      * Defines the maximum distance in pixels that a touch pad touch can move
154      * before being released for it to be considered a tap (click) as opposed
155      * to a hover movement gesture.
156      */
157     private static final int HOVER_TAP_SLOP = 20;
158 
159     /**
160      * Defines the duration in milliseconds we want to display zoom controls in response
161      * to a user panning within an application.
162      */
163     private static final int ZOOM_CONTROLS_TIMEOUT = 3000;
164 
165     /**
166      * Inset in dips to look for touchable content when the user touches the edge of the screen
167      */
168     private static final int EDGE_SLOP = 12;
169 
170     /**
171      * Distance a touch can wander before we think the user is scrolling in dips.
172      * Note that this value defined here is only used as a fallback by legacy/misbehaving
173      * applications that do not provide a Context for determining density/configuration-dependent
174      * values.
175      *
176      * To alter this value, see the configuration resource config_viewConfigurationTouchSlop
177      * in frameworks/base/core/res/res/values/config.xml or the appropriate device resource overlay.
178      * It may be appropriate to tweak this on a device-specific basis in an overlay based on
179      * the characteristics of the touch panel and firmware.
180      */
181     private static final int TOUCH_SLOP = 8;
182 
183     /** Distance a stylus touch can wander before we think the user is handwriting in dips. */
184     private static final int HANDWRITING_SLOP = 2;
185 
186     /**
187      * Defines the minimum size of the touch target for a scrollbar in dips
188      */
189     private static final int MIN_SCROLLBAR_TOUCH_TARGET = 48;
190 
191     /**
192      * Distance the first touch can wander before we stop considering this event a double tap
193      * (in dips)
194      */
195     private static final int DOUBLE_TAP_TOUCH_SLOP = TOUCH_SLOP;
196 
197     /**
198      * Distance a touch can wander before we think the user is attempting a paged scroll
199      * (in dips)
200      *
201      * Note that this value defined here is only used as a fallback by legacy/misbehaving
202      * applications that do not provide a Context for determining density/configuration-dependent
203      * values.
204      *
205      * See the note above on {@link #TOUCH_SLOP} regarding the dimen resource
206      * config_viewConfigurationTouchSlop. ViewConfiguration will report a paging touch slop of
207      * config_viewConfigurationTouchSlop * 2 when provided with a Context.
208      */
209     private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 2;
210 
211     /**
212      * Distance in dips between the first touch and second touch to still be considered a double tap
213      */
214     private static final int DOUBLE_TAP_SLOP = 100;
215 
216     /**
217      * Distance in dips a touch needs to be outside of a window's bounds for it to
218      * count as outside for purposes of dismissing the window.
219      */
220     private static final int WINDOW_TOUCH_SLOP = 16;
221 
222     /**
223      * Margin in dips around text line bounds where stylus handwriting gestures should be supported.
224      */
225     private static final int HANDWRITING_GESTURE_LINE_MARGIN = 16;
226 
227     /**
228      * Minimum velocity to initiate a fling, as measured in dips per second
229      */
230     private static final int MINIMUM_FLING_VELOCITY = 50;
231 
232     /**
233      * Maximum velocity to initiate a fling, as measured in dips per second
234      */
235     private static final int MAXIMUM_FLING_VELOCITY = 8000;
236 
237     /** Value used as a minimum fling velocity, when fling is not supported. */
238     private static final int NO_FLING_MIN_VELOCITY = Integer.MAX_VALUE;
239 
240     /** Value used as a maximum fling velocity, when fling is not supported. */
241     private static final int NO_FLING_MAX_VELOCITY = Integer.MIN_VALUE;
242 
243     /**
244      * Delay before dispatching a recurring accessibility event in milliseconds.
245      * This delay guarantees that a recurring event will be send at most once
246      * during the {@link #SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS} time
247      * frame.
248      */
249     private static final long SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS = 100;
250 
251     /**
252      * The maximum size of View's drawing cache, expressed in bytes. This size
253      * should be at least equal to the size of the screen in ARGB888 format.
254      */
255     @Deprecated
256     private static final int MAXIMUM_DRAWING_CACHE_SIZE = 480 * 800 * 4; // ARGB8888
257 
258     /**
259      * The coefficient of friction applied to flings/scrolls.
260      */
261     @UnsupportedAppUsage
262     private static final float SCROLL_FRICTION = 0.015f;
263 
264     /**
265      * Max distance in dips to overscroll for edge effects
266      */
267     private static final int OVERSCROLL_DISTANCE = 0;
268 
269     /**
270      * Max distance in dips to overfling for edge effects
271      */
272     private static final int OVERFLING_DISTANCE = 6;
273 
274     /**
275      * Amount to scroll in response to a horizontal {@link MotionEvent#ACTION_SCROLL} event,
276      * in dips per axis value.
277      */
278     private static final float HORIZONTAL_SCROLL_FACTOR = 64;
279 
280     /**
281      * Amount to scroll in response to a vertical {@link MotionEvent#ACTION_SCROLL} event,
282      * in dips per axis value.
283      */
284     private static final float VERTICAL_SCROLL_FACTOR = 64;
285 
286     /**
287      * Default duration to hide an action mode for.
288      */
289     private static final long ACTION_MODE_HIDE_DURATION_DEFAULT = 2000;
290 
291     /**
292      * Defines the duration in milliseconds before an end of a long press causes a tooltip to be
293      * hidden.
294      */
295     private static final int LONG_PRESS_TOOLTIP_HIDE_TIMEOUT = 1500;
296 
297     /**
298      * Defines the duration in milliseconds before a hover event causes a tooltip to be shown.
299      */
300     private static final int HOVER_TOOLTIP_SHOW_TIMEOUT = 500;
301 
302     /**
303      * Defines the duration in milliseconds before mouse inactivity causes a tooltip to be hidden.
304      * (default variant to be used when {@link View#SYSTEM_UI_FLAG_LOW_PROFILE} is not set).
305      */
306     private static final int HOVER_TOOLTIP_HIDE_TIMEOUT = 15000;
307 
308     /**
309      * Defines the duration in milliseconds before mouse inactivity causes a tooltip to be hidden
310      * (short version to be used when {@link View#SYSTEM_UI_FLAG_LOW_PROFILE} is set).
311      */
312     private static final int HOVER_TOOLTIP_HIDE_SHORT_TIMEOUT = 3000;
313 
314     /**
315      * Configuration values for overriding {@link #hasPermanentMenuKey()} behavior.
316      * These constants must match the definition in res/values/config.xml.
317      */
318     private static final int HAS_PERMANENT_MENU_KEY_AUTODETECT = 0;
319     private static final int HAS_PERMANENT_MENU_KEY_TRUE = 1;
320     private static final int HAS_PERMANENT_MENU_KEY_FALSE = 2;
321 
322     /**
323      * The multiplication factor for inhibiting default gestures.
324      */
325     private static final float AMBIGUOUS_GESTURE_MULTIPLIER = 2f;
326 
327     /**
328      * The timeout value in milliseconds to adjust the selection span and actions for the selected
329      * text when TextClassifier has been initialized.
330      */
331     private static final int SMART_SELECTION_INITIALIZED_TIMEOUT_IN_MILLISECOND = 200;
332 
333     /**
334      * The timeout value in milliseconds to adjust the selection span and actions for the selected
335      * text when TextClassifier has not been initialized.
336      */
337     private static final int SMART_SELECTION_INITIALIZING_TIMEOUT_IN_MILLISECOND = 500;
338 
339     private final boolean mConstructedWithContext;
340     private final int mEdgeSlop;
341     private final int mFadingEdgeLength;
342     private final int mMinimumFlingVelocity;
343     private final int mMaximumFlingVelocity;
344     private final int mMinimumRotaryEncoderFlingVelocity;
345     private final int mMaximumRotaryEncoderFlingVelocity;
346     private final int mScrollbarSize;
347     private final int mTouchSlop;
348     private final int mHandwritingSlop;
349     private final int mMinScalingSpan;
350     private final int mHoverSlop;
351     private final int mMinScrollbarTouchTarget;
352     private final int mDoubleTapTouchSlop;
353     private final int mPagingTouchSlop;
354     private final int mDoubleTapSlop;
355     private final int mWindowTouchSlop;
356     private final int mHandwritingGestureLineMargin;
357     private final float mAmbiguousGestureMultiplier;
358     private final int mMaximumDrawingCacheSize;
359     private final int mOverscrollDistance;
360     private final int mOverflingDistance;
361     @UnsupportedAppUsage
362     private final boolean mFadingMarqueeEnabled;
363     private final long mGlobalActionsKeyTimeout;
364     private final float mVerticalScrollFactor;
365     private final float mHorizontalScrollFactor;
366     private final boolean mShowMenuShortcutsWhenKeyboardPresent;
367     private final long mScreenshotChordKeyTimeout;
368     private final int mSmartSelectionInitializedTimeout;
369     private final int mSmartSelectionInitializingTimeout;
370     private final boolean mPreferKeepClearForFocusEnabled;
371 
372     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915)
373     private boolean sHasPermanentMenuKey;
374     @UnsupportedAppUsage
375     private boolean sHasPermanentMenuKeySet;
376 
377     @UnsupportedAppUsage
378     static final SparseArray<ViewConfiguration> sConfigurations =
379             new SparseArray<ViewConfiguration>(2);
380 
381     /**
382      * @deprecated Use {@link android.view.ViewConfiguration#get(android.content.Context)} instead.
383      */
384     @Deprecated
ViewConfiguration()385     public ViewConfiguration() {
386         mConstructedWithContext = false;
387         mEdgeSlop = EDGE_SLOP;
388         mFadingEdgeLength = FADING_EDGE_LENGTH;
389         mMinimumFlingVelocity = MINIMUM_FLING_VELOCITY;
390         mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY;
391         mMinimumRotaryEncoderFlingVelocity = MINIMUM_FLING_VELOCITY;
392         mMaximumRotaryEncoderFlingVelocity = MAXIMUM_FLING_VELOCITY;
393         mScrollbarSize = SCROLL_BAR_SIZE;
394         mTouchSlop = TOUCH_SLOP;
395         mHandwritingSlop = HANDWRITING_SLOP;
396         mHoverSlop = TOUCH_SLOP / 2;
397         mMinScrollbarTouchTarget = MIN_SCROLLBAR_TOUCH_TARGET;
398         mDoubleTapTouchSlop = DOUBLE_TAP_TOUCH_SLOP;
399         mPagingTouchSlop = PAGING_TOUCH_SLOP;
400         mDoubleTapSlop = DOUBLE_TAP_SLOP;
401         mWindowTouchSlop = WINDOW_TOUCH_SLOP;
402         mHandwritingGestureLineMargin = HANDWRITING_GESTURE_LINE_MARGIN;
403         mAmbiguousGestureMultiplier = AMBIGUOUS_GESTURE_MULTIPLIER;
404         //noinspection deprecation
405         mMaximumDrawingCacheSize = MAXIMUM_DRAWING_CACHE_SIZE;
406         mOverscrollDistance = OVERSCROLL_DISTANCE;
407         mOverflingDistance = OVERFLING_DISTANCE;
408         mFadingMarqueeEnabled = true;
409         mGlobalActionsKeyTimeout = GLOBAL_ACTIONS_KEY_TIMEOUT;
410         mHorizontalScrollFactor = HORIZONTAL_SCROLL_FACTOR;
411         mVerticalScrollFactor = VERTICAL_SCROLL_FACTOR;
412         mShowMenuShortcutsWhenKeyboardPresent = false;
413         mScreenshotChordKeyTimeout = SCREENSHOT_CHORD_KEY_TIMEOUT;
414 
415         // Getter throws if mConstructedWithContext is false so doesn't matter what
416         // this value is.
417         mMinScalingSpan = 0;
418         mSmartSelectionInitializedTimeout = SMART_SELECTION_INITIALIZED_TIMEOUT_IN_MILLISECOND;
419         mSmartSelectionInitializingTimeout = SMART_SELECTION_INITIALIZING_TIMEOUT_IN_MILLISECOND;
420         mPreferKeepClearForFocusEnabled = false;
421     }
422 
423     /**
424      * Creates a new configuration for the specified visual {@link Context}. The configuration
425      * depends on various parameters of the {@link Context}, like the dimension of the display or
426      * the density of the display.
427      *
428      * @param context A visual {@link Context} used to initialize the view configuration. It must
429      *                be {@link Activity} or other {@link Context} created with
430      *                {@link Context#createWindowContext(int, Bundle)}.
431      *
432      * @see #get(android.content.Context)
433      * @see android.util.DisplayMetrics
434      */
ViewConfiguration(@onNull @iContext Context context)435     private ViewConfiguration(@NonNull @UiContext Context context) {
436         mConstructedWithContext = true;
437         final Resources res = context.getResources();
438         final DisplayMetrics metrics = res.getDisplayMetrics();
439         final Configuration config = res.getConfiguration();
440         final float density = metrics.density;
441         final float sizeAndDensity;
442         if (config.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE)) {
443             sizeAndDensity = density * 1.5f;
444         } else {
445             sizeAndDensity = density;
446         }
447 
448         mEdgeSlop = (int) (sizeAndDensity * EDGE_SLOP + 0.5f);
449         mFadingEdgeLength = (int) (sizeAndDensity * FADING_EDGE_LENGTH + 0.5f);
450         mScrollbarSize = res.getDimensionPixelSize(
451                 com.android.internal.R.dimen.config_scrollbarSize);
452         mDoubleTapSlop = (int) (sizeAndDensity * DOUBLE_TAP_SLOP + 0.5f);
453         mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
454 
455         final TypedValue multiplierValue = new TypedValue();
456         res.getValue(
457                 com.android.internal.R.dimen.config_ambiguousGestureMultiplier,
458                 multiplierValue,
459                 true /*resolveRefs*/);
460         mAmbiguousGestureMultiplier = Math.max(1.0f, multiplierValue.getFloat());
461 
462         // Size of the screen in bytes, in ARGB_8888 format
463         final Rect maxBounds = config.windowConfiguration.getMaxBounds();
464         mMaximumDrawingCacheSize = 4 * maxBounds.width() * maxBounds.height();
465 
466         mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);
467         mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
468 
469         if (!sHasPermanentMenuKeySet) {
470             final int configVal = res.getInteger(
471                     com.android.internal.R.integer.config_overrideHasPermanentMenuKey);
472 
473             switch (configVal) {
474                 default:
475                 case HAS_PERMANENT_MENU_KEY_AUTODETECT: {
476                     IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
477                     try {
478                         sHasPermanentMenuKey = !wm.hasNavigationBar(context.getDisplayId());
479                         sHasPermanentMenuKeySet = true;
480                     } catch (RemoteException ex) {
481                         sHasPermanentMenuKey = false;
482                     }
483                 }
484                 break;
485 
486                 case HAS_PERMANENT_MENU_KEY_TRUE:
487                     sHasPermanentMenuKey = true;
488                     sHasPermanentMenuKeySet = true;
489                     break;
490 
491                 case HAS_PERMANENT_MENU_KEY_FALSE:
492                     sHasPermanentMenuKey = false;
493                     sHasPermanentMenuKeySet = true;
494                     break;
495             }
496         }
497 
498         mFadingMarqueeEnabled = res.getBoolean(
499                 com.android.internal.R.bool.config_ui_enableFadingMarquee);
500         mTouchSlop = res.getDimensionPixelSize(
501                 com.android.internal.R.dimen.config_viewConfigurationTouchSlop);
502         mHandwritingSlop = res.getDimensionPixelSize(
503                 com.android.internal.R.dimen.config_viewConfigurationHandwritingSlop);
504         mHoverSlop = res.getDimensionPixelSize(
505                 com.android.internal.R.dimen.config_viewConfigurationHoverSlop);
506         mMinScrollbarTouchTarget = res.getDimensionPixelSize(
507                 com.android.internal.R.dimen.config_minScrollbarTouchTarget);
508         mPagingTouchSlop = mTouchSlop * 2;
509 
510         mDoubleTapTouchSlop = mTouchSlop;
511 
512         mHandwritingGestureLineMargin = res.getDimensionPixelSize(
513                 com.android.internal.R.dimen.config_viewConfigurationHandwritingGestureLineMargin);
514 
515         mMinimumFlingVelocity = res.getDimensionPixelSize(
516                 com.android.internal.R.dimen.config_viewMinFlingVelocity);
517         mMaximumFlingVelocity = res.getDimensionPixelSize(
518                 com.android.internal.R.dimen.config_viewMaxFlingVelocity);
519 
520         int configMinRotaryEncoderFlingVelocity = res.getDimensionPixelSize(
521                 com.android.internal.R.dimen.config_viewMinRotaryEncoderFlingVelocity);
522         int configMaxRotaryEncoderFlingVelocity = res.getDimensionPixelSize(
523                 com.android.internal.R.dimen.config_viewMaxRotaryEncoderFlingVelocity);
524         if (configMinRotaryEncoderFlingVelocity < 0 || configMaxRotaryEncoderFlingVelocity < 0) {
525             mMinimumRotaryEncoderFlingVelocity = NO_FLING_MIN_VELOCITY;
526             mMaximumRotaryEncoderFlingVelocity = NO_FLING_MAX_VELOCITY;
527         } else {
528             mMinimumRotaryEncoderFlingVelocity = configMinRotaryEncoderFlingVelocity;
529             mMaximumRotaryEncoderFlingVelocity = configMaxRotaryEncoderFlingVelocity;
530         }
531 
532         mGlobalActionsKeyTimeout = res.getInteger(
533                 com.android.internal.R.integer.config_globalActionsKeyTimeout);
534 
535         mHorizontalScrollFactor = res.getDimensionPixelSize(
536                 com.android.internal.R.dimen.config_horizontalScrollFactor);
537         mVerticalScrollFactor = res.getDimensionPixelSize(
538                 com.android.internal.R.dimen.config_verticalScrollFactor);
539 
540         mShowMenuShortcutsWhenKeyboardPresent = res.getBoolean(
541             com.android.internal.R.bool.config_showMenuShortcutsWhenKeyboardPresent);
542 
543         mMinScalingSpan = res.getDimensionPixelSize(
544                 com.android.internal.R.dimen.config_minScalingSpan);
545 
546         mScreenshotChordKeyTimeout = res.getInteger(
547                 com.android.internal.R.integer.config_screenshotChordKeyTimeout);
548 
549         mSmartSelectionInitializedTimeout = res.getInteger(
550                 com.android.internal.R.integer.config_smartSelectionInitializedTimeoutMillis);
551         mSmartSelectionInitializingTimeout = res.getInteger(
552                 com.android.internal.R.integer.config_smartSelectionInitializingTimeoutMillis);
553         mPreferKeepClearForFocusEnabled = res.getBoolean(
554                 com.android.internal.R.bool.config_preferKeepClearForFocus);
555     }
556 
557     /**
558      * Returns a configuration for the specified visual {@link Context}. The configuration depends
559      * on various parameters of the {@link Context}, like the dimension of the display or the
560      * density of the display.
561      *
562      * @param context A visual {@link Context} used to initialize the view configuration. It must
563      *                be {@link Activity} or other {@link Context} created with
564      *                {@link Context#createWindowContext(int, Bundle)}.
565      */
566     // TODO(b/182007470): Use @ConfigurationContext instead
get(@onNull @iContext Context context)567     public static ViewConfiguration get(@NonNull @UiContext Context context) {
568         StrictMode.assertConfigurationContext(context, "ViewConfiguration");
569 
570         final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
571         final int density = (int) (100.0f * metrics.density);
572 
573         ViewConfiguration configuration = sConfigurations.get(density);
574         if (configuration == null) {
575             configuration = new ViewConfiguration(context);
576             sConfigurations.put(density, configuration);
577         }
578 
579         return configuration;
580     }
581 
582     /**
583      * @return The width of the horizontal scrollbar and the height of the vertical
584      *         scrollbar in dips
585      *
586      * @deprecated Use {@link #getScaledScrollBarSize()} instead.
587      */
588     @Deprecated
getScrollBarSize()589     public static int getScrollBarSize() {
590         return SCROLL_BAR_SIZE;
591     }
592 
593     /**
594      * @return The width of the horizontal scrollbar and the height of the vertical
595      *         scrollbar in pixels
596      */
getScaledScrollBarSize()597     public int getScaledScrollBarSize() {
598         return mScrollbarSize;
599     }
600 
601     /**
602      * @return the minimum size of the scrollbar thumb's touch target in pixels
603      * @hide
604      */
getScaledMinScrollbarTouchTarget()605     public int getScaledMinScrollbarTouchTarget() {
606         return mMinScrollbarTouchTarget;
607     }
608 
609     /**
610      * @return Duration of the fade when scrollbars fade away in milliseconds
611      */
getScrollBarFadeDuration()612     public static int getScrollBarFadeDuration() {
613         return SCROLL_BAR_FADE_DURATION;
614     }
615 
616     /**
617      * @return Default delay before the scrollbars fade in milliseconds
618      */
getScrollDefaultDelay()619     public static int getScrollDefaultDelay() {
620         return SCROLL_BAR_DEFAULT_DELAY;
621     }
622 
623     /**
624      * @return the length of the fading edges in dips
625      *
626      * @deprecated Use {@link #getScaledFadingEdgeLength()} instead.
627      */
628     @Deprecated
getFadingEdgeLength()629     public static int getFadingEdgeLength() {
630         return FADING_EDGE_LENGTH;
631     }
632 
633     /**
634      * @return the length of the fading edges in pixels
635      */
getScaledFadingEdgeLength()636     public int getScaledFadingEdgeLength() {
637         return mFadingEdgeLength;
638     }
639 
640     /**
641      * @return the duration in milliseconds of the pressed state in child
642      * components.
643      */
getPressedStateDuration()644     public static int getPressedStateDuration() {
645         return PRESSED_STATE_DURATION;
646     }
647 
648     /**
649      * Used for both key and motion events.
650      *
651      * @return the duration in milliseconds before a press turns into
652      * a long press
653      */
getLongPressTimeout()654     public static int getLongPressTimeout() {
655         return AppGlobals.getIntCoreSetting(Settings.Secure.LONG_PRESS_TIMEOUT,
656                 DEFAULT_LONG_PRESS_TIMEOUT);
657     }
658 
659     /**
660      * @return the duration in milliseconds between the first tap's up event and the second tap's
661      * down event for an interaction to be considered part of the same multi-press.
662      */
getMultiPressTimeout()663     public static int getMultiPressTimeout() {
664         return AppGlobals.getIntCoreSetting(Settings.Secure.MULTI_PRESS_TIMEOUT,
665                 DEFAULT_MULTI_PRESS_TIMEOUT);
666     }
667 
668     /**
669      * @return the time before the first key repeat in milliseconds.
670      */
getKeyRepeatTimeout()671     public static int getKeyRepeatTimeout() {
672         return getLongPressTimeout();
673     }
674 
675     /**
676      * @return the time between successive key repeats in milliseconds.
677      */
getKeyRepeatDelay()678     public static int getKeyRepeatDelay() {
679         return KEY_REPEAT_DELAY;
680     }
681 
682     /**
683      * @return the duration in milliseconds we will wait to see if a touch event
684      * is a tap or a scroll. If the user does not move within this interval, it is
685      * considered to be a tap.
686      */
getTapTimeout()687     public static int getTapTimeout() {
688         return TAP_TIMEOUT;
689     }
690 
691     /**
692      * @return the duration in milliseconds we will wait to see if a touch event
693      * is a jump tap. If the user does not move within this interval, it is
694      * considered to be a tap.
695      */
getJumpTapTimeout()696     public static int getJumpTapTimeout() {
697         return JUMP_TAP_TIMEOUT;
698     }
699 
700     /**
701      * @return the duration in milliseconds between the first tap's up event and
702      * the second tap's down event for an interaction to be considered a
703      * double-tap.
704      */
getDoubleTapTimeout()705     public static int getDoubleTapTimeout() {
706         return DOUBLE_TAP_TIMEOUT;
707     }
708 
709     /**
710      * @return the minimum duration in milliseconds between the first tap's
711      * up event and the second tap's down event for an interaction to be considered a
712      * double-tap.
713      *
714      * @hide
715      */
716     @UnsupportedAppUsage
getDoubleTapMinTime()717     public static int getDoubleTapMinTime() {
718         return DOUBLE_TAP_MIN_TIME;
719     }
720 
721     /**
722      * @return the maximum duration in milliseconds between a touch pad
723      * touch and release for a given touch to be considered a tap (click) as
724      * opposed to a hover movement gesture.
725      * @hide
726      */
getHoverTapTimeout()727     public static int getHoverTapTimeout() {
728         return HOVER_TAP_TIMEOUT;
729     }
730 
731     /**
732      * @return the maximum distance in pixels that a touch pad touch can move
733      * before being released for it to be considered a tap (click) as opposed
734      * to a hover movement gesture.
735      * @hide
736      */
737     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getHoverTapSlop()738     public static int getHoverTapSlop() {
739         return HOVER_TAP_SLOP;
740     }
741 
742     /**
743      * @return Inset in dips to look for touchable content when the user touches the edge of the
744      *         screen
745      *
746      * @deprecated Use {@link #getScaledEdgeSlop()} instead.
747      */
748     @Deprecated
getEdgeSlop()749     public static int getEdgeSlop() {
750         return EDGE_SLOP;
751     }
752 
753     /**
754      * @return Inset in pixels to look for touchable content when the user touches the edge of the
755      *         screen
756      */
getScaledEdgeSlop()757     public int getScaledEdgeSlop() {
758         return mEdgeSlop;
759     }
760 
761     /**
762      * @return Distance in dips a touch can wander before we think the user is scrolling
763      *
764      * @deprecated Use {@link #getScaledTouchSlop()} instead.
765      */
766     @Deprecated
getTouchSlop()767     public static int getTouchSlop() {
768         return TOUCH_SLOP;
769     }
770 
771     /**
772      * @return Distance in pixels a touch can wander before we think the user is scrolling
773      */
getScaledTouchSlop()774     public int getScaledTouchSlop() {
775         return mTouchSlop;
776     }
777 
778     /**
779      * @return Distance in pixels a stylus touch can wander before we think the user is
780      * handwriting.
781      */
getScaledHandwritingSlop()782     public int getScaledHandwritingSlop() {
783         return mHandwritingSlop;
784     }
785 
786     /**
787      * @return Distance in pixels a hover can wander while it is still considered "stationary".
788      *
789      */
getScaledHoverSlop()790     public int getScaledHoverSlop() {
791         return mHoverSlop;
792     }
793 
794     /**
795      * @return Distance in pixels the first touch can wander before we do not consider this a
796      * potential double tap event
797      * @hide
798      */
799     @UnsupportedAppUsage
getScaledDoubleTapTouchSlop()800     public int getScaledDoubleTapTouchSlop() {
801         return mDoubleTapTouchSlop;
802     }
803 
804     /**
805      * @return Distance in pixels a touch can wander before we think the user is scrolling a full
806      * page
807      */
getScaledPagingTouchSlop()808     public int getScaledPagingTouchSlop() {
809         return mPagingTouchSlop;
810     }
811 
812     /**
813      * @return Distance in dips between the first touch and second touch to still be
814      *         considered a double tap
815      * @deprecated Use {@link #getScaledDoubleTapSlop()} instead.
816      * @hide The only client of this should be GestureDetector, which needs this
817      *       for clients that still use its deprecated constructor.
818      */
819     @Deprecated
820     @UnsupportedAppUsage
getDoubleTapSlop()821     public static int getDoubleTapSlop() {
822         return DOUBLE_TAP_SLOP;
823     }
824 
825     /**
826      * @return Distance in pixels between the first touch and second touch to still be
827      *         considered a double tap
828      */
getScaledDoubleTapSlop()829     public int getScaledDoubleTapSlop() {
830         return mDoubleTapSlop;
831     }
832 
833     /**
834      * @return margin in pixels around text line bounds where stylus handwriting gestures should be
835      *     supported.
836      */
getScaledHandwritingGestureLineMargin()837     public int getScaledHandwritingGestureLineMargin() {
838         return mHandwritingGestureLineMargin;
839     }
840 
841     /**
842      * Interval for dispatching a recurring accessibility event in milliseconds.
843      * This interval guarantees that a recurring event will be send at most once
844      * during the {@link #getSendRecurringAccessibilityEventsInterval()} time frame.
845      *
846      * @return The delay in milliseconds.
847      *
848      * @hide
849      */
getSendRecurringAccessibilityEventsInterval()850     public static long getSendRecurringAccessibilityEventsInterval() {
851         return SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS;
852     }
853 
854     /**
855      * @return Distance in dips a touch must be outside the bounds of a window for it
856      * to be counted as outside the window for purposes of dismissing that
857      * window.
858      *
859      * @deprecated Use {@link #getScaledWindowTouchSlop()} instead.
860      */
861     @Deprecated
getWindowTouchSlop()862     public static int getWindowTouchSlop() {
863         return WINDOW_TOUCH_SLOP;
864     }
865 
866     /**
867      * @return Distance in pixels a touch must be outside the bounds of a window for it
868      * to be counted as outside the window for purposes of dismissing that window.
869      */
getScaledWindowTouchSlop()870     public int getScaledWindowTouchSlop() {
871         return mWindowTouchSlop;
872     }
873 
874     /**
875      * @return Minimum velocity to initiate a fling, as measured in dips per second.
876      *
877      * @deprecated Use {@link #getScaledMinimumFlingVelocity()} instead.
878      */
879     @Deprecated
getMinimumFlingVelocity()880     public static int getMinimumFlingVelocity() {
881         return MINIMUM_FLING_VELOCITY;
882     }
883 
884     /**
885      * @return Minimum velocity to initiate a fling, as measured in pixels per second.
886      */
getScaledMinimumFlingVelocity()887     public int getScaledMinimumFlingVelocity() {
888         return mMinimumFlingVelocity;
889     }
890 
891     /**
892      * @return Maximum velocity to initiate a fling, as measured in dips per second.
893      *
894      * @deprecated Use {@link #getScaledMaximumFlingVelocity()} instead.
895      */
896     @Deprecated
getMaximumFlingVelocity()897     public static int getMaximumFlingVelocity() {
898         return MAXIMUM_FLING_VELOCITY;
899     }
900 
901     /**
902      * @return Maximum velocity to initiate a fling, as measured in pixels per second.
903      */
getScaledMaximumFlingVelocity()904     public int getScaledMaximumFlingVelocity() {
905         return mMaximumFlingVelocity;
906     }
907 
908     /**
909      * @return Amount to scroll in response to a {@link MotionEvent#ACTION_SCROLL} event. Multiply
910      * this by the event's axis value to obtain the number of pixels to be scrolled.
911      *
912      * @removed
913      */
getScaledScrollFactor()914     public int getScaledScrollFactor() {
915         return (int) mVerticalScrollFactor;
916     }
917 
918     /**
919      * @return Amount to scroll in response to a horizontal {@link MotionEvent#ACTION_SCROLL} event.
920      * Multiply this by the event's axis value to obtain the number of pixels to be scrolled.
921      */
getScaledHorizontalScrollFactor()922     public float getScaledHorizontalScrollFactor() {
923         return mHorizontalScrollFactor;
924     }
925 
926     /**
927      * @return Amount to scroll in response to a vertical {@link MotionEvent#ACTION_SCROLL} event.
928      * Multiply this by the event's axis value to obtain the number of pixels to be scrolled.
929      */
getScaledVerticalScrollFactor()930     public float getScaledVerticalScrollFactor() {
931         return mVerticalScrollFactor;
932     }
933 
934     /**
935      * The maximum drawing cache size expressed in bytes.
936      *
937      * @return the maximum size of View's drawing cache expressed in bytes
938      *
939      * @deprecated Use {@link #getScaledMaximumDrawingCacheSize()} instead.
940      */
941     @Deprecated
getMaximumDrawingCacheSize()942     public static int getMaximumDrawingCacheSize() {
943         //noinspection deprecation
944         return MAXIMUM_DRAWING_CACHE_SIZE;
945     }
946 
947     /**
948      * The maximum drawing cache size expressed in bytes.
949      *
950      * @return the maximum size of View's drawing cache expressed in bytes
951      */
getScaledMaximumDrawingCacheSize()952     public int getScaledMaximumDrawingCacheSize() {
953         return mMaximumDrawingCacheSize;
954     }
955 
956     /**
957      * @return The maximum distance a View should overscroll by when showing edge effects (in
958      * pixels).
959      */
getScaledOverscrollDistance()960     public int getScaledOverscrollDistance() {
961         return mOverscrollDistance;
962     }
963 
964     /**
965      * @return The maximum distance a View should overfling by when showing edge effects (in
966      * pixels).
967      */
getScaledOverflingDistance()968     public int getScaledOverflingDistance() {
969         return mOverflingDistance;
970     }
971 
972     /**
973      * The amount of time that the zoom controls should be
974      * displayed on the screen expressed in milliseconds.
975      *
976      * @return the time the zoom controls should be visible expressed
977      * in milliseconds.
978      */
getZoomControlsTimeout()979     public static long getZoomControlsTimeout() {
980         return ZOOM_CONTROLS_TIMEOUT;
981     }
982 
983     /**
984      * The amount of time a user needs to press the relevant key to bring up
985      * the global actions dialog.
986      *
987      * @return how long a user needs to press the relevant key to bring up
988      *   the global actions dialog.
989      * @deprecated This timeout should not be used by applications
990      */
991     @Deprecated
getGlobalActionKeyTimeout()992     public static long getGlobalActionKeyTimeout() {
993         return GLOBAL_ACTIONS_KEY_TIMEOUT;
994     }
995 
996     /**
997      * The amount of time a user needs to press the relevant key to bring up
998      * the global actions dialog.
999      *
1000      * @return how long a user needs to press the relevant key to bring up
1001      *   the global actions dialog.
1002      * @hide
1003      */
1004     @TestApi
getDeviceGlobalActionKeyTimeout()1005     public long getDeviceGlobalActionKeyTimeout() {
1006         return mGlobalActionsKeyTimeout;
1007     }
1008 
1009     /**
1010      * The amount of time a user needs to press the relevant keys to trigger
1011      * the screenshot chord.
1012      *
1013      * @return how long a user needs to press the relevant keys to trigger
1014      *   the screenshot chord.
1015      * @hide
1016      */
getScreenshotChordKeyTimeout()1017     public long getScreenshotChordKeyTimeout() {
1018         return mScreenshotChordKeyTimeout;
1019     }
1020 
1021     /**
1022      * The amount of time a user needs to press the relevant keys to activate the accessibility
1023      * shortcut.
1024      *
1025      * @return how long a user needs to press the relevant keys to activate the accessibility
1026      *   shortcut.
1027      * @hide
1028      */
getAccessibilityShortcutKeyTimeout()1029     public long getAccessibilityShortcutKeyTimeout() {
1030         return A11Y_SHORTCUT_KEY_TIMEOUT;
1031     }
1032 
1033     /**
1034      * @return The amount of time a user needs to press the relevant keys to activate the
1035      *   accessibility shortcut after it's confirmed that accessibility shortcut is used.
1036      * @hide
1037      */
getAccessibilityShortcutKeyTimeoutAfterConfirmation()1038     public long getAccessibilityShortcutKeyTimeoutAfterConfirmation() {
1039         return A11Y_SHORTCUT_KEY_TIMEOUT_AFTER_CONFIRMATION;
1040     }
1041 
1042     /**
1043      * The amount of friction applied to scrolls and flings.
1044      *
1045      * @return A scalar dimensionless value representing the coefficient of
1046      *         friction.
1047      */
getScrollFriction()1048     public static float getScrollFriction() {
1049         return SCROLL_FRICTION;
1050     }
1051 
1052     /**
1053      * @return the default duration in milliseconds for {@link ActionMode#hide(long)}.
1054      */
getDefaultActionModeHideDuration()1055     public static long getDefaultActionModeHideDuration() {
1056         return ACTION_MODE_HIDE_DURATION_DEFAULT;
1057     }
1058 
1059     /**
1060      * The multiplication factor for inhibiting default gestures.
1061      *
1062      * If a MotionEvent has {@link android.view.MotionEvent#CLASSIFICATION_AMBIGUOUS_GESTURE} set,
1063      * then certain actions, such as scrolling, will be inhibited. However, to account for the
1064      * possibility of an incorrect classification, existing gesture thresholds (e.g. scrolling
1065      * touch slop and the long-press timeout) should be scaled by this factor and remain in effect.
1066      *
1067      * @deprecated Use {@link #getScaledAmbiguousGestureMultiplier()}.
1068      */
1069     @Deprecated
1070     @FloatRange(from = 1.0)
getAmbiguousGestureMultiplier()1071     public static float getAmbiguousGestureMultiplier() {
1072         return AMBIGUOUS_GESTURE_MULTIPLIER;
1073     }
1074 
1075     /**
1076      * The multiplication factor for inhibiting default gestures.
1077      *
1078      * If a MotionEvent has {@link android.view.MotionEvent#CLASSIFICATION_AMBIGUOUS_GESTURE} set,
1079      * then certain actions, such as scrolling, will be inhibited. However, to account for the
1080      * possibility of an incorrect classification, existing gesture thresholds (e.g. scrolling
1081      * touch slop and the long-press timeout) should be scaled by this factor and remain in effect.
1082      */
1083     @FloatRange(from = 1.0)
getScaledAmbiguousGestureMultiplier()1084     public float getScaledAmbiguousGestureMultiplier() {
1085         return mAmbiguousGestureMultiplier;
1086     }
1087 
1088     /**
1089      * Report if the device has a permanent menu key available to the user.
1090      *
1091      * <p>As of Android 3.0, devices may not have a permanent menu key available.
1092      * Apps should use the action bar to present menu options to users.
1093      * However, there are some apps where the action bar is inappropriate
1094      * or undesirable. This method may be used to detect if a menu key is present.
1095      * If not, applications should provide another on-screen affordance to access
1096      * functionality.
1097      *
1098      * @return true if a permanent menu key is present, false otherwise.
1099      */
hasPermanentMenuKey()1100     public boolean hasPermanentMenuKey() {
1101         return sHasPermanentMenuKey;
1102     }
1103 
1104     /**
1105      * Minimum absolute value of velocity to initiate a fling for a motion generated by an
1106      * {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and on
1107      * a given motion event {@code axis}.
1108      *
1109      * <p>Before utilizing this method to get a minimum fling velocity for a motion generated by the
1110      * input device, scale the velocity of the motion events generated by the input device to pixels
1111      * per second.
1112      *
1113      * <p>For instance, if you tracked {@link MotionEvent#AXIS_SCROLL} vertical velocities generated
1114      * from a {@link InputDevice#SOURCE_ROTARY_ENCODER}, the velocity returned from
1115      * {@link VelocityTracker} will be in the units with which the axis values were reported in the
1116      * motion event. Before comparing that velocity against the minimum fling velocity specified
1117      * here, make sure that the {@link MotionEvent#AXIS_SCROLL} velocity from the tracker is
1118      * calculated in "units per second" (see {@link VelocityTracker#computeCurrentVelocity(int)},
1119      * {@link VelocityTracker#computeCurrentVelocity(int, float)} to adjust your velocity
1120      * computations to "per second"), and use {@link #getScaledVerticalScrollFactor} to change this
1121      * velocity value to "pixels/second".
1122      *
1123      * <p>If the provided {@code inputDeviceId} is not valid, or if the input device whose ID is
1124      * provided does not support the given motion event source and/or axis, this method will return
1125      * {@code Integer.MAX_VALUE}.
1126      *
1127      * <h3>Obtaining the correct arguments for this method call</h3>
1128      * <p><b>inputDeviceId</b>: if calling this method in response to a {@link MotionEvent}, use
1129      * the device ID that is reported by the event, which can be obtained using
1130      * {@link MotionEvent#getDeviceId()}. Otherwise, use a valid ID that is obtained from
1131      * {@link InputDevice#getId()}, or from an {@link InputManager} instance
1132      * ({@link InputManager#getInputDeviceIds()} gives all the valid input device IDs).
1133      *
1134      * <p><b>axis</b>: a {@link MotionEvent} may report data for multiple axes, and each axis may
1135      * have multiple data points for different pointers. Use the axis for which you obtained the
1136      * velocity for ({@link VelocityTracker} lets you calculate velocities for a specific axis. Use
1137      * the axis for which you calculated velocity). You can use
1138      * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the
1139      * {@link InputDevice}, from which you can derive all the valid axes for the device.
1140      *
1141      * <p><b>source</b>: use {@link MotionEvent#getSource()} if calling this method in response to a
1142      * {@link MotionEvent}. Otherwise, use a valid source for the {@link InputDevice}. You can use
1143      * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the
1144      * {@link InputDevice}, from which you can derive all the valid sources for the device.
1145      *
1146      *
1147      * <p>This method optimizes calls over multiple input device IDs, so caching the return value of
1148      * the method is not necessary if you are handling multiple input devices.
1149      *
1150      * @param inputDeviceId the ID of the {@link InputDevice} that generated the motion triggering
1151      *          fling.
1152      * @param axis the axis on which the motion triggering the fling happened. This axis should be
1153      *          a valid axis that can be reported by the provided input device from the provided
1154      *          input device source.
1155      * @param source the input source of the motion causing fling. This source should be a valid
1156      *          source for the {@link InputDevice} whose ID is {@code inputDeviceId}.
1157      *
1158      * @return the minimum velocity, in pixels/second, to trigger fling.
1159      *
1160      * @see InputDevice#getMotionRange(int, int)
1161      * @see InputDevice#getMotionRanges()
1162      * @see VelocityTracker#getAxisVelocity(int, int)
1163      * @see VelocityTracker#getAxisVelocity(int)
1164      */
getScaledMinimumFlingVelocity(int inputDeviceId, int axis, int source)1165     public int getScaledMinimumFlingVelocity(int inputDeviceId, int axis, int source) {
1166         if (!isInputDeviceInfoValid(inputDeviceId, axis, source)) return NO_FLING_MIN_VELOCITY;
1167 
1168         if (source == InputDevice.SOURCE_ROTARY_ENCODER) return mMinimumRotaryEncoderFlingVelocity;
1169 
1170         return mMinimumFlingVelocity;
1171     }
1172 
1173     /**
1174      * Maximum absolute value of velocity to initiate a fling for a motion generated by an
1175      * {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and on
1176      * a given motion event {@code axis}.
1177      *
1178      * <p>Similar to {@link #getScaledMinimumFlingVelocity(int, int, int)}, but for maximum fling
1179      * velocity, instead of minimum. Also, unlike that method which returns
1180      * {@code Integer.MAX_VALUE} for bad input device ID, source and/or motion event axis inputs,
1181      * this method returns {@code Integer.MIN_VALUE} for such bad inputs.
1182      */
getScaledMaximumFlingVelocity(int inputDeviceId, int axis, int source)1183     public int getScaledMaximumFlingVelocity(int inputDeviceId, int axis, int source) {
1184         if (!isInputDeviceInfoValid(inputDeviceId, axis, source)) return NO_FLING_MAX_VELOCITY;
1185 
1186         if (source == InputDevice.SOURCE_ROTARY_ENCODER) return mMaximumRotaryEncoderFlingVelocity;
1187 
1188         return mMaximumFlingVelocity;
1189     }
1190 
isInputDeviceInfoValid(int id, int axis, int source)1191     private static boolean isInputDeviceInfoValid(int id, int axis, int source) {
1192         InputDevice device = InputManagerGlobal.getInstance().getInputDevice(id);
1193         return device != null && device.getMotionRange(axis, source) != null;
1194     }
1195 
1196     /**
1197      * Check if shortcuts should be displayed in menus.
1198      *
1199      * @return {@code True} if shortcuts should be displayed in menus.
1200      */
shouldShowMenuShortcutsWhenKeyboardPresent()1201     public boolean shouldShowMenuShortcutsWhenKeyboardPresent() {
1202         return mShowMenuShortcutsWhenKeyboardPresent;
1203     }
1204 
1205     /**
1206      * Retrieves the distance in pixels between touches that must be reached for a gesture to be
1207      * interpreted as scaling.
1208      *
1209      * In general, scaling shouldn't start until this distance has been met or surpassed, and
1210      * scaling should end when the distance in pixels between touches drops below this distance.
1211      *
1212      * @return The distance in pixels
1213      * @throws IllegalStateException if this method is called on a ViewConfiguration that was
1214      *         instantiated using a constructor with no Context parameter.
1215      */
getScaledMinimumScalingSpan()1216     public int getScaledMinimumScalingSpan() {
1217         if (!mConstructedWithContext) {
1218             throw new IllegalStateException("Min scaling span cannot be determined when this "
1219                     + "method is called on a ViewConfiguration that was instantiated using a "
1220                     + "constructor with no Context parameter");
1221         }
1222         return mMinScalingSpan;
1223     }
1224 
1225     /**
1226      * @hide
1227      * @return Whether or not marquee should use fading edges.
1228      */
1229     @UnsupportedAppUsage
isFadingMarqueeEnabled()1230     public boolean isFadingMarqueeEnabled() {
1231         return mFadingMarqueeEnabled;
1232     }
1233 
1234     /**
1235      * @return the timeout value in milliseconds to adjust the selection span and actions for the
1236      *         selected text when TextClassifier has been initialized.
1237      * @hide
1238      */
getSmartSelectionInitializedTimeout()1239     public int getSmartSelectionInitializedTimeout() {
1240         return mSmartSelectionInitializedTimeout;
1241     }
1242 
1243     /**
1244      * @return the timeout value in milliseconds to adjust the selection span and actions for the
1245      *         selected text when TextClassifier has not been initialized.
1246      * @hide
1247      */
getSmartSelectionInitializingTimeout()1248     public int getSmartSelectionInitializingTimeout() {
1249         return mSmartSelectionInitializingTimeout;
1250     }
1251 
1252     /**
1253      * @return {@code true} if Views should set themselves as preferred to keep clear when focused,
1254      * {@code false} otherwise.
1255      * @hide
1256      */
1257     @TestApi
isPreferKeepClearForFocusEnabled()1258     public boolean isPreferKeepClearForFocusEnabled() {
1259         return mPreferKeepClearForFocusEnabled;
1260     }
1261 
1262     /**
1263      * @return the duration in milliseconds before an end of a long press causes a tooltip to be
1264      * hidden
1265      * @hide
1266      */
1267     @TestApi
getLongPressTooltipHideTimeout()1268     public static int getLongPressTooltipHideTimeout() {
1269         return LONG_PRESS_TOOLTIP_HIDE_TIMEOUT;
1270     }
1271 
1272     /**
1273      * @return the duration in milliseconds before a hover event causes a tooltip to be shown
1274      * @hide
1275      */
1276     @TestApi
getHoverTooltipShowTimeout()1277     public static int getHoverTooltipShowTimeout() {
1278         return HOVER_TOOLTIP_SHOW_TIMEOUT;
1279     }
1280 
1281     /**
1282      * @return the duration in milliseconds before mouse inactivity causes a tooltip to be hidden
1283      * (default variant to be used when {@link View#SYSTEM_UI_FLAG_LOW_PROFILE} is not set).
1284      * @hide
1285      */
1286     @TestApi
getHoverTooltipHideTimeout()1287     public static int getHoverTooltipHideTimeout() {
1288         return HOVER_TOOLTIP_HIDE_TIMEOUT;
1289     }
1290 
1291     /**
1292      * @return the duration in milliseconds before mouse inactivity causes a tooltip to be hidden
1293      * (shorter variant to be used when {@link View#SYSTEM_UI_FLAG_LOW_PROFILE} is set).
1294      * @hide
1295      */
1296     @TestApi
getHoverTooltipHideShortTimeout()1297     public static int getHoverTooltipHideShortTimeout() {
1298         return HOVER_TOOLTIP_HIDE_SHORT_TIMEOUT;
1299     }
1300 }
1301