DisplayMetrics.java revision 723738cfaec3dd7b0fe152c872c41bebf94074c4
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.util; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshimaimport android.content.res.CompatibilityInfo; 209189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshimaimport android.content.res.Configuration; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.*; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A structure describing general information about a display, such as its 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * size, density, and font scaling. 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class DisplayMetrics { 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The reference density used throughout the system. 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide Pending API council approval 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DEFAULT_DENSITY = 160; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 362e3d3b9ce74cb9c906e5cc0e9898d757d45c4237Mitsuru Oshima /** 372e3d3b9ce74cb9c906e5cc0e9898d757d45c4237Mitsuru Oshima * The device's density. 382e3d3b9ce74cb9c906e5cc0e9898d757d45c4237Mitsuru Oshima * @hide 392e3d3b9ce74cb9c906e5cc0e9898d757d45c4237Mitsuru Oshima */ 402a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner public static final int DEVICE_DENSITY = getDeviceDensity(); 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The absolute width of the display in pixels. 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int widthPixels; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The absolute height of the display in pixels. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int heightPixels; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The logical density of the display. This is a scaling factor for the 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Density Independent Pixel unit, where one DIP is one pixel on an 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providing the baseline of the system's display. Thus on a 160dpi screen 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this density value will be 1; on a 106 dpi screen it would be .75; etc. 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This value does not exactly follow the real screen size (as given by 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the overall UI in steps based on gross changes in the display dpi. For 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * example, a 240x320 screen will have a density of 1 even if its width is 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1.8", 1.3", etc. However, if the screen resolution is increased to 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 320x480 but the screen size remained 1.5"x2" then the density would be 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * increased (probably to 1.5). 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #DEFAULT_DENSITY 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float density; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A scaling factor for fonts displayed on the display. This is the same 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as {@link #density}, except that it may be adjusted in smaller 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * increments at runtime based on a user preference for the font size. 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float scaledDensity; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The exact physical pixels per inch of the screen in the X dimension. 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float xdpi; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The exact physical pixels per inch of the screen in the Y dimension. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float ydpi; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public DisplayMetrics() { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTo(DisplayMetrics o) { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthPixels = o.widthPixels; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heightPixels = o.heightPixels; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project density = o.density; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaledDensity = o.scaledDensity; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xdpi = o.xdpi; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ydpi = o.ydpi; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setToDefaults() { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthPixels = 0; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heightPixels = 0; 982e3d3b9ce74cb9c906e5cc0e9898d757d45c4237Mitsuru Oshima density = DEVICE_DENSITY / (float) DEFAULT_DENSITY; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scaledDensity = density; 1002e3d3b9ce74cb9c906e5cc0e9898d757d45c4237Mitsuru Oshima xdpi = DEVICE_DENSITY; 1012e3d3b9ce74cb9c906e5cc0e9898d757d45c4237Mitsuru Oshima ydpi = DEVICE_DENSITY; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10358feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima 10458feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima /** 105e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima * Update the display metrics based on the compatibility info and orientation 106723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn * NOTE: DO NOT EXPOSE THIS API! It is introducing a circular dependency 107723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn * with the higher-level android.res package. 1089189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima * {@hide} 10958feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima */ 110723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation, 111723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int screenLayout) { 11264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima int xOffset = 0; 11364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima if (!compatibilityInfo.isConfiguredExpandable()) { 1149189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima // Note: this assume that configuration is updated before calling 1159189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima // updateMetrics method. 116723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn if (screenLayout == Configuration.SCREENLAYOUT_LARGE) { 117723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // This is a large screen device and the app is not 118723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // compatible with large screens, to diddle it. 119723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn 12064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima compatibilityInfo.setExpandable(false); 121723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // Figure out the compatibility width and height of the screen. 122723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int defaultWidth; 123723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn int defaultHeight; 124723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn switch (orientation) { 125723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn case Configuration.ORIENTATION_LANDSCAPE: { 126723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density); 127723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density); 128723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn break; 129723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 130723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn case Configuration.ORIENTATION_PORTRAIT: 131723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn case Configuration.ORIENTATION_SQUARE: 132723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn default: { 133723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density); 134723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density); 135723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn break; 136723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 137723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn case Configuration.ORIENTATION_UNDEFINED: { 138723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // don't change 139723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn return; 140723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 141723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } 142723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn 143e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima if (defaultWidth < widthPixels) { 14464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima // content/window's x offset in original pixels 14564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima xOffset = ((widthPixels - defaultWidth) / 2); 146e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima widthPixels = defaultWidth; 147e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima } 148e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima if (defaultHeight < heightPixels) { 149e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima heightPixels = defaultHeight; 150e5fb328825995aa33b5b7ecf8b5bee2b17f81715Mitsuru Oshima } 151723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn 152723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn } else { 153723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn // the screen size is same as expected size. make it expandable 154723738cfaec3dd7b0fe152c872c41bebf94074c4Dianne Hackborn compatibilityInfo.setExpandable(true); 1559189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima } 1569189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima } 15764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels); 15864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima if (compatibilityInfo.isScalingRequired()) { 15964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima float invertedRatio = compatibilityInfo.applicationInvertedScale; 16064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima density *= invertedRatio; 16164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima scaledDensity *= invertedRatio; 16264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima xdpi *= invertedRatio; 16364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima ydpi *= invertedRatio; 16464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima widthPixels *= invertedRatio; 16564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima heightPixels *= invertedRatio; 16664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 16758feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima } 16858feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima 16964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima @Override 17058feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima public String toString() { 17158feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima return "DisplayMetrics{density=" + density + ", width=" + widthPixels + 17258feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima ", height=" + heightPixels + ", scaledDensity=" + scaledDensity + 17358feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima ", xdpi=" + xdpi + ", ydpi=" + ydpi + "}"; 17458feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima } 1752a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner 1762a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner private static int getDeviceDensity() { 1772a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner // qemu.sf.lcd_density can be used to override ro.sf.lcd_density 1782a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner // when running in the emulator, allowing for dynamic configurations. 1792a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner // The reason for this is that ro.sf.lcd_density is write-once and is 1802a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner // set by the init process when it parses build.prop before anything else. 1812a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner return SystemProperties.getInt("qemu.sf.lcd_density", 1822a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner SystemProperties.getInt("ro.sf.lcd_density", DEFAULT_DENSITY)); 1832a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 185