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