1 /* 2 * Copyright (C) 2006 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 android.util; 18 19 import static com.android.window.flags.Flags.FLAG_DENSITY_390_API; 20 21 import android.annotation.FlaggedApi; 22 import android.annotation.IntDef; 23 import android.annotation.Nullable; 24 import android.compat.annotation.UnsupportedAppUsage; 25 import android.content.res.FontScaleConverter; 26 import android.os.SystemProperties; 27 import android.view.WindowManager; 28 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 32 /** 33 * A structure describing general information about a display, such as its 34 * size, density, and font scaling. 35 * <p>To access the DisplayMetrics members, retrieve display metrics like this:</p> 36 * <pre>context.getResources().getDisplayMetrics();</pre> 37 * 38 * <p> 39 * For UI layout, obtain {@link android.view.WindowMetrics} from 40 * {@link WindowManager#getCurrentWindowMetrics()}. {@code DisplayMetrics} should only be used for 41 * obtaining display related properties, such as {@link #xdpi} and {@link #ydpi} 42 * </p><p> 43 * See {@link #density} for more information about the differences between {@link #xdpi}, 44 * {@link #ydpi} and {@link #density}. 45 * </p> 46 * 47 */ 48 public class DisplayMetrics { 49 50 @IntDef(prefix = { "DENSITY_" }, value = { 51 DENSITY_LOW, 52 DENSITY_140, 53 DENSITY_MEDIUM, 54 DENSITY_180, 55 DENSITY_200, 56 DENSITY_TV, 57 DENSITY_220, 58 DENSITY_HIGH, 59 DENSITY_260, 60 DENSITY_280, 61 DENSITY_300, 62 DENSITY_XHIGH, 63 DENSITY_340, 64 DENSITY_360, 65 DENSITY_390, 66 DENSITY_400, 67 DENSITY_420, 68 DENSITY_440, 69 DENSITY_450, 70 DENSITY_XXHIGH, 71 DENSITY_520, 72 DENSITY_560, 73 DENSITY_600, 74 DENSITY_XXXHIGH, 75 }) 76 @Retention(RetentionPolicy.SOURCE) 77 @interface DensityDpi{} 78 79 /** 80 * Standard quantized DPI for low-density screens. 81 */ 82 public static final int DENSITY_LOW = 120; 83 84 /** 85 * Intermediate density for screens that sit between {@link #DENSITY_LOW} (120dpi) and 86 * {@link #DENSITY_MEDIUM} (160dpi). This is not a density that applications should target, 87 * instead relying on the system to scale their {@link #DENSITY_MEDIUM} assets for them. 88 */ 89 public static final int DENSITY_140 = 140; 90 91 /** 92 * Standard quantized DPI for medium-density screens. 93 */ 94 public static final int DENSITY_MEDIUM = 160; 95 96 /** 97 * Intermediate density for screens that sit between {@link #DENSITY_MEDIUM} (160dpi) and 98 * {@link #DENSITY_HIGH} (240dpi). This is not a density that applications should target, 99 * instead relying on the system to scale their {@link #DENSITY_HIGH} assets for them. 100 */ 101 public static final int DENSITY_180 = 180; 102 103 /** 104 * Intermediate density for screens that sit between {@link #DENSITY_MEDIUM} (160dpi) and 105 * {@link #DENSITY_HIGH} (240dpi). This is not a density that applications should target, 106 * instead relying on the system to scale their {@link #DENSITY_HIGH} assets for them. 107 */ 108 public static final int DENSITY_200 = 200; 109 110 /** 111 * This is a secondary density, added for some common screen configurations. 112 * It is recommended that applications not generally target this as a first 113 * class density -- that is, don't supply specific graphics for this 114 * density, instead allow the platform to scale from other densities 115 * (typically {@link #DENSITY_HIGH}) as 116 * appropriate. In most cases (such as using bitmaps in 117 * {@link android.graphics.drawable.Drawable}) the platform 118 * can perform this scaling at load time, so the only cost is some slight 119 * startup runtime overhead. 120 * 121 * <p>This density was original introduced to correspond with a 122 * 720p TV screen: the density for 1080p televisions is 123 * {@link #DENSITY_XHIGH}, and the value here provides the same UI 124 * size for a TV running at 720p. It has also found use in 7" tablets, 125 * when these devices have 1280x720 displays. 126 */ 127 public static final int DENSITY_TV = 213; 128 129 /** 130 * Intermediate density for screens that sit between {@link #DENSITY_MEDIUM} (160dpi) and 131 * {@link #DENSITY_HIGH} (240dpi). This is not a density that applications should target, 132 * instead relying on the system to scale their {@link #DENSITY_HIGH} assets for them. 133 */ 134 public static final int DENSITY_220 = 220; 135 136 /** 137 * Standard quantized DPI for high-density screens. 138 */ 139 public static final int DENSITY_HIGH = 240; 140 141 /** 142 * Intermediate density for screens that sit between {@link #DENSITY_HIGH} (240dpi) and 143 * {@link #DENSITY_XHIGH} (320dpi). This is not a density that applications should target, 144 * instead relying on the system to scale their {@link #DENSITY_XHIGH} assets for them. 145 */ 146 public static final int DENSITY_260 = 260; 147 148 /** 149 * Intermediate density for screens that sit between {@link #DENSITY_HIGH} (240dpi) and 150 * {@link #DENSITY_XHIGH} (320dpi). This is not a density that applications should target, 151 * instead relying on the system to scale their {@link #DENSITY_XHIGH} assets for them. 152 */ 153 public static final int DENSITY_280 = 280; 154 155 /** 156 * Intermediate density for screens that sit between {@link #DENSITY_HIGH} (240dpi) and 157 * {@link #DENSITY_XHIGH} (320dpi). This is not a density that applications should target, 158 * instead relying on the system to scale their {@link #DENSITY_XHIGH} assets for them. 159 */ 160 public static final int DENSITY_300 = 300; 161 162 /** 163 * Standard quantized DPI for extra-high-density screens. 164 */ 165 public static final int DENSITY_XHIGH = 320; 166 167 /** 168 * Intermediate density for screens that sit somewhere between 169 * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi). 170 * This is not a density that applications should target, instead relying 171 * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. 172 */ 173 public static final int DENSITY_340 = 340; 174 175 /** 176 * Intermediate density for screens that sit somewhere between 177 * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi). 178 * This is not a density that applications should target, instead relying 179 * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. 180 */ 181 public static final int DENSITY_360 = 360; 182 183 /** 184 * Intermediate density for screens that sit somewhere between 185 * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi). 186 * This is not a density that applications should target, instead relying 187 * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. 188 */ 189 @FlaggedApi(FLAG_DENSITY_390_API) 190 public static final int DENSITY_390 = 390; 191 192 /** 193 * Intermediate density for screens that sit somewhere between 194 * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi). 195 * This is not a density that applications should target, instead relying 196 * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. 197 */ 198 public static final int DENSITY_400 = 400; 199 200 /** 201 * Intermediate density for screens that sit somewhere between 202 * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi). 203 * This is not a density that applications should target, instead relying 204 * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. 205 */ 206 public static final int DENSITY_420 = 420; 207 208 /** 209 * Intermediate density for screens that sit somewhere between 210 * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi). 211 * This is not a density that applications should target, instead relying 212 * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. 213 */ 214 public static final int DENSITY_440 = 440; 215 216 /** 217 * Intermediate density for screens that sit somewhere between 218 * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi). 219 * This is not a density that applications should target, instead relying 220 * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. 221 */ 222 public static final int DENSITY_450 = 450; 223 224 /** 225 * Standard quantized DPI for extra-extra-high-density screens. 226 */ 227 public static final int DENSITY_XXHIGH = 480; 228 229 /** 230 * Intermediate density for screens that sit somewhere between 231 * {@link #DENSITY_XXHIGH} (480 dpi) and {@link #DENSITY_XXXHIGH} (640 dpi). 232 * This is not a density that applications should target, instead relying 233 * on the system to scale their {@link #DENSITY_XXXHIGH} assets for them. 234 */ 235 public static final int DENSITY_520 = 520; 236 237 /** 238 * Intermediate density for screens that sit somewhere between 239 * {@link #DENSITY_XXHIGH} (480 dpi) and {@link #DENSITY_XXXHIGH} (640 dpi). 240 * This is not a density that applications should target, instead relying 241 * on the system to scale their {@link #DENSITY_XXXHIGH} assets for them. 242 */ 243 public static final int DENSITY_560 = 560; 244 245 /** 246 * Intermediate density for screens that sit somewhere between 247 * {@link #DENSITY_XXHIGH} (480 dpi) and {@link #DENSITY_XXXHIGH} (640 dpi). 248 * This is not a density that applications should target, instead relying 249 * on the system to scale their {@link #DENSITY_XXXHIGH} assets for them. 250 */ 251 public static final int DENSITY_600 = 600; 252 253 /** 254 * Standard quantized DPI for extra-extra-extra-high-density screens. Applications 255 * should not generally worry about this density; relying on XHIGH graphics 256 * being scaled up to it should be sufficient for almost all cases. A typical 257 * use of this density would be 4K television screens -- 3840x2160, which 258 * is 2x a traditional HD 1920x1080 screen which runs at DENSITY_XHIGH. 259 */ 260 public static final int DENSITY_XXXHIGH = 640; 261 262 /** 263 * The reference density used throughout the system. 264 */ 265 public static final int DENSITY_DEFAULT = DENSITY_MEDIUM; 266 267 /** 268 * Scaling factor to convert a density in DPI units to the density scale. 269 * @hide 270 */ 271 public static final float DENSITY_DEFAULT_SCALE = 1.0f / DENSITY_DEFAULT; 272 273 /** 274 * The device's current density. 275 * <p> 276 * This value reflects any changes made to the device density. To obtain 277 * the device's stable density, use {@link #DENSITY_DEVICE_STABLE}. 278 * 279 * @hide This value should not be used. 280 * @deprecated Use {@link #DENSITY_DEVICE_STABLE} to obtain the stable 281 * device density or {@link #densityDpi} to obtain the current 282 * density for a specific display. 283 */ 284 @Deprecated 285 @UnsupportedAppUsage 286 public static int DENSITY_DEVICE = getDeviceDensity(); 287 288 /** 289 * The device's stable density. 290 * <p> 291 * This value is constant at run time and may not reflect the current 292 * display density. To obtain the current density for a specific display, 293 * use {@link #densityDpi}. 294 */ 295 public static final int DENSITY_DEVICE_STABLE = getDeviceDensity(); 296 297 /** 298 * The absolute width of the available display size in pixels. 299 */ 300 public int widthPixels; 301 /** 302 * The absolute height of the available display size in pixels. 303 */ 304 public int heightPixels; 305 /** 306 * The logical density of the display. This is a scaling factor for the 307 * Density Independent Pixel unit, where one DIP is one pixel on an 308 * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), 309 * providing the baseline of the system's display. Thus on a 160dpi screen 310 * this density value will be 1; on a 120 dpi screen it would be .75; etc. 311 * 312 * <p>This value does not exactly follow the real screen size (as given by 313 * {@link #xdpi} and {@link #ydpi}), but rather is used to scale the size of 314 * the overall UI in steps based on gross changes in the display dpi. For 315 * example, a 240x320 screen will have a density of 1 even if its width is 316 * 1.8", 1.3", etc. However, if the screen resolution is increased to 317 * 320x480 but the screen size remained 1.5"x2" then the density would be 318 * increased (probably to 1.5). 319 * 320 * @see #DENSITY_DEFAULT 321 */ 322 public float density; 323 /** 324 * The screen density expressed as dots-per-inch. May be any one of the 325 * {@code DENSITY_} constants defined above. 326 * 327 * New constants are frequently added, and constants added on new Android 328 * versions may be backported to previous Android versions, so applications 329 * should not strongly rely on density matching one of the enum constants. 330 */ 331 @DensityDpi 332 public int densityDpi; 333 /** 334 * A scaling factor for fonts displayed on the display. This is the same 335 * as {@link #density}, except that it may be adjusted in smaller 336 * increments at runtime based on a user preference for the font size. 337 * 338 * @deprecated this scalar factor is no longer accurate due to adaptive non-linear font scaling. 339 * Please use {@link TypedValue#applyDimension(int, float, DisplayMetrics)} or 340 * {@link TypedValue#deriveDimension(int, float, DisplayMetrics)} to convert between SP font 341 * sizes and pixels. 342 */ 343 @Deprecated 344 public float scaledDensity; 345 346 /** 347 * If non-null, this will be used to calculate font sizes instead of {@link #scaledDensity}. 348 * 349 * @hide 350 */ 351 @Nullable 352 public FontScaleConverter fontScaleConverter; 353 354 /** 355 * The exact physical pixels per inch of the screen in the X dimension. 356 */ 357 public float xdpi; 358 /** 359 * The exact physical pixels per inch of the screen in the Y dimension. 360 */ 361 public float ydpi; 362 363 /** 364 * The reported display width prior to any compatibility mode scaling 365 * being applied. 366 * @hide 367 */ 368 @UnsupportedAppUsage 369 public int noncompatWidthPixels; 370 /** 371 * The reported display height prior to any compatibility mode scaling 372 * being applied. 373 * @hide 374 */ 375 @UnsupportedAppUsage 376 public int noncompatHeightPixels; 377 /** 378 * The reported display density prior to any compatibility mode scaling 379 * being applied. 380 * @hide 381 */ 382 public float noncompatDensity; 383 /** 384 * The reported display density prior to any compatibility mode scaling 385 * being applied. 386 * @hide 387 */ 388 @UnsupportedAppUsage 389 public int noncompatDensityDpi; 390 /** 391 * The reported scaled density prior to any compatibility mode scaling 392 * being applied. 393 * @hide 394 */ 395 public float noncompatScaledDensity; 396 /** 397 * The reported display xdpi prior to any compatibility mode scaling 398 * being applied. 399 * @hide 400 */ 401 public float noncompatXdpi; 402 /** 403 * The reported display ydpi prior to any compatibility mode scaling 404 * being applied. 405 * @hide 406 */ 407 public float noncompatYdpi; 408 DisplayMetrics()409 public DisplayMetrics() { 410 } 411 setTo(DisplayMetrics o)412 public void setTo(DisplayMetrics o) { 413 if (this == o) { 414 return; 415 } 416 417 widthPixels = o.widthPixels; 418 heightPixels = o.heightPixels; 419 density = o.density; 420 densityDpi = o.densityDpi; 421 scaledDensity = o.scaledDensity; 422 xdpi = o.xdpi; 423 ydpi = o.ydpi; 424 noncompatWidthPixels = o.noncompatWidthPixels; 425 noncompatHeightPixels = o.noncompatHeightPixels; 426 noncompatDensity = o.noncompatDensity; 427 noncompatDensityDpi = o.noncompatDensityDpi; 428 noncompatScaledDensity = o.noncompatScaledDensity; 429 noncompatXdpi = o.noncompatXdpi; 430 noncompatYdpi = o.noncompatYdpi; 431 fontScaleConverter = o.fontScaleConverter; 432 } 433 setToDefaults()434 public void setToDefaults() { 435 widthPixels = 0; 436 heightPixels = 0; 437 density = DENSITY_DEVICE / (float) DENSITY_DEFAULT; 438 densityDpi = DENSITY_DEVICE; 439 scaledDensity = density; 440 xdpi = DENSITY_DEVICE; 441 ydpi = DENSITY_DEVICE; 442 noncompatWidthPixels = widthPixels; 443 noncompatHeightPixels = heightPixels; 444 noncompatDensity = density; 445 noncompatDensityDpi = densityDpi; 446 noncompatScaledDensity = scaledDensity; 447 noncompatXdpi = xdpi; 448 noncompatYdpi = ydpi; 449 fontScaleConverter = null; 450 } 451 452 @Override equals(@ullable Object o)453 public boolean equals(@Nullable Object o) { 454 return o instanceof DisplayMetrics && equals((DisplayMetrics)o); 455 } 456 457 /** 458 * Returns true if these display metrics equal the other display metrics. 459 * 460 * @param other The display metrics with which to compare. 461 * @return True if the display metrics are equal. 462 */ equals(DisplayMetrics other)463 public boolean equals(DisplayMetrics other) { 464 return equalsPhysical(other) 465 && scaledDensity == other.scaledDensity 466 && noncompatScaledDensity == other.noncompatScaledDensity; 467 } 468 469 /** 470 * Returns true if the physical aspects of the two display metrics 471 * are equal. This ignores the scaled density, which is a logical 472 * attribute based on the current desired font size. 473 * 474 * @param other The display metrics with which to compare. 475 * @return True if the display metrics are equal. 476 * @hide 477 */ equalsPhysical(DisplayMetrics other)478 public boolean equalsPhysical(DisplayMetrics other) { 479 return other != null 480 && widthPixels == other.widthPixels 481 && heightPixels == other.heightPixels 482 && density == other.density 483 && densityDpi == other.densityDpi 484 && xdpi == other.xdpi 485 && ydpi == other.ydpi 486 && noncompatWidthPixels == other.noncompatWidthPixels 487 && noncompatHeightPixels == other.noncompatHeightPixels 488 && noncompatDensity == other.noncompatDensity 489 && noncompatDensityDpi == other.noncompatDensityDpi 490 && noncompatXdpi == other.noncompatXdpi 491 && noncompatYdpi == other.noncompatYdpi; 492 } 493 494 @Override hashCode()495 public int hashCode() { 496 return widthPixels * heightPixels * densityDpi; 497 } 498 499 @Override toString()500 public String toString() { 501 return "DisplayMetrics{density=" + density + ", width=" + widthPixels + 502 ", height=" + heightPixels + ", scaledDensity=" + scaledDensity + 503 ", xdpi=" + xdpi + ", ydpi=" + ydpi + "}"; 504 } 505 getDeviceDensity()506 private static int getDeviceDensity() { 507 // qemu.sf.lcd_density can be used to override ro.sf.lcd_density 508 // when running in the emulator, allowing for dynamic configurations. 509 // The reason for this is that ro.sf.lcd_density is write-once and is 510 // set by the init process when it parses build.prop before anything else. 511 return SystemProperties.getInt("qemu.sf.lcd_density", 512 SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT)); 513 } 514 } 515