DisplayInfo.java revision 7f3994ec2a5dce1a037f04714b1f25cab85affb6
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 android.view; 18 19import android.content.res.CompatibilityInfo; 20import android.os.Parcel; 21import android.os.Parcelable; 22import android.util.DisplayMetrics; 23 24import libcore.util.Objects; 25 26/** 27 * Describes the characteristics of a particular logical display. 28 * @hide 29 */ 30public final class DisplayInfo implements Parcelable { 31 /** 32 * The surface flinger layer stack associated with this logical display. 33 */ 34 public int layerStack; 35 36 /** 37 * Display flags. 38 */ 39 public int flags; 40 41 /** 42 * Display type. 43 */ 44 public int type; 45 46 /** 47 * Display address, or null if none. 48 * Interpretation varies by display type. 49 */ 50 public String address; 51 52 /** 53 * The human-readable name of the display. 54 */ 55 public String name; 56 57 /** 58 * The width of the portion of the display that is available to applications, in pixels. 59 * Represents the size of the display minus any system decorations. 60 */ 61 public int appWidth; 62 63 /** 64 * The height of the portion of the display that is available to applications, in pixels. 65 * Represents the size of the display minus any system decorations. 66 */ 67 public int appHeight; 68 69 /** 70 * The smallest value of {@link #appWidth} that an application is likely to encounter, 71 * in pixels, excepting cases where the width may be even smaller due to the presence 72 * of a soft keyboard, for example. 73 */ 74 public int smallestNominalAppWidth; 75 76 /** 77 * The smallest value of {@link #appHeight} that an application is likely to encounter, 78 * in pixels, excepting cases where the height may be even smaller due to the presence 79 * of a soft keyboard, for example. 80 */ 81 public int smallestNominalAppHeight; 82 83 /** 84 * The largest value of {@link #appWidth} that an application is likely to encounter, 85 * in pixels, excepting cases where the width may be even larger due to system decorations 86 * such as the status bar being hidden, for example. 87 */ 88 public int largestNominalAppWidth; 89 90 /** 91 * The largest value of {@link #appHeight} that an application is likely to encounter, 92 * in pixels, excepting cases where the height may be even larger due to system decorations 93 * such as the status bar being hidden, for example. 94 */ 95 public int largestNominalAppHeight; 96 97 /** 98 * The logical width of the display, in pixels. 99 * Represents the usable size of the display which may be smaller than the 100 * physical size when the system is emulating a smaller display. 101 */ 102 public int logicalWidth; 103 104 /** 105 * The logical height of the display, in pixels. 106 * Represents the usable size of the display which may be smaller than the 107 * physical size when the system is emulating a smaller display. 108 */ 109 public int logicalHeight; 110 111 /** 112 * The rotation of the display relative to its natural orientation. 113 * May be one of {@link android.view.Surface#ROTATION_0}, 114 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180}, 115 * {@link android.view.Surface#ROTATION_270}. 116 * <p> 117 * The value of this field is indeterminate if the logical display is presented on 118 * more than one physical display. 119 * </p> 120 */ 121 public int rotation; 122 123 /** 124 * The refresh rate of this display in frames per second. 125 * <p> 126 * The value of this field is indeterminate if the logical display is presented on 127 * more than one physical display. 128 * </p> 129 */ 130 public float refreshRate; 131 132 /** 133 * The logical display density which is the basis for density-independent 134 * pixels. 135 */ 136 public int logicalDensityDpi; 137 138 /** 139 * The exact physical pixels per inch of the screen in the X dimension. 140 * <p> 141 * The value of this field is indeterminate if the logical display is presented on 142 * more than one physical display. 143 * </p> 144 */ 145 public float physicalXDpi; 146 147 /** 148 * The exact physical pixels per inch of the screen in the Y dimension. 149 * <p> 150 * The value of this field is indeterminate if the logical display is presented on 151 * more than one physical display. 152 * </p> 153 */ 154 public float physicalYDpi; 155 156 public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() { 157 @Override 158 public DisplayInfo createFromParcel(Parcel source) { 159 return new DisplayInfo(source); 160 } 161 162 @Override 163 public DisplayInfo[] newArray(int size) { 164 return new DisplayInfo[size]; 165 } 166 }; 167 168 public DisplayInfo() { 169 } 170 171 public DisplayInfo(DisplayInfo other) { 172 copyFrom(other); 173 } 174 175 private DisplayInfo(Parcel source) { 176 readFromParcel(source); 177 } 178 179 @Override 180 public boolean equals(Object o) { 181 return o instanceof DisplayInfo && equals((DisplayInfo)o); 182 } 183 184 public boolean equals(DisplayInfo other) { 185 return other != null 186 && layerStack == other.layerStack 187 && flags == other.flags 188 && type == other.type 189 && Objects.equal(address, other.address) 190 && Objects.equal(name, other.name) 191 && appWidth == other.appWidth 192 && appHeight == other.appHeight 193 && smallestNominalAppWidth == other.smallestNominalAppWidth 194 && smallestNominalAppHeight == other.smallestNominalAppHeight 195 && largestNominalAppWidth == other.largestNominalAppWidth 196 && largestNominalAppHeight == other.largestNominalAppHeight 197 && logicalWidth == other.logicalWidth 198 && logicalHeight == other.logicalHeight 199 && rotation == other.rotation 200 && refreshRate == other.refreshRate 201 && logicalDensityDpi == other.logicalDensityDpi 202 && physicalXDpi == other.physicalXDpi 203 && physicalYDpi == other.physicalYDpi; 204 } 205 206 @Override 207 public int hashCode() { 208 return 0; // don't care 209 } 210 211 public void copyFrom(DisplayInfo other) { 212 layerStack = other.layerStack; 213 flags = other.flags; 214 type = other.type; 215 address = other.address; 216 name = other.name; 217 appWidth = other.appWidth; 218 appHeight = other.appHeight; 219 smallestNominalAppWidth = other.smallestNominalAppWidth; 220 smallestNominalAppHeight = other.smallestNominalAppHeight; 221 largestNominalAppWidth = other.largestNominalAppWidth; 222 largestNominalAppHeight = other.largestNominalAppHeight; 223 logicalWidth = other.logicalWidth; 224 logicalHeight = other.logicalHeight; 225 rotation = other.rotation; 226 refreshRate = other.refreshRate; 227 logicalDensityDpi = other.logicalDensityDpi; 228 physicalXDpi = other.physicalXDpi; 229 physicalYDpi = other.physicalYDpi; 230 } 231 232 public void readFromParcel(Parcel source) { 233 layerStack = source.readInt(); 234 flags = source.readInt(); 235 type = source.readInt(); 236 address = source.readString(); 237 name = source.readString(); 238 appWidth = source.readInt(); 239 appHeight = source.readInt(); 240 smallestNominalAppWidth = source.readInt(); 241 smallestNominalAppHeight = source.readInt(); 242 largestNominalAppWidth = source.readInt(); 243 largestNominalAppHeight = source.readInt(); 244 logicalWidth = source.readInt(); 245 logicalHeight = source.readInt(); 246 rotation = source.readInt(); 247 refreshRate = source.readFloat(); 248 logicalDensityDpi = source.readInt(); 249 physicalXDpi = source.readFloat(); 250 physicalYDpi = source.readFloat(); 251 } 252 253 @Override 254 public void writeToParcel(Parcel dest, int flags) { 255 dest.writeInt(layerStack); 256 dest.writeInt(this.flags); 257 dest.writeInt(type); 258 dest.writeString(address); 259 dest.writeString(name); 260 dest.writeInt(appWidth); 261 dest.writeInt(appHeight); 262 dest.writeInt(smallestNominalAppWidth); 263 dest.writeInt(smallestNominalAppHeight); 264 dest.writeInt(largestNominalAppWidth); 265 dest.writeInt(largestNominalAppHeight); 266 dest.writeInt(logicalWidth); 267 dest.writeInt(logicalHeight); 268 dest.writeInt(rotation); 269 dest.writeFloat(refreshRate); 270 dest.writeInt(logicalDensityDpi); 271 dest.writeFloat(physicalXDpi); 272 dest.writeFloat(physicalYDpi); 273 } 274 275 @Override 276 public int describeContents() { 277 return 0; 278 } 279 280 public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) { 281 getMetricsWithSize(outMetrics, cih, appWidth, appHeight); 282 } 283 284 public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) { 285 getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight); 286 } 287 288 public int getNaturalWidth() { 289 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? 290 logicalWidth : logicalHeight; 291 } 292 293 public int getNaturalHeight() { 294 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? 295 logicalHeight : logicalWidth; 296 } 297 298 private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih, 299 int width, int height) { 300 outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi; 301 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width; 302 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height; 303 304 outMetrics.density = outMetrics.noncompatDensity = 305 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; 306 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density; 307 outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi; 308 outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi; 309 310 if (cih != null) { 311 CompatibilityInfo ci = cih.getIfNeeded(); 312 if (ci != null) { 313 ci.applyToDisplayMetrics(outMetrics); 314 } 315 } 316 } 317 318 // For debugging purposes 319 @Override 320 public String toString() { 321 return "DisplayInfo{\"" + name + "\", app " + appWidth + " x " + appHeight 322 + ", real " + logicalWidth + " x " + logicalHeight 323 + ", largest app " + largestNominalAppWidth + " x " + largestNominalAppHeight 324 + ", smallest app " + smallestNominalAppWidth + " x " + smallestNominalAppHeight 325 + ", " + refreshRate + " fps" 326 + ", rotation " + rotation 327 + ", density " + logicalDensityDpi 328 + ", " + physicalXDpi + " x " + physicalYDpi + " dpi" 329 + ", layerStack " + layerStack 330 + ", type " + Display.typeToString(type) 331 + ", address " + address 332 + flagsToString(flags) + "}"; 333 } 334 335 private static String flagsToString(int flags) { 336 StringBuilder result = new StringBuilder(); 337 if ((flags & Display.FLAG_SECURE) != 0) { 338 result.append(", FLAG_SECURE"); 339 } 340 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 341 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); 342 } 343 return result.toString(); 344 } 345} 346