Home | History | Annotate | Download | only in cts
      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