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 android.hardware.display.DeviceProductInfo; 20 import android.hardware.display.DisplayViewport; 21 import android.util.DisplayMetrics; 22 import android.view.Display; 23 import android.view.DisplayAddress; 24 import android.view.DisplayCutout; 25 import android.view.DisplayEventReceiver; 26 import android.view.RoundedCorners; 27 import android.view.Surface; 28 29 import com.android.internal.display.BrightnessSynchronizer; 30 31 import java.util.Arrays; 32 import java.util.Objects; 33 34 /** 35 * Describes the characteristics of a physical display device. 36 */ 37 final class DisplayDeviceInfo { 38 /** 39 * Flag: Indicates that this display device should be considered the default display 40 * device of the system. 41 */ 42 public static final int FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY = 1 << 0; 43 44 /** 45 * Flag: Indicates that the orientation of this display device is coupled to the 46 * rotation of its associated logical display. 47 * <p> 48 * This flag should be applied to the default display to indicate that the user 49 * physically rotates the display when content is presented in a different orientation. 50 * The display manager will apply a coordinate transformation assuming that the 51 * physical orientation of the display matches the logical orientation of its content. 52 * </p><p> 53 * The flag should not be set when the display device is mounted in a fixed orientation 54 * such as on a desk. The display manager will apply a coordinate transformation 55 * such as a scale and translation to letterbox or pillarbox format under the 56 * assumption that the physical orientation of the display is invariant. 57 * </p> 58 */ 59 public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1; 60 61 /** 62 * Flag: Indicates that this display device has secure video output, such as HDCP. 63 */ 64 public static final int FLAG_SECURE = 1 << 2; 65 66 /** 67 * Flag: Indicates that this display device supports compositing 68 * from gralloc protected buffers. 69 */ 70 public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3; 71 72 /** 73 * Flag: Indicates that the display device is owned by a particular application 74 * and that no other application should be able to interact with it. 75 * Should typically be used together with {@link #FLAG_OWN_CONTENT_ONLY}. 76 */ 77 public static final int FLAG_PRIVATE = 1 << 4; 78 79 /** 80 * Flag: Indicates that the display device is not blanked automatically by 81 * the power manager. 82 */ 83 public static final int FLAG_NEVER_BLANK = 1 << 5; 84 85 /** 86 * Flag: Indicates that the display is suitable for presentations. 87 */ 88 public static final int FLAG_PRESENTATION = 1 << 6; 89 90 /** 91 * Flag: Only show this display's own content; do not mirror 92 * the content of another display. 93 */ 94 public static final int FLAG_OWN_CONTENT_ONLY = 1 << 7; 95 96 /** 97 * Flag: This display device has a round shape. 98 */ 99 public static final int FLAG_ROUND = 1 << 8; 100 101 /** 102 * Flag: This display can show its content when non-secure keyguard is shown. 103 */ 104 // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard 105 public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 9; 106 107 /** 108 * Flag: This display will destroy its content on removal. 109 * @hide 110 */ 111 // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY 112 public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10; 113 114 /** 115 * Flag: The display cutout of this display is masked. 116 * @hide 117 */ 118 public static final int FLAG_MASK_DISPLAY_CUTOUT = 1 << 11; 119 120 /** 121 * Flag: This flag identifies secondary displays that should show system decorations, such as 122 * status bar, navigation bar, home activity or IME. 123 * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p> 124 * @hide 125 */ 126 // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors 127 public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 12; 128 129 /** 130 * Flag: The display is trusted to show system decorations and receive inputs without users' 131 * touch. 132 * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 133 */ 134 public static final int FLAG_TRUSTED = 1 << 13; 135 136 /** 137 * Flag: Indicates that the display should not be a part of the default {@link DisplayGroup} and 138 * instead be part of a new {@link DisplayGroup}. 139 * 140 * @hide 141 */ 142 public static final int FLAG_OWN_DISPLAY_GROUP = 1 << 14; 143 144 /** 145 * Flag: Indicates that the display should always be unlocked. Only valid on virtual displays 146 * that aren't in the default display group. 147 * @see #FLAG_OWN_DISPLAY_GROUP 148 * @hide 149 */ 150 public static final int FLAG_ALWAYS_UNLOCKED = 1 << 15; 151 152 /** 153 * Flag: Indicates that the display should not play sound effects or perform haptic feedback 154 * when the user touches the screen. 155 * 156 * @hide 157 */ 158 public static final int FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 16; 159 160 /** 161 * Touch attachment: Display does not receive touch. 162 */ 163 public static final int TOUCH_NONE = 0; 164 165 /** 166 * Touch attachment: Touch input is via the internal interface. 167 */ 168 public static final int TOUCH_INTERNAL = 1; 169 170 /** 171 * Touch attachment: Touch input is via an external interface, such as USB. 172 */ 173 public static final int TOUCH_EXTERNAL = 2; 174 175 /** 176 * Touch attachment: Touch input is via an input device matching {@link VirtualDisplay}'s 177 * uniqueId. 178 * @hide 179 */ 180 public static final int TOUCH_VIRTUAL = 3; 181 182 /** 183 * Diff result: The {@link #state} or {@link #committedState} fields differ. 184 */ 185 public static final int DIFF_STATE = 1 << 0; 186 187 /** 188 * Diff result: Other fields differ. 189 */ 190 public static final int DIFF_OTHER = 1 << 1; 191 192 /** 193 * Diff result: The color mode fields differ. 194 */ 195 public static final int DIFF_COLOR_MODE = 1 << 2; 196 197 /** 198 * Gets the name of the display device, which may be derived from EDID or 199 * other sources. The name may be localized and displayed to the user. 200 */ 201 public String name; 202 203 /** 204 * Unique Id of display device. 205 */ 206 public String uniqueId; 207 208 /** 209 * The width of the display in its natural orientation, in pixels. 210 * This value is not affected by display rotation. 211 */ 212 public int width; 213 214 /** 215 * The height of the display in its natural orientation, in pixels. 216 * This value is not affected by display rotation. 217 */ 218 public int height; 219 220 /** 221 * The active mode of the display. 222 */ 223 public int modeId; 224 225 /** 226 * The default mode of the display. 227 */ 228 public int defaultModeId; 229 230 /** 231 * The supported modes of the display. 232 */ 233 public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY; 234 235 /** The active color mode of the display */ 236 public int colorMode; 237 238 /** The supported color modes of the display */ 239 public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT }; 240 241 /** 242 * The HDR capabilities this display claims to support. 243 */ 244 public Display.HdrCapabilities hdrCapabilities; 245 246 /** 247 * Indicates whether this display supports Auto Low Latency Mode. 248 */ 249 public boolean allmSupported; 250 251 /** 252 * Indicates whether this display suppors Game content type. 253 */ 254 public boolean gameContentTypeSupported; 255 256 /** 257 * The nominal apparent density of the display in DPI used for layout calculations. 258 * This density is sensitive to the viewing distance. A big TV and a tablet may have 259 * the same apparent density even though the pixels on the TV are much bigger than 260 * those on the tablet. 261 */ 262 public int densityDpi; 263 264 /** 265 * The physical density of the display in DPI in the X direction. 266 * This density should specify the physical size of each pixel. 267 */ 268 public float xDpi; 269 270 /** 271 * The physical density of the display in DPI in the X direction. 272 * This density should specify the physical size of each pixel. 273 */ 274 public float yDpi; 275 276 /** 277 * This is a positive value indicating the phase offset of the VSYNC events provided by 278 * Choreographer relative to the display refresh. For example, if Choreographer reports 279 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos). 280 */ 281 public long appVsyncOffsetNanos; 282 283 /** 284 * This is how far in advance a buffer must be queued for presentation at 285 * a given time. If you want a buffer to appear on the screen at 286 * time N, you must submit the buffer before (N - bufferDeadlineNanos). 287 */ 288 public long presentationDeadlineNanos; 289 290 /** 291 * Display flags. 292 */ 293 public int flags; 294 295 /** 296 * The {@link DisplayCutout} if present or {@code null} otherwise. 297 */ 298 public DisplayCutout displayCutout; 299 300 /** 301 * The {@link RoundedCorners} if present or {@code null} otherwise. 302 */ 303 public RoundedCorners roundedCorners; 304 305 /** 306 * The touch attachment, per {@link DisplayViewport#touch}. 307 */ 308 public int touch; 309 310 /** 311 * The additional rotation to apply to all content presented on the display device 312 * relative to its physical coordinate system. Default is {@link Surface#ROTATION_0}. 313 * <p> 314 * This field can be used to compensate for the fact that the display has been 315 * physically rotated relative to its natural orientation such as an HDMI monitor 316 * that has been mounted sideways to appear to be portrait rather than landscape. 317 * </p> 318 */ 319 public int rotation = Surface.ROTATION_0; 320 321 /** 322 * Display type. 323 */ 324 public int type; 325 326 /** 327 * Display address, or null if none. 328 * Interpretation varies by display type. 329 */ 330 public DisplayAddress address; 331 332 /** 333 * Product-specific information about the display or the directly connected device on the 334 * display chain. For example, if the display is transitively connected, this field may contain 335 * product information about the intermediate device. 336 */ 337 public DeviceProductInfo deviceProductInfo; 338 339 /** 340 * Display state. 341 */ 342 public int state = Display.STATE_ON; 343 344 /** 345 * Display committed state. 346 * 347 * This matches {@link DisplayDeviceInfo#state} only after the power state change finishes. 348 */ 349 public int committedState = Display.STATE_UNKNOWN; 350 351 /** 352 * The UID of the application that owns this display, or zero if it is owned by the system. 353 * <p> 354 * If the display is private, then only the owner can use it. 355 * </p> 356 */ 357 public int ownerUid; 358 359 /** 360 * The package name of the application that owns this display, or null if it is 361 * owned by the system. 362 * <p> 363 * If the display is private, then only the owner can use it. 364 * </p> 365 */ 366 public String ownerPackageName; 367 368 public DisplayEventReceiver.FrameRateOverride[] frameRateOverrides = 369 new DisplayEventReceiver.FrameRateOverride[0]; 370 371 public float brightnessMinimum; 372 public float brightnessMaximum; 373 public float brightnessDefault; 374 375 /** 376 * Install orientation of display panel relative to its natural orientation. 377 */ 378 @Surface.Rotation 379 public int installOrientation = Surface.ROTATION_0; 380 setAssumedDensityForExternalDisplay(int width, int height)381 public void setAssumedDensityForExternalDisplay(int width, int height) { 382 densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; 383 // Technically, these values should be smaller than the apparent density 384 // but we don't know the physical size of the display. 385 xDpi = densityDpi; 386 yDpi = densityDpi; 387 } 388 389 @Override equals(Object o)390 public boolean equals(Object o) { 391 return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o); 392 } 393 equals(DisplayDeviceInfo other)394 public boolean equals(DisplayDeviceInfo other) { 395 return other != null && diff(other) == 0; 396 } 397 398 /** 399 * Computes the difference between display device infos. 400 * Assumes other is not null. 401 */ diff(DisplayDeviceInfo other)402 public int diff(DisplayDeviceInfo other) { 403 int diff = 0; 404 if (state != other.state || committedState != other.committedState) { 405 diff |= DIFF_STATE; 406 } 407 if (colorMode != other.colorMode) { 408 diff |= DIFF_COLOR_MODE; 409 } 410 if (!Objects.equals(name, other.name) 411 || !Objects.equals(uniqueId, other.uniqueId) 412 || width != other.width 413 || height != other.height 414 || modeId != other.modeId 415 || defaultModeId != other.defaultModeId 416 || !Arrays.equals(supportedModes, other.supportedModes) 417 || !Arrays.equals(supportedColorModes, other.supportedColorModes) 418 || !Objects.equals(hdrCapabilities, other.hdrCapabilities) 419 || allmSupported != other.allmSupported 420 || gameContentTypeSupported != other.gameContentTypeSupported 421 || densityDpi != other.densityDpi 422 || xDpi != other.xDpi 423 || yDpi != other.yDpi 424 || appVsyncOffsetNanos != other.appVsyncOffsetNanos 425 || presentationDeadlineNanos != other.presentationDeadlineNanos 426 || flags != other.flags 427 || !Objects.equals(displayCutout, other.displayCutout) 428 || touch != other.touch 429 || rotation != other.rotation 430 || type != other.type 431 || !Objects.equals(address, other.address) 432 || !Objects.equals(deviceProductInfo, other.deviceProductInfo) 433 || ownerUid != other.ownerUid 434 || !Objects.equals(ownerPackageName, other.ownerPackageName) 435 || !Arrays.equals(frameRateOverrides, other.frameRateOverrides) 436 || !BrightnessSynchronizer.floatEquals(brightnessMinimum, other.brightnessMinimum) 437 || !BrightnessSynchronizer.floatEquals(brightnessMaximum, other.brightnessMaximum) 438 || !BrightnessSynchronizer.floatEquals(brightnessDefault, 439 other.brightnessDefault) 440 || !Objects.equals(roundedCorners, other.roundedCorners) 441 || installOrientation != other.installOrientation) { 442 diff |= DIFF_OTHER; 443 } 444 return diff; 445 } 446 447 @Override hashCode()448 public int hashCode() { 449 return 0; // don't care 450 } 451 copyFrom(DisplayDeviceInfo other)452 public void copyFrom(DisplayDeviceInfo other) { 453 name = other.name; 454 uniqueId = other.uniqueId; 455 width = other.width; 456 height = other.height; 457 modeId = other.modeId; 458 defaultModeId = other.defaultModeId; 459 supportedModes = other.supportedModes; 460 colorMode = other.colorMode; 461 supportedColorModes = other.supportedColorModes; 462 hdrCapabilities = other.hdrCapabilities; 463 allmSupported = other.allmSupported; 464 gameContentTypeSupported = other.gameContentTypeSupported; 465 densityDpi = other.densityDpi; 466 xDpi = other.xDpi; 467 yDpi = other.yDpi; 468 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 469 presentationDeadlineNanos = other.presentationDeadlineNanos; 470 flags = other.flags; 471 displayCutout = other.displayCutout; 472 touch = other.touch; 473 rotation = other.rotation; 474 type = other.type; 475 address = other.address; 476 deviceProductInfo = other.deviceProductInfo; 477 state = other.state; 478 committedState = other.committedState; 479 ownerUid = other.ownerUid; 480 ownerPackageName = other.ownerPackageName; 481 frameRateOverrides = other.frameRateOverrides; 482 brightnessMinimum = other.brightnessMinimum; 483 brightnessMaximum = other.brightnessMaximum; 484 brightnessDefault = other.brightnessDefault; 485 roundedCorners = other.roundedCorners; 486 installOrientation = other.installOrientation; 487 } 488 489 // For debugging purposes 490 @Override toString()491 public String toString() { 492 StringBuilder sb = new StringBuilder(); 493 sb.append("DisplayDeviceInfo{\""); 494 sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", "); 495 sb.append(width).append(" x ").append(height); 496 sb.append(", modeId ").append(modeId); 497 sb.append(", defaultModeId ").append(defaultModeId); 498 sb.append(", supportedModes ").append(Arrays.toString(supportedModes)); 499 sb.append(", colorMode ").append(colorMode); 500 sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes)); 501 sb.append(", hdrCapabilities ").append(hdrCapabilities); 502 sb.append(", allmSupported ").append(allmSupported); 503 sb.append(", gameContentTypeSupported ").append(gameContentTypeSupported); 504 sb.append(", density ").append(densityDpi); 505 sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi"); 506 sb.append(", appVsyncOff ").append(appVsyncOffsetNanos); 507 sb.append(", presDeadline ").append(presentationDeadlineNanos); 508 if (displayCutout != null) { 509 sb.append(", cutout ").append(displayCutout); 510 } 511 sb.append(", touch ").append(touchToString(touch)); 512 sb.append(", rotation ").append(rotation); 513 sb.append(", type ").append(Display.typeToString(type)); 514 if (address != null) { 515 sb.append(", address ").append(address); 516 } 517 sb.append(", deviceProductInfo ").append(deviceProductInfo); 518 sb.append(", state ").append(Display.stateToString(state)); 519 sb.append(", committedState ").append(Display.stateToString(committedState)); 520 if (ownerUid != 0 || ownerPackageName != null) { 521 sb.append(", owner ").append(ownerPackageName); 522 sb.append(" (uid ").append(ownerUid).append(")"); 523 } 524 sb.append(", frameRateOverride "); 525 for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { 526 sb.append(frameRateOverride).append(" "); 527 } 528 sb.append(", brightnessMinimum ").append(brightnessMinimum); 529 sb.append(", brightnessMaximum ").append(brightnessMaximum); 530 sb.append(", brightnessDefault ").append(brightnessDefault); 531 if (roundedCorners != null) { 532 sb.append(", roundedCorners ").append(roundedCorners); 533 } 534 sb.append(flagsToString(flags)); 535 sb.append(", installOrientation ").append(installOrientation); 536 sb.append("}"); 537 return sb.toString(); 538 } 539 touchToString(int touch)540 private static String touchToString(int touch) { 541 switch (touch) { 542 case TOUCH_NONE: 543 return "NONE"; 544 case TOUCH_INTERNAL: 545 return "INTERNAL"; 546 case TOUCH_EXTERNAL: 547 return "EXTERNAL"; 548 case TOUCH_VIRTUAL: 549 return "VIRTUAL"; 550 default: 551 return Integer.toString(touch); 552 } 553 } 554 flagsToString(int flags)555 private static String flagsToString(int flags) { 556 StringBuilder msg = new StringBuilder(); 557 if ((flags & FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) { 558 msg.append(", FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY"); 559 } 560 if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) { 561 msg.append(", FLAG_ROTATES_WITH_CONTENT"); 562 } 563 if ((flags & FLAG_SECURE) != 0) { 564 msg.append(", FLAG_SECURE"); 565 } 566 if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 567 msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); 568 } 569 if ((flags & FLAG_PRIVATE) != 0) { 570 msg.append(", FLAG_PRIVATE"); 571 } 572 if ((flags & FLAG_NEVER_BLANK) != 0) { 573 msg.append(", FLAG_NEVER_BLANK"); 574 } 575 if ((flags & FLAG_PRESENTATION) != 0) { 576 msg.append(", FLAG_PRESENTATION"); 577 } 578 if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) { 579 msg.append(", FLAG_OWN_CONTENT_ONLY"); 580 } 581 if ((flags & FLAG_ROUND) != 0) { 582 msg.append(", FLAG_ROUND"); 583 } 584 if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 585 msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD"); 586 } 587 if ((flags & FLAG_MASK_DISPLAY_CUTOUT) != 0) { 588 msg.append(", FLAG_MASK_DISPLAY_CUTOUT"); 589 } 590 return msg.toString(); 591 } 592 } 593