• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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