1 /* 2 * Copyright (C) 2009 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.dpi.cts; 18 19 import android.content.Context; 20 import android.content.res.Configuration; 21 import android.test.AndroidTestCase; 22 import android.view.Display; 23 import android.view.WindowManager; 24 import android.util.DisplayMetrics; 25 26 import java.lang.Integer; 27 import java.util.EnumSet; 28 29 /** 30 * This is verifying that the device under test is running a supported 31 * resolution, and is being classified as the right Screen Layout 32 * Size. 33 */ 34 public class ConfigurationTest extends AndroidTestCase { 35 36 private enum Density { 37 // It is important to keep these sorted 38 INVALID_LOW(Integer.MIN_VALUE, 99), 39 LOW (100, 140), 40 MEDIUM (141, 190), 41 HIGH (191, 250), 42 INVALID_HIGH(251, Integer.MAX_VALUE); 43 44 private int low; 45 private int high; 46 Density(int low, int high)47 Density(int low, int high) { 48 this.low = low; 49 this.high = high; 50 } 51 findDensity(int value)52 public static Density findDensity(int value) { 53 Density density = INVALID_LOW; 54 for (Density d : EnumSet.range(Density.INVALID_LOW, Density.INVALID_HIGH)) { 55 if (value >= d.low && value <= d.high) { 56 density = d; 57 break; 58 } 59 } 60 return density; 61 } 62 }; 63 64 /** 65 * Holds information on the current active screen's configuration. 66 */ 67 private static class ActiveScreenConfiguration { 68 private final int width; 69 private final int height; 70 private final Density density; 71 72 /** 73 * Create a new ActiveScreenConfiguration. 74 * 75 * @param width the width of the screen 76 * @param height the height of the screen 77 * @param density the scaling factor for DIP from standard 78 * density (160.0) 79 */ ActiveScreenConfiguration(int width, int height, float density)80 public ActiveScreenConfiguration(int width, 81 int height, 82 float density) { 83 // 160 DIP is the "standard" density 84 this(width, height, Density.findDensity((int) (160.0f * density))); 85 } 86 ActiveScreenConfiguration(int width, int height, Density density)87 protected ActiveScreenConfiguration(int width, 88 int height, 89 Density density) { 90 this.width = width; 91 this.height = height; 92 this.density = density; 93 } 94 getDensity()95 public Density getDensity() { 96 return density; 97 } 98 getWidth()99 public int getWidth() { 100 return width; 101 } 102 getHeight()103 public int getHeight() { 104 return height; 105 } 106 } 107 108 private static class ScreenConfiguration extends ActiveScreenConfiguration { 109 private final int screenLayout; 110 private final boolean isWide; 111 ScreenConfiguration(int width, int height, Density density, int screenLayout, boolean isWide)112 public ScreenConfiguration(int width, 113 int height, 114 Density density, 115 int screenLayout, 116 boolean isWide) { 117 super(width, height, density); 118 this.screenLayout = screenLayout; 119 this.isWide = isWide; 120 } 121 ScreenConfiguration(int width, int height, Density density, int screenLayout)122 public ScreenConfiguration(int width, 123 int height, 124 Density density, 125 int screenLayout) { 126 this(width, height, density, screenLayout, false); 127 } 128 getScreenLayout()129 public int getScreenLayout() { 130 return screenLayout; 131 } 132 isWide()133 public boolean isWide() { 134 return isWide; 135 } 136 }; 137 areConfigsEqual(ActiveScreenConfiguration active, ScreenConfiguration screenConfig)138 private static boolean areConfigsEqual(ActiveScreenConfiguration active, 139 ScreenConfiguration screenConfig) { 140 if (screenConfig.isWide()) { 141 // For widescreen configs, the height is fixed but the 142 // width only specifies a minimum. But since the device 143 // can be both landscape and portrait, we have to search 144 // for which way it is. 145 if (active.getHeight() == screenConfig.getHeight()) { 146 // active height matches config height. Make sure 147 // that the active width is at least the config width. 148 return active.getWidth() >= screenConfig.getWidth(); 149 } else if (active.getWidth() == screenConfig.getHeight()) { 150 // directions are swapped 151 return active.getHeight() >= screenConfig.getWidth(); 152 } else { 153 return false; 154 } 155 } else { 156 if (active.getWidth() == screenConfig.getWidth() && 157 active.getHeight() == screenConfig.getHeight() && 158 active.getDensity().equals(screenConfig.getDensity())) { 159 return true; 160 } 161 // It is also possible that the device is in landscape 162 // mode, which flips the active w/h. 163 if (active.getHeight() == screenConfig.getWidth() && 164 active.getWidth() == screenConfig.getHeight() && 165 active.getDensity().equals(screenConfig.getDensity())) { 166 return true; 167 } 168 // nope. 169 return false; 170 } 171 } 172 173 /** 174 * Here's the current configuration table: 175 * 176 * Resoluion | Density | Size 177 * QVGA | low (100-140) | small 178 * WQVGA | low (100-140) | normal 179 * HVGA | medium (141-190) | normal 180 * WVGA | high (191-250) | normal 181 * FWVGA | high (191-250) | normal 182 183 * VGA | medium (141-190) | large 184 * WVGA | medium (141-190) | large 185 * FWVGA | medium (141-190) | large 186 * 187 * Any changes to allow additional resolutions will need to update this table 188 */ 189 190 private static final ScreenConfiguration[] SUPPORTED_SCREEN_CONFIGS = { 191 // QVGA | low (100-140) | small 192 new ScreenConfiguration(240, 320, Density.LOW, Configuration.SCREENLAYOUT_SIZE_SMALL), 193 // WQVGA | low (100-140) | normal 194 new ScreenConfiguration(240, 320, Density.LOW, Configuration.SCREENLAYOUT_SIZE_SMALL, true), 195 // HVGA | medium (141-190) | normal 196 new ScreenConfiguration(480, 320, Density.MEDIUM, Configuration.SCREENLAYOUT_SIZE_NORMAL), 197 new ScreenConfiguration(640, 240, Density.MEDIUM, Configuration.SCREENLAYOUT_SIZE_NORMAL), 198 // WVGA | high (191-250) | normal 199 new ScreenConfiguration(640, 480, Density.HIGH, Configuration.SCREENLAYOUT_SIZE_NORMAL, true), 200 // FWVGA | high (191-250) | normal 201 new ScreenConfiguration(864, 480, Density.HIGH, Configuration.SCREENLAYOUT_SIZE_NORMAL), 202 203 // VGA | medium (141-190) | large 204 new ScreenConfiguration(640, 480, Density.MEDIUM, Configuration.SCREENLAYOUT_SIZE_LARGE), 205 // WVGA | medium (141-190) | large 206 new ScreenConfiguration(640, 480, Density.MEDIUM, Configuration.SCREENLAYOUT_SIZE_LARGE, true), 207 // FWVGA | medium (141-190) | large 208 new ScreenConfiguration(864, 480, Density.MEDIUM, Configuration.SCREENLAYOUT_SIZE_LARGE), 209 210 }; 211 getCurrentScreenConfig()212 private ActiveScreenConfiguration getCurrentScreenConfig() { 213 WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); 214 Display display = wm.getDefaultDisplay(); 215 DisplayMetrics dm = new DisplayMetrics(); 216 display.getMetrics(dm); 217 return new ActiveScreenConfiguration(display.getWidth(), 218 display.getHeight(), 219 dm.density); 220 } 221 222 /** 223 * Get the current screen configuration, make sure it is a 224 * supported screen configuration and that the screenlayout size 225 * is being set correctly according to the compatibility 226 * definition. 227 */ testScreenLayoutSize()228 public void testScreenLayoutSize() { 229 ActiveScreenConfiguration currentScreenConfig = getCurrentScreenConfig(); 230 // Make sure we have a valid density for the current screent. 231 assertFalse(Density.INVALID_LOW.equals(currentScreenConfig.getDensity())); 232 assertFalse(Density.INVALID_HIGH.equals(currentScreenConfig.getDensity())); 233 234 // Look up the ScreenConfig in the supported table and make 235 // sure we find a match. 236 for (ScreenConfiguration screenConfig: SUPPORTED_SCREEN_CONFIGS) { 237 if (areConfigsEqual(currentScreenConfig, screenConfig)) { 238 Configuration config = getContext().getResources().getConfiguration(); 239 int size = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; 240 if (screenConfig.getScreenLayout() == size) { 241 // we have a match, this is a supported device. 242 return; 243 } 244 } 245 } 246 fail("Current screen configuration is not supported."); 247 } 248 } 249