DisplayDeviceInfo.java revision 3f145a2f958320766ae9240c7a57debc20d578aa
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.EmptyArray; 27import libcore.util.Objects; 28 29/** 30 * Describes the characteristics of a physical display device. 31 */ 32final 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 * 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 * Gets the name of the display device, which may be derived from 108 * EDID or other sources. The name may be displayed to the user. 109 */ 110 public String name; 111 112 /** 113 * The width of the display in its natural orientation, in pixels. 114 * This value is not affected by display rotation. 115 */ 116 public int width; 117 118 /** 119 * The height of the display in its natural orientation, in pixels. 120 * This value is not affected by display rotation. 121 */ 122 public int height; 123 124 /** 125 * The refresh rate of the display, in frames per second. 126 */ 127 public float refreshRate; 128 129 /** 130 * The supported refresh rates of the display at the current resolution in frames per second. 131 */ 132 public float[] supportedRefreshRates = EmptyArray.FLOAT; 133 134 /** 135 * The nominal apparent density of the display in DPI used for layout calculations. 136 * This density is sensitive to the viewing distance. A big TV and a tablet may have 137 * the same apparent density even though the pixels on the TV are much bigger than 138 * those on the tablet. 139 */ 140 public int densityDpi; 141 142 /** 143 * The physical density of the display in DPI in the X direction. 144 * This density should specify the physical size of each pixel. 145 */ 146 public float xDpi; 147 148 /** 149 * The physical density of the display in DPI in the X direction. 150 * This density should specify the physical size of each pixel. 151 */ 152 public float yDpi; 153 154 /** 155 * This is a positive value indicating the phase offset of the VSYNC events provided by 156 * Choreographer relative to the display refresh. For example, if Choreographer reports 157 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos). 158 */ 159 public long appVsyncOffsetNanos; 160 161 /** 162 * This is how far in advance a buffer must be queued for presentation at 163 * a given time. If you want a buffer to appear on the screen at 164 * time N, you must submit the buffer before (N - bufferDeadlineNanos). 165 */ 166 public long presentationDeadlineNanos; 167 168 /** 169 * Display flags. 170 */ 171 public int flags; 172 173 /** 174 * The touch attachment, per {@link DisplayViewport#touch}. 175 */ 176 public int touch; 177 178 /** 179 * The additional rotation to apply to all content presented on the display device 180 * relative to its physical coordinate system. Default is {@link Surface#ROTATION_0}. 181 * <p> 182 * This field can be used to compensate for the fact that the display has been 183 * physically rotated relative to its natural orientation such as an HDMI monitor 184 * that has been mounted sideways to appear to be portrait rather than landscape. 185 * </p> 186 */ 187 public int rotation = Surface.ROTATION_0; 188 189 /** 190 * Display type. 191 */ 192 public int type; 193 194 /** 195 * Display address, or null if none. 196 * Interpretation varies by display type. 197 */ 198 public String address; 199 200 /** 201 * Display state. 202 */ 203 public int state = Display.STATE_ON; 204 205 /** 206 * The UID of the application that owns this display, or zero if it is owned by the system. 207 * <p> 208 * If the display is private, then only the owner can use it. 209 * </p> 210 */ 211 public int ownerUid; 212 213 /** 214 * The package name of the application that owns this display, or null if it is 215 * owned by the system. 216 * <p> 217 * If the display is private, then only the owner can use it. 218 * </p> 219 */ 220 public String ownerPackageName; 221 222 public void setAssumedDensityForExternalDisplay(int width, int height) { 223 densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; 224 // Technically, these values should be smaller than the apparent density 225 // but we don't know the physical size of the display. 226 xDpi = densityDpi; 227 yDpi = densityDpi; 228 } 229 230 @Override 231 public boolean equals(Object o) { 232 return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o); 233 } 234 235 public boolean equals(DisplayDeviceInfo other) { 236 return other != null 237 && Objects.equal(name, other.name) 238 && width == other.width 239 && height == other.height 240 && refreshRate == other.refreshRate 241 && Arrays.equals(supportedRefreshRates, other.supportedRefreshRates) 242 && densityDpi == other.densityDpi 243 && xDpi == other.xDpi 244 && yDpi == other.yDpi 245 && appVsyncOffsetNanos == other.appVsyncOffsetNanos 246 && presentationDeadlineNanos == other.presentationDeadlineNanos 247 && flags == other.flags 248 && touch == other.touch 249 && rotation == other.rotation 250 && type == other.type 251 && Objects.equal(address, other.address) 252 && state == other.state 253 && ownerUid == other.ownerUid 254 && Objects.equal(ownerPackageName, other.ownerPackageName); 255 } 256 257 @Override 258 public int hashCode() { 259 return 0; // don't care 260 } 261 262 public void copyFrom(DisplayDeviceInfo other) { 263 name = other.name; 264 width = other.width; 265 height = other.height; 266 refreshRate = other.refreshRate; 267 supportedRefreshRates = other.supportedRefreshRates; 268 densityDpi = other.densityDpi; 269 xDpi = other.xDpi; 270 yDpi = other.yDpi; 271 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 272 presentationDeadlineNanos = other.presentationDeadlineNanos; 273 flags = other.flags; 274 touch = other.touch; 275 rotation = other.rotation; 276 type = other.type; 277 address = other.address; 278 state = other.state; 279 ownerUid = other.ownerUid; 280 ownerPackageName = other.ownerPackageName; 281 } 282 283 // For debugging purposes 284 @Override 285 public String toString() { 286 StringBuilder sb = new StringBuilder(); 287 sb.append("DisplayDeviceInfo{\""); 288 sb.append(name).append("\": ").append(width).append(" x ").append(height); 289 sb.append(", ").append(refreshRate).append(" fps"); 290 sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates)); 291 sb.append(", density ").append(densityDpi); 292 sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi"); 293 sb.append(", appVsyncOff ").append(appVsyncOffsetNanos); 294 sb.append(", presDeadline ").append(presentationDeadlineNanos); 295 sb.append(", touch ").append(touchToString(touch)); 296 sb.append(", rotation ").append(rotation); 297 sb.append(", type ").append(Display.typeToString(type)); 298 if (address != null) { 299 sb.append(", address ").append(address); 300 } 301 sb.append(", state ").append(Display.stateToString(state)); 302 if (ownerUid != 0 || ownerPackageName != null) { 303 sb.append(", owner ").append(ownerPackageName); 304 sb.append(" (uid ").append(ownerUid).append(")"); 305 } 306 sb.append(flagsToString(flags)); 307 sb.append("}"); 308 return sb.toString(); 309 } 310 311 private static String touchToString(int touch) { 312 switch (touch) { 313 case TOUCH_NONE: 314 return "NONE"; 315 case TOUCH_INTERNAL: 316 return "INTERNAL"; 317 case TOUCH_EXTERNAL: 318 return "EXTERNAL"; 319 default: 320 return Integer.toString(touch); 321 } 322 } 323 324 private static String flagsToString(int flags) { 325 StringBuilder msg = new StringBuilder(); 326 if ((flags & FLAG_DEFAULT_DISPLAY) != 0) { 327 msg.append(", FLAG_DEFAULT_DISPLAY"); 328 } 329 if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) { 330 msg.append(", FLAG_ROTATES_WITH_CONTENT"); 331 } 332 if ((flags & FLAG_SECURE) != 0) { 333 msg.append(", FLAG_SECURE"); 334 } 335 if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 336 msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); 337 } 338 if ((flags & FLAG_PRIVATE) != 0) { 339 msg.append(", FLAG_PRIVATE"); 340 } 341 if ((flags & FLAG_NEVER_BLANK) != 0) { 342 msg.append(", FLAG_NEVER_BLANK"); 343 } 344 if ((flags & FLAG_PRESENTATION) != 0) { 345 msg.append(", FLAG_PRESENTATION"); 346 } 347 if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) { 348 msg.append(", FLAG_OWN_CONTENT_ONLY"); 349 } 350 return msg.toString(); 351 } 352} 353