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