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