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
17package android.view;
18
19import android.app.AppGlobals;
20import android.content.Context;
21import android.content.res.Configuration;
22import android.content.res.Resources;
23import android.graphics.Point;
24import android.os.RemoteException;
25import android.provider.Settings;
26import android.util.DisplayMetrics;
27import android.util.SparseArray;
28
29/**
30 * Contains methods to standard constants used in the UI for timeouts, sizes, and distances.
31 */
32public class ViewConfiguration {
33    /**
34     * Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
35     * dips
36     */
37    private static final int SCROLL_BAR_SIZE = 10;
38
39    /**
40     * Duration of the fade when scrollbars fade away in milliseconds
41     */
42    private static final int SCROLL_BAR_FADE_DURATION = 250;
43
44    /**
45     * Default delay before the scrollbars fade in milliseconds
46     */
47    private static final int SCROLL_BAR_DEFAULT_DELAY = 300;
48
49    /**
50     * Defines the length of the fading edges in dips
51     */
52    private static final int FADING_EDGE_LENGTH = 12;
53
54    /**
55     * Defines the duration in milliseconds of the pressed state in child
56     * components.
57     */
58    private static final int PRESSED_STATE_DURATION = 64;
59
60    /**
61     * Defines the default duration in milliseconds before a press turns into
62     * a long press
63     */
64    private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500;
65
66    /**
67     * Defines the time between successive key repeats in milliseconds.
68     */
69    private static final int KEY_REPEAT_DELAY = 50;
70
71    /**
72     * Defines the duration in milliseconds a user needs to hold down the
73     * appropriate button to bring up the global actions dialog (power off,
74     * lock screen, etc).
75     */
76    private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 500;
77
78    /**
79     * Defines the duration in milliseconds we will wait to see if a touch event
80     * is a tap or a scroll. If the user does not move within this interval, it is
81     * considered to be a tap.
82     */
83    private static final int TAP_TIMEOUT = 100;
84
85    /**
86     * Defines the duration in milliseconds we will wait to see if a touch event
87     * is a jump tap. If the user does not complete the jump tap within this interval, it is
88     * considered to be a tap.
89     */
90    private static final int JUMP_TAP_TIMEOUT = 500;
91
92    /**
93     * Defines the duration in milliseconds between the first tap's up event and
94     * the second tap's down event for an interaction to be considered a
95     * double-tap.
96     */
97    private static final int DOUBLE_TAP_TIMEOUT = 300;
98
99    /**
100     * Defines the minimum duration in milliseconds between the first tap's up event and
101     * the second tap's down event for an interaction to be considered a
102     * double-tap.
103     */
104    private static final int DOUBLE_TAP_MIN_TIME = 40;
105
106    /**
107     * Defines the maximum duration in milliseconds between a touch pad
108     * touch and release for a given touch to be considered a tap (click) as
109     * opposed to a hover movement gesture.
110     */
111    private static final int HOVER_TAP_TIMEOUT = 150;
112
113    /**
114     * Defines the maximum distance in pixels that a touch pad touch can move
115     * before being released for it to be considered a tap (click) as opposed
116     * to a hover movement gesture.
117     */
118    private static final int HOVER_TAP_SLOP = 20;
119
120    /**
121     * Defines the duration in milliseconds we want to display zoom controls in response
122     * to a user panning within an application.
123     */
124    private static final int ZOOM_CONTROLS_TIMEOUT = 3000;
125
126    /**
127     * Inset in dips to look for touchable content when the user touches the edge of the screen
128     */
129    private static final int EDGE_SLOP = 12;
130
131    /**
132     * Distance a touch can wander before we think the user is scrolling in dips.
133     * Note that this value defined here is only used as a fallback by legacy/misbehaving
134     * applications that do not provide a Context for determining density/configuration-dependent
135     * values.
136     *
137     * To alter this value, see the configuration resource config_viewConfigurationTouchSlop
138     * in frameworks/base/core/res/res/values/config.xml or the appropriate device resource overlay.
139     * It may be appropriate to tweak this on a device-specific basis in an overlay based on
140     * the characteristics of the touch panel and firmware.
141     */
142    private static final int TOUCH_SLOP = 8;
143
144    /**
145     * Distance the first touch can wander before we stop considering this event a double tap
146     * (in dips)
147     */
148    private static final int DOUBLE_TAP_TOUCH_SLOP = TOUCH_SLOP;
149
150    /**
151     * Distance a touch can wander before we think the user is attempting a paged scroll
152     * (in dips)
153     *
154     * Note that this value defined here is only used as a fallback by legacy/misbehaving
155     * applications that do not provide a Context for determining density/configuration-dependent
156     * values.
157     *
158     * See the note above on {@link #TOUCH_SLOP} regarding the dimen resource
159     * config_viewConfigurationTouchSlop. ViewConfiguration will report a paging touch slop of
160     * config_viewConfigurationTouchSlop * 2 when provided with a Context.
161     */
162    private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 2;
163
164    /**
165     * Distance in dips between the first touch and second touch to still be considered a double tap
166     */
167    private static final int DOUBLE_TAP_SLOP = 100;
168
169    /**
170     * Distance in dips a touch needs to be outside of a window's bounds for it to
171     * count as outside for purposes of dismissing the window.
172     */
173    private static final int WINDOW_TOUCH_SLOP = 16;
174
175    /**
176     * Minimum velocity to initiate a fling, as measured in dips per second
177     */
178    private static final int MINIMUM_FLING_VELOCITY = 50;
179
180    /**
181     * Maximum velocity to initiate a fling, as measured in dips per second
182     */
183    private static final int MAXIMUM_FLING_VELOCITY = 8000;
184
185    /**
186     * Delay before dispatching a recurring accessibility event in milliseconds.
187     * This delay guarantees that a recurring event will be send at most once
188     * during the {@link #SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS} time
189     * frame.
190     */
191    private static final long SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS = 100;
192
193    /**
194     * The maximum size of View's drawing cache, expressed in bytes. This size
195     * should be at least equal to the size of the screen in ARGB888 format.
196     */
197    @Deprecated
198    private static final int MAXIMUM_DRAWING_CACHE_SIZE = 480 * 800 * 4; // ARGB8888
199
200    /**
201     * The coefficient of friction applied to flings/scrolls.
202     */
203    private static final float SCROLL_FRICTION = 0.015f;
204
205    /**
206     * Max distance in dips to overscroll for edge effects
207     */
208    private static final int OVERSCROLL_DISTANCE = 0;
209
210    /**
211     * Max distance in dips to overfling for edge effects
212     */
213    private static final int OVERFLING_DISTANCE = 6;
214
215    /**
216     * Default duration to hide an action mode for.
217     */
218    private static final long ACTION_MODE_HIDE_DURATION_DEFAULT = 2000;
219
220    /**
221     * Configuration values for overriding {@link #hasPermanentMenuKey()} behavior.
222     * These constants must match the definition in res/values/config.xml.
223     */
224    private static final int HAS_PERMANENT_MENU_KEY_AUTODETECT = 0;
225    private static final int HAS_PERMANENT_MENU_KEY_TRUE = 1;
226    private static final int HAS_PERMANENT_MENU_KEY_FALSE = 2;
227
228    private final int mEdgeSlop;
229    private final int mFadingEdgeLength;
230    private final int mMinimumFlingVelocity;
231    private final int mMaximumFlingVelocity;
232    private final int mScrollbarSize;
233    private final int mTouchSlop;
234    private final int mDoubleTapTouchSlop;
235    private final int mPagingTouchSlop;
236    private final int mDoubleTapSlop;
237    private final int mWindowTouchSlop;
238    private final int mMaximumDrawingCacheSize;
239    private final int mOverscrollDistance;
240    private final int mOverflingDistance;
241    private final boolean mFadingMarqueeEnabled;
242    private final long mGlobalActionsKeyTimeout;
243
244    private boolean sHasPermanentMenuKey;
245    private boolean sHasPermanentMenuKeySet;
246
247    static final SparseArray<ViewConfiguration> sConfigurations =
248            new SparseArray<ViewConfiguration>(2);
249
250    /**
251     * @deprecated Use {@link android.view.ViewConfiguration#get(android.content.Context)} instead.
252     */
253    @Deprecated
254    public ViewConfiguration() {
255        mEdgeSlop = EDGE_SLOP;
256        mFadingEdgeLength = FADING_EDGE_LENGTH;
257        mMinimumFlingVelocity = MINIMUM_FLING_VELOCITY;
258        mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY;
259        mScrollbarSize = SCROLL_BAR_SIZE;
260        mTouchSlop = TOUCH_SLOP;
261        mDoubleTapTouchSlop = DOUBLE_TAP_TOUCH_SLOP;
262        mPagingTouchSlop = PAGING_TOUCH_SLOP;
263        mDoubleTapSlop = DOUBLE_TAP_SLOP;
264        mWindowTouchSlop = WINDOW_TOUCH_SLOP;
265        //noinspection deprecation
266        mMaximumDrawingCacheSize = MAXIMUM_DRAWING_CACHE_SIZE;
267        mOverscrollDistance = OVERSCROLL_DISTANCE;
268        mOverflingDistance = OVERFLING_DISTANCE;
269        mFadingMarqueeEnabled = true;
270        mGlobalActionsKeyTimeout = GLOBAL_ACTIONS_KEY_TIMEOUT;
271    }
272
273    /**
274     * Creates a new configuration for the specified context. The configuration depends on
275     * various parameters of the context, like the dimension of the display or the density
276     * of the display.
277     *
278     * @param context The application context used to initialize this view configuration.
279     *
280     * @see #get(android.content.Context)
281     * @see android.util.DisplayMetrics
282     */
283    private ViewConfiguration(Context context) {
284        final Resources res = context.getResources();
285        final DisplayMetrics metrics = res.getDisplayMetrics();
286        final Configuration config = res.getConfiguration();
287        final float density = metrics.density;
288        final float sizeAndDensity;
289        if (config.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE)) {
290            sizeAndDensity = density * 1.5f;
291        } else {
292            sizeAndDensity = density;
293        }
294
295        mEdgeSlop = (int) (sizeAndDensity * EDGE_SLOP + 0.5f);
296        mFadingEdgeLength = (int) (sizeAndDensity * FADING_EDGE_LENGTH + 0.5f);
297        mScrollbarSize = (int) (density * SCROLL_BAR_SIZE + 0.5f);
298        mDoubleTapSlop = (int) (sizeAndDensity * DOUBLE_TAP_SLOP + 0.5f);
299        mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
300
301        // Size of the screen in bytes, in ARGB_8888 format
302        final WindowManager win = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
303        final Display display = win.getDefaultDisplay();
304        final Point size = new Point();
305        display.getRealSize(size);
306        mMaximumDrawingCacheSize = 4 * size.x * size.y;
307
308        mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);
309        mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
310
311        if (!sHasPermanentMenuKeySet) {
312            final int configVal = res.getInteger(
313                    com.android.internal.R.integer.config_overrideHasPermanentMenuKey);
314
315            switch (configVal) {
316                default:
317                case HAS_PERMANENT_MENU_KEY_AUTODETECT: {
318                    IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
319                    try {
320                        sHasPermanentMenuKey = !wm.hasNavigationBar();
321                        sHasPermanentMenuKeySet = true;
322                    } catch (RemoteException ex) {
323                        sHasPermanentMenuKey = false;
324                    }
325                }
326                break;
327
328                case HAS_PERMANENT_MENU_KEY_TRUE:
329                    sHasPermanentMenuKey = true;
330                    sHasPermanentMenuKeySet = true;
331                    break;
332
333                case HAS_PERMANENT_MENU_KEY_FALSE:
334                    sHasPermanentMenuKey = false;
335                    sHasPermanentMenuKeySet = true;
336                    break;
337            }
338        }
339
340        mFadingMarqueeEnabled = res.getBoolean(
341                com.android.internal.R.bool.config_ui_enableFadingMarquee);
342        mTouchSlop = res.getDimensionPixelSize(
343                com.android.internal.R.dimen.config_viewConfigurationTouchSlop);
344        mPagingTouchSlop = mTouchSlop * 2;
345
346        mDoubleTapTouchSlop = mTouchSlop;
347
348        mMinimumFlingVelocity = res.getDimensionPixelSize(
349                com.android.internal.R.dimen.config_viewMinFlingVelocity);
350        mMaximumFlingVelocity = res.getDimensionPixelSize(
351                com.android.internal.R.dimen.config_viewMaxFlingVelocity);
352        mGlobalActionsKeyTimeout = res.getInteger(
353                com.android.internal.R.integer.config_globalActionsKeyTimeout);
354    }
355
356    /**
357     * Returns a configuration for the specified context. The configuration depends on
358     * various parameters of the context, like the dimension of the display or the
359     * density of the display.
360     *
361     * @param context The application context used to initialize the view configuration.
362     */
363    public static ViewConfiguration get(Context context) {
364        final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
365        final int density = (int) (100.0f * metrics.density);
366
367        ViewConfiguration configuration = sConfigurations.get(density);
368        if (configuration == null) {
369            configuration = new ViewConfiguration(context);
370            sConfigurations.put(density, configuration);
371        }
372
373        return configuration;
374    }
375
376    /**
377     * @return The width of the horizontal scrollbar and the height of the vertical
378     *         scrollbar in dips
379     *
380     * @deprecated Use {@link #getScaledScrollBarSize()} instead.
381     */
382    @Deprecated
383    public static int getScrollBarSize() {
384        return SCROLL_BAR_SIZE;
385    }
386
387    /**
388     * @return The width of the horizontal scrollbar and the height of the vertical
389     *         scrollbar in pixels
390     */
391    public int getScaledScrollBarSize() {
392        return mScrollbarSize;
393    }
394
395    /**
396     * @return Duration of the fade when scrollbars fade away in milliseconds
397     */
398    public static int getScrollBarFadeDuration() {
399        return SCROLL_BAR_FADE_DURATION;
400    }
401
402    /**
403     * @return Default delay before the scrollbars fade in milliseconds
404     */
405    public static int getScrollDefaultDelay() {
406        return SCROLL_BAR_DEFAULT_DELAY;
407    }
408
409    /**
410     * @return the length of the fading edges in dips
411     *
412     * @deprecated Use {@link #getScaledFadingEdgeLength()} instead.
413     */
414    @Deprecated
415    public static int getFadingEdgeLength() {
416        return FADING_EDGE_LENGTH;
417    }
418
419    /**
420     * @return the length of the fading edges in pixels
421     */
422    public int getScaledFadingEdgeLength() {
423        return mFadingEdgeLength;
424    }
425
426    /**
427     * @return the duration in milliseconds of the pressed state in child
428     * components.
429     */
430    public static int getPressedStateDuration() {
431        return PRESSED_STATE_DURATION;
432    }
433
434    /**
435     * @return the duration in milliseconds before a press turns into
436     * a long press
437     */
438    public static int getLongPressTimeout() {
439        return AppGlobals.getIntCoreSetting(Settings.Secure.LONG_PRESS_TIMEOUT,
440                DEFAULT_LONG_PRESS_TIMEOUT);
441    }
442
443    /**
444     * @return the time before the first key repeat in milliseconds.
445     */
446    public static int getKeyRepeatTimeout() {
447        return getLongPressTimeout();
448    }
449
450    /**
451     * @return the time between successive key repeats in milliseconds.
452     */
453    public static int getKeyRepeatDelay() {
454        return KEY_REPEAT_DELAY;
455    }
456
457    /**
458     * @return the duration in milliseconds we will wait to see if a touch event
459     * is a tap or a scroll. If the user does not move within this interval, it is
460     * considered to be a tap.
461     */
462    public static int getTapTimeout() {
463        return TAP_TIMEOUT;
464    }
465
466    /**
467     * @return the duration in milliseconds we will wait to see if a touch event
468     * is a jump tap. If the user does not move within this interval, it is
469     * considered to be a tap.
470     */
471    public static int getJumpTapTimeout() {
472        return JUMP_TAP_TIMEOUT;
473    }
474
475    /**
476     * @return the duration in milliseconds between the first tap's up event and
477     * the second tap's down event for an interaction to be considered a
478     * double-tap.
479     */
480    public static int getDoubleTapTimeout() {
481        return DOUBLE_TAP_TIMEOUT;
482    }
483
484    /**
485     * @return the minimum duration in milliseconds between the first tap's
486     * up event and the second tap's down event for an interaction to be considered a
487     * double-tap.
488     *
489     * @hide
490     */
491    public static int getDoubleTapMinTime() {
492        return DOUBLE_TAP_MIN_TIME;
493    }
494
495    /**
496     * @return the maximum duration in milliseconds between a touch pad
497     * touch and release for a given touch to be considered a tap (click) as
498     * opposed to a hover movement gesture.
499     * @hide
500     */
501    public static int getHoverTapTimeout() {
502        return HOVER_TAP_TIMEOUT;
503    }
504
505    /**
506     * @return the maximum distance in pixels that a touch pad touch can move
507     * before being released for it to be considered a tap (click) as opposed
508     * to a hover movement gesture.
509     * @hide
510     */
511    public static int getHoverTapSlop() {
512        return HOVER_TAP_SLOP;
513    }
514
515    /**
516     * @return Inset in dips to look for touchable content when the user touches the edge of the
517     *         screen
518     *
519     * @deprecated Use {@link #getScaledEdgeSlop()} instead.
520     */
521    @Deprecated
522    public static int getEdgeSlop() {
523        return EDGE_SLOP;
524    }
525
526    /**
527     * @return Inset in pixels to look for touchable content when the user touches the edge of the
528     *         screen
529     */
530    public int getScaledEdgeSlop() {
531        return mEdgeSlop;
532    }
533
534    /**
535     * @return Distance in dips a touch can wander before we think the user is scrolling
536     *
537     * @deprecated Use {@link #getScaledTouchSlop()} instead.
538     */
539    @Deprecated
540    public static int getTouchSlop() {
541        return TOUCH_SLOP;
542    }
543
544    /**
545     * @return Distance in pixels a touch can wander before we think the user is scrolling
546     */
547    public int getScaledTouchSlop() {
548        return mTouchSlop;
549    }
550
551    /**
552     * @return Distance in pixels the first touch can wander before we do not consider this a
553     * potential double tap event
554     * @hide
555     */
556    public int getScaledDoubleTapTouchSlop() {
557        return mDoubleTapTouchSlop;
558    }
559
560    /**
561     * @return Distance in pixels a touch can wander before we think the user is scrolling a full
562     * page
563     */
564    public int getScaledPagingTouchSlop() {
565        return mPagingTouchSlop;
566    }
567
568    /**
569     * @return Distance in dips between the first touch and second touch to still be
570     *         considered a double tap
571     * @deprecated Use {@link #getScaledDoubleTapSlop()} instead.
572     * @hide The only client of this should be GestureDetector, which needs this
573     *       for clients that still use its deprecated constructor.
574     */
575    @Deprecated
576    public static int getDoubleTapSlop() {
577        return DOUBLE_TAP_SLOP;
578    }
579
580    /**
581     * @return Distance in pixels between the first touch and second touch to still be
582     *         considered a double tap
583     */
584    public int getScaledDoubleTapSlop() {
585        return mDoubleTapSlop;
586    }
587
588    /**
589     * Interval for dispatching a recurring accessibility event in milliseconds.
590     * This interval guarantees that a recurring event will be send at most once
591     * during the {@link #getSendRecurringAccessibilityEventsInterval()} time frame.
592     *
593     * @return The delay in milliseconds.
594     *
595     * @hide
596     */
597    public static long getSendRecurringAccessibilityEventsInterval() {
598        return SEND_RECURRING_ACCESSIBILITY_EVENTS_INTERVAL_MILLIS;
599    }
600
601    /**
602     * @return Distance in dips a touch must be outside the bounds of a window for it
603     * to be counted as outside the window for purposes of dismissing that
604     * window.
605     *
606     * @deprecated Use {@link #getScaledWindowTouchSlop()} instead.
607     */
608    @Deprecated
609    public static int getWindowTouchSlop() {
610        return WINDOW_TOUCH_SLOP;
611    }
612
613    /**
614     * @return Distance in pixels a touch must be outside the bounds of a window for it
615     * to be counted as outside the window for purposes of dismissing that window.
616     */
617    public int getScaledWindowTouchSlop() {
618        return mWindowTouchSlop;
619    }
620
621    /**
622     * @return Minimum velocity to initiate a fling, as measured in dips per second.
623     *
624     * @deprecated Use {@link #getScaledMinimumFlingVelocity()} instead.
625     */
626    @Deprecated
627    public static int getMinimumFlingVelocity() {
628        return MINIMUM_FLING_VELOCITY;
629    }
630
631    /**
632     * @return Minimum velocity to initiate a fling, as measured in pixels per second.
633     */
634    public int getScaledMinimumFlingVelocity() {
635        return mMinimumFlingVelocity;
636    }
637
638    /**
639     * @return Maximum velocity to initiate a fling, as measured in dips per second.
640     *
641     * @deprecated Use {@link #getScaledMaximumFlingVelocity()} instead.
642     */
643    @Deprecated
644    public static int getMaximumFlingVelocity() {
645        return MAXIMUM_FLING_VELOCITY;
646    }
647
648    /**
649     * @return Maximum velocity to initiate a fling, as measured in pixels per second.
650     */
651    public int getScaledMaximumFlingVelocity() {
652        return mMaximumFlingVelocity;
653    }
654
655    /**
656     * The maximum drawing cache size expressed in bytes.
657     *
658     * @return the maximum size of View's drawing cache expressed in bytes
659     *
660     * @deprecated Use {@link #getScaledMaximumDrawingCacheSize()} instead.
661     */
662    @Deprecated
663    public static int getMaximumDrawingCacheSize() {
664        //noinspection deprecation
665        return MAXIMUM_DRAWING_CACHE_SIZE;
666    }
667
668    /**
669     * The maximum drawing cache size expressed in bytes.
670     *
671     * @return the maximum size of View's drawing cache expressed in bytes
672     */
673    public int getScaledMaximumDrawingCacheSize() {
674        return mMaximumDrawingCacheSize;
675    }
676
677    /**
678     * @return The maximum distance a View should overscroll by when showing edge effects (in
679     * pixels).
680     */
681    public int getScaledOverscrollDistance() {
682        return mOverscrollDistance;
683    }
684
685    /**
686     * @return The maximum distance a View should overfling by when showing edge effects (in
687     * pixels).
688     */
689    public int getScaledOverflingDistance() {
690        return mOverflingDistance;
691    }
692
693    /**
694     * The amount of time that the zoom controls should be
695     * displayed on the screen expressed in milliseconds.
696     *
697     * @return the time the zoom controls should be visible expressed
698     * in milliseconds.
699     */
700    public static long getZoomControlsTimeout() {
701        return ZOOM_CONTROLS_TIMEOUT;
702    }
703
704    /**
705     * The amount of time a user needs to press the relevant key to bring up
706     * the global actions dialog.
707     *
708     * @return how long a user needs to press the relevant key to bring up
709     *   the global actions dialog.
710     * @deprecated This timeout should not be used by applications
711     */
712    @Deprecated
713    public static long getGlobalActionKeyTimeout() {
714        return GLOBAL_ACTIONS_KEY_TIMEOUT;
715    }
716
717    /**
718     * The amount of time a user needs to press the relevant key to bring up
719     * the global actions dialog.
720     *
721     * @return how long a user needs to press the relevant key to bring up
722     *   the global actions dialog.
723     * @hide
724     */
725    public long getDeviceGlobalActionKeyTimeout() {
726        return mGlobalActionsKeyTimeout;
727    }
728
729    /**
730     * The amount of friction applied to scrolls and flings.
731     *
732     * @return A scalar dimensionless value representing the coefficient of
733     *         friction.
734     */
735    public static float getScrollFriction() {
736        return SCROLL_FRICTION;
737    }
738
739    /**
740     * @return the default duration in milliseconds for {@link ActionMode#hide(long)}.
741     */
742    public static long getDefaultActionModeHideDuration() {
743        return ACTION_MODE_HIDE_DURATION_DEFAULT;
744    }
745
746    /**
747     * Report if the device has a permanent menu key available to the user.
748     *
749     * <p>As of Android 3.0, devices may not have a permanent menu key available.
750     * Apps should use the action bar to present menu options to users.
751     * However, there are some apps where the action bar is inappropriate
752     * or undesirable. This method may be used to detect if a menu key is present.
753     * If not, applications should provide another on-screen affordance to access
754     * functionality.
755     *
756     * @return true if a permanent menu key is present, false otherwise.
757     */
758    public boolean hasPermanentMenuKey() {
759        return sHasPermanentMenuKey;
760    }
761
762    /**
763     * @hide
764     * @return Whether or not marquee should use fading edges.
765     */
766    public boolean isFadingMarqueeEnabled() {
767        return mFadingMarqueeEnabled;
768    }
769}
770