1 /* 2 * Copyright (C) 2011 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 package android.app.cts; 17 18 import android.app.Activity; 19 import android.app.ActivityManager; 20 import android.app.stubs.ActivityManagerMemoryClassLaunchActivity; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.content.res.Configuration; 25 import android.support.test.uiautomator.UiDevice; 26 import android.test.ActivityInstrumentationTestCase2; 27 import android.util.DisplayMetrics; 28 import android.view.Display; 29 import android.view.WindowManager; 30 31 import com.android.compatibility.common.util.CddTest; 32 33 import java.util.HashMap; 34 import java.util.Map; 35 import java.util.regex.Matcher; 36 import java.util.regex.Pattern; 37 38 /** 39 * {@link ActivityInstrumentationTestCase2} that tests {@link ActivityManager#getMemoryClass()} 40 * by checking that the memory class matches the proper screen density and by launching an 41 * application that attempts to allocate memory on the heap. 42 */ 43 public class ActivityManagerMemoryClassTest 44 extends ActivityInstrumentationTestCase2<ActivityManagerMemoryClassLaunchActivity> { 45 46 public ActivityManagerMemoryClassTest() { 47 super(ActivityManagerMemoryClassLaunchActivity.class); 48 } 49 50 public static class ExpectedMemorySizesClass { 51 private static final Map<Integer, Integer> expectedMemorySizeForWatch 52 = new HashMap<Integer, Integer>(); 53 private static final Map<Integer, Integer> expectedMemorySizeForSmallNormalScreen 54 = new HashMap<Integer, Integer>(); 55 private static final Map<Integer, Integer> expectedMemorySizeForLargeScreen 56 = new HashMap<Integer, Integer>(); 57 private static final Map<Integer, Integer> expectedMemorySizeForXLargeScreen 58 = new HashMap<Integer, Integer>(); 59 60 static { 61 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_LOW, 32); 62 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_140, 32); 63 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_MEDIUM, 32); 64 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_180, 32); 65 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_200, 32); 66 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_TV, 32); 67 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_220, 36); 68 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_HIGH, 36); 69 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_260, 36); 70 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_280, 36); 71 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_300, 36); 72 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XHIGH, 48); 73 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_340, 48); 74 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_360, 48); 75 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_400, 56); 76 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_420, 64); 77 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_440, 88); 78 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_450, 88); 79 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XXHIGH, 88); 80 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_560, 112); 81 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_600, 138); 82 expectedMemorySizeForWatch.put(DisplayMetrics.DENSITY_XXXHIGH, 154); 83 } 84 85 static { 86 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_LOW, 32); 87 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_140, 32); 88 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_MEDIUM, 32); 89 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_180, 48); 90 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_200, 48); 91 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_TV, 48); 92 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_220, 48); 93 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_HIGH, 48); 94 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_260, 48); 95 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_280, 48); 96 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_300, 48); 97 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XHIGH, 80); 98 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_340, 80); 99 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_360, 80); 100 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_400, 96); 101 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_420, 112); 102 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_440, 128); 103 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_450, 128); 104 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXHIGH, 128); 105 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_560, 192); 106 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_600, 228); 107 expectedMemorySizeForSmallNormalScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 256); 108 } 109 110 static { 111 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_LOW, 32); 112 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_140, 48); 113 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_MEDIUM, 48); 114 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_180, 80); 115 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_200, 80); 116 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_TV, 80); 117 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_220, 80); 118 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_HIGH, 80); 119 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_260, 96); 120 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_280, 96); 121 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_300, 96); 122 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XHIGH, 128); 123 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_340, 160); 124 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_360, 160); 125 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_400, 192); 126 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_420, 228); 127 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_440, 256); 128 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_450, 256); 129 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XXHIGH, 256); 130 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_560, 384); 131 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_600, 448); 132 expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 512); 133 } 134 135 static { 136 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_LOW, 48); 137 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_140, 80); 138 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_MEDIUM, 80); 139 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_180, 96); 140 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_200, 96); 141 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_TV, 96); 142 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_220, 96); 143 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_HIGH, 96); 144 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_260, 144); 145 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_280, 144); 146 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_300, 144); 147 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XHIGH, 192); 148 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_340, 192); 149 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_360, 240); 150 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_400, 288); 151 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_420, 336); 152 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_440, 384); 153 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_450, 384); 154 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XXHIGH, 384); 155 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_560, 576); 156 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_600, 672); 157 expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XXXHIGH, 768); 158 } 159 160 public static Integer getExpectedMemorySize( 161 int screenSize, 162 int screenDensity, 163 boolean isWatch) { 164 165 if (isWatch) { 166 return expectedMemorySizeForWatch.get(screenDensity); 167 } 168 169 switch (screenSize) { 170 case Configuration.SCREENLAYOUT_SIZE_SMALL: 171 case Configuration.SCREENLAYOUT_SIZE_NORMAL: 172 return expectedMemorySizeForSmallNormalScreen.get(screenDensity); 173 case Configuration.SCREENLAYOUT_SIZE_LARGE: 174 return expectedMemorySizeForLargeScreen.get(screenDensity); 175 case Configuration.SCREENLAYOUT_SIZE_XLARGE: 176 return expectedMemorySizeForXLargeScreen.get(screenDensity); 177 default: 178 throw new IllegalArgumentException("No memory requirement specified " 179 + " for screen layout size " + screenSize); 180 } 181 } 182 } 183 184 @CddTest(requirement="3.7") 185 public void testGetMemoryClass() throws Exception { 186 UiDevice uiDevice = UiDevice.getInstance(getInstrumentation()); 187 int density = resetDensityIfNeeded(uiDevice); 188 189 int memoryClass = getMemoryClass(); 190 int screenDensity = getScreenDensity(); 191 int screenSize = getScreenSize(); 192 assertMemoryForScreenDensity(memoryClass, screenDensity, screenSize); 193 194 runHeapTestApp(memoryClass); 195 196 restoreDensityIfNeeded(uiDevice, density); 197 } 198 199 private int resetDensityIfNeeded(UiDevice device) throws Exception { 200 final String output = device.executeShellCommand("wm density"); 201 final Pattern p = Pattern.compile("Override density: (\\d+)"); 202 final Matcher m = p.matcher(output); 203 if (m.find()) { 204 device.executeShellCommand("wm density reset"); 205 int restoreDensity = Integer.parseInt(m.group(1)); 206 return restoreDensity; 207 } 208 return -1; 209 } 210 211 private void restoreDensityIfNeeded(UiDevice device, int restoreDensity) throws Exception { 212 if (restoreDensity > 0) { 213 device.executeShellCommand("wm density " + restoreDensity); 214 } 215 } 216 217 private int getMemoryClass() { 218 Context context = getInstrumentation().getTargetContext(); 219 ActivityManager activityManager = 220 (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 221 return activityManager.getMemoryClass(); 222 } 223 224 private int getScreenDensity() { 225 Context context = getInstrumentation().getTargetContext(); 226 WindowManager windowManager = 227 (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 228 Display display = windowManager.getDefaultDisplay(); 229 DisplayMetrics metrics = new DisplayMetrics(); 230 display.getMetrics(metrics); 231 return metrics.densityDpi; 232 } 233 234 private int getScreenSize() { 235 Context context = getInstrumentation().getTargetContext(); 236 Configuration config = context.getResources().getConfiguration(); 237 return config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; 238 } 239 240 private void assertMemoryForScreenDensity(int memoryClass, int screenDensity, int screenSize) { 241 Context context = getInstrumentation().getTargetContext(); 242 boolean isWatch = 243 context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH); 244 int expectedMinimumMemory = 245 ExpectedMemorySizesClass.getExpectedMemorySize(screenSize, screenDensity, isWatch); 246 247 assertTrue("Expected to have at least " + expectedMinimumMemory 248 + "mb of memory for screen density " + screenDensity, 249 memoryClass >= expectedMinimumMemory); 250 } 251 252 private void runHeapTestApp(int memoryClass) throws InterruptedException { 253 Intent intent = new Intent(); 254 intent.putExtra(ActivityManagerMemoryClassLaunchActivity.MEMORY_CLASS_EXTRA, 255 memoryClass); 256 setActivityIntent(intent); 257 ActivityManagerMemoryClassLaunchActivity activity = getActivity(); 258 assertEquals("The test application couldn't allocate memory close to the amount " 259 + " specified by the memory class.", Activity.RESULT_OK, activity.getResult()); 260 } 261 } 262