1 /* 2 * Copyright (C) 2012 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 com.android.server.display; 18 19 import static android.view.Display.Mode.INVALID_MODE_ID; 20 21 import android.hardware.display.DeviceProductInfo; 22 import android.hardware.display.DisplayViewport; 23 import android.util.DisplayMetrics; 24 import android.view.Display; 25 import android.view.DisplayAddress; 26 import android.view.DisplayCutout; 27 import android.view.DisplayEventReceiver; 28 import android.view.DisplayShape; 29 import android.view.FrameRateCategoryRate; 30 import android.view.RoundedCorners; 31 import android.view.Surface; 32 33 import com.android.internal.display.BrightnessSynchronizer; 34 35 import java.util.Arrays; 36 import java.util.Objects; 37 38 /** 39 * Describes the characteristics of a physical display device. 40 */ 41 final class DisplayDeviceInfo { 42 /** 43 * Flag: Indicates that this display device should be considered the default display 44 * device of the system. 45 */ 46 public static final int FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY = 1 << 0; 47 48 /** 49 * Flag: Indicates that the orientation of this display device is coupled to the 50 * rotation of its associated logical display. 51 * <p> 52 * This flag should be applied to the default display to indicate that the user 53 * physically rotates the display when content is presented in a different orientation. 54 * The display manager will apply a coordinate transformation assuming that the 55 * physical orientation of the display matches the logical orientation of its content. 56 * </p><p> 57 * The flag should not be set when the display device is mounted in a fixed orientation 58 * such as on a desk. The display manager will apply a coordinate transformation 59 * such as a scale and translation to letterbox or pillarbox format under the 60 * assumption that the physical orientation of the display is invariant. 61 * </p> 62 */ 63 public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1; 64 65 /** 66 * Flag: Indicates that this display device has secure video output, such as HDCP. 67 */ 68 public static final int FLAG_SECURE = 1 << 2; 69 70 /** 71 * Flag: Indicates that this display device supports compositing 72 * from gralloc protected buffers. 73 */ 74 public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3; 75 76 /** 77 * Flag: Indicates that the display device is owned by a particular application 78 * and that no other application should be able to interact with it. 79 * Should typically be used together with {@link #FLAG_OWN_CONTENT_ONLY}. 80 */ 81 public static final int FLAG_PRIVATE = 1 << 4; 82 83 /** 84 * Flag: Indicates that the display device is not blanked automatically by 85 * the power manager. 86 */ 87 public static final int FLAG_NEVER_BLANK = 1 << 5; 88 89 /** 90 * Flag: Indicates that the display is suitable for presentations. 91 */ 92 public static final int FLAG_PRESENTATION = 1 << 6; 93 94 /** 95 * Flag: Only show this display's own content; do not mirror 96 * the content of another display. 97 */ 98 public static final int FLAG_OWN_CONTENT_ONLY = 1 << 7; 99 100 /** 101 * Flag: This display device has a round shape. 102 */ 103 public static final int FLAG_ROUND = 1 << 8; 104 105 /** 106 * Flag: This display can show its content when non-secure keyguard is shown. 107 */ 108 // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard 109 public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 9; 110 111 /** 112 * Flag: This display will destroy its content on removal. 113 * @hide 114 */ 115 // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY 116 public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10; 117 118 /** 119 * Flag: The display cutout of this display is masked. 120 * @hide 121 */ 122 public static final int FLAG_MASK_DISPLAY_CUTOUT = 1 << 11; 123 124 /** 125 * Flag: This flag identifies secondary displays that should always show system decorations, 126 * such as navigation bar, home activity or wallpaper. 127 * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p> 128 * @hide 129 */ 130 public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 12; 131 132 /** 133 * Flag: The display is trusted to show system decorations and receive inputs without users' 134 * touch. 135 * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 136 */ 137 public static final int FLAG_TRUSTED = 1 << 13; 138 139 /** 140 * Flag: Indicates that the display should not be a part of the default {@link DisplayGroup} and 141 * instead be part of a new {@link DisplayGroup}. 142 * 143 * @hide 144 */ 145 public static final int FLAG_OWN_DISPLAY_GROUP = 1 << 14; 146 147 /** 148 * Flag: Indicates that the display should always be unlocked. Only valid on virtual displays 149 * that aren't in the default display group. 150 * @see #FLAG_OWN_DISPLAY_GROUP and #FLAG_DEVICE_DISPLAY_GROUP 151 * @hide 152 */ 153 public static final int FLAG_ALWAYS_UNLOCKED = 1 << 15; 154 155 /** 156 * Flag: Indicates that the display should not play sound effects or perform haptic feedback 157 * when the user touches the screen. 158 * 159 * @hide 160 */ 161 public static final int FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 16; 162 163 /** 164 * Flag: Indicates that the display maintains its own focus and touch mode. 165 * 166 * This flag is similar to {@link com.android.internal.R.bool.config_perDisplayFocusEnabled} in 167 * behavior, but only applies to the specific display instead of system-wide to all displays. 168 * 169 * Note: The display must be trusted in order to have its own focus. 170 * 171 * @see #FLAG_TRUSTED 172 * @hide 173 */ 174 public static final int FLAG_OWN_FOCUS = 1 << 17; 175 176 /** 177 * Flag: indicates that the display should not be a part of the default {@link DisplayGroup} and 178 * instead be part of a {@link DisplayGroup} associated with the Virtual Device. 179 * 180 * @hide 181 */ 182 public static final int FLAG_DEVICE_DISPLAY_GROUP = 1 << 18; 183 184 /** 185 * Flag: Indicates that the display should not become the top focused display by stealing the 186 * top focus from another display. 187 * 188 * @see Display#FLAG_STEAL_TOP_FOCUS_DISABLED 189 * @hide 190 */ 191 public static final int FLAG_STEAL_TOP_FOCUS_DISABLED = 1 << 19; 192 193 /** 194 * Flag: Indicates that the display is allowed to switch the content mode between 195 * projected/extended and mirroring. This allows the display to dynamically add or remove the 196 * home and system decorations. 197 * 198 * Note that this flag should not be enabled with any of {@link #FLAG_PRIVATE}, 199 * {@link #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS}, or {@link #FLAG_OWN_CONTENT_ONLY} at the 200 * same time; otherwise it will be ignored. 201 * 202 * @hide 203 */ 204 public static final int FLAG_ALLOWS_CONTENT_MODE_SWITCH = 1 << 20; 205 206 /** 207 * Touch attachment: Display does not receive touch. 208 */ 209 public static final int TOUCH_NONE = 0; 210 211 /** 212 * Touch attachment: Touch input is via the internal interface. 213 */ 214 public static final int TOUCH_INTERNAL = 1; 215 216 /** 217 * Touch attachment: Touch input is via an external interface, such as USB. 218 */ 219 public static final int TOUCH_EXTERNAL = 2; 220 221 /** 222 * Touch attachment: Touch input is via an input device matching {@link VirtualDisplay}'s 223 * uniqueId. 224 * @hide 225 */ 226 public static final int TOUCH_VIRTUAL = 3; 227 228 /** 229 * Diff result: Other fields differ. 230 */ 231 public static final int DIFF_OTHER = 1 << 0; 232 233 /** 234 * Diff result: The {@link #state} or {@link #committedState} fields differ. 235 */ 236 public static final int DIFF_STATE = 1 << 1; 237 238 /** 239 * Diff result: The committed state differs. Note this is slightly different from the state, 240 * which is what most of the device should care about. 241 */ 242 public static final int DIFF_COMMITTED_STATE = 1 << 2; 243 244 /** 245 * Diff result: The color mode fields differ. 246 */ 247 public static final int DIFF_COLOR_MODE = 1 << 3; 248 249 /** 250 * Diff result: The hdr/sdr ratio differs 251 */ 252 public static final int DIFF_HDR_SDR_RATIO = 1 << 4; 253 254 /** 255 * Diff result: The rotation differs 256 */ 257 public static final int DIFF_ROTATION = 1 << 5; 258 259 /** 260 * Diff result: The render timings. Note this could be any of {@link #renderFrameRate}, 261 * {@link #presentationDeadlineNanos}, or {@link #appVsyncOffsetNanos}. 262 */ 263 public static final int DIFF_RENDER_TIMINGS = 1 << 6; 264 265 /** 266 * Diff result: The mode ID differs. 267 */ 268 public static final int DIFF_MODE_ID = 1 << 7; 269 270 /** 271 * Diff result: The frame rate override list differs. 272 */ 273 public static final int DIFF_FRAME_RATE_OVERRIDE = 1 << 8; 274 275 /** 276 * Diff result: Catch-all for "everything changed" 277 */ 278 public static final int DIFF_EVERYTHING = 0XFFFFFFFF; 279 280 /** 281 * Gets the name of the display device, which may be derived from EDID or 282 * other sources. The name may be localized and displayed to the user. 283 */ 284 public String name; 285 286 /** 287 * Unique Id of display device. 288 */ 289 public String uniqueId; 290 291 /** 292 * The width of the display in its natural orientation, in pixels. 293 * This value is not affected by display rotation. 294 */ 295 public int width; 296 297 /** 298 * The height of the display in its natural orientation, in pixels. 299 * This value is not affected by display rotation. 300 */ 301 public int height; 302 303 /** 304 * The active mode of the display. 305 */ 306 public int modeId; 307 308 /** 309 * The render frame rate this display is scheduled at. 310 * @see android.view.DisplayInfo#renderFrameRate for more details. 311 */ 312 public float renderFrameRate; 313 314 315 /** 316 * If {@code true}, this Display supports adaptive refresh rates. 317 * @see android.view.DisplayInfo#hasArrSupport for more details. 318 */ 319 public boolean hasArrSupport; 320 321 /** 322 * Represents frame rate for the FrameRateCategory Normal and High. 323 * @see android.view.Display#getSuggestedFrameRate(int) for more details. 324 */ 325 public FrameRateCategoryRate frameRateCategoryRate; 326 /** 327 * All the refresh rates supported for the default display mode. 328 */ 329 public float[] supportedRefreshRates = new float[0]; 330 331 /** 332 * The default mode of the display. 333 */ 334 public int defaultModeId; 335 336 /** 337 * The mode of the display which is preferred by user. 338 */ 339 public int userPreferredModeId = INVALID_MODE_ID; 340 341 /** 342 * The supported modes of the display. 343 */ 344 public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY; 345 346 /** The active color mode of the display */ 347 public int colorMode; 348 349 /** The supported color modes of the display */ 350 public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT }; 351 352 /** 353 * The HDR capabilities this display claims to support. 354 */ 355 public Display.HdrCapabilities hdrCapabilities; 356 357 /** When true, all HDR capabilities are hidden from public APIs */ 358 public boolean isForceSdr; 359 360 /** 361 * Indicates whether this display supports Auto Low Latency Mode. 362 */ 363 public boolean allmSupported; 364 365 /** 366 * Indicates whether this display supports Game content type. 367 */ 368 public boolean gameContentTypeSupported; 369 370 /** 371 * The nominal apparent density of the display in DPI used for layout calculations. 372 * This density is sensitive to the viewing distance. A big TV and a tablet may have 373 * the same apparent density even though the pixels on the TV are much bigger than 374 * those on the tablet. 375 */ 376 public int densityDpi; 377 378 /** 379 * The physical density of the display in DPI in the X direction. 380 * This density should specify the physical size of each pixel. 381 */ 382 public float xDpi; 383 384 /** 385 * The physical density of the display in DPI in the X direction. 386 * This density should specify the physical size of each pixel. 387 */ 388 public float yDpi; 389 390 /** 391 * This is a positive value indicating the phase offset of the VSYNC events provided by 392 * Choreographer relative to the display refresh. For example, if Choreographer reports 393 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos). 394 */ 395 public long appVsyncOffsetNanos; 396 397 /** 398 * This is how far in advance a buffer must be queued for presentation at 399 * a given time. If you want a buffer to appear on the screen at 400 * time N, you must submit the buffer before (N - bufferDeadlineNanos). 401 */ 402 public long presentationDeadlineNanos; 403 404 /** 405 * Display flags. 406 */ 407 public int flags; 408 409 /** 410 * The {@link DisplayCutout} if present or {@code null} otherwise. 411 */ 412 public DisplayCutout displayCutout; 413 414 /** 415 * The {@link RoundedCorners} if present or {@code null} otherwise. 416 */ 417 public RoundedCorners roundedCorners; 418 419 /** 420 * The {@link RoundedCorners} if present or {@code null} otherwise. 421 */ 422 public DisplayShape displayShape; 423 424 /** 425 * The touch attachment, per {@link DisplayViewport#touch}. 426 */ 427 public int touch; 428 429 /** 430 * The additional rotation to apply to all content presented on the display device 431 * relative to its physical coordinate system. Default is {@link Surface#ROTATION_0}. 432 * <p> 433 * This field can be used to compensate for the fact that the display has been 434 * physically rotated relative to its natural orientation such as an HDMI monitor 435 * that has been mounted sideways to appear to be portrait rather than landscape. 436 * </p> 437 */ 438 public int rotation = Surface.ROTATION_0; 439 440 /** 441 * Display type. 442 */ 443 public int type; 444 445 /** 446 * Display address, or null if none. 447 * Interpretation varies by display type. 448 */ 449 public DisplayAddress address; 450 451 /** 452 * Product-specific information about the display or the directly connected device on the 453 * display chain. For example, if the display is transitively connected, this field may contain 454 * product information about the intermediate device. 455 */ 456 public DeviceProductInfo deviceProductInfo; 457 458 /** 459 * Display state. 460 */ 461 public int state = Display.STATE_ON; 462 463 /** 464 * Display committed state. 465 * 466 * This matches {@link DisplayDeviceInfo#state} only after the power state change finishes. 467 */ 468 public int committedState = Display.STATE_UNKNOWN; 469 470 /** 471 * The UID of the application that owns this display, or zero if it is owned by the system. 472 * <p> 473 * If the display is private, then only the owner can use it. 474 * </p> 475 */ 476 public int ownerUid; 477 478 /** 479 * The package name of the application that owns this display, or null if it is 480 * owned by the system. 481 * <p> 482 * If the display is private, then only the owner can use it. 483 * </p> 484 */ 485 public String ownerPackageName; 486 487 public DisplayEventReceiver.FrameRateOverride[] frameRateOverrides = 488 new DisplayEventReceiver.FrameRateOverride[0]; 489 490 public float brightnessMinimum; 491 public float brightnessMaximum; 492 public float brightnessDefault; 493 public float brightnessDim; 494 495 // NaN means unsupported 496 public float hdrSdrRatio = Float.NaN; 497 498 /** 499 * Install orientation of display panel relative to its natural orientation. 500 */ 501 @Surface.Rotation 502 public int installOrientation = Surface.ROTATION_0; 503 setAssumedDensityForExternalDisplay(int width, int height)504 public void setAssumedDensityForExternalDisplay(int width, int height) { 505 densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; 506 // Technically, these values should be smaller than the apparent density 507 // but we don't know the physical size of the display. 508 xDpi = densityDpi; 509 yDpi = densityDpi; 510 } 511 512 @Override equals(Object o)513 public boolean equals(Object o) { 514 return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o); 515 } 516 equals(DisplayDeviceInfo other)517 public boolean equals(DisplayDeviceInfo other) { 518 return other != null && diff(other) == 0; 519 } 520 521 /** 522 * Computes the difference between display device infos. 523 * Assumes other is not null. 524 */ diff(DisplayDeviceInfo other)525 public int diff(DisplayDeviceInfo other) { 526 int diff = 0; 527 if (state != other.state) { 528 diff |= DIFF_STATE; 529 } 530 if (committedState != other.committedState) { 531 diff |= DIFF_COMMITTED_STATE; 532 } 533 if (colorMode != other.colorMode) { 534 diff |= DIFF_COLOR_MODE; 535 } 536 if (!BrightnessSynchronizer.floatEquals(hdrSdrRatio, other.hdrSdrRatio)) { 537 diff |= DIFF_HDR_SDR_RATIO; 538 } 539 if (rotation != other.rotation) { 540 diff |= DIFF_ROTATION; 541 } 542 if (renderFrameRate != other.renderFrameRate 543 || presentationDeadlineNanos != other.presentationDeadlineNanos 544 || appVsyncOffsetNanos != other.appVsyncOffsetNanos) { 545 diff |= DIFF_RENDER_TIMINGS; 546 } 547 if (modeId != other.modeId) { 548 diff |= DIFF_MODE_ID; 549 } 550 if (!Arrays.equals(frameRateOverrides, other.frameRateOverrides)) { 551 diff |= DIFF_FRAME_RATE_OVERRIDE; 552 } 553 if (!Objects.equals(name, other.name) 554 || !Objects.equals(uniqueId, other.uniqueId) 555 || width != other.width 556 || height != other.height 557 || defaultModeId != other.defaultModeId 558 || userPreferredModeId != other.userPreferredModeId 559 || !Arrays.equals(supportedModes, other.supportedModes) 560 || !Arrays.equals(supportedColorModes, other.supportedColorModes) 561 || !Objects.equals(hdrCapabilities, other.hdrCapabilities) 562 || isForceSdr != other.isForceSdr 563 || allmSupported != other.allmSupported 564 || gameContentTypeSupported != other.gameContentTypeSupported 565 || densityDpi != other.densityDpi 566 || xDpi != other.xDpi 567 || yDpi != other.yDpi 568 || flags != other.flags 569 || !Objects.equals(displayCutout, other.displayCutout) 570 || touch != other.touch 571 || type != other.type 572 || !Objects.equals(address, other.address) 573 || !Objects.equals(deviceProductInfo, other.deviceProductInfo) 574 || ownerUid != other.ownerUid 575 || !Objects.equals(ownerPackageName, other.ownerPackageName) 576 || !BrightnessSynchronizer.floatEquals(brightnessMinimum, other.brightnessMinimum) 577 || !BrightnessSynchronizer.floatEquals(brightnessMaximum, other.brightnessMaximum) 578 || !BrightnessSynchronizer.floatEquals(brightnessDefault, other.brightnessDefault) 579 || !BrightnessSynchronizer.floatEquals(brightnessDim, other.brightnessDim) 580 || !Objects.equals(roundedCorners, other.roundedCorners) 581 || installOrientation != other.installOrientation 582 || !Objects.equals(displayShape, other.displayShape) 583 || hasArrSupport != other.hasArrSupport 584 || !Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate) 585 || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)) { 586 diff |= DIFF_OTHER; 587 } 588 return diff; 589 } 590 591 @Override hashCode()592 public int hashCode() { 593 return 0; // don't care 594 } 595 copyFrom(DisplayDeviceInfo other)596 public void copyFrom(DisplayDeviceInfo other) { 597 name = other.name; 598 uniqueId = other.uniqueId; 599 width = other.width; 600 height = other.height; 601 modeId = other.modeId; 602 renderFrameRate = other.renderFrameRate; 603 hasArrSupport = other.hasArrSupport; 604 frameRateCategoryRate = other.frameRateCategoryRate; 605 supportedRefreshRates = other.supportedRefreshRates; 606 defaultModeId = other.defaultModeId; 607 userPreferredModeId = other.userPreferredModeId; 608 supportedModes = other.supportedModes; 609 colorMode = other.colorMode; 610 supportedColorModes = other.supportedColorModes; 611 hdrCapabilities = other.hdrCapabilities; 612 isForceSdr = other.isForceSdr; 613 allmSupported = other.allmSupported; 614 gameContentTypeSupported = other.gameContentTypeSupported; 615 densityDpi = other.densityDpi; 616 xDpi = other.xDpi; 617 yDpi = other.yDpi; 618 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 619 presentationDeadlineNanos = other.presentationDeadlineNanos; 620 flags = other.flags; 621 displayCutout = other.displayCutout; 622 touch = other.touch; 623 rotation = other.rotation; 624 type = other.type; 625 address = other.address; 626 deviceProductInfo = other.deviceProductInfo; 627 state = other.state; 628 committedState = other.committedState; 629 ownerUid = other.ownerUid; 630 ownerPackageName = other.ownerPackageName; 631 frameRateOverrides = other.frameRateOverrides; 632 brightnessMinimum = other.brightnessMinimum; 633 brightnessMaximum = other.brightnessMaximum; 634 brightnessDefault = other.brightnessDefault; 635 brightnessDim = other.brightnessDim; 636 hdrSdrRatio = other.hdrSdrRatio; 637 roundedCorners = other.roundedCorners; 638 installOrientation = other.installOrientation; 639 displayShape = other.displayShape; 640 } 641 642 // For debugging purposes 643 @Override toString()644 public String toString() { 645 StringBuilder sb = new StringBuilder(); 646 sb.append("DisplayDeviceInfo{\""); 647 sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", "); 648 sb.append(width).append(" x ").append(height); 649 sb.append(", modeId ").append(modeId); 650 sb.append(", renderFrameRate ").append(renderFrameRate); 651 sb.append(", hasArrSupport ").append(hasArrSupport); 652 sb.append(", frameRateCategoryRate ").append(frameRateCategoryRate); 653 sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates)); 654 sb.append(", defaultModeId ").append(defaultModeId); 655 sb.append(", userPreferredModeId ").append(userPreferredModeId); 656 sb.append(", supportedModes ").append(Arrays.toString(supportedModes)); 657 sb.append(", colorMode ").append(colorMode); 658 sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes)); 659 sb.append(", hdrCapabilities ").append(hdrCapabilities); 660 sb.append(", isForceSdr ").append(isForceSdr); 661 sb.append(", allmSupported ").append(allmSupported); 662 sb.append(", gameContentTypeSupported ").append(gameContentTypeSupported); 663 sb.append(", density ").append(densityDpi); 664 sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi"); 665 sb.append(", appVsyncOff ").append(appVsyncOffsetNanos); 666 sb.append(", presDeadline ").append(presentationDeadlineNanos); 667 if (displayCutout != null) { 668 sb.append(", cutout ").append(displayCutout); 669 } 670 sb.append(", touch ").append(touchToString(touch)); 671 sb.append(", rotation ").append(rotation); 672 sb.append(", type ").append(Display.typeToString(type)); 673 if (address != null) { 674 sb.append(", address ").append(address); 675 } 676 sb.append(", deviceProductInfo ").append(deviceProductInfo); 677 sb.append(", state ").append(Display.stateToString(state)); 678 sb.append(", committedState ").append(Display.stateToString(committedState)); 679 if (ownerUid != 0 || ownerPackageName != null) { 680 sb.append(", owner ").append(ownerPackageName); 681 sb.append(" (uid ").append(ownerUid).append(")"); 682 } 683 sb.append(", frameRateOverride "); 684 for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { 685 sb.append(frameRateOverride).append(" "); 686 } 687 sb.append(", brightnessMinimum ").append(brightnessMinimum); 688 sb.append(", brightnessMaximum ").append(brightnessMaximum); 689 sb.append(", brightnessDefault ").append(brightnessDefault); 690 sb.append(", brightnessDim ").append(brightnessDim); 691 sb.append(", hdrSdrRatio ").append(hdrSdrRatio); 692 if (roundedCorners != null) { 693 sb.append(", roundedCorners ").append(roundedCorners); 694 } 695 sb.append(flagsToString(flags)); 696 sb.append(", installOrientation ").append(installOrientation); 697 if (displayShape != null) { 698 sb.append(", displayShape ").append(displayShape); 699 } 700 sb.append("}"); 701 return sb.toString(); 702 } 703 touchToString(int touch)704 private static String touchToString(int touch) { 705 switch (touch) { 706 case TOUCH_NONE: 707 return "NONE"; 708 case TOUCH_INTERNAL: 709 return "INTERNAL"; 710 case TOUCH_EXTERNAL: 711 return "EXTERNAL"; 712 case TOUCH_VIRTUAL: 713 return "VIRTUAL"; 714 default: 715 return Integer.toString(touch); 716 } 717 } 718 flagsToString(int flags)719 private static String flagsToString(int flags) { 720 StringBuilder msg = new StringBuilder(); 721 if ((flags & FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) { 722 msg.append(", FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY"); 723 } 724 if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) { 725 msg.append(", FLAG_ROTATES_WITH_CONTENT"); 726 } 727 if ((flags & FLAG_SECURE) != 0) { 728 msg.append(", FLAG_SECURE"); 729 } 730 if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 731 msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); 732 } 733 if ((flags & FLAG_PRIVATE) != 0) { 734 msg.append(", FLAG_PRIVATE"); 735 } 736 if ((flags & FLAG_NEVER_BLANK) != 0) { 737 msg.append(", FLAG_NEVER_BLANK"); 738 } 739 if ((flags & FLAG_PRESENTATION) != 0) { 740 msg.append(", FLAG_PRESENTATION"); 741 } 742 if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) { 743 msg.append(", FLAG_OWN_CONTENT_ONLY"); 744 } 745 if ((flags & FLAG_ROUND) != 0) { 746 msg.append(", FLAG_ROUND"); 747 } 748 if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 749 msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD"); 750 } 751 if ((flags & FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) { 752 msg.append(", FLAG_DESTROY_CONTENT_ON_REMOVAL"); 753 } 754 if ((flags & FLAG_MASK_DISPLAY_CUTOUT) != 0) { 755 msg.append(", FLAG_MASK_DISPLAY_CUTOUT"); 756 } 757 if ((flags & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) { 758 msg.append(", FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS"); 759 } 760 if ((flags & FLAG_TRUSTED) != 0) { 761 msg.append(", FLAG_TRUSTED"); 762 } 763 if ((flags & FLAG_OWN_DISPLAY_GROUP) != 0) { 764 msg.append(", FLAG_OWN_DISPLAY_GROUP"); 765 } 766 if ((flags & FLAG_ALWAYS_UNLOCKED) != 0) { 767 msg.append(", FLAG_ALWAYS_UNLOCKED"); 768 } 769 if ((flags & FLAG_TOUCH_FEEDBACK_DISABLED) != 0) { 770 msg.append(", FLAG_TOUCH_FEEDBACK_DISABLED"); 771 } 772 if ((flags & FLAG_OWN_FOCUS) != 0) { 773 msg.append(", FLAG_OWN_FOCUS"); 774 } 775 if ((flags & FLAG_STEAL_TOP_FOCUS_DISABLED) != 0) { 776 msg.append(", FLAG_STEAL_TOP_FOCUS_DISABLED"); 777 } 778 return msg.toString(); 779 } 780 } 781