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