DisplayDeviceInfo.java revision 10acf6d3efde60977d2d2e82b90c53d722d9d357
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* 289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2012 The Android Open Source Project 389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5a64c8c79af1a15911c55306d83a797fa50969f77niko * you may not use this file except in compliance with the License. 6a64c8c79af1a15911c55306d83a797fa50969f77niko * You may obtain a copy of the License at 7a64c8c79af1a15911c55306d83a797fa50969f77niko * 8a64c8c79af1a15911c55306d83a797fa50969f77niko * http://www.apache.org/licenses/LICENSE-2.0 9a64c8c79af1a15911c55306d83a797fa50969f77niko * 10a64c8c79af1a15911c55306d83a797fa50969f77niko * Unless required by applicable law or agreed to in writing, software 11a64c8c79af1a15911c55306d83a797fa50969f77niko * distributed under the License is distributed on an "AS IS" BASIS, 12a64c8c79af1a15911c55306d83a797fa50969f77niko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a64c8c79af1a15911c55306d83a797fa50969f77niko * See the License for the specific language governing permissions and 14a64c8c79af1a15911c55306d83a797fa50969f77niko * limitations under the License. 15a64c8c79af1a15911c55306d83a797fa50969f77niko */ 16a64c8c79af1a15911c55306d83a797fa50969f77niko 17a64c8c79af1a15911c55306d83a797fa50969f77nikopackage com.android.server.display; 18a64c8c79af1a15911c55306d83a797fa50969f77niko 19a64c8c79af1a15911c55306d83a797fa50969f77nikoimport android.hardware.display.DisplayViewport; 20a64c8c79af1a15911c55306d83a797fa50969f77nikoimport android.util.DisplayMetrics; 21a64c8c79af1a15911c55306d83a797fa50969f77nikoimport android.view.Display; 22a64c8c79af1a15911c55306d83a797fa50969f77nikoimport android.view.Surface; 23c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent 24413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberimport java.util.Arrays; 25413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 26413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberimport libcore.util.EmptyArray; 27413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberimport libcore.util.Objects; 28413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber 29413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber/** 30413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * Describes the characteristics of a physical display device. 31413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber */ 32413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberfinal class DisplayDeviceInfo { 3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project /** 3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Flag: Indicates that this display device should be considered the default display 35413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * device of the system. 3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */ 3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project public static final int FLAG_DEFAULT_DISPLAY = 1 << 0; 3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project /** 402b50fba2b143c2e0597c941d67bea1b8e80c9cafMathias Agopian * Flag: Indicates that the orientation of this display device is coupled to the 4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * rotation of its associated logical display. 4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * <p> 4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * This flag should be applied to the default display to indicate that the user 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * physically rotates the display when content is presented in a different orientation. 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * The display manager will apply a coordinate transformation assuming that the 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * physical orientation of the display matches the logical orientation of its content. 4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * </p><p> 4810dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen * The flag should not be set when the display device is mounted in a fixed orientation 4910dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen * such as on a desk. The display manager will apply a coordinate transformation 5010dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen * such as a scale and translation to letterbox or pillarbox format under the 5110dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen * assumption that the physical orientation of the display is invariant. 52413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * </p> 53413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber */ 5410dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1; 5510dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen 5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project /** 5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 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 * Touch attachment: Display does not receive touch. 93 */ 94 public static final int TOUCH_NONE = 0; 95 96 /** 97 * Touch attachment: Touch input is via the internal interface. 98 */ 99 public static final int TOUCH_INTERNAL = 1; 100 101 /** 102 * Touch attachment: Touch input is via an external interface, such as USB. 103 */ 104 public static final int TOUCH_EXTERNAL = 2; 105 106 /** 107 * Diff result: The {@link #state} fields differ. 108 */ 109 public static final int DIFF_STATE = 1 << 0; 110 111 /** 112 * Diff result: Other fields differ. 113 */ 114 public static final int DIFF_OTHER = 1 << 1; 115 116 /** 117 * Gets the name of the display device, which may be derived from EDID or 118 * other sources. The name may be localized and displayed to the user. 119 */ 120 public String name; 121 122 /** 123 * Unique Id of display device. 124 */ 125 public String uniqueId; 126 127 /** 128 * The width of the display in its natural orientation, in pixels. 129 * This value is not affected by display rotation. 130 */ 131 public int width; 132 133 /** 134 * The height of the display in its natural orientation, in pixels. 135 * This value is not affected by display rotation. 136 */ 137 public int height; 138 139 /** 140 * The refresh rate of the display, in frames per second. 141 */ 142 public float refreshRate; 143 144 /** 145 * The supported refresh rates of the display at the current resolution in frames per second. 146 */ 147 public float[] supportedRefreshRates = EmptyArray.FLOAT; 148 149 /** 150 * The nominal apparent density of the display in DPI used for layout calculations. 151 * This density is sensitive to the viewing distance. A big TV and a tablet may have 152 * the same apparent density even though the pixels on the TV are much bigger than 153 * those on the tablet. 154 */ 155 public int densityDpi; 156 157 /** 158 * The physical density of the display in DPI in the X direction. 159 * This density should specify the physical size of each pixel. 160 */ 161 public float xDpi; 162 163 /** 164 * The physical density of the display in DPI in the X direction. 165 * This density should specify the physical size of each pixel. 166 */ 167 public float yDpi; 168 169 /** 170 * This is a positive value indicating the phase offset of the VSYNC events provided by 171 * Choreographer relative to the display refresh. For example, if Choreographer reports 172 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos). 173 */ 174 public long appVsyncOffsetNanos; 175 176 /** 177 * This is how far in advance a buffer must be queued for presentation at 178 * a given time. If you want a buffer to appear on the screen at 179 * time N, you must submit the buffer before (N - bufferDeadlineNanos). 180 */ 181 public long presentationDeadlineNanos; 182 183 /** 184 * Display flags. 185 */ 186 public int flags; 187 188 /** 189 * The touch attachment, per {@link DisplayViewport#touch}. 190 */ 191 public int touch; 192 193 /** 194 * The additional rotation to apply to all content presented on the display device 195 * relative to its physical coordinate system. Default is {@link Surface#ROTATION_0}. 196 * <p> 197 * This field can be used to compensate for the fact that the display has been 198 * physically rotated relative to its natural orientation such as an HDMI monitor 199 * that has been mounted sideways to appear to be portrait rather than landscape. 200 * </p> 201 */ 202 public int rotation = Surface.ROTATION_0; 203 204 /** 205 * Display type. 206 */ 207 public int type; 208 209 /** 210 * Display address, or null if none. 211 * Interpretation varies by display type. 212 */ 213 public String address; 214 215 /** 216 * Display state. 217 */ 218 public int state = Display.STATE_ON; 219 220 /** 221 * The UID of the application that owns this display, or zero if it is owned by the system. 222 * <p> 223 * If the display is private, then only the owner can use it. 224 * </p> 225 */ 226 public int ownerUid; 227 228 /** 229 * The package name of the application that owns this display, or null if it is 230 * owned by the system. 231 * <p> 232 * If the display is private, then only the owner can use it. 233 * </p> 234 */ 235 public String ownerPackageName; 236 237 public void setAssumedDensityForExternalDisplay(int width, int height) { 238 densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; 239 // Technically, these values should be smaller than the apparent density 240 // but we don't know the physical size of the display. 241 xDpi = densityDpi; 242 yDpi = densityDpi; 243 } 244 245 @Override 246 public boolean equals(Object o) { 247 return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o); 248 } 249 250 public boolean equals(DisplayDeviceInfo other) { 251 return other != null && diff(other) == 0; 252 } 253 254 /** 255 * Computes the difference between display device infos. 256 * Assumes other is not null. 257 */ 258 public int diff(DisplayDeviceInfo other) { 259 int diff = 0; 260 if (state != other.state) { 261 diff |= DIFF_STATE; 262 } 263 if (!Objects.equal(name, other.name) 264 || !Objects.equal(uniqueId, other.uniqueId) 265 || width != other.width 266 || height != other.height 267 || refreshRate != other.refreshRate 268 || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates) 269 || densityDpi != other.densityDpi 270 || xDpi != other.xDpi 271 || yDpi != other.yDpi 272 || appVsyncOffsetNanos != other.appVsyncOffsetNanos 273 || presentationDeadlineNanos != other.presentationDeadlineNanos 274 || flags != other.flags 275 || touch != other.touch 276 || rotation != other.rotation 277 || type != other.type 278 || !Objects.equal(address, other.address) 279 || ownerUid != other.ownerUid 280 || !Objects.equal(ownerPackageName, other.ownerPackageName)) { 281 diff |= DIFF_OTHER; 282 } 283 return diff; 284 } 285 286 @Override 287 public int hashCode() { 288 return 0; // don't care 289 } 290 291 public void copyFrom(DisplayDeviceInfo other) { 292 name = other.name; 293 uniqueId = other.uniqueId; 294 width = other.width; 295 height = other.height; 296 refreshRate = other.refreshRate; 297 supportedRefreshRates = other.supportedRefreshRates; 298 densityDpi = other.densityDpi; 299 xDpi = other.xDpi; 300 yDpi = other.yDpi; 301 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 302 presentationDeadlineNanos = other.presentationDeadlineNanos; 303 flags = other.flags; 304 touch = other.touch; 305 rotation = other.rotation; 306 type = other.type; 307 address = other.address; 308 state = other.state; 309 ownerUid = other.ownerUid; 310 ownerPackageName = other.ownerPackageName; 311 } 312 313 // For debugging purposes 314 @Override 315 public String toString() { 316 StringBuilder sb = new StringBuilder(); 317 sb.append("DisplayDeviceInfo{\""); 318 sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", "); 319 sb.append(width).append(" x ").append(height); 320 sb.append(", ").append(refreshRate).append(" fps"); 321 sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates)); 322 sb.append(", density ").append(densityDpi); 323 sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi"); 324 sb.append(", appVsyncOff ").append(appVsyncOffsetNanos); 325 sb.append(", presDeadline ").append(presentationDeadlineNanos); 326 sb.append(", touch ").append(touchToString(touch)); 327 sb.append(", rotation ").append(rotation); 328 sb.append(", type ").append(Display.typeToString(type)); 329 if (address != null) { 330 sb.append(", address ").append(address); 331 } 332 sb.append(", state ").append(Display.stateToString(state)); 333 if (ownerUid != 0 || ownerPackageName != null) { 334 sb.append(", owner ").append(ownerPackageName); 335 sb.append(" (uid ").append(ownerUid).append(")"); 336 } 337 sb.append(flagsToString(flags)); 338 sb.append("}"); 339 return sb.toString(); 340 } 341 342 private static String touchToString(int touch) { 343 switch (touch) { 344 case TOUCH_NONE: 345 return "NONE"; 346 case TOUCH_INTERNAL: 347 return "INTERNAL"; 348 case TOUCH_EXTERNAL: 349 return "EXTERNAL"; 350 default: 351 return Integer.toString(touch); 352 } 353 } 354 355 private static String flagsToString(int flags) { 356 StringBuilder msg = new StringBuilder(); 357 if ((flags & FLAG_DEFAULT_DISPLAY) != 0) { 358 msg.append(", FLAG_DEFAULT_DISPLAY"); 359 } 360 if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) { 361 msg.append(", FLAG_ROTATES_WITH_CONTENT"); 362 } 363 if ((flags & FLAG_SECURE) != 0) { 364 msg.append(", FLAG_SECURE"); 365 } 366 if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 367 msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); 368 } 369 if ((flags & FLAG_PRIVATE) != 0) { 370 msg.append(", FLAG_PRIVATE"); 371 } 372 if ((flags & FLAG_NEVER_BLANK) != 0) { 373 msg.append(", FLAG_NEVER_BLANK"); 374 } 375 if ((flags & FLAG_PRESENTATION) != 0) { 376 msg.append(", FLAG_PRESENTATION"); 377 } 378 if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) { 379 msg.append(", FLAG_OWN_CONTENT_ONLY"); 380 } 381 return msg.toString(); 382 } 383} 384