Display.java revision d46747a1c64b6ca3282e8841833980ab91829436
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.content.res.CompatibilityInfo; 20import android.graphics.PixelFormat; 21import android.graphics.Point; 22import android.graphics.Rect; 23import android.hardware.display.DisplayManagerGlobal; 24import android.os.Process; 25import android.os.SystemClock; 26import android.util.DisplayMetrics; 27import android.util.Log; 28 29import java.util.Arrays; 30 31/** 32 * Provides information about the size and density of a logical display. 33 * <p> 34 * The display area is described in two different ways. 35 * <ul> 36 * <li>The application display area specifies the part of the display that may contain 37 * an application window, excluding the system decorations. The application display area may 38 * be smaller than the real display area because the system subtracts the space needed 39 * for decor elements such as the status bar. Use the following methods to query the 40 * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li> 41 * <li>The real display area specifies the part of the display that contains content 42 * including the system decorations. Even so, the real display area may be smaller than the 43 * physical size of the display if the window manager is emulating a smaller display 44 * using (adb shell am display-size). Use the following methods to query the 45 * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li> 46 * </ul> 47 * </p><p> 48 * A logical display does not necessarily represent a particular physical display device 49 * such as the built-in screen or an external monitor. The contents of a logical 50 * display may be presented on one or more physical displays according to the devices 51 * that are currently attached and whether mirroring has been enabled. 52 * </p> 53 */ 54public final class Display { 55 private static final String TAG = "Display"; 56 private static final boolean DEBUG = false; 57 58 private final DisplayManagerGlobal mGlobal; 59 private final int mDisplayId; 60 private final int mLayerStack; 61 private final int mFlags; 62 private final int mType; 63 private final String mAddress; 64 private final int mOwnerUid; 65 private final String mOwnerPackageName; 66 private final DisplayAdjustments mDisplayAdjustments; 67 68 private DisplayInfo mDisplayInfo; // never null 69 private boolean mIsValid; 70 71 // Temporary display metrics structure used for compatibility mode. 72 private final DisplayMetrics mTempMetrics = new DisplayMetrics(); 73 74 // We cache the app width and height properties briefly between calls 75 // to getHeight() and getWidth() to ensure that applications perceive 76 // consistent results when the size changes (most of the time). 77 // Applications should now be using getSize() instead. 78 private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20; 79 private long mLastCachedAppSizeUpdate; 80 private int mCachedAppWidthCompat; 81 private int mCachedAppHeightCompat; 82 83 /** 84 * The default Display id, which is the id of the built-in primary display 85 * assuming there is one. 86 */ 87 public static final int DEFAULT_DISPLAY = 0; 88 89 /** 90 * Display flag: Indicates that the display supports compositing content 91 * that is stored in protected graphics buffers. 92 * <p> 93 * If this flag is set then the display device supports compositing protected buffers. 94 * </p><p> 95 * If this flag is not set then the display device may not support compositing 96 * protected buffers; the user may see a blank region on the screen instead of 97 * the protected content. 98 * </p><p> 99 * Secure (DRM) video decoders may allocate protected graphics buffers to request that 100 * a hardware-protected path be provided between the video decoder and the external 101 * display sink. If a hardware-protected path is not available, then content stored 102 * in protected graphics buffers may not be composited. 103 * </p><p> 104 * An application can use the absence of this flag as a hint that it should not use protected 105 * buffers for this display because the content may not be visible. For example, 106 * if the flag is not set then the application may choose not to show content on this 107 * display, show an informative error message, select an alternate content stream 108 * or adopt a different strategy for decoding content that does not rely on 109 * protected buffers. 110 * </p> 111 * 112 * @see #getFlags 113 */ 114 public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 0; 115 116 /** 117 * Display flag: Indicates that the display has a secure video output and 118 * supports compositing secure surfaces. 119 * <p> 120 * If this flag is set then the display device has a secure video output 121 * and is capable of showing secure surfaces. It may also be capable of 122 * showing {@link #FLAG_SUPPORTS_PROTECTED_BUFFERS protected buffers}. 123 * </p><p> 124 * If this flag is not set then the display device may not have a secure video 125 * output; the user may see a blank region on the screen instead of 126 * the contents of secure surfaces or protected buffers. 127 * </p><p> 128 * Secure surfaces are used to prevent content rendered into those surfaces 129 * by applications from appearing in screenshots or from being viewed 130 * on non-secure displays. Protected buffers are used by secure video decoders 131 * for a similar purpose. 132 * </p><p> 133 * An application creates a window with a secure surface by specifying the 134 * {@link WindowManager.LayoutParams#FLAG_SECURE} window flag. 135 * Likewise, an application creates a {@link SurfaceView} with a secure surface 136 * by calling {@link SurfaceView#setSecure} before attaching the secure view to 137 * its containing window. 138 * </p><p> 139 * An application can use the absence of this flag as a hint that it should not create 140 * secure surfaces or protected buffers on this display because the content may 141 * not be visible. For example, if the flag is not set then the application may 142 * choose not to show content on this display, show an informative error message, 143 * select an alternate content stream or adopt a different strategy for decoding 144 * content that does not rely on secure surfaces or protected buffers. 145 * </p> 146 * 147 * @see #getFlags 148 */ 149 public static final int FLAG_SECURE = 1 << 1; 150 151 /** 152 * Display flag: Indicates that the display is private. Only the application that 153 * owns the display can create windows on it. 154 * 155 * @see #getFlags 156 */ 157 public static final int FLAG_PRIVATE = 1 << 2; 158 159 /** 160 * Display flag: Indicates that the display is a presentation display. 161 * <p> 162 * This flag identifies secondary displays that are suitable for 163 * use as presentation displays such as HDMI or Wireless displays. Applications 164 * may automatically project their content to presentation displays to provide 165 * richer second screen experiences. 166 * </p> 167 * 168 * @see #getFlags 169 */ 170 public static final int FLAG_PRESENTATION = 1 << 3; 171 172 /** 173 * Display flag: Indicates that the contents of the display should not be scaled 174 * to fit the physical screen dimensions. Used for development only to emulate 175 * devices with smaller physicals screens while preserving density. 176 * 177 * @hide 178 */ 179 public static final int FLAG_SCALING_DISABLED = 1 << 30; 180 181 /** 182 * Display type: Unknown display type. 183 * @hide 184 */ 185 public static final int TYPE_UNKNOWN = 0; 186 187 /** 188 * Display type: Built-in display. 189 * @hide 190 */ 191 public static final int TYPE_BUILT_IN = 1; 192 193 /** 194 * Display type: HDMI display. 195 * @hide 196 */ 197 public static final int TYPE_HDMI = 2; 198 199 /** 200 * Display type: WiFi display. 201 * @hide 202 */ 203 public static final int TYPE_WIFI = 3; 204 205 /** 206 * Display type: Overlay display. 207 * @hide 208 */ 209 public static final int TYPE_OVERLAY = 4; 210 211 /** 212 * Display type: Virtual display. 213 * @hide 214 */ 215 public static final int TYPE_VIRTUAL = 5; 216 217 /** 218 * Display state: The display state is unknown. 219 * 220 * @see #getState 221 */ 222 public static final int STATE_UNKNOWN = 0; 223 224 /** 225 * Display state: The display is off. 226 * 227 * @see #getState 228 */ 229 public static final int STATE_OFF = 1; 230 231 /** 232 * Display state: The display is on. 233 * 234 * @see #getState 235 */ 236 public static final int STATE_ON = 2; 237 238 /** 239 * Display state: The display is dozing in a low power state; it is still 240 * on but is optimized for showing system-provided content while the 241 * device is non-interactive. 242 * 243 * @see #getState 244 * @see android.os.PowerManager#isInteractive 245 */ 246 public static final int STATE_DOZE = 3; 247 248 /** 249 * Display state: The display is dozing in a suspended low power state; it is still 250 * on but is optimized for showing static system-provided content while the device 251 * is non-interactive. This mode may be used to conserve even more power by allowing 252 * the hardware to stop applying frame buffer updates from the graphics subsystem or 253 * to take over the display and manage it autonomously to implement low power always-on 254 * display functionality. 255 * 256 * @see #getState 257 * @see android.os.PowerManager#isInteractive 258 */ 259 public static final int STATE_DOZE_SUSPEND = 4; 260 261 /** 262 * Internal method to create a display. 263 * Applications should use {@link android.view.WindowManager#getDefaultDisplay()} 264 * or {@link android.hardware.display.DisplayManager#getDisplay} 265 * to get a display object. 266 * 267 * @hide 268 */ 269 public Display(DisplayManagerGlobal global, 270 int displayId, DisplayInfo displayInfo /*not null*/, 271 DisplayAdjustments daj) { 272 mGlobal = global; 273 mDisplayId = displayId; 274 mDisplayInfo = displayInfo; 275 mDisplayAdjustments = new DisplayAdjustments(daj); 276 mIsValid = true; 277 278 // Cache properties that cannot change as long as the display is valid. 279 mLayerStack = displayInfo.layerStack; 280 mFlags = displayInfo.flags; 281 mType = displayInfo.type; 282 mAddress = displayInfo.address; 283 mOwnerUid = displayInfo.ownerUid; 284 mOwnerPackageName = displayInfo.ownerPackageName; 285 } 286 287 /** 288 * Gets the display id. 289 * <p> 290 * Each logical display has a unique id. 291 * The default display has id {@link #DEFAULT_DISPLAY}. 292 * </p> 293 */ 294 public int getDisplayId() { 295 return mDisplayId; 296 } 297 298 /** 299 * Returns true if this display is still valid, false if the display has been removed. 300 * 301 * If the display is invalid, then the methods of this class will 302 * continue to report the most recently observed display information. 303 * However, it is unwise (and rather fruitless) to continue using a 304 * {@link Display} object after the display's demise. 305 * 306 * It's possible for a display that was previously invalid to become 307 * valid again if a display with the same id is reconnected. 308 * 309 * @return True if the display is still valid. 310 */ 311 public boolean isValid() { 312 synchronized (this) { 313 updateDisplayInfoLocked(); 314 return mIsValid; 315 } 316 } 317 318 /** 319 * Gets a full copy of the display information. 320 * 321 * @param outDisplayInfo The object to receive the copy of the display information. 322 * @return True if the display is still valid. 323 * @hide 324 */ 325 public boolean getDisplayInfo(DisplayInfo outDisplayInfo) { 326 synchronized (this) { 327 updateDisplayInfoLocked(); 328 outDisplayInfo.copyFrom(mDisplayInfo); 329 return mIsValid; 330 } 331 } 332 333 /** 334 * Gets the display's layer stack. 335 * 336 * Each display has its own independent layer stack upon which surfaces 337 * are placed to be managed by surface flinger. 338 * 339 * @return The display's layer stack number. 340 * @hide 341 */ 342 public int getLayerStack() { 343 return mLayerStack; 344 } 345 346 /** 347 * Returns a combination of flags that describe the capabilities of the display. 348 * 349 * @return The display flags. 350 * 351 * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS 352 * @see #FLAG_SECURE 353 * @see #FLAG_PRIVATE 354 */ 355 public int getFlags() { 356 return mFlags; 357 } 358 359 /** 360 * Gets the display type. 361 * 362 * @return The display type. 363 * 364 * @see #TYPE_UNKNOWN 365 * @see #TYPE_BUILT_IN 366 * @see #TYPE_HDMI 367 * @see #TYPE_WIFI 368 * @see #TYPE_OVERLAY 369 * @see #TYPE_VIRTUAL 370 * @hide 371 */ 372 public int getType() { 373 return mType; 374 } 375 376 /** 377 * Gets the display address, or null if none. 378 * Interpretation varies by display type. 379 * 380 * @return The display address. 381 * @hide 382 */ 383 public String getAddress() { 384 return mAddress; 385 } 386 387 /** 388 * Gets the UID of the application that owns this display, or zero if it is 389 * owned by the system. 390 * <p> 391 * If the display is private, then only the owner can use it. 392 * </p> 393 * 394 * @hide 395 */ 396 public int getOwnerUid() { 397 return mOwnerUid; 398 } 399 400 /** 401 * Gets the package name of the application that owns this display, or null if it is 402 * owned by the system. 403 * <p> 404 * If the display is private, then only the owner can use it. 405 * </p> 406 * 407 * @hide 408 */ 409 public String getOwnerPackageName() { 410 return mOwnerPackageName; 411 } 412 413 /** 414 * Gets the compatibility info used by this display instance. 415 * 416 * @return The display adjustments holder, or null if none is required. 417 * @hide 418 */ 419 public DisplayAdjustments getDisplayAdjustments() { 420 return mDisplayAdjustments; 421 } 422 423 /** 424 * Gets the name of the display. 425 * <p> 426 * Note that some displays may be renamed by the user. 427 * </p> 428 * 429 * @return The display's name. 430 */ 431 public String getName() { 432 synchronized (this) { 433 updateDisplayInfoLocked(); 434 return mDisplayInfo.name; 435 } 436 } 437 438 /** 439 * Gets the size of the display, in pixels. 440 * <p> 441 * Note that this value should <em>not</em> be used for computing layouts, 442 * since a device will typically have screen decoration (such as a status bar) 443 * along the edges of the display that reduce the amount of application 444 * space available from the size returned here. Layouts should instead use 445 * the window size. 446 * </p><p> 447 * The size is adjusted based on the current rotation of the display. 448 * </p><p> 449 * The size returned by this method does not necessarily represent the 450 * actual raw size (native resolution) of the display. The returned size may 451 * be adjusted to exclude certain system decoration elements that are always visible. 452 * It may also be scaled to provide compatibility with older applications that 453 * were originally designed for smaller displays. 454 * </p> 455 * 456 * @param outSize A {@link Point} object to receive the size information. 457 */ 458 public void getSize(Point outSize) { 459 synchronized (this) { 460 updateDisplayInfoLocked(); 461 mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments); 462 outSize.x = mTempMetrics.widthPixels; 463 outSize.y = mTempMetrics.heightPixels; 464 } 465 } 466 467 /** 468 * Gets the size of the display as a rectangle, in pixels. 469 * 470 * @param outSize A {@link Rect} object to receive the size information. 471 * @see #getSize(Point) 472 */ 473 public void getRectSize(Rect outSize) { 474 synchronized (this) { 475 updateDisplayInfoLocked(); 476 mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments); 477 outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels); 478 } 479 } 480 481 /** 482 * Return the range of display sizes an application can expect to encounter 483 * under normal operation, as long as there is no physical change in screen 484 * size. This is basically the sizes you will see as the orientation 485 * changes, taking into account whatever screen decoration there is in 486 * each rotation. For example, the status bar is always at the top of the 487 * screen, so it will reduce the height both in landscape and portrait, and 488 * the smallest height returned here will be the smaller of the two. 489 * 490 * This is intended for applications to get an idea of the range of sizes 491 * they will encounter while going through device rotations, to provide a 492 * stable UI through rotation. The sizes here take into account all standard 493 * system decorations that reduce the size actually available to the 494 * application: the status bar, navigation bar, system bar, etc. It does 495 * <em>not</em> take into account more transient elements like an IME 496 * soft keyboard. 497 * 498 * @param outSmallestSize Filled in with the smallest width and height 499 * that the application will encounter, in pixels (not dp units). The x 500 * (width) dimension here directly corresponds to 501 * {@link android.content.res.Configuration#smallestScreenWidthDp 502 * Configuration.smallestScreenWidthDp}, except the value here is in raw 503 * screen pixels rather than dp units. Your application may of course 504 * still get smaller space yet if, for example, a soft keyboard is 505 * being displayed. 506 * @param outLargestSize Filled in with the largest width and height 507 * that the application will encounter, in pixels (not dp units). Your 508 * application may of course still get larger space than this if, 509 * for example, screen decorations like the status bar are being hidden. 510 */ 511 public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) { 512 synchronized (this) { 513 updateDisplayInfoLocked(); 514 outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth; 515 outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight; 516 outLargestSize.x = mDisplayInfo.largestNominalAppWidth; 517 outLargestSize.y = mDisplayInfo.largestNominalAppHeight; 518 } 519 } 520 521 /** 522 * Return the maximum screen size dimension that will happen. This is 523 * mostly for wallpapers. 524 * @hide 525 */ 526 public int getMaximumSizeDimension() { 527 synchronized (this) { 528 updateDisplayInfoLocked(); 529 return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); 530 } 531 } 532 533 /** 534 * @deprecated Use {@link #getSize(Point)} instead. 535 */ 536 @Deprecated 537 public int getWidth() { 538 synchronized (this) { 539 updateCachedAppSizeIfNeededLocked(); 540 return mCachedAppWidthCompat; 541 } 542 } 543 544 /** 545 * @deprecated Use {@link #getSize(Point)} instead. 546 */ 547 @Deprecated 548 public int getHeight() { 549 synchronized (this) { 550 updateCachedAppSizeIfNeededLocked(); 551 return mCachedAppHeightCompat; 552 } 553 } 554 555 /** 556 * @hide 557 * Return a rectangle defining the insets of the overscan region of the display. 558 * Each field of the rectangle is the number of pixels the overscan area extends 559 * into the display on that side. 560 */ 561 public void getOverscanInsets(Rect outRect) { 562 synchronized (this) { 563 updateDisplayInfoLocked(); 564 outRect.set(mDisplayInfo.overscanLeft, mDisplayInfo.overscanTop, 565 mDisplayInfo.overscanRight, mDisplayInfo.overscanBottom); 566 } 567 } 568 569 /** 570 * Returns the rotation of the screen from its "natural" orientation. 571 * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0} 572 * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90}, 573 * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or 574 * {@link Surface#ROTATION_270 Surface.ROTATION_270}. For 575 * example, if a device has a naturally tall screen, and the user has 576 * turned it on its side to go into a landscape orientation, the value 577 * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90} 578 * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on 579 * the direction it was turned. The angle is the rotation of the drawn 580 * graphics on the screen, which is the opposite direction of the physical 581 * rotation of the device. For example, if the device is rotated 90 582 * degrees counter-clockwise, to compensate rendering will be rotated by 583 * 90 degrees clockwise and thus the returned value here will be 584 * {@link Surface#ROTATION_90 Surface.ROTATION_90}. 585 */ 586 @Surface.Rotation 587 public int getRotation() { 588 synchronized (this) { 589 updateDisplayInfoLocked(); 590 return mDisplayInfo.rotation; 591 } 592 } 593 594 /** 595 * @deprecated use {@link #getRotation} 596 * @return orientation of this display. 597 */ 598 @Deprecated 599 @Surface.Rotation 600 public int getOrientation() { 601 return getRotation(); 602 } 603 604 /** 605 * Gets the pixel format of the display. 606 * @return One of the constants defined in {@link android.graphics.PixelFormat}. 607 * 608 * @deprecated This method is no longer supported. 609 * The result is always {@link PixelFormat#RGBA_8888}. 610 */ 611 @Deprecated 612 public int getPixelFormat() { 613 return PixelFormat.RGBA_8888; 614 } 615 616 /** 617 * Gets the refresh rate of this display in frames per second. 618 */ 619 public float getRefreshRate() { 620 synchronized (this) { 621 updateDisplayInfoLocked(); 622 return mDisplayInfo.refreshRate; 623 } 624 } 625 626 /** 627 * Get the supported refresh rates of this display in frames per second. 628 */ 629 public float[] getSupportedRefreshRates() { 630 synchronized (this) { 631 updateDisplayInfoLocked(); 632 final float[] refreshRates = mDisplayInfo.supportedRefreshRates; 633 return Arrays.copyOf(refreshRates, refreshRates.length); 634 } 635 } 636 637 /** 638 * Gets the app VSYNC offset, in nanoseconds. This is a positive value indicating 639 * the phase offset of the VSYNC events provided by Choreographer relative to the 640 * display refresh. For example, if Choreographer reports that the refresh occurred 641 * at time N, it actually occurred at (N - appVsyncOffset). 642 * <p> 643 * Apps generally do not need to be aware of this. It's only useful for fine-grained 644 * A/V synchronization. 645 */ 646 public long getAppVsyncOffsetNanos() { 647 synchronized (this) { 648 updateDisplayInfoLocked(); 649 return mDisplayInfo.appVsyncOffsetNanos; 650 } 651 } 652 653 /** 654 * This is how far in advance a buffer must be queued for presentation at 655 * a given time. If you want a buffer to appear on the screen at 656 * time N, you must submit the buffer before (N - presentationDeadline). 657 * <p> 658 * The desired presentation time for GLES rendering may be set with 659 * {@link android.opengl.EGLExt#eglPresentationTimeANDROID}. For video decoding, use 660 * {@link android.media.MediaCodec#releaseOutputBuffer(int, long)}. Times are 661 * expressed in nanoseconds, using the system monotonic clock 662 * ({@link System#nanoTime}). 663 */ 664 public long getPresentationDeadlineNanos() { 665 synchronized (this) { 666 updateDisplayInfoLocked(); 667 return mDisplayInfo.presentationDeadlineNanos; 668 } 669 } 670 671 /** 672 * Gets display metrics that describe the size and density of this display. 673 * <p> 674 * The size is adjusted based on the current rotation of the display. 675 * </p><p> 676 * The size returned by this method does not necessarily represent the 677 * actual raw size (native resolution) of the display. The returned size may 678 * be adjusted to exclude certain system decor elements that are always visible. 679 * It may also be scaled to provide compatibility with older applications that 680 * were originally designed for smaller displays. 681 * </p> 682 * 683 * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. 684 */ 685 public void getMetrics(DisplayMetrics outMetrics) { 686 synchronized (this) { 687 updateDisplayInfoLocked(); 688 mDisplayInfo.getAppMetrics(outMetrics, mDisplayAdjustments); 689 } 690 } 691 692 /** 693 * Gets the real size of the display without subtracting any window decor or 694 * applying any compatibility scale factors. 695 * <p> 696 * The size is adjusted based on the current rotation of the display. 697 * </p><p> 698 * The real size may be smaller than the physical size of the screen when the 699 * window manager is emulating a smaller display (using adb shell am display-size). 700 * </p> 701 * 702 * @param outSize Set to the real size of the display. 703 */ 704 public void getRealSize(Point outSize) { 705 synchronized (this) { 706 updateDisplayInfoLocked(); 707 outSize.x = mDisplayInfo.logicalWidth; 708 outSize.y = mDisplayInfo.logicalHeight; 709 } 710 } 711 712 /** 713 * Gets display metrics based on the real size of this display. 714 * <p> 715 * The size is adjusted based on the current rotation of the display. 716 * </p><p> 717 * The real size may be smaller than the physical size of the screen when the 718 * window manager is emulating a smaller display (using adb shell am display-size). 719 * </p> 720 * 721 * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. 722 */ 723 public void getRealMetrics(DisplayMetrics outMetrics) { 724 synchronized (this) { 725 updateDisplayInfoLocked(); 726 mDisplayInfo.getLogicalMetrics(outMetrics, 727 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, 728 mDisplayAdjustments.getConfiguration()); 729 } 730 } 731 732 /** 733 * Gets the state of the display, such as whether it is on or off. 734 * 735 * @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON}, 736 * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, or {@link #STATE_UNKNOWN}. 737 */ 738 public int getState() { 739 synchronized (this) { 740 updateDisplayInfoLocked(); 741 return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN; 742 } 743 } 744 745 /** 746 * Returns true if the specified UID has access to this display. 747 * @hide 748 */ 749 public boolean hasAccess(int uid) { 750 return Display.hasAccess(uid, mFlags, mOwnerUid); 751 } 752 753 /** @hide */ 754 public static boolean hasAccess(int uid, int flags, int ownerUid) { 755 return (flags & Display.FLAG_PRIVATE) == 0 756 || uid == ownerUid 757 || uid == Process.SYSTEM_UID 758 || uid == 0; 759 } 760 761 /** 762 * Returns true if the display is a public presentation display. 763 * @hide 764 */ 765 public boolean isPublicPresentation() { 766 return (mFlags & (Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION)) == 767 Display.FLAG_PRESENTATION; 768 } 769 770 private void updateDisplayInfoLocked() { 771 // Note: The display manager caches display info objects on our behalf. 772 DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId); 773 if (newInfo == null) { 774 // Preserve the old mDisplayInfo after the display is removed. 775 if (mIsValid) { 776 mIsValid = false; 777 if (DEBUG) { 778 Log.d(TAG, "Logical display " + mDisplayId + " was removed."); 779 } 780 } 781 } else { 782 // Use the new display info. (It might be the same object if nothing changed.) 783 mDisplayInfo = newInfo; 784 if (!mIsValid) { 785 mIsValid = true; 786 if (DEBUG) { 787 Log.d(TAG, "Logical display " + mDisplayId + " was recreated."); 788 } 789 } 790 } 791 } 792 793 private void updateCachedAppSizeIfNeededLocked() { 794 long now = SystemClock.uptimeMillis(); 795 if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) { 796 updateDisplayInfoLocked(); 797 mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments); 798 mCachedAppWidthCompat = mTempMetrics.widthPixels; 799 mCachedAppHeightCompat = mTempMetrics.heightPixels; 800 mLastCachedAppSizeUpdate = now; 801 } 802 } 803 804 // For debugging purposes 805 @Override 806 public String toString() { 807 synchronized (this) { 808 updateDisplayInfoLocked(); 809 mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments); 810 return "Display id " + mDisplayId + ": " + mDisplayInfo 811 + ", " + mTempMetrics + ", isValid=" + mIsValid; 812 } 813 } 814 815 /** 816 * @hide 817 */ 818 public static String typeToString(int type) { 819 switch (type) { 820 case TYPE_UNKNOWN: 821 return "UNKNOWN"; 822 case TYPE_BUILT_IN: 823 return "BUILT_IN"; 824 case TYPE_HDMI: 825 return "HDMI"; 826 case TYPE_WIFI: 827 return "WIFI"; 828 case TYPE_OVERLAY: 829 return "OVERLAY"; 830 case TYPE_VIRTUAL: 831 return "VIRTUAL"; 832 default: 833 return Integer.toString(type); 834 } 835 } 836 837 /** 838 * @hide 839 */ 840 public static String stateToString(int state) { 841 switch (state) { 842 case STATE_UNKNOWN: 843 return "UNKNOWN"; 844 case STATE_OFF: 845 return "OFF"; 846 case STATE_ON: 847 return "ON"; 848 case STATE_DOZE: 849 return "DOZE"; 850 case STATE_DOZE_SUSPEND: 851 return "DOZE_SUSPEND"; 852 default: 853 return Integer.toString(state); 854 } 855 } 856 857 /** 858 * Returns true if display updates may be suspended while in the specified 859 * display power state. 860 * @hide 861 */ 862 public static boolean isSuspendedState(int state) { 863 return state == STATE_OFF || state == STATE_DOZE_SUSPEND; 864 } 865} 866