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