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 import static android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS; 21 22 import android.Manifest; 23 import android.annotation.IntDef; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.annotation.RequiresPermission; 27 import android.annotation.SuppressLint; 28 import android.annotation.TestApi; 29 import android.app.KeyguardManager; 30 import android.app.WindowConfiguration; 31 import android.compat.annotation.UnsupportedAppUsage; 32 import android.content.res.CompatibilityInfo; 33 import android.content.res.Configuration; 34 import android.content.res.Resources; 35 import android.graphics.ColorSpace; 36 import android.graphics.PixelFormat; 37 import android.graphics.Point; 38 import android.graphics.Rect; 39 import android.hardware.display.BrightnessInfo; 40 import android.hardware.display.DeviceProductInfo; 41 import android.hardware.display.DisplayManager; 42 import android.hardware.display.DisplayManagerGlobal; 43 import android.hardware.graphics.common.DisplayDecorationSupport; 44 import android.os.Build; 45 import android.os.Parcel; 46 import android.os.Parcelable; 47 import android.os.Process; 48 import android.os.SystemClock; 49 import android.util.ArraySet; 50 import android.util.DisplayMetrics; 51 import android.util.Log; 52 53 import java.lang.annotation.Retention; 54 import java.lang.annotation.RetentionPolicy; 55 import java.util.ArrayList; 56 import java.util.Arrays; 57 import java.util.List; 58 59 /** 60 * Provides information about the size and density of a logical display. 61 * <p> 62 * The display area is described in two different ways. 63 * <ul> 64 * <li>The application display area specifies the part of the display that may contain 65 * an application window, excluding the system decorations. The application display area may 66 * be smaller than the real display area because the system subtracts the space needed 67 * for decor elements such as the status bar. Use {@link WindowMetrics#getBounds()} to query the 68 * application window bounds.</li> 69 * <li>The real display area specifies the part of the display that is accessible to an application 70 * in the current system state. The real display area may be smaller than the physical size of the 71 * display in a few scenarios. Use {@link WindowManager#getCurrentWindowMetrics()} to identify the 72 * current size of the activity window. UI-related work, such as choosing UI layouts, should rely 73 * upon {@link WindowMetrics#getBounds()}. See {@link #getRealSize} / {@link #getRealMetrics} for 74 * details.</li> 75 * </ul> 76 * </p><p> 77 * A logical display does not necessarily represent a particular physical display device 78 * such as the internal display or an external display. The contents of a logical 79 * display may be presented on one or more physical displays according to the devices 80 * that are currently attached and whether mirroring has been enabled. 81 * </p> 82 */ 83 public final class Display { 84 private static final String TAG = "Display"; 85 private static final boolean DEBUG = false; 86 87 private final Object mLock = new Object(); 88 private final DisplayManagerGlobal mGlobal; 89 private final int mDisplayId; 90 private final int mFlags; 91 private final int mType; 92 private final int mOwnerUid; 93 private final String mOwnerPackageName; 94 private final Resources mResources; 95 private DisplayAdjustments mDisplayAdjustments; 96 97 @UnsupportedAppUsage 98 private DisplayInfo mDisplayInfo; // never null 99 private boolean mIsValid; 100 101 // Temporary display metrics structure used for compatibility mode. 102 private final DisplayMetrics mTempMetrics = new DisplayMetrics(); 103 104 // We cache the app width and height properties briefly between calls 105 // to getHeight() and getWidth() to ensure that applications perceive 106 // consistent results when the size changes (most of the time). 107 // Applications should now be using WindowMetrics instead. 108 private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20; 109 private long mLastCachedAppSizeUpdate; 110 private int mCachedAppWidthCompat; 111 private int mCachedAppHeightCompat; 112 113 /** 114 * The default Display id, which is the id of the primary display assuming there is one. 115 */ 116 public static final int DEFAULT_DISPLAY = 0; 117 118 /** 119 * Invalid display id. 120 */ 121 public static final int INVALID_DISPLAY = -1; 122 123 /** 124 * Invalid resolution width. 125 * @hide 126 */ 127 public static final int INVALID_DISPLAY_WIDTH = -1; 128 129 /** 130 * Invalid resolution height. 131 * @hide 132 */ 133 public static final int INVALID_DISPLAY_HEIGHT = -1; 134 135 /** 136 * Invalid refresh rate. 137 * @hide 138 */ 139 public static final float INVALID_DISPLAY_REFRESH_RATE = 0.0f; 140 141 /** 142 * The default display group id, which is the display group id of the primary display assuming 143 * there is one. 144 * @hide 145 */ 146 public static final int DEFAULT_DISPLAY_GROUP = 0; 147 148 /** 149 * Invalid display group id. 150 * @hide 151 */ 152 public static final int INVALID_DISPLAY_GROUP = -1; 153 154 /** 155 * Display flag: Indicates that the display supports compositing content 156 * that is stored in protected graphics buffers. 157 * <p> 158 * If this flag is set then the display device supports compositing protected buffers. 159 * </p><p> 160 * If this flag is not set then the display device may not support compositing 161 * protected buffers; the user may see a blank region on the screen instead of 162 * the protected content. 163 * </p><p> 164 * Secure (DRM) video decoders may allocate protected graphics buffers to request that 165 * a hardware-protected path be provided between the video decoder and the external 166 * display sink. If a hardware-protected path is not available, then content stored 167 * in protected graphics buffers may not be composited. 168 * </p><p> 169 * An application can use the absence of this flag as a hint that it should not use protected 170 * buffers for this display because the content may not be visible. For example, 171 * if the flag is not set then the application may choose not to show content on this 172 * display, show an informative error message, select an alternate content stream 173 * or adopt a different strategy for decoding content that does not rely on 174 * protected buffers. 175 * </p> 176 * 177 * @see #getFlags 178 */ 179 public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 0; 180 181 /** 182 * Display flag: Indicates that the display has a secure video output and 183 * supports compositing secure surfaces. 184 * <p> 185 * If this flag is set then the display device has a secure video output 186 * and is capable of showing secure surfaces. It may also be capable of 187 * showing {@link #FLAG_SUPPORTS_PROTECTED_BUFFERS protected buffers}. 188 * </p><p> 189 * If this flag is not set then the display device may not have a secure video 190 * output; the user may see a blank region on the screen instead of 191 * the contents of secure surfaces or protected buffers. 192 * </p><p> 193 * Secure surfaces are used to prevent content rendered into those surfaces 194 * by applications from appearing in screenshots or from being viewed 195 * on non-secure displays. Protected buffers are used by secure video decoders 196 * for a similar purpose. 197 * </p><p> 198 * An application creates a window with a secure surface by specifying the 199 * {@link WindowManager.LayoutParams#FLAG_SECURE} window flag. 200 * Likewise, an application creates a {@link SurfaceView} with a secure surface 201 * by calling {@link SurfaceView#setSecure} before attaching the secure view to 202 * its containing window. 203 * </p><p> 204 * An application can use the absence of this flag as a hint that it should not create 205 * secure surfaces or protected buffers on this display because the content may 206 * not be visible. For example, if the flag is not set then the application may 207 * choose not to show content on this display, show an informative error message, 208 * select an alternate content stream or adopt a different strategy for decoding 209 * content that does not rely on secure surfaces or protected buffers. 210 * </p> 211 * 212 * @see #getFlags 213 */ 214 public static final int FLAG_SECURE = 1 << 1; 215 216 /** 217 * Display flag: Indicates that the display is private. Only the application that 218 * owns the display and apps that are already on the display can create windows on it. 219 * 220 * @see #getFlags 221 */ 222 public static final int FLAG_PRIVATE = 1 << 2; 223 224 /** 225 * Display flag: Indicates that the display is a presentation display. 226 * <p> 227 * This flag identifies secondary displays that are suitable for 228 * use as presentation displays such as external or wireless displays. Applications 229 * may automatically project their content to presentation displays to provide 230 * richer second screen experiences. 231 * </p> 232 * 233 * @see #getFlags 234 */ 235 public static final int FLAG_PRESENTATION = 1 << 3; 236 237 /** 238 * Display flag: Indicates that the display has a round shape. 239 * <p> 240 * This flag identifies displays that are circular, elliptical or otherwise 241 * do not permit the user to see all the way to the logical corners of the display. 242 * </p> 243 * 244 * @see #getFlags 245 */ 246 public static final int FLAG_ROUND = 1 << 4; 247 248 /** 249 * Display flag: Indicates that the display can show its content when non-secure keyguard is 250 * shown. 251 * <p> 252 * This flag identifies secondary displays that will continue showing content if keyguard can be 253 * dismissed without entering credentials. 254 * </p><p> 255 * An example of usage is a virtual display which content is displayed on external hardware 256 * display that is not visible to the system directly. 257 * </p> 258 * 259 * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD 260 * @see KeyguardManager#isDeviceSecure() 261 * @see KeyguardManager#isDeviceLocked() 262 * @see #getFlags 263 * @hide 264 */ 265 // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard 266 public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5; 267 268 /** 269 * Display flag: Indicates that the display should show system decorations. 270 * <p> 271 * This flag identifies secondary displays that should show system decorations, such as status 272 * bar, navigation bar, home activity or IME. 273 * </p> 274 * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p> 275 * 276 * @see #getFlags() 277 * @hide 278 */ 279 // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors 280 public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 6; 281 282 /** 283 * Flag: The display is trusted to show system decorations and receive inputs without users' 284 * touch. 285 * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 286 * 287 * @see #getFlags() 288 * @hide 289 */ 290 @TestApi 291 public static final int FLAG_TRUSTED = 1 << 7; 292 293 /** 294 * Flag: Indicates that the display should not be a part of the default DisplayGroup and 295 * instead be part of a new DisplayGroup. 296 * 297 * @hide 298 * @see #getFlags() 299 */ 300 public static final int FLAG_OWN_DISPLAY_GROUP = 1 << 8; 301 302 /** 303 * Flag: Indicates that the display should always be unlocked. Only valid on virtual displays 304 * that aren't in the default display group. 305 * 306 * @hide 307 * @see #getFlags() 308 */ 309 public static final int FLAG_ALWAYS_UNLOCKED = 1 << 9; 310 311 /** 312 * Flag: Indicates that the display should not play sound effects or perform haptic feedback 313 * when the user touches the screen. 314 * 315 * @hide 316 * @see #getFlags() 317 */ 318 public static final int FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 10; 319 320 /** 321 * Display flag: Indicates that the contents of the display should not be scaled 322 * to fit the physical screen dimensions. Used for development only to emulate 323 * devices with smaller physicals screens while preserving density. 324 * 325 * @hide 326 */ 327 public static final int FLAG_SCALING_DISABLED = 1 << 30; 328 329 /** 330 * Display type: Unknown display type. 331 * @hide 332 */ 333 @UnsupportedAppUsage 334 @TestApi 335 public static final int TYPE_UNKNOWN = 0; 336 337 /** 338 * Display type: Physical display connected through an internal port. 339 * @hide 340 */ 341 @TestApi 342 public static final int TYPE_INTERNAL = 1; 343 344 /** 345 * Display type: Physical display connected through an external port. 346 * @hide 347 */ 348 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 349 @TestApi 350 public static final int TYPE_EXTERNAL = 2; 351 352 /** 353 * Display type: WiFi display. 354 * @hide 355 */ 356 @UnsupportedAppUsage 357 @TestApi 358 public static final int TYPE_WIFI = 3; 359 360 /** 361 * Display type: Overlay display. 362 * @hide 363 */ 364 @TestApi 365 public static final int TYPE_OVERLAY = 4; 366 367 /** 368 * Display type: Virtual display. 369 * @hide 370 */ 371 @UnsupportedAppUsage 372 @TestApi 373 public static final int TYPE_VIRTUAL = 5; 374 375 /** 376 * Display state: The display state is unknown. 377 * 378 * @see #getState 379 */ 380 public static final int STATE_UNKNOWN = ViewProtoEnums.DISPLAY_STATE_UNKNOWN; // 0 381 382 /** 383 * Display state: The display is off. 384 * 385 * @see #getState 386 */ 387 public static final int STATE_OFF = ViewProtoEnums.DISPLAY_STATE_OFF; // 1 388 389 /** 390 * Display state: The display is on. 391 * 392 * @see #getState 393 */ 394 public static final int STATE_ON = ViewProtoEnums.DISPLAY_STATE_ON; // 2 395 396 /** 397 * Display state: The display is dozing in a low power state; it is still 398 * on but is optimized for showing system-provided content while the 399 * device is non-interactive. 400 * 401 * @see #getState 402 * @see android.os.PowerManager#isInteractive 403 */ 404 public static final int STATE_DOZE = ViewProtoEnums.DISPLAY_STATE_DOZE; // 3 405 406 /** 407 * Display state: The display is dozing in a suspended low power state; it is still 408 * on but the CPU is not updating it. This may be used in one of two ways: to show 409 * static system-provided content while the device is non-interactive, or to allow 410 * a "Sidekick" compute resource to update the display. For this reason, the 411 * CPU must not control the display in this mode. 412 * 413 * @see #getState 414 * @see android.os.PowerManager#isInteractive 415 */ 416 public static final int STATE_DOZE_SUSPEND = ViewProtoEnums.DISPLAY_STATE_DOZE_SUSPEND; // 4 417 418 /** 419 * Display state: The display is on and optimized for VR mode. 420 * 421 * @see #getState 422 * @see android.os.PowerManager#isInteractive 423 */ 424 public static final int STATE_VR = ViewProtoEnums.DISPLAY_STATE_VR; // 5 425 426 /** 427 * Display state: The display is in a suspended full power state; it is still 428 * on but the CPU is not updating it. This may be used in one of two ways: to show 429 * static system-provided content while the device is non-interactive, or to allow 430 * a "Sidekick" compute resource to update the display. For this reason, the 431 * CPU must not control the display in this mode. 432 * 433 * @see #getState 434 * @see android.os.PowerManager#isInteractive 435 */ 436 public static final int STATE_ON_SUSPEND = ViewProtoEnums.DISPLAY_STATE_ON_SUSPEND; // 6 437 438 /* The color mode constants defined below must be kept in sync with the ones in 439 * system/core/include/system/graphics-base.h */ 440 441 /** 442 * Display color mode: The current color mode is unknown or invalid. 443 * @hide 444 */ 445 public static final int COLOR_MODE_INVALID = -1; 446 447 /** 448 * Display color mode: The default or native gamut of the display. 449 * @hide 450 */ 451 public static final int COLOR_MODE_DEFAULT = 0; 452 453 /** @hide */ 454 public static final int COLOR_MODE_BT601_625 = 1; 455 /** @hide */ 456 public static final int COLOR_MODE_BT601_625_UNADJUSTED = 2; 457 /** @hide */ 458 public static final int COLOR_MODE_BT601_525 = 3; 459 /** @hide */ 460 public static final int COLOR_MODE_BT601_525_UNADJUSTED = 4; 461 /** @hide */ 462 public static final int COLOR_MODE_BT709 = 5; 463 /** @hide */ 464 public static final int COLOR_MODE_DCI_P3 = 6; 465 /** @hide */ 466 public static final int COLOR_MODE_SRGB = 7; 467 /** @hide */ 468 public static final int COLOR_MODE_ADOBE_RGB = 8; 469 /** @hide */ 470 public static final int COLOR_MODE_DISPLAY_P3 = 9; 471 472 /** @hide **/ 473 @IntDef(prefix = {"COLOR_MODE_"}, value = { 474 COLOR_MODE_INVALID, 475 COLOR_MODE_DEFAULT, 476 COLOR_MODE_BT601_625, 477 COLOR_MODE_BT601_625_UNADJUSTED, 478 COLOR_MODE_BT601_525, 479 COLOR_MODE_BT601_525_UNADJUSTED, 480 COLOR_MODE_BT709, 481 COLOR_MODE_DCI_P3, 482 COLOR_MODE_SRGB, 483 COLOR_MODE_ADOBE_RGB, 484 COLOR_MODE_DISPLAY_P3 485 }) 486 @Retention(RetentionPolicy.SOURCE) 487 public @interface ColorMode {} 488 489 /** 490 * Indicates that when display is removed, all its activities will be moved to the primary 491 * display and the topmost activity should become focused. 492 * 493 * @hide 494 */ 495 // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY 496 public static final int REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY = 0; 497 /** 498 * Indicates that when display is removed, all its stacks and tasks will be removed, all 499 * activities will be destroyed according to the usual lifecycle. 500 * 501 * @hide 502 */ 503 // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY 504 public static final int REMOVE_MODE_DESTROY_CONTENT = 1; 505 506 /** @hide */ 507 public static final int DISPLAY_MODE_ID_FOR_FRAME_RATE_OVERRIDE = 0xFF; 508 509 /** 510 * Internal method to create a display. 511 * The display created with this method will have a static {@link DisplayAdjustments} applied. 512 * Applications should use {@link android.content.Context#getDisplay} with 513 * {@link android.app.Activity} or a context associated with a {@link Display} via 514 * {@link android.content.Context#createDisplayContext(Display)} 515 * to get a display object associated with a {@link android.app.Context}, or 516 * {@link android.hardware.display.DisplayManager#getDisplay} to get a display object by id. 517 * 518 * @see android.content.Context#getDisplay() 519 * @see android.content.Context#createDisplayContext(Display) 520 * @hide 521 */ Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo, DisplayAdjustments daj)522 public Display(DisplayManagerGlobal global, int displayId, /*@NotNull*/ DisplayInfo displayInfo, 523 DisplayAdjustments daj) { 524 this(global, displayId, displayInfo, daj, null /*res*/); 525 } 526 527 /** 528 * Internal method to create a display. 529 * The display created with this method will be adjusted based on the adjustments in the 530 * supplied {@link Resources}. 531 * 532 * @hide 533 */ Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo, Resources res)534 public Display(DisplayManagerGlobal global, int displayId, /*@NotNull*/ DisplayInfo displayInfo, 535 Resources res) { 536 this(global, displayId, displayInfo, null /*daj*/, res); 537 } 538 Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo, DisplayAdjustments daj, Resources res)539 private Display(DisplayManagerGlobal global, int displayId, 540 /*@NotNull*/ DisplayInfo displayInfo, DisplayAdjustments daj, Resources res) { 541 mGlobal = global; 542 mDisplayId = displayId; 543 mDisplayInfo = displayInfo; 544 mResources = res; 545 mDisplayAdjustments = mResources != null 546 ? new DisplayAdjustments(mResources.getConfiguration()) 547 : daj != null ? new DisplayAdjustments(daj) : new DisplayAdjustments(); 548 mIsValid = true; 549 550 // Cache properties that cannot change as long as the display is valid. 551 mFlags = displayInfo.flags; 552 mType = displayInfo.type; 553 mOwnerUid = displayInfo.ownerUid; 554 mOwnerPackageName = displayInfo.ownerPackageName; 555 } 556 557 /** 558 * Gets the display id. 559 * <p> 560 * Each logical display has a unique id. 561 * The default display has id {@link #DEFAULT_DISPLAY}. 562 * </p> 563 */ getDisplayId()564 public int getDisplayId() { 565 return mDisplayId; 566 } 567 568 /** 569 * Gets the display unique id. 570 * <p> 571 * Unique id is different from display id because physical displays have stable unique id across 572 * reboots. 573 * 574 * @see com.android.service.display.DisplayDevice#hasStableUniqueId(). 575 * @hide 576 */ getUniqueId()577 public String getUniqueId() { 578 return mDisplayInfo.uniqueId; 579 } 580 581 /** 582 * Returns true if this display is still valid, false if the display has been removed. 583 * 584 * If the display is invalid, then the methods of this class will 585 * continue to report the most recently observed display information. 586 * However, it is unwise (and rather fruitless) to continue using a 587 * {@link Display} object after the display's demise. 588 * 589 * It's possible for a display that was previously invalid to become 590 * valid again if a display with the same id is reconnected. 591 * 592 * @return True if the display is still valid. 593 */ isValid()594 public boolean isValid() { 595 synchronized (mLock) { 596 updateDisplayInfoLocked(); 597 return mIsValid; 598 } 599 } 600 601 /** 602 * Gets a full copy of the display information. 603 * 604 * @param outDisplayInfo The object to receive the copy of the display information. 605 * @return True if the display is still valid. 606 * @hide 607 */ 608 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) getDisplayInfo(DisplayInfo outDisplayInfo)609 public boolean getDisplayInfo(DisplayInfo outDisplayInfo) { 610 synchronized (mLock) { 611 updateDisplayInfoLocked(); 612 outDisplayInfo.copyFrom(mDisplayInfo); 613 return mIsValid; 614 } 615 } 616 617 /** 618 * Gets the display's layer stack. 619 * 620 * Each display has its own independent layer stack upon which surfaces 621 * are placed to be managed by surface flinger. 622 * 623 * @return The display's layer stack number. 624 * @hide 625 */ getLayerStack()626 public int getLayerStack() { 627 synchronized (mLock) { 628 updateDisplayInfoLocked(); 629 return mDisplayInfo.layerStack; 630 } 631 } 632 633 /** 634 * Returns a combination of flags that describe the capabilities of the display. 635 * 636 * @return The display flags. 637 * 638 * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS 639 * @see #FLAG_SECURE 640 * @see #FLAG_PRIVATE 641 * @see #FLAG_ROUND 642 */ getFlags()643 public int getFlags() { 644 return mFlags; 645 } 646 647 /** 648 * Gets the display type. 649 * 650 * @return The display type. 651 * 652 * @see #TYPE_UNKNOWN 653 * @see #TYPE_INTERNAL 654 * @see #TYPE_EXTERNAL 655 * @see #TYPE_WIFI 656 * @see #TYPE_OVERLAY 657 * @see #TYPE_VIRTUAL 658 * @hide 659 */ 660 @UnsupportedAppUsage 661 @TestApi getType()662 public int getType() { 663 return mType; 664 } 665 666 /** 667 * Gets the display address, or null if none. 668 * Interpretation varies by display type. 669 * 670 * @return The display address. 671 * @hide 672 */ getAddress()673 public DisplayAddress getAddress() { 674 synchronized (mLock) { 675 updateDisplayInfoLocked(); 676 return mDisplayInfo.address; 677 } 678 } 679 680 /** 681 * Gets the UID of the application that owns this display, or zero if it is 682 * owned by the system. 683 * <p> 684 * If the display is private, then only the owner can use it. 685 * </p> 686 * 687 * @hide 688 */ getOwnerUid()689 public int getOwnerUid() { 690 return mOwnerUid; 691 } 692 693 /** 694 * Gets the package name of the application that owns this display, or null if it is 695 * owned by the system. 696 * <p> 697 * If the display is private, then only the owner can use it. 698 * </p> 699 * 700 * @hide 701 */ 702 @UnsupportedAppUsage getOwnerPackageName()703 public String getOwnerPackageName() { 704 return mOwnerPackageName; 705 } 706 707 /** 708 * Gets the compatibility info used by this display instance. 709 * 710 * @return The display adjustments holder, or null if none is required. 711 * @hide 712 */ 713 @UnsupportedAppUsage getDisplayAdjustments()714 public DisplayAdjustments getDisplayAdjustments() { 715 if (mResources != null) { 716 final DisplayAdjustments currentAdjustments = mResources.getDisplayAdjustments(); 717 if (!mDisplayAdjustments.equals(currentAdjustments)) { 718 mDisplayAdjustments = new DisplayAdjustments(currentAdjustments); 719 } 720 } 721 722 return mDisplayAdjustments; 723 } 724 725 /** 726 * Gets the name of the display. 727 * <p> 728 * Note that some displays may be renamed by the user. 729 * </p> 730 * 731 * @return The display's name. 732 */ getName()733 public String getName() { 734 synchronized (mLock) { 735 updateDisplayInfoLocked(); 736 return mDisplayInfo.name; 737 } 738 } 739 740 /** 741 * Gets the default brightness configured for the display. 742 * 743 * @return Default brightness between 0.0-1.0 744 * @hide 745 */ getBrightnessDefault()746 public float getBrightnessDefault() { 747 synchronized (mLock) { 748 updateDisplayInfoLocked(); 749 return mDisplayInfo.brightnessDefault; 750 } 751 } 752 753 /** 754 * @return Brightness information about the display. 755 * @hide 756 */ 757 @RequiresPermission(CONTROL_DISPLAY_BRIGHTNESS) getBrightnessInfo()758 public @Nullable BrightnessInfo getBrightnessInfo() { 759 return mGlobal.getBrightnessInfo(mDisplayId); 760 } 761 762 /** 763 * Gets the size of the display in pixels. 764 * 765 * <p>The return value does not necessarily represent the actual size (native resolution) of the 766 * display. The returned size might be adjusted to exclude certain system decor elements that 767 * are always visible, or the size might be scaled to provide compatibility with older 768 * applications that were originally designed for smaller displays. 769 * 770 * <p>The returned size can also be different depending on the WindowManager bound to the 771 * display: 772 * <ul> 773 * <li>If size is requested from an activity (either using a WindowManager accessed by 774 * {@code getWindowManager()} or {@code getSystemService(Context.WINDOW_SERVICE)}), the 775 * size of the current app window is returned. As a result, in multi-window mode, the 776 * returned size can be smaller than the size of the device screen. 777 * <li>If size is requested from a non-activity context (for example, the application 778 * context, where the WindowManager is accessed by 779 * {@code getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}), the 780 * returned size can vary depending on API level: 781 * <ul> 782 * <li>API level 29 and below — The size of the entire display (based on 783 * current rotation) minus system decoration areas is returned. 784 * <li>API level 30 and above — The size of the top running activity in the 785 * current process is returned. If the current process has no running 786 * activities, the size of the device default display, including system 787 * decoration areas, is returned. 788 * </ul> 789 * </ul> 790 * 791 * <p>For layout purposes, apps should make a request from an activity context to obtain the 792 * size of the display area available for app content. 793 * 794 * @param outSize A {@link Point} object which receives the display size information. 795 * 796 * @deprecated Use {@link WindowMetrics} instead. Obtain a {@code WindowMetrics} instance by 797 * calling {@link WindowManager#getCurrentWindowMetrics()}, then call 798 * {@link WindowMetrics#getBounds()} to get the dimensions of the application window. 799 */ 800 @Deprecated getSize(Point outSize)801 public void getSize(Point outSize) { 802 synchronized (mLock) { 803 updateDisplayInfoLocked(); 804 mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments()); 805 outSize.x = mTempMetrics.widthPixels; 806 outSize.y = mTempMetrics.heightPixels; 807 } 808 } 809 810 /** 811 * Gets the size of the display as a rectangle, in pixels. 812 * 813 * @param outSize A {@link Rect} object to receive the size information. 814 * 815 * @deprecated Use {@link WindowMetrics#getBounds()} to get the dimensions of the application 816 * window. 817 */ 818 @Deprecated getRectSize(Rect outSize)819 public void getRectSize(Rect outSize) { 820 synchronized (mLock) { 821 updateDisplayInfoLocked(); 822 mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments()); 823 outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels); 824 } 825 } 826 827 /** 828 * Return the range of display sizes an application can expect to encounter 829 * under normal operation, as long as there is no physical change in screen 830 * size. This is basically the sizes you will see as the orientation 831 * changes, taking into account whatever screen decoration there is in 832 * each rotation. For example, the status bar is always at the top of the 833 * screen, so it will reduce the height both in landscape and portrait, and 834 * the smallest height returned here will be the smaller of the two. 835 * 836 * This is intended for applications to get an idea of the range of sizes 837 * they will encounter while going through device rotations, to provide a 838 * stable UI through rotation. The sizes here take into account all standard 839 * system decorations that reduce the size actually available to the 840 * application: the status bar, navigation bar, system bar, etc. It does 841 * <em>not</em> take into account more transient elements like an IME 842 * soft keyboard. 843 * 844 * @param outSmallestSize Filled in with the smallest width and height 845 * that the application will encounter, in pixels (not dp units). The x 846 * (width) dimension here directly corresponds to 847 * {@link android.content.res.Configuration#smallestScreenWidthDp 848 * Configuration.smallestScreenWidthDp}, except the value here is in raw 849 * screen pixels rather than dp units. Your application may of course 850 * still get smaller space yet if, for example, a soft keyboard is 851 * being displayed. 852 * @param outLargestSize Filled in with the largest width and height 853 * that the application will encounter, in pixels (not dp units). Your 854 * application may of course still get larger space than this if, 855 * for example, screen decorations like the status bar are being hidden. 856 */ getCurrentSizeRange(Point outSmallestSize, Point outLargestSize)857 public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) { 858 synchronized (mLock) { 859 updateDisplayInfoLocked(); 860 outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth; 861 outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight; 862 outLargestSize.x = mDisplayInfo.largestNominalAppWidth; 863 outLargestSize.y = mDisplayInfo.largestNominalAppHeight; 864 } 865 } 866 867 /** 868 * Return the maximum screen size dimension that will happen. This is 869 * mostly for wallpapers. 870 * @hide 871 */ 872 @UnsupportedAppUsage getMaximumSizeDimension()873 public int getMaximumSizeDimension() { 874 synchronized (mLock) { 875 updateDisplayInfoLocked(); 876 return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); 877 } 878 } 879 880 /** 881 * @deprecated Use {@link WindowMetrics#getBounds#width()} instead. 882 */ 883 @Deprecated getWidth()884 public int getWidth() { 885 synchronized (mLock) { 886 updateCachedAppSizeIfNeededLocked(); 887 return mCachedAppWidthCompat; 888 } 889 } 890 891 /** 892 * @deprecated Use {@link WindowMetrics#getBounds()#height()} instead. 893 */ 894 @Deprecated getHeight()895 public int getHeight() { 896 synchronized (mLock) { 897 updateCachedAppSizeIfNeededLocked(); 898 return mCachedAppHeightCompat; 899 } 900 } 901 902 /** 903 * Returns the rotation of the screen from its "natural" orientation. 904 * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0} 905 * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90}, 906 * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or 907 * {@link Surface#ROTATION_270 Surface.ROTATION_270}. For 908 * example, if a device has a naturally tall screen, and the user has 909 * turned it on its side to go into a landscape orientation, the value 910 * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90} 911 * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on 912 * the direction it was turned. The angle is the rotation of the drawn 913 * graphics on the screen, which is the opposite direction of the physical 914 * rotation of the device. For example, if the device is rotated 90 915 * degrees counter-clockwise, to compensate rendering will be rotated by 916 * 90 degrees clockwise and thus the returned value here will be 917 * {@link Surface#ROTATION_90 Surface.ROTATION_90}. 918 * 919 * This rotation value will match the results of {@link #getMetrics}: this means that the 920 * rotation value will correspond to the activity if accessed through the activity. 921 */ 922 @Surface.Rotation getRotation()923 public int getRotation() { 924 synchronized (mLock) { 925 updateDisplayInfoLocked(); 926 return getLocalRotation(); 927 } 928 } 929 930 /** 931 * Returns the install orientation of the display. 932 * @hide 933 */ 934 @Surface.Rotation getInstallOrientation()935 public int getInstallOrientation() { 936 synchronized (mLock) { 937 updateDisplayInfoLocked(); 938 return mDisplayInfo.installOrientation; 939 } 940 } 941 942 /** 943 * @deprecated use {@link #getRotation} 944 * @return orientation of this display. 945 */ 946 @Deprecated 947 @Surface.Rotation getOrientation()948 public int getOrientation() { 949 return getRotation(); 950 } 951 952 953 /** 954 * Returns the {@link DisplayCutout}, or {@code null} if there is none. 955 * 956 * @see DisplayCutout 957 */ 958 @Nullable getCutout()959 public DisplayCutout getCutout() { 960 synchronized (mLock) { 961 updateDisplayInfoLocked(); 962 if (mResources == null) return mDisplayInfo.displayCutout; 963 final DisplayCutout localCutout = mDisplayInfo.displayCutout; 964 if (localCutout == null) return null; 965 int rotation = getLocalRotation(); 966 if (rotation != mDisplayInfo.rotation) { 967 return localCutout.getRotated(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight, 968 mDisplayInfo.rotation, rotation); 969 } 970 return localCutout; 971 } 972 } 973 974 /** 975 * Returns the {@link RoundedCorner} of the given position if there is one. 976 * 977 * @param position the position of the rounded corner on the display. 978 * 979 * @return the rounded corner of the given position. Returns {@code null} if there is none. 980 */ 981 @SuppressLint("VisiblySynchronized") 982 @Nullable getRoundedCorner(@oundedCorner.Position int position)983 public RoundedCorner getRoundedCorner(@RoundedCorner.Position int position) { 984 synchronized (mLock) { 985 updateDisplayInfoLocked(); 986 final RoundedCorners roundedCorners = mDisplayInfo.roundedCorners; 987 final @Surface.Rotation int rotation = getLocalRotation(); 988 if (roundedCorners != null && rotation != mDisplayInfo.rotation) { 989 roundedCorners.rotate(rotation, 990 mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); 991 } 992 return roundedCorners == null ? null : roundedCorners.getRoundedCorner(position); 993 } 994 } 995 996 /** 997 * Gets the pixel format of the display. 998 * @return One of the constants defined in {@link android.graphics.PixelFormat}. 999 * 1000 * @deprecated This method is no longer supported. 1001 * The result is always {@link PixelFormat#RGBA_8888}. 1002 */ 1003 @Deprecated getPixelFormat()1004 public int getPixelFormat() { 1005 return PixelFormat.RGBA_8888; 1006 } 1007 1008 /** 1009 * Gets the refresh rate of this display in frames per second. 1010 */ getRefreshRate()1011 public float getRefreshRate() { 1012 synchronized (mLock) { 1013 updateDisplayInfoLocked(); 1014 return mDisplayInfo.getRefreshRate(); 1015 } 1016 } 1017 1018 /** 1019 * Get the supported refresh rates of this display in frames per second. 1020 * <p> 1021 * This method only returns refresh rates for the display's default modes. For more options, use 1022 * {@link #getSupportedModes()}. 1023 * 1024 * @deprecated use {@link #getSupportedModes()} instead 1025 */ 1026 @Deprecated getSupportedRefreshRates()1027 public float[] getSupportedRefreshRates() { 1028 synchronized (mLock) { 1029 updateDisplayInfoLocked(); 1030 return mDisplayInfo.getDefaultRefreshRates(); 1031 } 1032 } 1033 1034 /** 1035 * Returns the active mode of the display. 1036 */ getMode()1037 public Mode getMode() { 1038 synchronized (mLock) { 1039 updateDisplayInfoLocked(); 1040 return mDisplayInfo.getMode(); 1041 } 1042 } 1043 1044 /** 1045 * Returns the default mode of the display. 1046 * @hide 1047 */ 1048 @TestApi getDefaultMode()1049 public @NonNull Mode getDefaultMode() { 1050 synchronized (mLock) { 1051 updateDisplayInfoLocked(); 1052 return mDisplayInfo.getDefaultMode(); 1053 } 1054 } 1055 1056 /** 1057 * Gets the supported modes of this display. 1058 */ getSupportedModes()1059 public Mode[] getSupportedModes() { 1060 synchronized (mLock) { 1061 updateDisplayInfoLocked(); 1062 final Display.Mode[] modes = mDisplayInfo.supportedModes; 1063 return Arrays.copyOf(modes, modes.length); 1064 } 1065 } 1066 1067 /** 1068 * <p> Returns true if the connected display can be switched into a mode with minimal 1069 * post processing. </p> 1070 * 1071 * <p> If the Display sink is connected via HDMI, this method will return true if the 1072 * display supports either Auto Low Latency Mode or Game Content Type. 1073 * 1074 * <p> If the Display sink has an internal connection or uses some other protocol than 1075 * HDMI, this method will return true if the sink can be switched into an 1076 * implementation-defined low latency image processing mode. </p> 1077 * 1078 * <p> The ability to switch to a mode with minimal post processing may be disabled 1079 * by a user setting in the system settings menu. In that case, this method returns 1080 * false. </p> 1081 * 1082 * @see android.view.Window#setPreferMinimalPostProcessing 1083 */ 1084 @SuppressLint("VisiblySynchronized") isMinimalPostProcessingSupported()1085 public boolean isMinimalPostProcessingSupported() { 1086 synchronized (mLock) { 1087 updateDisplayInfoLocked(); 1088 return mDisplayInfo.minimalPostProcessingSupported; 1089 } 1090 } 1091 1092 /** 1093 * Request the display applies a color mode. 1094 * @hide 1095 */ 1096 @RequiresPermission(CONFIGURE_DISPLAY_COLOR_MODE) requestColorMode(int colorMode)1097 public void requestColorMode(int colorMode) { 1098 mGlobal.requestColorMode(mDisplayId, colorMode); 1099 } 1100 1101 /** 1102 * Returns the active color mode of this display 1103 * @hide 1104 */ getColorMode()1105 public int getColorMode() { 1106 synchronized (mLock) { 1107 updateDisplayInfoLocked(); 1108 return mDisplayInfo.colorMode; 1109 } 1110 } 1111 1112 /** 1113 * @hide 1114 * Get current remove mode of the display - what actions should be performed with the display's 1115 * content when it is removed. Default behavior for public displays in this case is to move all 1116 * activities to the primary display and make it focused. For private display - destroy all 1117 * activities. 1118 * 1119 * @see #REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY 1120 * @see #REMOVE_MODE_DESTROY_CONTENT 1121 */ 1122 // TODO (b/114338689): Remove the method and use IWindowManager#getRemoveContentMode getRemoveMode()1123 public int getRemoveMode() { 1124 return mDisplayInfo.removeMode; 1125 } 1126 1127 /** 1128 * Returns the system's preferred display mode. This mode will be used when the user has not 1129 * specified a display-mode preference. This returns null if the boot display mode feature is 1130 * not supported by system. 1131 * 1132 * @hide 1133 */ 1134 @TestApi 1135 @Nullable getSystemPreferredDisplayMode()1136 public Display.Mode getSystemPreferredDisplayMode() { 1137 return mGlobal.getSystemPreferredDisplayMode(getDisplayId()); 1138 } 1139 1140 /** 1141 * Returns the display's HDR capabilities. 1142 * 1143 * @see #isHdr() 1144 */ getHdrCapabilities()1145 public HdrCapabilities getHdrCapabilities() { 1146 synchronized (mLock) { 1147 updateDisplayInfoLocked(); 1148 if (mDisplayInfo.userDisabledHdrTypes.length == 0) { 1149 return mDisplayInfo.hdrCapabilities; 1150 } 1151 1152 if (mDisplayInfo.hdrCapabilities == null) { 1153 return null; 1154 } 1155 1156 ArraySet<Integer> enabledTypesSet = new ArraySet<>(); 1157 for (int supportedType : mDisplayInfo.hdrCapabilities.getSupportedHdrTypes()) { 1158 boolean typeDisabled = false; 1159 for (int userDisabledType : mDisplayInfo.userDisabledHdrTypes) { 1160 if (supportedType == userDisabledType) { 1161 typeDisabled = true; 1162 break; 1163 } 1164 } 1165 if (!typeDisabled) { 1166 enabledTypesSet.add(supportedType); 1167 } 1168 } 1169 1170 int[] enabledTypes = new int[enabledTypesSet.size()]; 1171 int index = 0; 1172 for (int enabledType : enabledTypesSet) { 1173 enabledTypes[index++] = enabledType; 1174 } 1175 return new HdrCapabilities(enabledTypes, 1176 mDisplayInfo.hdrCapabilities.mMaxLuminance, 1177 mDisplayInfo.hdrCapabilities.mMaxAverageLuminance, 1178 mDisplayInfo.hdrCapabilities.mMinLuminance); 1179 } 1180 } 1181 1182 /** 1183 * @hide 1184 * Returns the display's HDR supported types. 1185 * 1186 * @see #isHdr() 1187 * @see HdrCapabilities#getSupportedHdrTypes() 1188 */ 1189 @TestApi 1190 @NonNull getReportedHdrTypes()1191 public int[] getReportedHdrTypes() { 1192 synchronized (mLock) { 1193 updateDisplayInfoLocked(); 1194 if (mDisplayInfo.hdrCapabilities == null) { 1195 return new int[0]; 1196 } 1197 return mDisplayInfo.hdrCapabilities.getSupportedHdrTypes(); 1198 } 1199 } 1200 1201 /** 1202 * Returns whether this display supports any HDR type. 1203 * 1204 * @see #getHdrCapabilities() 1205 * @see HdrCapabilities#getSupportedHdrTypes() 1206 */ isHdr()1207 public boolean isHdr() { 1208 synchronized (mLock) { 1209 updateDisplayInfoLocked(); 1210 HdrCapabilities hdrCapabilities = getHdrCapabilities(); 1211 if (hdrCapabilities == null) { 1212 return false; 1213 } 1214 return !(hdrCapabilities.getSupportedHdrTypes().length == 0); 1215 } 1216 } 1217 1218 /** 1219 * Sets the default {@link Display.Mode} to use for the display. The display mode includes 1220 * preference for resolution and refresh rate. 1221 * If the mode specified is not supported by the display, then no mode change occurs. 1222 * 1223 * @param mode The {@link Display.Mode} to set, which can include resolution and/or 1224 * refresh-rate. It is created using {@link Display.Mode.Builder}. 1225 *` 1226 * @hide 1227 */ 1228 @TestApi 1229 @RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) setUserPreferredDisplayMode(@onNull Display.Mode mode)1230 public void setUserPreferredDisplayMode(@NonNull Display.Mode mode) { 1231 // Create a new object containing default values for the unused fields like mode ID and 1232 // alternative refresh rates. 1233 Display.Mode preferredMode = new Display.Mode(mode.getPhysicalWidth(), 1234 mode.getPhysicalHeight(), mode.getRefreshRate()); 1235 mGlobal.setUserPreferredDisplayMode(mDisplayId, preferredMode); 1236 } 1237 1238 /** 1239 * Removes the display's user preferred display mode. 1240 * 1241 * @hide 1242 */ 1243 @TestApi 1244 @RequiresPermission(Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) clearUserPreferredDisplayMode()1245 public void clearUserPreferredDisplayMode() { 1246 mGlobal.setUserPreferredDisplayMode(mDisplayId, null); 1247 } 1248 1249 /** 1250 * Returns the display's user preferred display mode. 1251 * 1252 * @hide 1253 */ 1254 @TestApi 1255 @Nullable getUserPreferredDisplayMode()1256 public Display.Mode getUserPreferredDisplayMode() { 1257 return mGlobal.getUserPreferredDisplayMode(mDisplayId); 1258 } 1259 1260 1261 /** 1262 * Returns whether this display can be used to display wide color gamut content. 1263 * This does not necessarily mean the device itself can render wide color gamut 1264 * content. To ensure wide color gamut content can be produced, refer to 1265 * {@link Configuration#isScreenWideColorGamut()}. 1266 */ isWideColorGamut()1267 public boolean isWideColorGamut() { 1268 synchronized (mLock) { 1269 updateDisplayInfoLocked(); 1270 return mDisplayInfo.isWideColorGamut(); 1271 } 1272 } 1273 1274 /** 1275 * Returns the preferred wide color space of the Display. 1276 * The returned wide gamut color space is based on hardware capability and 1277 * is preferred by the composition pipeline. 1278 * Returns null if the display doesn't support wide color gamut. 1279 * {@link Display#isWideColorGamut()}. 1280 */ 1281 @Nullable getPreferredWideGamutColorSpace()1282 public ColorSpace getPreferredWideGamutColorSpace() { 1283 synchronized (mLock) { 1284 updateDisplayInfoLocked(); 1285 if (mDisplayInfo.isWideColorGamut()) { 1286 return mGlobal.getPreferredWideGamutColorSpace(); 1287 } 1288 return null; 1289 } 1290 } 1291 1292 /** 1293 * Gets the supported color modes of this device. 1294 * @hide 1295 */ getSupportedColorModes()1296 public int[] getSupportedColorModes() { 1297 synchronized (mLock) { 1298 updateDisplayInfoLocked(); 1299 int[] colorModes = mDisplayInfo.supportedColorModes; 1300 return Arrays.copyOf(colorModes, colorModes.length); 1301 } 1302 } 1303 1304 /** 1305 * Gets the supported wide color gamuts of this device. 1306 * 1307 * @return Supported WCG color spaces. 1308 * @hide 1309 */ 1310 @SuppressLint("VisiblySynchronized") 1311 @NonNull 1312 @TestApi getSupportedWideColorGamut()1313 public @ColorMode ColorSpace[] getSupportedWideColorGamut() { 1314 synchronized (mLock) { 1315 final ColorSpace[] defaultColorSpaces = new ColorSpace[0]; 1316 updateDisplayInfoLocked(); 1317 if (!isWideColorGamut()) { 1318 return defaultColorSpaces; 1319 } 1320 1321 final int[] colorModes = getSupportedColorModes(); 1322 final List<ColorSpace> colorSpaces = new ArrayList<>(); 1323 for (int colorMode : colorModes) { 1324 // Refer to DisplayInfo#isWideColorGamut. 1325 switch (colorMode) { 1326 case COLOR_MODE_DCI_P3: 1327 colorSpaces.add(ColorSpace.get(ColorSpace.Named.DCI_P3)); 1328 break; 1329 case COLOR_MODE_DISPLAY_P3: 1330 colorSpaces.add(ColorSpace.get(ColorSpace.Named.DISPLAY_P3)); 1331 break; 1332 } 1333 } 1334 return colorSpaces.toArray(defaultColorSpaces); 1335 } 1336 } 1337 1338 /** 1339 * Gets the app VSYNC offset, in nanoseconds. This is a positive value indicating 1340 * the phase offset of the VSYNC events provided by Choreographer relative to the 1341 * display refresh. For example, if Choreographer reports that the refresh occurred 1342 * at time N, it actually occurred at (N - appVsyncOffset). 1343 * <p> 1344 * Apps generally do not need to be aware of this. It's only useful for fine-grained 1345 * A/V synchronization. 1346 */ getAppVsyncOffsetNanos()1347 public long getAppVsyncOffsetNanos() { 1348 synchronized (mLock) { 1349 updateDisplayInfoLocked(); 1350 return mDisplayInfo.appVsyncOffsetNanos; 1351 } 1352 } 1353 1354 /** 1355 * This is how far in advance a buffer must be queued for presentation at 1356 * a given time. If you want a buffer to appear on the screen at 1357 * time N, you must submit the buffer before (N - presentationDeadline). 1358 * <p> 1359 * The desired presentation time for GLES rendering may be set with 1360 * {@link android.opengl.EGLExt#eglPresentationTimeANDROID}. For video decoding, use 1361 * {@link android.media.MediaCodec#releaseOutputBuffer(int, long)}. Times are 1362 * expressed in nanoseconds, using the system monotonic clock 1363 * ({@link System#nanoTime}). 1364 */ getPresentationDeadlineNanos()1365 public long getPresentationDeadlineNanos() { 1366 synchronized (mLock) { 1367 updateDisplayInfoLocked(); 1368 return mDisplayInfo.presentationDeadlineNanos; 1369 } 1370 } 1371 1372 /** 1373 * Returns the product-specific information about the display or the directly connected 1374 * device on the display chain. 1375 * For example, if the display is transitively connected, this field may contain product 1376 * information about the intermediate device. 1377 * Returns {@code null} if product information is not available. 1378 */ 1379 @Nullable getDeviceProductInfo()1380 public DeviceProductInfo getDeviceProductInfo() { 1381 synchronized (mLock) { 1382 updateDisplayInfoLocked(); 1383 return mDisplayInfo.deviceProductInfo; 1384 } 1385 } 1386 1387 /** 1388 * Gets the size and density of this display. 1389 * 1390 * <p>The size returned does not necessarily represent the actual size (native resolution) of 1391 * the display. The returned size might be adjusted to exclude certain system decor elements 1392 * that are always visible, or the size might be scaled to provide compatibility with older 1393 * applications that were originally designed for smaller displays. 1394 * 1395 * <p>The returned size can also be different depending on the WindowManager associated with the 1396 * display: 1397 * <ul> 1398 * <li>If metrics are requested from an activity (either using a WindowManager accessed by 1399 * {@code getWindowManager()} or {@code getSystemService(Context.WINDOW_SERVICE)}), the 1400 * returned metrics provide the size of the current app window. As a result, in 1401 * multi-window mode, the returned size can be smaller than the size of the device 1402 * screen. 1403 * <li>If metrics are requested from a non-activity context (for example, the application 1404 * context, where the WindowManager is accessed by 1405 * {@code getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}), the 1406 * returned size can vary depending on API level: 1407 * <ul> 1408 * <li>API level 29 and below — The returned metrics provide the size of the 1409 * entire display (based on current rotation) minus system decoration areas. 1410 * <li>API level 30 and above — The returned metrics provide the size of the 1411 * top running activity in the current process. If the current process has no 1412 * running activities, the metrics provide the size of the default display of 1413 * the device, including system decoration areas. 1414 * </ul> 1415 * </ul> 1416 * 1417 * @param outMetrics A {@link DisplayMetrics} object which receives the display metrics. 1418 * 1419 * @deprecated Use {@link WindowMetrics#getBounds()} to get the dimensions of the application 1420 * window. Use {@link Configuration#densityDpi} to get the display density. 1421 */ 1422 @Deprecated getMetrics(DisplayMetrics outMetrics)1423 public void getMetrics(DisplayMetrics outMetrics) { 1424 synchronized (mLock) { 1425 updateDisplayInfoLocked(); 1426 mDisplayInfo.getAppMetrics(outMetrics, getDisplayAdjustments()); 1427 } 1428 } 1429 1430 /** 1431 * Gets the size of the largest region of the display accessible to an app in the current system 1432 * state, without subtracting any window decor or applying scaling factors. 1433 * <p> 1434 * The size is adjusted based on the current rotation of the display. 1435 * <p></p> 1436 * The returned size will fall into one of these scenarios: 1437 * <ol> 1438 * <li>The device has no partitions on the display. The returned value is the largest region 1439 * of the display accessible to an app in the current system state, regardless of windowing 1440 * mode.</li> 1441 * <li>The device divides a single display into multiple partitions. An application is 1442 * restricted to a portion of the display. This is common in devices where the display changes 1443 * size, such as foldables or large screens. The returned size will match the portion of 1444 * the display the application is restricted to.</li> 1445 * <li>The window manager is emulating a different display size, using {@code adb shell wm 1446 * size}. The returned size will match the emulated display size.</li> 1447 * </ol> 1448 * </p><p> 1449 * The returned value is <b>unsuitable to use when sizing and placing UI elements</b>, since it 1450 * does not reflect the application window size in any of these scenarios. 1451 * {@link WindowManager#getCurrentWindowMetrics()} is an alternative that returns the size 1452 * of the current application window, even if the window is on a device with a partitioned 1453 * display. This helps prevent UI bugs where UI elements are misaligned or placed beyond the 1454 * bounds of the window. 1455 * <p></p> 1456 * Handling multi-window mode correctly is necessary since applications are not always 1457 * fullscreen. A user on a large screen device, such as a tablet or Chrome OS devices, is more 1458 * likely to use multi-window modes. 1459 * <p></p> 1460 * For example, consider a device with a display partitioned into two halves. The user may have 1461 * a fullscreen application open on the first partition. They may have two applications open in 1462 * split screen (an example of multi-window mode) on the second partition, with each application 1463 * consuming half of the partition. In this case, 1464 * {@link WindowManager#getCurrentWindowMetrics()} reports the fullscreen window is half of the 1465 * screen in size, and each split screen window is a quarter of the screen in size. On the other 1466 * hand, {@link #getRealSize} reports half of the screen size for all windows, since the 1467 * application windows are all restricted to their respective partitions. 1468 * </p> 1469 * 1470 * @param outSize Set to the real size of the display. 1471 * @deprecated Use {@link WindowManager#getCurrentWindowMetrics()} to identify the current size 1472 * of the activity window. UI-related work, such as choosing UI layouts, should rely 1473 * upon {@link WindowMetrics#getBounds()}. 1474 */ 1475 @Deprecated getRealSize(Point outSize)1476 public void getRealSize(Point outSize) { 1477 synchronized (mLock) { 1478 updateDisplayInfoLocked(); 1479 if (shouldReportMaxBounds()) { 1480 final Rect bounds = mResources.getConfiguration() 1481 .windowConfiguration.getMaxBounds(); 1482 outSize.x = bounds.width(); 1483 outSize.y = bounds.height(); 1484 if (DEBUG) { 1485 Log.d(TAG, "getRealSize determined from max bounds: " + outSize); 1486 } 1487 // Skip adjusting by fixed rotation, since if it is necessary, the configuration 1488 // should already reflect the expected rotation. 1489 return; 1490 } 1491 outSize.x = mDisplayInfo.logicalWidth; 1492 outSize.y = mDisplayInfo.logicalHeight; 1493 final @Surface.Rotation int rotation = getLocalRotation(); 1494 if (rotation != mDisplayInfo.rotation) { 1495 adjustSize(outSize, mDisplayInfo.rotation, rotation); 1496 } 1497 } 1498 } 1499 1500 /** 1501 * Gets the size of the largest region of the display accessible to an app in the current system 1502 * state, without subtracting any window decor or applying scaling factors. 1503 * <p> 1504 * The size is adjusted based on the current rotation of the display. 1505 * <p></p> 1506 * The returned size will fall into one of these scenarios: 1507 * <ol> 1508 * <li>The device has no partitions on the display. The returned value is the largest region 1509 * of the display accessible to an app in the current system state, regardless of windowing 1510 * mode.</li> 1511 * <li>The device divides a single display into multiple partitions. An application is 1512 * restricted to a portion of the display. This is common in devices where the display changes 1513 * size, such as foldables or large screens. The returned size will match the portion of 1514 * the display the application is restricted to.</li> 1515 * <li>The window manager is emulating a different display size, using {@code adb shell wm 1516 * size}. The returned size will match the emulated display size.</li> 1517 * </ol> 1518 * </p><p> 1519 * The returned value is <b>unsuitable to use when sizing and placing UI elements</b>, since it 1520 * does not reflect the application window size in any of these scenarios. 1521 * {@link WindowManager#getCurrentWindowMetrics()} is an alternative that returns the size 1522 * of the current application window, even if the window is on a device with a partitioned 1523 * display. This helps prevent UI bugs where UI elements are misaligned or placed beyond the 1524 * bounds of the window. 1525 * <p></p> 1526 * Handling multi-window mode correctly is necessary since applications are not always 1527 * fullscreen. A user on a large screen device, such as a tablet or Chrome OS devices, is more 1528 * likely to use multi-window modes. 1529 * <p></p> 1530 * For example, consider a device with a display partitioned into two halves. The user may have 1531 * a fullscreen application open on the first partition. They may have two applications open in 1532 * split screen (an example of multi-window mode) on the second partition, with each application 1533 * consuming half of the partition. In this case, 1534 * {@link WindowManager#getCurrentWindowMetrics()} reports the fullscreen window is half of the 1535 * screen in size, and each split screen window is a quarter of the screen in size. On the other 1536 * hand, {@link #getRealMetrics} reports half of the screen size for all windows, since the 1537 * application windows are all restricted to their respective partitions. 1538 * </p> 1539 * 1540 * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. 1541 * @deprecated Use {@link WindowManager#getCurrentWindowMetrics()} to identify the current size 1542 * of the activity window. UI-related work, such as choosing UI layouts, should rely 1543 * upon {@link WindowMetrics#getBounds()}. Use {@link Configuration#densityDpi} to 1544 * get the current density. 1545 */ 1546 @Deprecated getRealMetrics(DisplayMetrics outMetrics)1547 public void getRealMetrics(DisplayMetrics outMetrics) { 1548 synchronized (mLock) { 1549 updateDisplayInfoLocked(); 1550 if (shouldReportMaxBounds()) { 1551 mDisplayInfo.getMaxBoundsMetrics(outMetrics, 1552 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, 1553 mResources.getConfiguration()); 1554 if (DEBUG) { 1555 Log.d(TAG, "getRealMetrics determined from max bounds: " + outMetrics); 1556 } 1557 // Skip adjusting by fixed rotation, since if it is necessary, the configuration 1558 // should already reflect the expected rotation. 1559 return; 1560 } 1561 mDisplayInfo.getLogicalMetrics(outMetrics, 1562 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 1563 final @Surface.Rotation int rotation = getLocalRotation(); 1564 if (rotation != mDisplayInfo.rotation) { 1565 adjustMetrics(outMetrics, mDisplayInfo.rotation, rotation); 1566 } 1567 } 1568 } 1569 1570 /** 1571 * Determines if {@link WindowConfiguration#getMaxBounds()} should be reported as the 1572 * display dimensions. The max bounds field may be smaller than the logical dimensions 1573 * when apps need to be sandboxed. 1574 * 1575 * Depends upon {@link WindowConfiguration#getMaxBounds()} being set in 1576 * {@link com.android.server.wm.ConfigurationContainer#providesMaxBounds()}. In most cases, this 1577 * value reflects the size of the current DisplayArea. 1578 * @return {@code true} when max bounds should be applied. 1579 */ shouldReportMaxBounds()1580 private boolean shouldReportMaxBounds() { 1581 if (mResources == null) { 1582 return false; 1583 } 1584 final Configuration config = mResources.getConfiguration(); 1585 return config != null && !config.windowConfiguration.getMaxBounds().isEmpty(); 1586 } 1587 1588 /** 1589 * Gets the state of the display, such as whether it is on or off. 1590 * 1591 * @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON}, 1592 * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, {@link #STATE_ON_SUSPEND}, or 1593 * {@link #STATE_UNKNOWN}. 1594 */ getState()1595 public int getState() { 1596 synchronized (mLock) { 1597 updateDisplayInfoLocked(); 1598 return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN; 1599 } 1600 } 1601 1602 /** 1603 * Returns the committed state of the display. 1604 * 1605 * @return The latest committed display state, such as {@link #STATE_ON}. The display state 1606 * {@link Display#getState()} is set as committed only after power state changes finish. 1607 * 1608 * @hide 1609 */ getCommittedState()1610 public int getCommittedState() { 1611 synchronized (mLock) { 1612 updateDisplayInfoLocked(); 1613 return mIsValid ? mDisplayInfo.committedState : STATE_UNKNOWN; 1614 } 1615 } 1616 1617 /** 1618 * Returns true if the specified UID has access to this display. 1619 * @hide 1620 */ 1621 @TestApi hasAccess(int uid)1622 public boolean hasAccess(int uid) { 1623 return hasAccess(uid, mFlags, mOwnerUid, mDisplayId); 1624 } 1625 1626 /** @hide */ hasAccess(int uid, int flags, int ownerUid, int displayId)1627 public static boolean hasAccess(int uid, int flags, int ownerUid, int displayId) { 1628 return (flags & Display.FLAG_PRIVATE) == 0 1629 || uid == ownerUid 1630 || uid == Process.SYSTEM_UID 1631 || uid == 0 1632 // Check if the UID is present on given display. 1633 || DisplayManagerGlobal.getInstance().isUidPresentOnDisplay(uid, displayId); 1634 } 1635 1636 /** 1637 * Returns true if the display is a public presentation display. 1638 * @hide 1639 */ isPublicPresentation()1640 public boolean isPublicPresentation() { 1641 return (mFlags & (Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION)) == 1642 Display.FLAG_PRESENTATION; 1643 } 1644 1645 /** 1646 * @return {@code true} if the display is a trusted display. 1647 * 1648 * @see #FLAG_TRUSTED 1649 * @hide 1650 */ isTrusted()1651 public boolean isTrusted() { 1652 return (mFlags & FLAG_TRUSTED) == FLAG_TRUSTED; 1653 } 1654 updateDisplayInfoLocked()1655 private void updateDisplayInfoLocked() { 1656 // Note: The display manager caches display info objects on our behalf. 1657 DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId); 1658 if (newInfo == null) { 1659 // Preserve the old mDisplayInfo after the display is removed. 1660 if (mIsValid) { 1661 mIsValid = false; 1662 if (DEBUG) { 1663 Log.d(TAG, "Logical display " + mDisplayId + " was removed."); 1664 } 1665 } 1666 } else { 1667 // Use the new display info. (It might be the same object if nothing changed.) 1668 mDisplayInfo = newInfo; 1669 if (!mIsValid) { 1670 mIsValid = true; 1671 if (DEBUG) { 1672 Log.d(TAG, "Logical display " + mDisplayId + " was recreated."); 1673 } 1674 } 1675 } 1676 } 1677 updateCachedAppSizeIfNeededLocked()1678 private void updateCachedAppSizeIfNeededLocked() { 1679 long now = SystemClock.uptimeMillis(); 1680 if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) { 1681 updateDisplayInfoLocked(); 1682 mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments()); 1683 mCachedAppWidthCompat = mTempMetrics.widthPixels; 1684 mCachedAppHeightCompat = mTempMetrics.heightPixels; 1685 mLastCachedAppSizeUpdate = now; 1686 } 1687 } 1688 1689 /** Returns {@code false} if the width and height of display should swap. */ noFlip(@urface.Rotation int realRotation, @Surface.Rotation int localRotation)1690 private static boolean noFlip(@Surface.Rotation int realRotation, 1691 @Surface.Rotation int localRotation) { 1692 // Check if the delta is rotated by 90 degrees. 1693 return (realRotation - localRotation + 4) % 2 == 0; 1694 } 1695 1696 /** 1697 * Adjusts the given size by a rotation offset if necessary. 1698 * @hide 1699 */ adjustSize(@onNull Point size, @Surface.Rotation int realRotation, @Surface.Rotation int localRotation)1700 private void adjustSize(@NonNull Point size, @Surface.Rotation int realRotation, 1701 @Surface.Rotation int localRotation) { 1702 if (noFlip(realRotation, localRotation)) return; 1703 final int w = size.x; 1704 size.x = size.y; 1705 size.y = w; 1706 } 1707 1708 /** 1709 * Adjusts the given metrics by a rotation offset if necessary. 1710 * @hide 1711 */ adjustMetrics(@onNull DisplayMetrics metrics, @Surface.Rotation int realRotation, @Surface.Rotation int localRotation)1712 private void adjustMetrics(@NonNull DisplayMetrics metrics, 1713 @Surface.Rotation int realRotation, @Surface.Rotation int localRotation) { 1714 if (noFlip(realRotation, localRotation)) return; 1715 int w = metrics.widthPixels; 1716 metrics.widthPixels = metrics.heightPixels; 1717 metrics.heightPixels = w; 1718 1719 w = metrics.noncompatWidthPixels; 1720 metrics.noncompatWidthPixels = metrics.noncompatHeightPixels; 1721 metrics.noncompatHeightPixels = w; 1722 } 1723 getLocalRotation()1724 private @Surface.Rotation int getLocalRotation() { 1725 if (mResources == null) return mDisplayInfo.rotation; 1726 final @Surface.Rotation int localRotation = 1727 mResources.getConfiguration().windowConfiguration.getDisplayRotation(); 1728 if (localRotation != WindowConfiguration.ROTATION_UNDEFINED) return localRotation; 1729 return mDisplayInfo.rotation; 1730 } 1731 1732 // For debugging purposes 1733 @Override toString()1734 public String toString() { 1735 synchronized (mLock) { 1736 updateDisplayInfoLocked(); 1737 final DisplayAdjustments adjustments = getDisplayAdjustments(); 1738 mDisplayInfo.getAppMetrics(mTempMetrics, adjustments); 1739 return "Display id " + mDisplayId + ": " + mDisplayInfo + ", " 1740 + mTempMetrics + ", isValid=" + mIsValid; 1741 } 1742 } 1743 1744 /** 1745 * @hide 1746 */ typeToString(int type)1747 public static String typeToString(int type) { 1748 switch (type) { 1749 case TYPE_UNKNOWN: 1750 return "UNKNOWN"; 1751 case TYPE_INTERNAL: 1752 return "INTERNAL"; 1753 case TYPE_EXTERNAL: 1754 return "EXTERNAL"; 1755 case TYPE_WIFI: 1756 return "WIFI"; 1757 case TYPE_OVERLAY: 1758 return "OVERLAY"; 1759 case TYPE_VIRTUAL: 1760 return "VIRTUAL"; 1761 default: 1762 return Integer.toString(type); 1763 } 1764 } 1765 1766 /** 1767 * @hide 1768 */ stateToString(int state)1769 public static String stateToString(int state) { 1770 switch (state) { 1771 case STATE_UNKNOWN: 1772 return "UNKNOWN"; 1773 case STATE_OFF: 1774 return "OFF"; 1775 case STATE_ON: 1776 return "ON"; 1777 case STATE_DOZE: 1778 return "DOZE"; 1779 case STATE_DOZE_SUSPEND: 1780 return "DOZE_SUSPEND"; 1781 case STATE_VR: 1782 return "VR"; 1783 case STATE_ON_SUSPEND: 1784 return "ON_SUSPEND"; 1785 default: 1786 return Integer.toString(state); 1787 } 1788 } 1789 1790 /** 1791 * Returns true if display updates may be suspended while in the specified 1792 * display power state. In SUSPEND states, updates are absolutely forbidden. 1793 * @hide 1794 */ isSuspendedState(int state)1795 public static boolean isSuspendedState(int state) { 1796 return state == STATE_OFF || state == STATE_DOZE_SUSPEND || state == STATE_ON_SUSPEND; 1797 } 1798 1799 /** 1800 * Returns true if the display may be in a reduced operating mode while in the 1801 * specified display power state. 1802 * @hide 1803 */ isDozeState(int state)1804 public static boolean isDozeState(int state) { 1805 return state == STATE_DOZE || state == STATE_DOZE_SUSPEND; 1806 } 1807 1808 /** 1809 * Returns true if the display is in active state such as {@link #STATE_ON} 1810 * or {@link #STATE_VR}. 1811 * @hide 1812 */ isActiveState(int state)1813 public static boolean isActiveState(int state) { 1814 return state == STATE_ON || state == STATE_VR; 1815 } 1816 1817 /** 1818 * Returns true if the display is in an off state such as {@link #STATE_OFF}. 1819 * @hide 1820 */ isOffState(int state)1821 public static boolean isOffState(int state) { 1822 return state == STATE_OFF; 1823 } 1824 1825 /** 1826 * Returns true if the display is in an on state such as {@link #STATE_ON} 1827 * or {@link #STATE_VR} or {@link #STATE_ON_SUSPEND}. 1828 * @hide 1829 */ isOnState(int state)1830 public static boolean isOnState(int state) { 1831 return state == STATE_ON || state == STATE_VR || state == STATE_ON_SUSPEND; 1832 } 1833 1834 /** 1835 * Returns true if the specified width is valid. 1836 * @hide 1837 */ isWidthValid(int width)1838 public static boolean isWidthValid(int width) { 1839 return width > 0; 1840 } 1841 1842 /** 1843 * Returns true if the specified height is valid. 1844 * @hide 1845 */ isHeightValid(int height)1846 public static boolean isHeightValid(int height) { 1847 return height > 0; 1848 } 1849 1850 /** 1851 * Returns true if the specified refresh-rate is valid. 1852 * @hide 1853 */ isRefreshRateValid(float refreshRate)1854 public static boolean isRefreshRateValid(float refreshRate) { 1855 return refreshRate > 0.0f; 1856 } 1857 1858 /** 1859 * Returns whether/how the specified display supports DISPLAY_DECORATION. 1860 * 1861 * Composition.DISPLAY_DECORATION is a special layer type which is used to 1862 * render the screen decorations (i.e. antialiased rounded corners and 1863 * cutouts) while taking advantage of specific hardware. 1864 * 1865 * @hide 1866 */ getDisplayDecorationSupport()1867 public DisplayDecorationSupport getDisplayDecorationSupport() { 1868 return mGlobal.getDisplayDecorationSupport(mDisplayId); 1869 } 1870 1871 /** 1872 * A mode supported by a given display. 1873 * 1874 * @see Display#getSupportedModes() 1875 */ 1876 public static final class Mode implements Parcelable { 1877 /** 1878 * @hide 1879 */ 1880 public static final Mode[] EMPTY_ARRAY = new Mode[0]; 1881 1882 /** 1883 * @hide 1884 */ 1885 public static final int INVALID_MODE_ID = -1; 1886 1887 private final int mModeId; 1888 private final int mWidth; 1889 private final int mHeight; 1890 private final float mRefreshRate; 1891 @NonNull 1892 private final float[] mAlternativeRefreshRates; 1893 1894 /** 1895 * @hide 1896 */ 1897 @TestApi Mode(int width, int height, float refreshRate)1898 public Mode(int width, int height, float refreshRate) { 1899 this(INVALID_MODE_ID, width, height, refreshRate, new float[0]); 1900 } 1901 1902 /** 1903 * @hide 1904 */ 1905 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Mode(int modeId, int width, int height, float refreshRate)1906 public Mode(int modeId, int width, int height, float refreshRate) { 1907 this(modeId, width, height, refreshRate, new float[0]); 1908 } 1909 1910 /** 1911 * @hide 1912 */ Mode(int modeId, int width, int height, float refreshRate, float[] alternativeRefreshRates)1913 public Mode(int modeId, int width, int height, float refreshRate, 1914 float[] alternativeRefreshRates) { 1915 mModeId = modeId; 1916 mWidth = width; 1917 mHeight = height; 1918 mRefreshRate = refreshRate; 1919 mAlternativeRefreshRates = 1920 Arrays.copyOf(alternativeRefreshRates, alternativeRefreshRates.length); 1921 Arrays.sort(mAlternativeRefreshRates); 1922 } 1923 1924 /** 1925 * Returns this mode's id. 1926 */ getModeId()1927 public int getModeId() { 1928 return mModeId; 1929 } 1930 1931 /** 1932 * Returns the physical width of the display in pixels when configured in this mode's 1933 * resolution. 1934 * <p> 1935 * Note that due to application UI scaling, the number of pixels made available to 1936 * applications when the mode is active (as reported by {@link Display#getWidth()} may 1937 * differ from the mode's actual resolution (as reported by this function). 1938 * <p> 1939 * For example, applications running on a 4K display may have their UI laid out and rendered 1940 * in 1080p and then scaled up. Applications can take advantage of the extra resolution by 1941 * rendering content through a {@link android.view.SurfaceView} using full size buffers. 1942 */ getPhysicalWidth()1943 public int getPhysicalWidth() { 1944 return mWidth; 1945 } 1946 1947 /** 1948 * Returns the physical height of the display in pixels when configured in this mode's 1949 * resolution. 1950 * <p> 1951 * Note that due to application UI scaling, the number of pixels made available to 1952 * applications when the mode is active (as reported by {@link Display#getHeight()} may 1953 * differ from the mode's actual resolution (as reported by this function). 1954 * <p> 1955 * For example, applications running on a 4K display may have their UI laid out and rendered 1956 * in 1080p and then scaled up. Applications can take advantage of the extra resolution by 1957 * rendering content through a {@link android.view.SurfaceView} using full size buffers. 1958 */ getPhysicalHeight()1959 public int getPhysicalHeight() { 1960 return mHeight; 1961 } 1962 1963 /** 1964 * Returns the refresh rate in frames per second. 1965 */ getRefreshRate()1966 public float getRefreshRate() { 1967 return mRefreshRate; 1968 } 1969 1970 /** 1971 * Returns an array of refresh rates which can be switched to seamlessly. 1972 * <p> 1973 * A seamless switch is one without visual interruptions, such as a black screen for 1974 * a second or two. 1975 * <p> 1976 * Presence in this list does not guarantee a switch will occur to the desired 1977 * refresh rate, but rather, if a switch does occur to a refresh rate in this list, 1978 * it is guaranteed to be seamless. 1979 * <p> 1980 * The binary relation "refresh rate X is alternative to Y" is non-reflexive, 1981 * symmetric and transitive. For example the mode 1920x1080 60Hz, will never have an 1982 * alternative refresh rate of 60Hz. If 1920x1080 60Hz has an alternative of 50Hz 1983 * then 1920x1080 50Hz will have alternative refresh rate of 60Hz. If 1920x1080 60Hz 1984 * has an alternative of 50Hz and 1920x1080 50Hz has an alternative of 24Hz, then 1920x1080 1985 * 60Hz will also have an alternative of 24Hz. 1986 * 1987 * @see Surface#setFrameRate 1988 * @see SurfaceControl.Transaction#setFrameRate 1989 */ 1990 @NonNull getAlternativeRefreshRates()1991 public float[] getAlternativeRefreshRates() { 1992 return mAlternativeRefreshRates; 1993 } 1994 1995 /** 1996 * Returns {@code true} if this mode matches the given parameters. 1997 * 1998 * @hide 1999 */ 2000 @TestApi matches(int width, int height, float refreshRate)2001 public boolean matches(int width, int height, float refreshRate) { 2002 return mWidth == width && 2003 mHeight == height && 2004 Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate); 2005 } 2006 2007 /** 2008 * Returns {@code true} if this mode matches the given parameters, if those parameters are 2009 * valid.<p> 2010 * If resolution (width and height) is valid and refresh-rate is not, the method matches 2011 * only resolution. 2012 * If refresh-rate is valid and resolution (width and height) is not, the method matches 2013 * only refresh-rate.</p> 2014 * 2015 * @hide 2016 */ matchesIfValid(int width, int height, float refreshRate)2017 public boolean matchesIfValid(int width, int height, float refreshRate) { 2018 if (!isWidthValid(width) && !isHeightValid(height) 2019 && !isRefreshRateValid(refreshRate)) { 2020 return false; 2021 } 2022 if (isWidthValid(width) != isHeightValid(height)) { 2023 return false; 2024 } 2025 return (!isWidthValid(width) || mWidth == width) 2026 && (!isHeightValid(height) || mHeight == height) 2027 && (!isRefreshRateValid(refreshRate) 2028 || Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate)); 2029 } 2030 2031 /** 2032 * Returns {@code true} if this mode equals to the other mode in all parameters except 2033 * the refresh rate. 2034 * 2035 * @hide 2036 */ equalsExceptRefreshRate(@ullable Display.Mode other)2037 public boolean equalsExceptRefreshRate(@Nullable Display.Mode other) { 2038 return mWidth == other.mWidth && mHeight == other.mHeight; 2039 } 2040 2041 /** 2042 * Returns {@code true} if refresh-rate is set for a display mode 2043 * 2044 * @hide 2045 */ isRefreshRateSet()2046 public boolean isRefreshRateSet() { 2047 return mRefreshRate != INVALID_DISPLAY_REFRESH_RATE; 2048 } 2049 2050 /** 2051 * Returns {@code true} if refresh-rate is set for a display mode 2052 * 2053 * @hide 2054 */ isResolutionSet()2055 public boolean isResolutionSet() { 2056 return mWidth != INVALID_DISPLAY_WIDTH && mHeight != INVALID_DISPLAY_HEIGHT; 2057 } 2058 2059 @Override equals(@ullable Object other)2060 public boolean equals(@Nullable Object other) { 2061 if (this == other) { 2062 return true; 2063 } 2064 if (!(other instanceof Mode)) { 2065 return false; 2066 } 2067 Mode that = (Mode) other; 2068 return mModeId == that.mModeId && matches(that.mWidth, that.mHeight, that.mRefreshRate) 2069 && Arrays.equals(mAlternativeRefreshRates, that.mAlternativeRefreshRates); 2070 } 2071 2072 @Override hashCode()2073 public int hashCode() { 2074 int hash = 1; 2075 hash = hash * 17 + mModeId; 2076 hash = hash * 17 + mWidth; 2077 hash = hash * 17 + mHeight; 2078 hash = hash * 17 + Float.floatToIntBits(mRefreshRate); 2079 hash = hash * 17 + Arrays.hashCode(mAlternativeRefreshRates); 2080 return hash; 2081 } 2082 2083 @Override toString()2084 public String toString() { 2085 return new StringBuilder("{") 2086 .append("id=").append(mModeId) 2087 .append(", width=").append(mWidth) 2088 .append(", height=").append(mHeight) 2089 .append(", fps=").append(mRefreshRate) 2090 .append(", alternativeRefreshRates=") 2091 .append(Arrays.toString(mAlternativeRefreshRates)) 2092 .append("}") 2093 .toString(); 2094 } 2095 2096 @Override describeContents()2097 public int describeContents() { 2098 return 0; 2099 } 2100 Mode(Parcel in)2101 private Mode(Parcel in) { 2102 this(in.readInt(), in.readInt(), in.readInt(), in.readFloat(), in.createFloatArray()); 2103 } 2104 2105 @Override writeToParcel(Parcel out, int parcelableFlags)2106 public void writeToParcel(Parcel out, int parcelableFlags) { 2107 out.writeInt(mModeId); 2108 out.writeInt(mWidth); 2109 out.writeInt(mHeight); 2110 out.writeFloat(mRefreshRate); 2111 out.writeFloatArray(mAlternativeRefreshRates); 2112 } 2113 2114 @SuppressWarnings("hiding") 2115 public static final @android.annotation.NonNull Parcelable.Creator<Mode> CREATOR 2116 = new Parcelable.Creator<Mode>() { 2117 @Override 2118 public Mode createFromParcel(Parcel in) { 2119 return new Mode(in); 2120 } 2121 2122 @Override 2123 public Mode[] newArray(int size) { 2124 return new Mode[size]; 2125 } 2126 }; 2127 2128 /** 2129 * Builder is used to create {@link Display.Mode} objects 2130 * 2131 * @hide 2132 */ 2133 @TestApi 2134 public static final class Builder { 2135 private int mWidth; 2136 private int mHeight; 2137 private float mRefreshRate; 2138 Builder()2139 public Builder() { 2140 mWidth = Display.INVALID_DISPLAY_WIDTH; 2141 mHeight = Display.INVALID_DISPLAY_HEIGHT; 2142 mRefreshRate = Display.INVALID_DISPLAY_REFRESH_RATE; 2143 } 2144 2145 /** 2146 * Sets the resolution (width and height) of a {@link Display.Mode} 2147 * 2148 * @return Instance of {@link Builder} 2149 */ 2150 @NonNull setResolution(int width, int height)2151 public Builder setResolution(int width, int height) { 2152 if (width > 0 && height > 0) { 2153 mWidth = width; 2154 mHeight = height; 2155 } 2156 return this; 2157 } 2158 2159 /** 2160 * Sets the refresh rate of a {@link Display.Mode} 2161 * 2162 * @return Instance of {@link Builder} 2163 */ 2164 @NonNull setRefreshRate(float refreshRate)2165 public Builder setRefreshRate(float refreshRate) { 2166 if (refreshRate > 0.0f) { 2167 mRefreshRate = refreshRate; 2168 } 2169 return this; 2170 } 2171 2172 /** 2173 * Creates the {@link Display.Mode} object. 2174 * 2175 * <p> 2176 * If resolution needs to be set, but refresh-rate doesn't matter, create a mode with 2177 * Builder and call setResolution. 2178 * {@code 2179 * Display.Mode mode = 2180 * new Display.Mode.Builder() 2181 * .setResolution(width, height) 2182 * .build(); 2183 * } 2184 * </p><p> 2185 * If refresh-rate needs to be set, but resolution doesn't matter, create a mode with 2186 * Builder and call setRefreshRate. 2187 * {@code 2188 * Display.Mode mode = 2189 * new Display.Mode.Builder() 2190 * .setRefreshRate(refreshRate) 2191 * .build(); 2192 * } 2193 * </p> 2194 */ 2195 @NonNull build()2196 public Mode build() { 2197 Display.Mode mode = new Mode(mWidth, mHeight, mRefreshRate); 2198 return mode; 2199 } 2200 } 2201 } 2202 2203 /** 2204 * Encapsulates the HDR capabilities of a given display. 2205 * For example, what HDR types it supports and details about the desired luminance data. 2206 * <p>You can get an instance for a given {@link Display} object with 2207 * {@link Display#getHdrCapabilities getHdrCapabilities()}. 2208 */ 2209 public static final class HdrCapabilities implements Parcelable { 2210 /** 2211 * Invalid luminance value. 2212 */ 2213 public static final float INVALID_LUMINANCE = -1; 2214 /** 2215 * Dolby Vision high dynamic range (HDR) display. 2216 */ 2217 public static final int HDR_TYPE_DOLBY_VISION = 1; 2218 /** 2219 * HDR10 display. 2220 */ 2221 public static final int HDR_TYPE_HDR10 = 2; 2222 /** 2223 * Hybrid Log-Gamma HDR display. 2224 */ 2225 public static final int HDR_TYPE_HLG = 3; 2226 2227 /** 2228 * HDR10+ display. 2229 */ 2230 public static final int HDR_TYPE_HDR10_PLUS = 4; 2231 2232 /** @hide */ 2233 public static final int[] HDR_TYPES = { 2234 HDR_TYPE_DOLBY_VISION, 2235 HDR_TYPE_HDR10, 2236 HDR_TYPE_HLG, 2237 HDR_TYPE_HDR10_PLUS 2238 }; 2239 2240 /** @hide */ 2241 @IntDef(prefix = { "HDR_TYPE_" }, value = { 2242 HDR_TYPE_DOLBY_VISION, 2243 HDR_TYPE_HDR10, 2244 HDR_TYPE_HLG, 2245 HDR_TYPE_HDR10_PLUS, 2246 }) 2247 @Retention(RetentionPolicy.SOURCE) 2248 public @interface HdrType {} 2249 2250 private @HdrType int[] mSupportedHdrTypes = new int[0]; 2251 private float mMaxLuminance = INVALID_LUMINANCE; 2252 private float mMaxAverageLuminance = INVALID_LUMINANCE; 2253 private float mMinLuminance = INVALID_LUMINANCE; 2254 2255 /** 2256 * @hide 2257 */ HdrCapabilities()2258 public HdrCapabilities() { 2259 } 2260 2261 /** 2262 * @hide 2263 */ 2264 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) HdrCapabilities(int[] supportedHdrTypes, float maxLuminance, float maxAverageLuminance, float minLuminance)2265 public HdrCapabilities(int[] supportedHdrTypes, float maxLuminance, 2266 float maxAverageLuminance, float minLuminance) { 2267 mSupportedHdrTypes = supportedHdrTypes; 2268 Arrays.sort(mSupportedHdrTypes); 2269 mMaxLuminance = maxLuminance; 2270 mMaxAverageLuminance = maxAverageLuminance; 2271 mMinLuminance = minLuminance; 2272 } 2273 2274 /** 2275 * Gets the supported HDR types of this display. 2276 * Returns empty array if HDR is not supported by the display. 2277 */ getSupportedHdrTypes()2278 public @HdrType int[] getSupportedHdrTypes() { 2279 return mSupportedHdrTypes; 2280 } 2281 /** 2282 * Returns the desired content max luminance data in cd/m2 for this display. 2283 */ getDesiredMaxLuminance()2284 public float getDesiredMaxLuminance() { 2285 return mMaxLuminance; 2286 } 2287 /** 2288 * Returns the desired content max frame-average luminance data in cd/m2 for this display. 2289 */ getDesiredMaxAverageLuminance()2290 public float getDesiredMaxAverageLuminance() { 2291 return mMaxAverageLuminance; 2292 } 2293 /** 2294 * Returns the desired content min luminance data in cd/m2 for this display. 2295 */ getDesiredMinLuminance()2296 public float getDesiredMinLuminance() { 2297 return mMinLuminance; 2298 } 2299 2300 @Override equals(@ullable Object other)2301 public boolean equals(@Nullable Object other) { 2302 if (this == other) { 2303 return true; 2304 } 2305 2306 if (!(other instanceof HdrCapabilities)) { 2307 return false; 2308 } 2309 HdrCapabilities that = (HdrCapabilities) other; 2310 2311 return Arrays.equals(mSupportedHdrTypes, that.mSupportedHdrTypes) 2312 && mMaxLuminance == that.mMaxLuminance 2313 && mMaxAverageLuminance == that.mMaxAverageLuminance 2314 && mMinLuminance == that.mMinLuminance; 2315 } 2316 2317 @Override hashCode()2318 public int hashCode() { 2319 int hash = 23; 2320 hash = hash * 17 + Arrays.hashCode(mSupportedHdrTypes); 2321 hash = hash * 17 + Float.floatToIntBits(mMaxLuminance); 2322 hash = hash * 17 + Float.floatToIntBits(mMaxAverageLuminance); 2323 hash = hash * 17 + Float.floatToIntBits(mMinLuminance); 2324 return hash; 2325 } 2326 2327 public static final @android.annotation.NonNull Creator<HdrCapabilities> CREATOR = new Creator<HdrCapabilities>() { 2328 @Override 2329 public HdrCapabilities createFromParcel(Parcel source) { 2330 return new HdrCapabilities(source); 2331 } 2332 2333 @Override 2334 public HdrCapabilities[] newArray(int size) { 2335 return new HdrCapabilities[size]; 2336 } 2337 }; 2338 HdrCapabilities(Parcel source)2339 private HdrCapabilities(Parcel source) { 2340 readFromParcel(source); 2341 } 2342 2343 /** 2344 * @hide 2345 */ readFromParcel(Parcel source)2346 public void readFromParcel(Parcel source) { 2347 int types = source.readInt(); 2348 mSupportedHdrTypes = new int[types]; 2349 for (int i = 0; i < types; ++i) { 2350 mSupportedHdrTypes[i] = source.readInt(); 2351 } 2352 mMaxLuminance = source.readFloat(); 2353 mMaxAverageLuminance = source.readFloat(); 2354 mMinLuminance = source.readFloat(); 2355 } 2356 2357 @Override writeToParcel(Parcel dest, int flags)2358 public void writeToParcel(Parcel dest, int flags) { 2359 dest.writeInt(mSupportedHdrTypes.length); 2360 for (int i = 0; i < mSupportedHdrTypes.length; ++i) { 2361 dest.writeInt(mSupportedHdrTypes[i]); 2362 } 2363 dest.writeFloat(mMaxLuminance); 2364 dest.writeFloat(mMaxAverageLuminance); 2365 dest.writeFloat(mMinLuminance); 2366 } 2367 2368 @Override describeContents()2369 public int describeContents() { 2370 return 0; 2371 } 2372 2373 @Override toString()2374 public String toString() { 2375 return "HdrCapabilities{" 2376 + "mSupportedHdrTypes=" + Arrays.toString(mSupportedHdrTypes) 2377 + ", mMaxLuminance=" + mMaxLuminance 2378 + ", mMaxAverageLuminance=" + mMaxAverageLuminance 2379 + ", mMinLuminance=" + mMinLuminance + '}'; 2380 } 2381 } 2382 } 2383