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.annotation.IntDef; 20import android.annotation.RequiresPermission; 21import android.content.Context; 22import android.content.res.CompatibilityInfo; 23import android.content.res.Resources; 24import android.graphics.PixelFormat; 25import android.graphics.Point; 26import android.graphics.Rect; 27import android.hardware.display.DisplayManagerGlobal; 28import android.os.Parcel; 29import android.os.Parcelable; 30import android.os.Process; 31import android.os.SystemClock; 32import android.util.DisplayMetrics; 33import android.util.Log; 34 35import java.lang.annotation.Retention; 36import java.lang.annotation.RetentionPolicy; 37import java.util.Arrays; 38 39import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_TRANSFORM; 40 41/** 42 * Provides information about the size and density of a logical display. 43 * <p> 44 * The display area is described in two different ways. 45 * <ul> 46 * <li>The application display area specifies the part of the display that may contain 47 * an application window, excluding the system decorations. The application display area may 48 * be smaller than the real display area because the system subtracts the space needed 49 * for decor elements such as the status bar. Use the following methods to query the 50 * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li> 51 * <li>The real display area specifies the part of the display that contains content 52 * including the system decorations. Even so, the real display area may be smaller than the 53 * physical size of the display if the window manager is emulating a smaller display 54 * using (adb shell am display-size). Use the following methods to query the 55 * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li> 56 * </ul> 57 * </p><p> 58 * A logical display does not necessarily represent a particular physical display device 59 * such as the built-in screen or an external monitor. The contents of a logical 60 * display may be presented on one or more physical displays according to the devices 61 * that are currently attached and whether mirroring has been enabled. 62 * </p> 63 */ 64public final class Display { 65 private static final String TAG = "Display"; 66 private static final boolean DEBUG = false; 67 68 private final DisplayManagerGlobal mGlobal; 69 private final int mDisplayId; 70 private final int mLayerStack; 71 private final int mFlags; 72 private final int mType; 73 private final String mAddress; 74 private final int mOwnerUid; 75 private final String mOwnerPackageName; 76 private final DisplayAdjustments mDisplayAdjustments; 77 78 private DisplayInfo mDisplayInfo; // never null 79 private boolean mIsValid; 80 81 // Temporary display metrics structure used for compatibility mode. 82 private final DisplayMetrics mTempMetrics = new DisplayMetrics(); 83 84 // We cache the app width and height properties briefly between calls 85 // to getHeight() and getWidth() to ensure that applications perceive 86 // consistent results when the size changes (most of the time). 87 // Applications should now be using getSize() instead. 88 private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20; 89 private long mLastCachedAppSizeUpdate; 90 private int mCachedAppWidthCompat; 91 private int mCachedAppHeightCompat; 92 93 /** 94 * The default Display id, which is the id of the built-in primary display 95 * assuming there is one. 96 */ 97 public static final int DEFAULT_DISPLAY = 0; 98 99 /** 100 * Invalid display id. 101 */ 102 public static final int INVALID_DISPLAY = -1; 103 104 /** 105 * Display flag: Indicates that the display supports compositing content 106 * that is stored in protected graphics buffers. 107 * <p> 108 * If this flag is set then the display device supports compositing protected buffers. 109 * </p><p> 110 * If this flag is not set then the display device may not support compositing 111 * protected buffers; the user may see a blank region on the screen instead of 112 * the protected content. 113 * </p><p> 114 * Secure (DRM) video decoders may allocate protected graphics buffers to request that 115 * a hardware-protected path be provided between the video decoder and the external 116 * display sink. If a hardware-protected path is not available, then content stored 117 * in protected graphics buffers may not be composited. 118 * </p><p> 119 * An application can use the absence of this flag as a hint that it should not use protected 120 * buffers for this display because the content may not be visible. For example, 121 * if the flag is not set then the application may choose not to show content on this 122 * display, show an informative error message, select an alternate content stream 123 * or adopt a different strategy for decoding content that does not rely on 124 * protected buffers. 125 * </p> 126 * 127 * @see #getFlags 128 */ 129 public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 0; 130 131 /** 132 * Display flag: Indicates that the display has a secure video output and 133 * supports compositing secure surfaces. 134 * <p> 135 * If this flag is set then the display device has a secure video output 136 * and is capable of showing secure surfaces. It may also be capable of 137 * showing {@link #FLAG_SUPPORTS_PROTECTED_BUFFERS protected buffers}. 138 * </p><p> 139 * If this flag is not set then the display device may not have a secure video 140 * output; the user may see a blank region on the screen instead of 141 * the contents of secure surfaces or protected buffers. 142 * </p><p> 143 * Secure surfaces are used to prevent content rendered into those surfaces 144 * by applications from appearing in screenshots or from being viewed 145 * on non-secure displays. Protected buffers are used by secure video decoders 146 * for a similar purpose. 147 * </p><p> 148 * An application creates a window with a secure surface by specifying the 149 * {@link WindowManager.LayoutParams#FLAG_SECURE} window flag. 150 * Likewise, an application creates a {@link SurfaceView} with a secure surface 151 * by calling {@link SurfaceView#setSecure} before attaching the secure view to 152 * its containing window. 153 * </p><p> 154 * An application can use the absence of this flag as a hint that it should not create 155 * secure surfaces or protected buffers on this display because the content may 156 * not be visible. For example, if the flag is not set then the application may 157 * choose not to show content on this display, show an informative error message, 158 * select an alternate content stream or adopt a different strategy for decoding 159 * content that does not rely on secure surfaces or protected buffers. 160 * </p> 161 * 162 * @see #getFlags 163 */ 164 public static final int FLAG_SECURE = 1 << 1; 165 166 /** 167 * Display flag: Indicates that the display is private. Only the application that 168 * owns the display can create windows on it. 169 * 170 * @see #getFlags 171 */ 172 public static final int FLAG_PRIVATE = 1 << 2; 173 174 /** 175 * Display flag: Indicates that the display is a presentation display. 176 * <p> 177 * This flag identifies secondary displays that are suitable for 178 * use as presentation displays such as HDMI or Wireless displays. Applications 179 * may automatically project their content to presentation displays to provide 180 * richer second screen experiences. 181 * </p> 182 * 183 * @see #getFlags 184 */ 185 public static final int FLAG_PRESENTATION = 1 << 3; 186 187 /** 188 * Display flag: Indicates that the display has a round shape. 189 * <p> 190 * This flag identifies displays that are circular, elliptical or otherwise 191 * do not permit the user to see all the way to the logical corners of the display. 192 * </p> 193 * 194 * @see #getFlags 195 */ 196 public static final int FLAG_ROUND = 1 << 4; 197 198 /** 199 * Display flag: Indicates that the contents of the display should not be scaled 200 * to fit the physical screen dimensions. Used for development only to emulate 201 * devices with smaller physicals screens while preserving density. 202 * 203 * @hide 204 */ 205 public static final int FLAG_SCALING_DISABLED = 1 << 30; 206 207 /** 208 * Display type: Unknown display type. 209 * @hide 210 */ 211 public static final int TYPE_UNKNOWN = 0; 212 213 /** 214 * Display type: Built-in display. 215 * @hide 216 */ 217 public static final int TYPE_BUILT_IN = 1; 218 219 /** 220 * Display type: HDMI display. 221 * @hide 222 */ 223 public static final int TYPE_HDMI = 2; 224 225 /** 226 * Display type: WiFi display. 227 * @hide 228 */ 229 public static final int TYPE_WIFI = 3; 230 231 /** 232 * Display type: Overlay display. 233 * @hide 234 */ 235 public static final int TYPE_OVERLAY = 4; 236 237 /** 238 * Display type: Virtual display. 239 * @hide 240 */ 241 public static final int TYPE_VIRTUAL = 5; 242 243 /** 244 * Display state: The display state is unknown. 245 * 246 * @see #getState 247 */ 248 public static final int STATE_UNKNOWN = 0; 249 250 /** 251 * Display state: The display is off. 252 * 253 * @see #getState 254 */ 255 public static final int STATE_OFF = 1; 256 257 /** 258 * Display state: The display is on. 259 * 260 * @see #getState 261 */ 262 public static final int STATE_ON = 2; 263 264 /** 265 * Display state: The display is dozing in a low power state; it is still 266 * on but is optimized for showing system-provided content while the 267 * device is non-interactive. 268 * 269 * @see #getState 270 * @see android.os.PowerManager#isInteractive 271 */ 272 public static final int STATE_DOZE = 3; 273 274 /** 275 * Display state: The display is dozing in a suspended low power state; it is still 276 * on but is optimized for showing static system-provided content while the device 277 * is non-interactive. This mode may be used to conserve even more power by allowing 278 * the hardware to stop applying frame buffer updates from the graphics subsystem or 279 * to take over the display and manage it autonomously to implement low power always-on 280 * display functionality. 281 * 282 * @see #getState 283 * @see android.os.PowerManager#isInteractive 284 */ 285 public static final int STATE_DOZE_SUSPEND = 4; 286 287 /** 288 * Internal method to create a display. 289 * Applications should use {@link android.view.WindowManager#getDefaultDisplay()} 290 * or {@link android.hardware.display.DisplayManager#getDisplay} 291 * to get a display object. 292 * 293 * @hide 294 */ 295 public Display(DisplayManagerGlobal global, 296 int displayId, DisplayInfo displayInfo /*not null*/, 297 DisplayAdjustments daj) { 298 mGlobal = global; 299 mDisplayId = displayId; 300 mDisplayInfo = displayInfo; 301 mDisplayAdjustments = new DisplayAdjustments(daj); 302 mIsValid = true; 303 304 // Cache properties that cannot change as long as the display is valid. 305 mLayerStack = displayInfo.layerStack; 306 mFlags = displayInfo.flags; 307 mType = displayInfo.type; 308 mAddress = displayInfo.address; 309 mOwnerUid = displayInfo.ownerUid; 310 mOwnerPackageName = displayInfo.ownerPackageName; 311 } 312 313 /** 314 * Gets the display id. 315 * <p> 316 * Each logical display has a unique id. 317 * The default display has id {@link #DEFAULT_DISPLAY}. 318 * </p> 319 */ 320 public int getDisplayId() { 321 return mDisplayId; 322 } 323 324 /** 325 * Returns true if this display is still valid, false if the display has been removed. 326 * 327 * If the display is invalid, then the methods of this class will 328 * continue to report the most recently observed display information. 329 * However, it is unwise (and rather fruitless) to continue using a 330 * {@link Display} object after the display's demise. 331 * 332 * It's possible for a display that was previously invalid to become 333 * valid again if a display with the same id is reconnected. 334 * 335 * @return True if the display is still valid. 336 */ 337 public boolean isValid() { 338 synchronized (this) { 339 updateDisplayInfoLocked(); 340 return mIsValid; 341 } 342 } 343 344 /** 345 * Gets a full copy of the display information. 346 * 347 * @param outDisplayInfo The object to receive the copy of the display information. 348 * @return True if the display is still valid. 349 * @hide 350 */ 351 public boolean getDisplayInfo(DisplayInfo outDisplayInfo) { 352 synchronized (this) { 353 updateDisplayInfoLocked(); 354 outDisplayInfo.copyFrom(mDisplayInfo); 355 return mIsValid; 356 } 357 } 358 359 /** 360 * Gets the display's layer stack. 361 * 362 * Each display has its own independent layer stack upon which surfaces 363 * are placed to be managed by surface flinger. 364 * 365 * @return The display's layer stack number. 366 * @hide 367 */ 368 public int getLayerStack() { 369 return mLayerStack; 370 } 371 372 /** 373 * Returns a combination of flags that describe the capabilities of the display. 374 * 375 * @return The display flags. 376 * 377 * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS 378 * @see #FLAG_SECURE 379 * @see #FLAG_PRIVATE 380 */ 381 public int getFlags() { 382 return mFlags; 383 } 384 385 /** 386 * Gets the display type. 387 * 388 * @return The display type. 389 * 390 * @see #TYPE_UNKNOWN 391 * @see #TYPE_BUILT_IN 392 * @see #TYPE_HDMI 393 * @see #TYPE_WIFI 394 * @see #TYPE_OVERLAY 395 * @see #TYPE_VIRTUAL 396 * @hide 397 */ 398 public int getType() { 399 return mType; 400 } 401 402 /** 403 * Gets the display address, or null if none. 404 * Interpretation varies by display type. 405 * 406 * @return The display address. 407 * @hide 408 */ 409 public String getAddress() { 410 return mAddress; 411 } 412 413 /** 414 * Gets the UID of the application that owns this display, or zero if it is 415 * owned by the system. 416 * <p> 417 * If the display is private, then only the owner can use it. 418 * </p> 419 * 420 * @hide 421 */ 422 public int getOwnerUid() { 423 return mOwnerUid; 424 } 425 426 /** 427 * Gets the package name of the application that owns this display, or null if it is 428 * owned by the system. 429 * <p> 430 * If the display is private, then only the owner can use it. 431 * </p> 432 * 433 * @hide 434 */ 435 public String getOwnerPackageName() { 436 return mOwnerPackageName; 437 } 438 439 /** 440 * Gets the compatibility info used by this display instance. 441 * 442 * @return The display adjustments holder, or null if none is required. 443 * @hide 444 */ 445 public DisplayAdjustments getDisplayAdjustments() { 446 return mDisplayAdjustments; 447 } 448 449 /** 450 * Gets the name of the display. 451 * <p> 452 * Note that some displays may be renamed by the user. 453 * </p> 454 * 455 * @return The display's name. 456 */ 457 public String getName() { 458 synchronized (this) { 459 updateDisplayInfoLocked(); 460 return mDisplayInfo.name; 461 } 462 } 463 464 /** 465 * Gets the size of the display, in pixels. 466 * <p> 467 * Note that this value should <em>not</em> be used for computing layouts, 468 * since a device will typically have screen decoration (such as a status bar) 469 * along the edges of the display that reduce the amount of application 470 * space available from the size returned here. Layouts should instead use 471 * the window size. 472 * </p><p> 473 * The size is adjusted based on the current rotation of the display. 474 * </p><p> 475 * The size returned by this method does not necessarily represent the 476 * actual raw size (native resolution) of the display. The returned size may 477 * be adjusted to exclude certain system decoration elements that are always visible. 478 * It may also be scaled to provide compatibility with older applications that 479 * were originally designed for smaller displays. 480 * </p> 481 * 482 * @param outSize A {@link Point} object to receive the size information. 483 */ 484 public void getSize(Point outSize) { 485 synchronized (this) { 486 updateDisplayInfoLocked(); 487 mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments); 488 outSize.x = mTempMetrics.widthPixels; 489 outSize.y = mTempMetrics.heightPixels; 490 } 491 } 492 493 /** 494 * Gets the size of the display as a rectangle, in pixels. 495 * 496 * @param outSize A {@link Rect} object to receive the size information. 497 * @see #getSize(Point) 498 */ 499 public void getRectSize(Rect outSize) { 500 synchronized (this) { 501 updateDisplayInfoLocked(); 502 mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments); 503 outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels); 504 } 505 } 506 507 /** 508 * Return the range of display sizes an application can expect to encounter 509 * under normal operation, as long as there is no physical change in screen 510 * size. This is basically the sizes you will see as the orientation 511 * changes, taking into account whatever screen decoration there is in 512 * each rotation. For example, the status bar is always at the top of the 513 * screen, so it will reduce the height both in landscape and portrait, and 514 * the smallest height returned here will be the smaller of the two. 515 * 516 * This is intended for applications to get an idea of the range of sizes 517 * they will encounter while going through device rotations, to provide a 518 * stable UI through rotation. The sizes here take into account all standard 519 * system decorations that reduce the size actually available to the 520 * application: the status bar, navigation bar, system bar, etc. It does 521 * <em>not</em> take into account more transient elements like an IME 522 * soft keyboard. 523 * 524 * @param outSmallestSize Filled in with the smallest width and height 525 * that the application will encounter, in pixels (not dp units). The x 526 * (width) dimension here directly corresponds to 527 * {@link android.content.res.Configuration#smallestScreenWidthDp 528 * Configuration.smallestScreenWidthDp}, except the value here is in raw 529 * screen pixels rather than dp units. Your application may of course 530 * still get smaller space yet if, for example, a soft keyboard is 531 * being displayed. 532 * @param outLargestSize Filled in with the largest width and height 533 * that the application will encounter, in pixels (not dp units). Your 534 * application may of course still get larger space than this if, 535 * for example, screen decorations like the status bar are being hidden. 536 */ 537 public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) { 538 synchronized (this) { 539 updateDisplayInfoLocked(); 540 outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth; 541 outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight; 542 outLargestSize.x = mDisplayInfo.largestNominalAppWidth; 543 outLargestSize.y = mDisplayInfo.largestNominalAppHeight; 544 } 545 } 546 547 /** 548 * Return the maximum screen size dimension that will happen. This is 549 * mostly for wallpapers. 550 * @hide 551 */ 552 public int getMaximumSizeDimension() { 553 synchronized (this) { 554 updateDisplayInfoLocked(); 555 return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); 556 } 557 } 558 559 /** 560 * @deprecated Use {@link #getSize(Point)} instead. 561 */ 562 @Deprecated 563 public int getWidth() { 564 synchronized (this) { 565 updateCachedAppSizeIfNeededLocked(); 566 return mCachedAppWidthCompat; 567 } 568 } 569 570 /** 571 * @deprecated Use {@link #getSize(Point)} instead. 572 */ 573 @Deprecated 574 public int getHeight() { 575 synchronized (this) { 576 updateCachedAppSizeIfNeededLocked(); 577 return mCachedAppHeightCompat; 578 } 579 } 580 581 /** 582 * @hide 583 * Return a rectangle defining the insets of the overscan region of the display. 584 * Each field of the rectangle is the number of pixels the overscan area extends 585 * into the display on that side. 586 */ 587 public void getOverscanInsets(Rect outRect) { 588 synchronized (this) { 589 updateDisplayInfoLocked(); 590 outRect.set(mDisplayInfo.overscanLeft, mDisplayInfo.overscanTop, 591 mDisplayInfo.overscanRight, mDisplayInfo.overscanBottom); 592 } 593 } 594 595 /** 596 * Returns the rotation of the screen from its "natural" orientation. 597 * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0} 598 * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90}, 599 * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or 600 * {@link Surface#ROTATION_270 Surface.ROTATION_270}. For 601 * example, if a device has a naturally tall screen, and the user has 602 * turned it on its side to go into a landscape orientation, the value 603 * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90} 604 * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on 605 * the direction it was turned. The angle is the rotation of the drawn 606 * graphics on the screen, which is the opposite direction of the physical 607 * rotation of the device. For example, if the device is rotated 90 608 * degrees counter-clockwise, to compensate rendering will be rotated by 609 * 90 degrees clockwise and thus the returned value here will be 610 * {@link Surface#ROTATION_90 Surface.ROTATION_90}. 611 */ 612 @Surface.Rotation 613 public int getRotation() { 614 synchronized (this) { 615 updateDisplayInfoLocked(); 616 return mDisplayInfo.rotation; 617 } 618 } 619 620 /** 621 * @deprecated use {@link #getRotation} 622 * @return orientation of this display. 623 */ 624 @Deprecated 625 @Surface.Rotation 626 public int getOrientation() { 627 return getRotation(); 628 } 629 630 /** 631 * Gets the pixel format of the display. 632 * @return One of the constants defined in {@link android.graphics.PixelFormat}. 633 * 634 * @deprecated This method is no longer supported. 635 * The result is always {@link PixelFormat#RGBA_8888}. 636 */ 637 @Deprecated 638 public int getPixelFormat() { 639 return PixelFormat.RGBA_8888; 640 } 641 642 /** 643 * Gets the refresh rate of this display in frames per second. 644 */ 645 public float getRefreshRate() { 646 synchronized (this) { 647 updateDisplayInfoLocked(); 648 return mDisplayInfo.getMode().getRefreshRate(); 649 } 650 } 651 652 /** 653 * Get the supported refresh rates of this display in frames per second. 654 * <p> 655 * This method only returns refresh rates for the display's default modes. For more options, use 656 * {@link #getSupportedModes()}. 657 * 658 * @deprecated use {@link #getSupportedModes()} instead 659 */ 660 @Deprecated 661 public float[] getSupportedRefreshRates() { 662 synchronized (this) { 663 updateDisplayInfoLocked(); 664 return mDisplayInfo.getDefaultRefreshRates(); 665 } 666 } 667 668 /** 669 * Returns the active mode of the display. 670 */ 671 public Mode getMode() { 672 synchronized (this) { 673 updateDisplayInfoLocked(); 674 return mDisplayInfo.getMode(); 675 } 676 } 677 678 /** 679 * Gets the supported modes of this display. 680 */ 681 public Mode[] getSupportedModes() { 682 synchronized (this) { 683 updateDisplayInfoLocked(); 684 final Display.Mode[] modes = mDisplayInfo.supportedModes; 685 return Arrays.copyOf(modes, modes.length); 686 } 687 } 688 689 /** 690 * Request the display applies a color transform. 691 * @hide 692 */ 693 @RequiresPermission(CONFIGURE_DISPLAY_COLOR_TRANSFORM) 694 public void requestColorTransform(ColorTransform colorTransform) { 695 mGlobal.requestColorTransform(mDisplayId, colorTransform.getId()); 696 } 697 698 /** 699 * Returns the active color transform of this display 700 * @hide 701 */ 702 public ColorTransform getColorTransform() { 703 synchronized (this) { 704 updateDisplayInfoLocked(); 705 return mDisplayInfo.getColorTransform(); 706 } 707 } 708 709 /** 710 * Returns the default color transform of this display 711 * @hide 712 */ 713 public ColorTransform getDefaultColorTransform() { 714 synchronized (this) { 715 updateDisplayInfoLocked(); 716 return mDisplayInfo.getDefaultColorTransform(); 717 } 718 } 719 720 /** 721 * Returns the display's HDR capabilities. 722 */ 723 public HdrCapabilities getHdrCapabilities() { 724 synchronized (this) { 725 updateDisplayInfoLocked(); 726 return mDisplayInfo.hdrCapabilities; 727 } 728 } 729 730 /** 731 * Gets the supported color transforms of this device. 732 * @hide 733 */ 734 public ColorTransform[] getSupportedColorTransforms() { 735 synchronized (this) { 736 updateDisplayInfoLocked(); 737 ColorTransform[] transforms = mDisplayInfo.supportedColorTransforms; 738 return Arrays.copyOf(transforms, transforms.length); 739 } 740 } 741 742 /** 743 * Gets the app VSYNC offset, in nanoseconds. This is a positive value indicating 744 * the phase offset of the VSYNC events provided by Choreographer relative to the 745 * display refresh. For example, if Choreographer reports that the refresh occurred 746 * at time N, it actually occurred at (N - appVsyncOffset). 747 * <p> 748 * Apps generally do not need to be aware of this. It's only useful for fine-grained 749 * A/V synchronization. 750 */ 751 public long getAppVsyncOffsetNanos() { 752 synchronized (this) { 753 updateDisplayInfoLocked(); 754 return mDisplayInfo.appVsyncOffsetNanos; 755 } 756 } 757 758 /** 759 * This is how far in advance a buffer must be queued for presentation at 760 * a given time. If you want a buffer to appear on the screen at 761 * time N, you must submit the buffer before (N - presentationDeadline). 762 * <p> 763 * The desired presentation time for GLES rendering may be set with 764 * {@link android.opengl.EGLExt#eglPresentationTimeANDROID}. For video decoding, use 765 * {@link android.media.MediaCodec#releaseOutputBuffer(int, long)}. Times are 766 * expressed in nanoseconds, using the system monotonic clock 767 * ({@link System#nanoTime}). 768 */ 769 public long getPresentationDeadlineNanos() { 770 synchronized (this) { 771 updateDisplayInfoLocked(); 772 return mDisplayInfo.presentationDeadlineNanos; 773 } 774 } 775 776 /** 777 * Gets display metrics that describe the size and density of this display. 778 * The size returned by this method does not necessarily represent the 779 * actual raw size (native resolution) of the display. 780 * <p> 781 * 1. The returned size may be adjusted to exclude certain system decor elements 782 * that are always visible. 783 * </p><p> 784 * 2. It may be scaled to provide compatibility with older applications that 785 * were originally designed for smaller displays. 786 * </p><p> 787 * 3. It can be different depending on the WindowManager to which the display belongs. 788 * <pre> 789 * - If requested from non-Activity context (e.g. Application context via 790 * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}) 791 * metrics will report real size of the display based on current rotation. 792 * - If requested from activity resulting metrics will correspond to current window metrics. 793 * In this case the size can be smaller than physical size in multi-window mode. 794 * </pre> 795 * </p> 796 * 797 * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. 798 */ 799 public void getMetrics(DisplayMetrics outMetrics) { 800 synchronized (this) { 801 updateDisplayInfoLocked(); 802 mDisplayInfo.getAppMetrics(outMetrics, mDisplayAdjustments); 803 } 804 } 805 806 /** 807 * Gets the real size of the display without subtracting any window decor or 808 * applying any compatibility scale factors. 809 * <p> 810 * The size is adjusted based on the current rotation of the display. 811 * </p><p> 812 * The real size may be smaller than the physical size of the screen when the 813 * window manager is emulating a smaller display (using adb shell am display-size). 814 * </p> 815 * 816 * @param outSize Set to the real size of the display. 817 */ 818 public void getRealSize(Point outSize) { 819 synchronized (this) { 820 updateDisplayInfoLocked(); 821 outSize.x = mDisplayInfo.logicalWidth; 822 outSize.y = mDisplayInfo.logicalHeight; 823 } 824 } 825 826 /** 827 * Gets display metrics based on the real size of this display. 828 * <p> 829 * The size is adjusted based on the current rotation of the display. 830 * </p><p> 831 * The real size may be smaller than the physical size of the screen when the 832 * window manager is emulating a smaller display (using adb shell wm size). 833 * </p> 834 * 835 * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. 836 */ 837 public void getRealMetrics(DisplayMetrics outMetrics) { 838 synchronized (this) { 839 updateDisplayInfoLocked(); 840 mDisplayInfo.getLogicalMetrics(outMetrics, 841 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 842 } 843 } 844 845 /** 846 * Gets the state of the display, such as whether it is on or off. 847 * 848 * @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON}, 849 * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, or {@link #STATE_UNKNOWN}. 850 */ 851 public int getState() { 852 synchronized (this) { 853 updateDisplayInfoLocked(); 854 return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN; 855 } 856 } 857 858 /** 859 * Returns true if the specified UID has access to this display. 860 * @hide 861 */ 862 public boolean hasAccess(int uid) { 863 return Display.hasAccess(uid, mFlags, mOwnerUid); 864 } 865 866 /** @hide */ 867 public static boolean hasAccess(int uid, int flags, int ownerUid) { 868 return (flags & Display.FLAG_PRIVATE) == 0 869 || uid == ownerUid 870 || uid == Process.SYSTEM_UID 871 || uid == 0; 872 } 873 874 /** 875 * Returns true if the display is a public presentation display. 876 * @hide 877 */ 878 public boolean isPublicPresentation() { 879 return (mFlags & (Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION)) == 880 Display.FLAG_PRESENTATION; 881 } 882 883 private void updateDisplayInfoLocked() { 884 // Note: The display manager caches display info objects on our behalf. 885 DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId); 886 if (newInfo == null) { 887 // Preserve the old mDisplayInfo after the display is removed. 888 if (mIsValid) { 889 mIsValid = false; 890 if (DEBUG) { 891 Log.d(TAG, "Logical display " + mDisplayId + " was removed."); 892 } 893 } 894 } else { 895 // Use the new display info. (It might be the same object if nothing changed.) 896 mDisplayInfo = newInfo; 897 if (!mIsValid) { 898 mIsValid = true; 899 if (DEBUG) { 900 Log.d(TAG, "Logical display " + mDisplayId + " was recreated."); 901 } 902 } 903 } 904 } 905 906 private void updateCachedAppSizeIfNeededLocked() { 907 long now = SystemClock.uptimeMillis(); 908 if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) { 909 updateDisplayInfoLocked(); 910 mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments); 911 mCachedAppWidthCompat = mTempMetrics.widthPixels; 912 mCachedAppHeightCompat = mTempMetrics.heightPixels; 913 mLastCachedAppSizeUpdate = now; 914 } 915 } 916 917 // For debugging purposes 918 @Override 919 public String toString() { 920 synchronized (this) { 921 updateDisplayInfoLocked(); 922 mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments); 923 return "Display id " + mDisplayId + ": " + mDisplayInfo 924 + ", " + mTempMetrics + ", isValid=" + mIsValid; 925 } 926 } 927 928 /** 929 * @hide 930 */ 931 public static String typeToString(int type) { 932 switch (type) { 933 case TYPE_UNKNOWN: 934 return "UNKNOWN"; 935 case TYPE_BUILT_IN: 936 return "BUILT_IN"; 937 case TYPE_HDMI: 938 return "HDMI"; 939 case TYPE_WIFI: 940 return "WIFI"; 941 case TYPE_OVERLAY: 942 return "OVERLAY"; 943 case TYPE_VIRTUAL: 944 return "VIRTUAL"; 945 default: 946 return Integer.toString(type); 947 } 948 } 949 950 /** 951 * @hide 952 */ 953 public static String stateToString(int state) { 954 switch (state) { 955 case STATE_UNKNOWN: 956 return "UNKNOWN"; 957 case STATE_OFF: 958 return "OFF"; 959 case STATE_ON: 960 return "ON"; 961 case STATE_DOZE: 962 return "DOZE"; 963 case STATE_DOZE_SUSPEND: 964 return "DOZE_SUSPEND"; 965 default: 966 return Integer.toString(state); 967 } 968 } 969 970 /** 971 * Returns true if display updates may be suspended while in the specified 972 * display power state. 973 * @hide 974 */ 975 public static boolean isSuspendedState(int state) { 976 return state == STATE_OFF || state == STATE_DOZE_SUSPEND; 977 } 978 979 /** 980 * A mode supported by a given display. 981 * 982 * @see Display#getSupportedModes() 983 */ 984 public static final class Mode implements Parcelable { 985 /** 986 * @hide 987 */ 988 public static final Mode[] EMPTY_ARRAY = new Mode[0]; 989 990 private final int mModeId; 991 private final int mWidth; 992 private final int mHeight; 993 private final float mRefreshRate; 994 995 /** 996 * @hide 997 */ 998 public Mode(int modeId, int width, int height, float refreshRate) { 999 mModeId = modeId; 1000 mWidth = width; 1001 mHeight = height; 1002 mRefreshRate = refreshRate; 1003 } 1004 1005 /** 1006 * Returns this mode's id. 1007 */ 1008 public int getModeId() { 1009 return mModeId; 1010 } 1011 1012 /** 1013 * Returns the physical width of the display in pixels when configured in this mode's 1014 * resolution. 1015 * <p> 1016 * Note that due to application UI scaling, the number of pixels made available to 1017 * applications when the mode is active (as reported by {@link Display#getWidth()} may 1018 * differ from the mode's actual resolution (as reported by this function). 1019 * <p> 1020 * For example, applications running on a 4K display may have their UI laid out and rendered 1021 * in 1080p and then scaled up. Applications can take advantage of the extra resolution by 1022 * rendering content through a {@link android.view.SurfaceView} using full size buffers. 1023 */ 1024 public int getPhysicalWidth() { 1025 return mWidth; 1026 } 1027 1028 /** 1029 * Returns the physical height of the display in pixels when configured in this mode's 1030 * resolution. 1031 * <p> 1032 * Note that due to application UI scaling, the number of pixels made available to 1033 * applications when the mode is active (as reported by {@link Display#getHeight()} may 1034 * differ from the mode's actual resolution (as reported by this function). 1035 * <p> 1036 * For example, applications running on a 4K display may have their UI laid out and rendered 1037 * in 1080p and then scaled up. Applications can take advantage of the extra resolution by 1038 * rendering content through a {@link android.view.SurfaceView} using full size buffers. 1039 */ 1040 public int getPhysicalHeight() { 1041 return mHeight; 1042 } 1043 1044 /** 1045 * Returns the refresh rate in frames per second. 1046 */ 1047 public float getRefreshRate() { 1048 return mRefreshRate; 1049 } 1050 1051 /** 1052 * Returns {@code true} if this mode matches the given parameters. 1053 * 1054 * @hide 1055 */ 1056 public boolean matches(int width, int height, float refreshRate) { 1057 return mWidth == width && 1058 mHeight == height && 1059 Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate); 1060 } 1061 1062 @Override 1063 public boolean equals(Object other) { 1064 if (this == other) { 1065 return true; 1066 } 1067 if (!(other instanceof Mode)) { 1068 return false; 1069 } 1070 Mode that = (Mode) other; 1071 return mModeId == that.mModeId && matches(that.mWidth, that.mHeight, that.mRefreshRate); 1072 } 1073 1074 @Override 1075 public int hashCode() { 1076 int hash = 1; 1077 hash = hash * 17 + mModeId; 1078 hash = hash * 17 + mWidth; 1079 hash = hash * 17 + mHeight; 1080 hash = hash * 17 + Float.floatToIntBits(mRefreshRate); 1081 return hash; 1082 } 1083 1084 @Override 1085 public String toString() { 1086 return new StringBuilder("{") 1087 .append("id=").append(mModeId) 1088 .append(", width=").append(mWidth) 1089 .append(", height=").append(mHeight) 1090 .append(", fps=").append(mRefreshRate) 1091 .append("}") 1092 .toString(); 1093 } 1094 1095 @Override 1096 public int describeContents() { 1097 return 0; 1098 } 1099 1100 private Mode(Parcel in) { 1101 this(in.readInt(), in.readInt(), in.readInt(), in.readFloat()); 1102 } 1103 1104 @Override 1105 public void writeToParcel(Parcel out, int parcelableFlags) { 1106 out.writeInt(mModeId); 1107 out.writeInt(mWidth); 1108 out.writeInt(mHeight); 1109 out.writeFloat(mRefreshRate); 1110 } 1111 1112 @SuppressWarnings("hiding") 1113 public static final Parcelable.Creator<Mode> CREATOR 1114 = new Parcelable.Creator<Mode>() { 1115 @Override 1116 public Mode createFromParcel(Parcel in) { 1117 return new Mode(in); 1118 } 1119 1120 @Override 1121 public Mode[] newArray(int size) { 1122 return new Mode[size]; 1123 } 1124 }; 1125 } 1126 1127 /** 1128 * Encapsulates the HDR capabilities of a given display. 1129 * For example, what HDR types it supports and details about the desired luminance data. 1130 * <p>You can get an instance for a given {@link Display} object with 1131 * {@link Display#getHdrCapabilities getHdrCapabilities()}. 1132 */ 1133 public static final class HdrCapabilities implements Parcelable { 1134 /** 1135 * Invalid luminance value. 1136 */ 1137 public static final float INVALID_LUMINANCE = -1; 1138 /** 1139 * Dolby Vision high dynamic range (HDR) display. 1140 */ 1141 public static final int HDR_TYPE_DOLBY_VISION = 1; 1142 /** 1143 * HDR10 display. 1144 */ 1145 public static final int HDR_TYPE_HDR10 = 2; 1146 /** 1147 * Hybrid Log-Gamma HDR display. 1148 */ 1149 public static final int HDR_TYPE_HLG = 3; 1150 1151 /** @hide */ 1152 @IntDef({ 1153 HDR_TYPE_DOLBY_VISION, 1154 HDR_TYPE_HDR10, 1155 HDR_TYPE_HLG, 1156 }) 1157 @Retention(RetentionPolicy.SOURCE) 1158 public @interface HdrType {} 1159 1160 private @HdrType int[] mSupportedHdrTypes = new int[0]; 1161 private float mMaxLuminance = INVALID_LUMINANCE; 1162 private float mMaxAverageLuminance = INVALID_LUMINANCE; 1163 private float mMinLuminance = INVALID_LUMINANCE; 1164 1165 /** 1166 * @hide 1167 */ 1168 public HdrCapabilities() { 1169 } 1170 1171 /** 1172 * @hide 1173 */ 1174 public HdrCapabilities(int[] supportedHdrTypes, float maxLuminance, 1175 float maxAverageLuminance, float minLuminance) { 1176 mSupportedHdrTypes = supportedHdrTypes; 1177 mMaxLuminance = maxLuminance; 1178 mMaxAverageLuminance = maxAverageLuminance; 1179 mMinLuminance = minLuminance; 1180 } 1181 1182 /** 1183 * Gets the supported HDR types of this display. 1184 * Returns empty array if HDR is not supported by the display. 1185 */ 1186 public @HdrType int[] getSupportedHdrTypes() { 1187 return mSupportedHdrTypes; 1188 } 1189 /** 1190 * Returns the desired content max luminance data in cd/m2 for this display. 1191 */ 1192 public float getDesiredMaxLuminance() { 1193 return mMaxLuminance; 1194 } 1195 /** 1196 * Returns the desired content max frame-average luminance data in cd/m2 for this display. 1197 */ 1198 public float getDesiredMaxAverageLuminance() { 1199 return mMaxAverageLuminance; 1200 } 1201 /** 1202 * Returns the desired content min luminance data in cd/m2 for this display. 1203 */ 1204 public float getDesiredMinLuminance() { 1205 return mMinLuminance; 1206 } 1207 1208 public static final Creator<HdrCapabilities> CREATOR = new Creator<HdrCapabilities>() { 1209 @Override 1210 public HdrCapabilities createFromParcel(Parcel source) { 1211 return new HdrCapabilities(source); 1212 } 1213 1214 @Override 1215 public HdrCapabilities[] newArray(int size) { 1216 return new HdrCapabilities[size]; 1217 } 1218 }; 1219 1220 private HdrCapabilities(Parcel source) { 1221 readFromParcel(source); 1222 } 1223 1224 /** 1225 * @hide 1226 */ 1227 public void readFromParcel(Parcel source) { 1228 int types = source.readInt(); 1229 mSupportedHdrTypes = new int[types]; 1230 for (int i = 0; i < types; ++i) { 1231 mSupportedHdrTypes[i] = source.readInt(); 1232 } 1233 mMaxLuminance = source.readFloat(); 1234 mMaxAverageLuminance = source.readFloat(); 1235 mMinLuminance = source.readFloat(); 1236 } 1237 1238 @Override 1239 public void writeToParcel(Parcel dest, int flags) { 1240 dest.writeInt(mSupportedHdrTypes.length); 1241 for (int i = 0; i < mSupportedHdrTypes.length; ++i) { 1242 dest.writeInt(mSupportedHdrTypes[i]); 1243 } 1244 dest.writeFloat(mMaxLuminance); 1245 dest.writeFloat(mMaxAverageLuminance); 1246 dest.writeFloat(mMinLuminance); 1247 } 1248 1249 @Override 1250 public int describeContents() { 1251 return 0; 1252 } 1253 } 1254 1255 /** 1256 * A color transform supported by a given display. 1257 * 1258 * @see Display#getSupportedColorTransforms() 1259 * @hide 1260 */ 1261 public static final class ColorTransform implements Parcelable { 1262 public static final ColorTransform[] EMPTY_ARRAY = new ColorTransform[0]; 1263 1264 private final int mId; 1265 private final int mColorTransform; 1266 1267 public ColorTransform(int id, int colorTransform) { 1268 mId = id; 1269 mColorTransform = colorTransform; 1270 } 1271 1272 public int getId() { 1273 return mId; 1274 } 1275 1276 public int getColorTransform() { 1277 return mColorTransform; 1278 } 1279 1280 @Override 1281 public boolean equals(Object other) { 1282 if (this == other) { 1283 return true; 1284 } 1285 if (!(other instanceof ColorTransform)) { 1286 return false; 1287 } 1288 ColorTransform that = (ColorTransform) other; 1289 return mId == that.mId 1290 && mColorTransform == that.mColorTransform; 1291 } 1292 1293 @Override 1294 public int hashCode() { 1295 int hash = 1; 1296 hash = hash * 17 + mId; 1297 hash = hash * 17 + mColorTransform; 1298 return hash; 1299 } 1300 1301 @Override 1302 public String toString() { 1303 return new StringBuilder("{") 1304 .append("id=").append(mId) 1305 .append(", colorTransform=").append(mColorTransform) 1306 .append("}") 1307 .toString(); 1308 } 1309 1310 @Override 1311 public int describeContents() { 1312 return 0; 1313 } 1314 1315 private ColorTransform(Parcel in) { 1316 this(in.readInt(), in.readInt()); 1317 } 1318 1319 @Override 1320 public void writeToParcel(Parcel out, int parcelableFlags) { 1321 out.writeInt(mId); 1322 out.writeInt(mColorTransform); 1323 } 1324 1325 @SuppressWarnings("hiding") 1326 public static final Parcelable.Creator<ColorTransform> CREATOR 1327 = new Parcelable.Creator<ColorTransform>() { 1328 @Override 1329 public ColorTransform createFromParcel(Parcel in) { 1330 return new ColorTransform(in); 1331 } 1332 1333 @Override 1334 public ColorTransform[] newArray(int size) { 1335 return new ColorTransform[size]; 1336 } 1337 }; 1338 } 1339} 1340