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