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