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