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