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