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