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