DisplayMetrics.java revision a6d9c7c04c4b17d85ac70f4494777555655f3be1
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 17package android.util; 18 19import android.content.res.CompatibilityInfo; 20import android.content.res.Configuration; 21import android.os.*; 22 23 24/** 25 * A structure describing general information about a display, such as its 26 * size, density, and font scaling. 27 * <p>To access the DisplayMetrics members, initialize an object like this:</p> 28 * <pre> DisplayMetrics metrics = new DisplayMetrics(); 29 * getWindowManager().getDefaultDisplay().getMetrics(metrics);</pre> 30 */ 31public class DisplayMetrics { 32 /** 33 * Standard quantized DPI for low-density screens. 34 */ 35 public static final int DENSITY_LOW = 120; 36 37 /** 38 * Standard quantized DPI for medium-density screens. 39 */ 40 public static final int DENSITY_MEDIUM = 160; 41 42 /** 43 * Standard quantized DPI for high-density screens. 44 */ 45 public static final int DENSITY_HIGH = 240; 46 47 /** 48 * Standard quantized DPI for extra-high-density screens. 49 */ 50 public static final int DENSITY_XHIGH = 320; 51 52 /** 53 * The reference density used throughout the system. 54 */ 55 public static final int DENSITY_DEFAULT = DENSITY_MEDIUM; 56 57 /** 58 * The device's density. 59 * @hide becase eventually this should be able to change while 60 * running, so shouldn't be a constant. 61 */ 62 public static final int DENSITY_DEVICE = getDeviceDensity(); 63 64 /** 65 * The absolute width of the display in pixels. 66 */ 67 public int widthPixels; 68 /** 69 * The absolute height of the display in pixels. 70 */ 71 public int heightPixels; 72 /** 73 * The logical density of the display. This is a scaling factor for the 74 * Density Independent Pixel unit, where one DIP is one pixel on an 75 * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), 76 * providing the baseline of the system's display. Thus on a 160dpi screen 77 * this density value will be 1; on a 120 dpi screen it would be .75; etc. 78 * 79 * <p>This value does not exactly follow the real screen size (as given by 80 * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of 81 * the overall UI in steps based on gross changes in the display dpi. For 82 * example, a 240x320 screen will have a density of 1 even if its width is 83 * 1.8", 1.3", etc. However, if the screen resolution is increased to 84 * 320x480 but the screen size remained 1.5"x2" then the density would be 85 * increased (probably to 1.5). 86 * 87 * @see #DENSITY_DEFAULT 88 */ 89 public float density; 90 /** 91 * The screen density expressed as dots-per-inch. May be either 92 * {@link #DENSITY_LOW}, {@link #DENSITY_MEDIUM}, or {@link #DENSITY_HIGH}. 93 */ 94 public int densityDpi; 95 /** 96 * A scaling factor for fonts displayed on the display. This is the same 97 * as {@link #density}, except that it may be adjusted in smaller 98 * increments at runtime based on a user preference for the font size. 99 */ 100 public float scaledDensity; 101 /** 102 * The exact physical pixels per inch of the screen in the X dimension. 103 */ 104 public float xdpi; 105 /** 106 * The exact physical pixels per inch of the screen in the Y dimension. 107 */ 108 public float ydpi; 109 110 public DisplayMetrics() { 111 } 112 113 public void setTo(DisplayMetrics o) { 114 widthPixels = o.widthPixels; 115 heightPixels = o.heightPixels; 116 density = o.density; 117 densityDpi = o.densityDpi; 118 scaledDensity = o.scaledDensity; 119 xdpi = o.xdpi; 120 ydpi = o.ydpi; 121 } 122 123 public void setToDefaults() { 124 widthPixels = 0; 125 heightPixels = 0; 126 density = DENSITY_DEVICE / (float) DENSITY_DEFAULT; 127 densityDpi = DENSITY_DEVICE; 128 scaledDensity = density; 129 xdpi = DENSITY_DEVICE; 130 ydpi = DENSITY_DEVICE; 131 } 132 133 /** 134 * Update the display metrics based on the compatibility info and orientation 135 * NOTE: DO NOT EXPOSE THIS API! It is introducing a circular dependency 136 * with the higher-level android.res package. 137 * {@hide} 138 */ 139 public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation, 140 int screenLayout) { 141 boolean expandable = compatibilityInfo.isConfiguredExpandable(); 142 boolean largeScreens = compatibilityInfo.isConfiguredLargeScreens(); 143 boolean xlargeScreens = compatibilityInfo.isConfiguredXLargeScreens(); 144 145 // Note: this assume that configuration is updated before calling 146 // updateMetrics method. 147 if (!expandable) { 148 if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) == 0) { 149 expandable = true; 150 // the current screen size is compatible with non-resizing apps. 151 compatibilityInfo.setExpandable(true); 152 } else { 153 compatibilityInfo.setExpandable(false); 154 } 155 } 156 if (!largeScreens) { 157 if ((screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK) 158 != Configuration.SCREENLAYOUT_SIZE_LARGE) { 159 largeScreens = true; 160 // the current screen size is not large. 161 compatibilityInfo.setLargeScreens(true); 162 } else { 163 compatibilityInfo.setLargeScreens(false); 164 } 165 } 166 if (!xlargeScreens) { 167 if ((screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK) 168 != Configuration.SCREENLAYOUT_SIZE_XLARGE) { 169 xlargeScreens = true; 170 // the current screen size is not large. 171 compatibilityInfo.setXLargeScreens(true); 172 } else { 173 compatibilityInfo.setXLargeScreens(false); 174 } 175 } 176 177 if (!expandable || (!largeScreens && !xlargeScreens)) { 178 // This is a larger screen device and the app is not 179 // compatible with large screens, so diddle it. 180 181 // Figure out the compatibility width and height of the screen. 182 int defaultWidth; 183 int defaultHeight; 184 switch (orientation) { 185 case Configuration.ORIENTATION_LANDSCAPE: { 186 defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density + 187 0.5f); 188 defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density + 189 0.5f); 190 break; 191 } 192 case Configuration.ORIENTATION_PORTRAIT: 193 case Configuration.ORIENTATION_SQUARE: 194 default: { 195 defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density + 196 0.5f); 197 defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density + 198 0.5f); 199 break; 200 } 201 case Configuration.ORIENTATION_UNDEFINED: { 202 // don't change 203 return; 204 } 205 } 206 207 if (defaultWidth < widthPixels) { 208 // content/window's x offset in original pixels 209 widthPixels = defaultWidth; 210 } 211 if (defaultHeight < heightPixels) { 212 heightPixels = defaultHeight; 213 } 214 } 215 216 if (compatibilityInfo.isScalingRequired()) { 217 float invertedRatio = compatibilityInfo.applicationInvertedScale; 218 density *= invertedRatio; 219 densityDpi = (int)((density*DisplayMetrics.DENSITY_DEFAULT)+.5f); 220 scaledDensity *= invertedRatio; 221 xdpi *= invertedRatio; 222 ydpi *= invertedRatio; 223 widthPixels = (int) (widthPixels * invertedRatio + 0.5f); 224 heightPixels = (int) (heightPixels * invertedRatio + 0.5f); 225 } 226 } 227 228 @Override 229 public String toString() { 230 return "DisplayMetrics{density=" + density + ", width=" + widthPixels + 231 ", height=" + heightPixels + ", scaledDensity=" + scaledDensity + 232 ", xdpi=" + xdpi + ", ydpi=" + ydpi + "}"; 233 } 234 235 private static int getDeviceDensity() { 236 // qemu.sf.lcd_density can be used to override ro.sf.lcd_density 237 // when running in the emulator, allowing for dynamic configurations. 238 // The reason for this is that ro.sf.lcd_density is write-once and is 239 // set by the init process when it parses build.prop before anything else. 240 return SystemProperties.getInt("qemu.sf.lcd_density", 241 SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT)); 242 } 243} 244