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