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