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