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