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