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