1 /* 2 * Copyright (C) 2013 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.hardware.cts; 18 19 import static android.content.res.Configuration.SCREENLAYOUT_SIZE_LARGE; 20 import static android.content.res.Configuration.SCREENLAYOUT_SIZE_NORMAL; 21 import static android.content.res.Configuration.SCREENLAYOUT_SIZE_SMALL; 22 import static android.content.res.Configuration.SCREENLAYOUT_SIZE_XLARGE; 23 24 import static android.util.DisplayMetrics.DENSITY_400; 25 import static android.util.DisplayMetrics.DENSITY_560; 26 import static android.util.DisplayMetrics.DENSITY_HIGH; 27 import static android.util.DisplayMetrics.DENSITY_LOW; 28 import static android.util.DisplayMetrics.DENSITY_MEDIUM; 29 import static android.util.DisplayMetrics.DENSITY_TV; 30 import static android.util.DisplayMetrics.DENSITY_XHIGH; 31 32 import android.app.ActivityManager; 33 import android.content.Context; 34 import android.content.pm.PackageManager; 35 import android.content.res.Configuration; 36 import android.os.Build; 37 import android.test.AndroidTestCase; 38 import android.util.DisplayMetrics; 39 import android.view.WindowManager; 40 import android.util.Log; 41 42 import java.io.FileInputStream; 43 import java.io.IOException; 44 import java.io.InputStream; 45 import java.util.Scanner; 46 import java.util.StringTokenizer; 47 48 /** 49 * Tests that devices with low RAM specify themselves as Low RAM devices 50 */ 51 public class LowRamDeviceTest extends AndroidTestCase { 52 53 private static final long ONE_MEGABYTE = 1048576L; 54 private static final String TAG = "LowRamDeviceTest"; 55 private static final long LOW_RAM_MAX = 1024; 56 57 private PackageManager mPackageManager; 58 private ActivityManager mActivityManager; 59 private DisplayMetrics mDisplayMetrics; 60 61 @Override 62 protected void setUp() throws Exception { 63 super.setUp(); 64 mPackageManager = getContext().getPackageManager(); 65 mActivityManager = 66 (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE); 67 68 mDisplayMetrics = new DisplayMetrics(); 69 WindowManager windowManager = 70 (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); 71 windowManager.getDefaultDisplay().getMetrics(mDisplayMetrics); 72 } 73 74 /** 75 * Test the devices reported memory to ensure it meets the minimum values described 76 * in CDD 7.6.1. 77 */ 78 public void testMinimumMemory() { 79 int density = mDisplayMetrics.densityDpi; 80 Boolean supports64Bit = supportsSixtyFourBit(); 81 int screenSize = getScreenSize(); 82 Boolean lowRamDevice = mActivityManager.isLowRamDevice(); 83 Boolean watch = mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH); 84 85 Log.i(TAG, String.format("density=%d, supports64Bit=%s, screenSize=%d, watch=%s", 86 density, supports64Bit, screenSize, watch)); 87 88 if (watch) { 89 assertFalse("Device is not expected to be 64-bit", supports64Bit); 90 assertMinMemoryMb(416); 91 } else if (lessThanDpi(density, DENSITY_HIGH, screenSize, 92 SCREENLAYOUT_SIZE_NORMAL, SCREENLAYOUT_SIZE_SMALL) || 93 lessThanDpi(density, DENSITY_MEDIUM, screenSize, SCREENLAYOUT_SIZE_LARGE) || 94 lessThanDpi(density, DENSITY_LOW, screenSize, SCREENLAYOUT_SIZE_XLARGE)) { 95 96 if (supports64Bit) { 97 assertMinMemoryMb(704); 98 } else { 99 assertMinMemoryMb(424); 100 } 101 } else if (greaterThanDpi(density, DENSITY_560, screenSize, 102 SCREENLAYOUT_SIZE_NORMAL, SCREENLAYOUT_SIZE_SMALL) || 103 greaterThanDpi(density, DENSITY_400, screenSize, SCREENLAYOUT_SIZE_LARGE) || 104 greaterThanDpi(density, DENSITY_XHIGH, screenSize, SCREENLAYOUT_SIZE_XLARGE)) { 105 106 if (supports64Bit) { 107 assertMinMemoryMb(1824); 108 } else { 109 assertMinMemoryMb(1344); 110 } 111 } else if (greaterThanDpi(density, DENSITY_400, screenSize, 112 SCREENLAYOUT_SIZE_NORMAL, SCREENLAYOUT_SIZE_SMALL) || 113 greaterThanDpi(density, DENSITY_XHIGH, screenSize, SCREENLAYOUT_SIZE_LARGE) || 114 greaterThanDpi(density, DENSITY_TV, screenSize, SCREENLAYOUT_SIZE_XLARGE)) { 115 116 if (supports64Bit) { 117 assertMinMemoryMb(1280); 118 } else { 119 assertMinMemoryMb(896); 120 } 121 } else if (greaterThanDpi(density, DENSITY_XHIGH, screenSize, 122 SCREENLAYOUT_SIZE_NORMAL, SCREENLAYOUT_SIZE_SMALL) || 123 greaterThanDpi(density, DENSITY_TV, screenSize, SCREENLAYOUT_SIZE_LARGE) || 124 greaterThanDpi(density, DENSITY_MEDIUM, screenSize, SCREENLAYOUT_SIZE_XLARGE)) { 125 126 if (supports64Bit) { 127 assertMinMemoryMb(832); 128 } else { 129 assertMinMemoryMb(512); 130 } 131 } 132 } 133 134 /** 135 * @return the total memory accessible by the kernel as defined by 136 * {@code ActivityManager.MemoryInfo}. 137 */ 138 private long getTotalMemory() { 139 ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); 140 mActivityManager.getMemoryInfo(memoryInfo); 141 return memoryInfo.totalMem; 142 } 143 144 /** @return the screen size as defined in {@Configuration}. */ 145 private int getScreenSize() { 146 Configuration config = getContext().getResources().getConfiguration(); 147 return config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; 148 } 149 150 /** @return true iff this device supports 64 bit ABIs */ 151 private static boolean supportsSixtyFourBit() { 152 return Build.SUPPORTED_64_BIT_ABIS.length > 0; 153 } 154 155 /** Asserts that the given values conform to the specs in CDD 7.6.1 */ 156 private void assertMinMemoryMb(long minMb) { 157 158 long totalMemoryMb = getTotalMemory() / ONE_MEGABYTE; 159 boolean lowRam = totalMemoryMb <= LOW_RAM_MAX; 160 boolean lowRamDevice = mActivityManager.isLowRamDevice(); 161 162 Log.i(TAG, String.format("minMb=%,d", minMb)); 163 Log.i(TAG, String.format("totalMemoryMb=%,d", totalMemoryMb)); 164 Log.i(TAG, "lowRam=" + lowRam); 165 Log.i(TAG, "lowRamDevice=" + lowRamDevice); 166 167 assertTrue(String.format("Does not meet minimum memory requirements (CDD 7.6.1)." 168 + "Found = %d, Minimum = %d", totalMemoryMb, minMb), totalMemoryMb >= minMb); 169 170 assertTrue("Device must specify low RAM property: ro.config.low_ram=true", 171 !lowRam || (lowRam && lowRamDevice)); 172 } 173 174 private static boolean lessThanDpi(int actualDensityDpi, int expectedDensityDpi, 175 int actualScreenSize, int... expectedScreenSizes) { 176 return actualDensityDpi <= expectedDensityDpi && 177 contains(expectedScreenSizes, actualScreenSize); 178 } 179 180 private static boolean greaterThanDpi(int actualDensityDpi, int expectedDensityDpi, 181 int actualScreenSize, int... expectedScreenSizes) { 182 return actualDensityDpi >= expectedDensityDpi && 183 contains(expectedScreenSizes, actualScreenSize); 184 } 185 186 /** @return true iff the {@code array} contains the {@code target} */ 187 private static boolean contains(int [] array, int target) { 188 for(int a : array) { 189 if (a == target) { 190 return true; 191 } 192 } 193 return false; 194 } 195 } 196