DisplayDeviceInfo.java revision 58e829f71d2c525309e5bb5a1c02dc64397df221
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 17package com.android.server.display; 18 19import android.hardware.display.DisplayViewport; 20import android.util.DisplayMetrics; 21import android.view.Display; 22import android.view.Surface; 23 24import java.util.Arrays; 25 26import libcore.util.Objects; 27 28/** 29 * Describes the characteristics of a physical display device. 30 */ 31final 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 nominal apparent density of the display in DPI used for layout calculations. 169 * This density is sensitive to the viewing distance. A big TV and a tablet may have 170 * the same apparent density even though the pixels on the TV are much bigger than 171 * those on the tablet. 172 */ 173 public int densityDpi; 174 175 /** 176 * The physical density of the display in DPI in the X direction. 177 * This density should specify the physical size of each pixel. 178 */ 179 public float xDpi; 180 181 /** 182 * The physical density of the display in DPI in the X direction. 183 * This density should specify the physical size of each pixel. 184 */ 185 public float yDpi; 186 187 /** 188 * This is a positive value indicating the phase offset of the VSYNC events provided by 189 * Choreographer relative to the display refresh. For example, if Choreographer reports 190 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos). 191 */ 192 public long appVsyncOffsetNanos; 193 194 /** 195 * This is how far in advance a buffer must be queued for presentation at 196 * a given time. If you want a buffer to appear on the screen at 197 * time N, you must submit the buffer before (N - bufferDeadlineNanos). 198 */ 199 public long presentationDeadlineNanos; 200 201 /** 202 * Display flags. 203 */ 204 public int flags; 205 206 /** 207 * The touch attachment, per {@link DisplayViewport#touch}. 208 */ 209 public int touch; 210 211 /** 212 * The additional rotation to apply to all content presented on the display device 213 * relative to its physical coordinate system. Default is {@link Surface#ROTATION_0}. 214 * <p> 215 * This field can be used to compensate for the fact that the display has been 216 * physically rotated relative to its natural orientation such as an HDMI monitor 217 * that has been mounted sideways to appear to be portrait rather than landscape. 218 * </p> 219 */ 220 public int rotation = Surface.ROTATION_0; 221 222 /** 223 * Display type. 224 */ 225 public int type; 226 227 /** 228 * Display address, or null if none. 229 * Interpretation varies by display type. 230 */ 231 public String address; 232 233 /** 234 * Display state. 235 */ 236 public int state = Display.STATE_ON; 237 238 /** 239 * The UID of the application that owns this display, or zero if it is owned by the system. 240 * <p> 241 * If the display is private, then only the owner can use it. 242 * </p> 243 */ 244 public int ownerUid; 245 246 /** 247 * The package name of the application that owns this display, or null if it is 248 * owned by the system. 249 * <p> 250 * If the display is private, then only the owner can use it. 251 * </p> 252 */ 253 public String ownerPackageName; 254 255 public void setAssumedDensityForExternalDisplay(int width, int height) { 256 densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; 257 // Technically, these values should be smaller than the apparent density 258 // but we don't know the physical size of the display. 259 xDpi = densityDpi; 260 yDpi = densityDpi; 261 } 262 263 @Override 264 public boolean equals(Object o) { 265 return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o); 266 } 267 268 public boolean equals(DisplayDeviceInfo other) { 269 return other != null && diff(other) == 0; 270 } 271 272 /** 273 * Computes the difference between display device infos. 274 * Assumes other is not null. 275 */ 276 public int diff(DisplayDeviceInfo other) { 277 int diff = 0; 278 if (state != other.state) { 279 diff |= DIFF_STATE; 280 } 281 if (!Objects.equal(name, other.name) 282 || !Objects.equal(uniqueId, other.uniqueId) 283 || width != other.width 284 || height != other.height 285 || modeId != other.modeId 286 || defaultModeId != other.defaultModeId 287 || !Arrays.equals(supportedModes, other.supportedModes) 288 || colorTransformId != other.colorTransformId 289 || defaultColorTransformId != other.defaultColorTransformId 290 || !Arrays.equals(supportedColorTransforms, other.supportedColorTransforms) 291 || densityDpi != other.densityDpi 292 || xDpi != other.xDpi 293 || yDpi != other.yDpi 294 || appVsyncOffsetNanos != other.appVsyncOffsetNanos 295 || presentationDeadlineNanos != other.presentationDeadlineNanos 296 || flags != other.flags 297 || touch != other.touch 298 || rotation != other.rotation 299 || type != other.type 300 || !Objects.equal(address, other.address) 301 || ownerUid != other.ownerUid 302 || !Objects.equal(ownerPackageName, other.ownerPackageName)) { 303 diff |= DIFF_OTHER; 304 } 305 return diff; 306 } 307 308 @Override 309 public int hashCode() { 310 return 0; // don't care 311 } 312 313 public void copyFrom(DisplayDeviceInfo other) { 314 name = other.name; 315 uniqueId = other.uniqueId; 316 width = other.width; 317 height = other.height; 318 modeId = other.modeId; 319 defaultModeId = other.defaultModeId; 320 supportedModes = other.supportedModes; 321 colorTransformId = other.colorTransformId; 322 defaultColorTransformId = other.defaultColorTransformId; 323 supportedColorTransforms = other.supportedColorTransforms; 324 densityDpi = other.densityDpi; 325 xDpi = other.xDpi; 326 yDpi = other.yDpi; 327 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 328 presentationDeadlineNanos = other.presentationDeadlineNanos; 329 flags = other.flags; 330 touch = other.touch; 331 rotation = other.rotation; 332 type = other.type; 333 address = other.address; 334 state = other.state; 335 ownerUid = other.ownerUid; 336 ownerPackageName = other.ownerPackageName; 337 } 338 339 // For debugging purposes 340 @Override 341 public String toString() { 342 StringBuilder sb = new StringBuilder(); 343 sb.append("DisplayDeviceInfo{\""); 344 sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", "); 345 sb.append(width).append(" x ").append(height); 346 sb.append(", modeId ").append(modeId); 347 sb.append(", defaultModeId ").append(defaultModeId); 348 sb.append(", supportedModes ").append(Arrays.toString(supportedModes)); 349 sb.append(", colorTransformId ").append(colorTransformId); 350 sb.append(", defaultColorTransformId ").append(defaultColorTransformId); 351 sb.append(", supportedColorTransforms ").append(Arrays.toString(supportedColorTransforms)); 352 sb.append(", density ").append(densityDpi); 353 sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi"); 354 sb.append(", appVsyncOff ").append(appVsyncOffsetNanos); 355 sb.append(", presDeadline ").append(presentationDeadlineNanos); 356 sb.append(", touch ").append(touchToString(touch)); 357 sb.append(", rotation ").append(rotation); 358 sb.append(", type ").append(Display.typeToString(type)); 359 if (address != null) { 360 sb.append(", address ").append(address); 361 } 362 sb.append(", state ").append(Display.stateToString(state)); 363 if (ownerUid != 0 || ownerPackageName != null) { 364 sb.append(", owner ").append(ownerPackageName); 365 sb.append(" (uid ").append(ownerUid).append(")"); 366 } 367 sb.append(flagsToString(flags)); 368 sb.append("}"); 369 return sb.toString(); 370 } 371 372 private static String touchToString(int touch) { 373 switch (touch) { 374 case TOUCH_NONE: 375 return "NONE"; 376 case TOUCH_INTERNAL: 377 return "INTERNAL"; 378 case TOUCH_EXTERNAL: 379 return "EXTERNAL"; 380 default: 381 return Integer.toString(touch); 382 } 383 } 384 385 private static String flagsToString(int flags) { 386 StringBuilder msg = new StringBuilder(); 387 if ((flags & FLAG_DEFAULT_DISPLAY) != 0) { 388 msg.append(", FLAG_DEFAULT_DISPLAY"); 389 } 390 if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) { 391 msg.append(", FLAG_ROTATES_WITH_CONTENT"); 392 } 393 if ((flags & FLAG_SECURE) != 0) { 394 msg.append(", FLAG_SECURE"); 395 } 396 if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 397 msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); 398 } 399 if ((flags & FLAG_PRIVATE) != 0) { 400 msg.append(", FLAG_PRIVATE"); 401 } 402 if ((flags & FLAG_NEVER_BLANK) != 0) { 403 msg.append(", FLAG_NEVER_BLANK"); 404 } 405 if ((flags & FLAG_PRESENTATION) != 0) { 406 msg.append(", FLAG_PRESENTATION"); 407 } 408 if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) { 409 msg.append(", FLAG_OWN_CONTENT_ONLY"); 410 } 411 if ((flags & FLAG_ROUND) != 0) { 412 msg.append(", FLAG_ROUND"); 413 } 414 return msg.toString(); 415 } 416} 417