1 /* 2 * Copyright (C) 2008 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.tests.getinfo; 18 19 import android.app.Activity; 20 import android.app.Instrumentation; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.FeatureInfo; 24 import android.content.pm.PackageManager; 25 import android.content.res.Configuration; 26 import android.os.Build; 27 import android.os.Bundle; 28 import android.telephony.TelephonyManager; 29 import android.util.DisplayMetrics; 30 import android.util.Log; 31 import android.view.Display; 32 import android.view.WindowManager; 33 34 import java.io.IOException; 35 import java.lang.reflect.Field; 36 import java.util.ArrayList; 37 import java.util.HashSet; 38 import java.util.List; 39 import java.util.Scanner; 40 import java.util.Set; 41 42 public class DeviceInfoInstrument extends Instrumentation implements DeviceInfoConstants { 43 44 private static final String TAG = "DeviceInfoInstrument"; 45 46 private static Bundle mResults = new Bundle(); 47 48 public DeviceInfoInstrument() { 49 super(); 50 } 51 52 @Override 53 public void onCreate(Bundle arguments) { 54 start(); 55 } 56 57 @Override 58 public void onStart() { 59 60 addResult(BUILD_ID, Build.ID); 61 addResult(PRODUCT_NAME, Build.PRODUCT); 62 addResult(BUILD_DEVICE, Build.DEVICE); 63 addResult(BUILD_BOARD, Build.BOARD); 64 addResult(BUILD_MANUFACTURER, Build.MANUFACTURER); 65 addResult(BUILD_BRAND, Build.BRAND); 66 addResult(BUILD_MODEL, Build.MODEL); 67 addResult(BUILD_TYPE, Build.TYPE); 68 addResult(BUILD_FINGERPRINT, Build.FINGERPRINT); 69 addResult(BUILD_ABI, Build.CPU_ABI); 70 addResult(BUILD_ABI2, Build.CPU_ABI2); 71 addResult(SERIAL_NUMBER, Build.SERIAL); 72 73 addResult(VERSION_RELEASE, Build.VERSION.RELEASE); 74 addResult(VERSION_SDK, Build.VERSION.SDK); 75 76 DisplayMetrics metrics = new DisplayMetrics(); 77 WindowManager wm = (WindowManager) getContext().getSystemService( 78 Context.WINDOW_SERVICE); 79 Display d = wm.getDefaultDisplay(); 80 d.getMetrics(metrics); 81 addResult(RESOLUTION, String.format("%sx%s", metrics.widthPixels, metrics.heightPixels)); 82 addResult(SCREEN_DENSITY, metrics.density); 83 addResult(SCREEN_X_DENSITY, metrics.xdpi); 84 addResult(SCREEN_Y_DENSITY, metrics.ydpi); 85 86 String screenDensityBucket = getScreenDensityBucket(metrics); 87 addResult(SCREEN_DENSITY_BUCKET, screenDensityBucket); 88 89 String screenSize = getScreenSize(); 90 addResult(SCREEN_SIZE, screenSize); 91 92 Intent intent = new Intent(); 93 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 94 intent.setClass(this.getContext(), DeviceInfoActivity.class); 95 96 DeviceInfoActivity activity = (DeviceInfoActivity) startActivitySync(intent); 97 waitForIdleSync(); 98 activity.waitForAcitityToFinish(); 99 100 TelephonyManager tm = (TelephonyManager) getContext().getSystemService( 101 Context.TELEPHONY_SERVICE); 102 // network 103 String network = tm.getNetworkOperatorName(); 104 addResult(NETWORK, network.trim()); 105 106 // imei 107 String imei = tm.getDeviceId(); 108 addResult(IMEI, imei); 109 110 // imsi 111 String imsi = tm.getSubscriberId(); 112 addResult(IMSI, imsi); 113 114 // phone number 115 String phoneNumber = tm.getLine1Number(); 116 addResult(PHONE_NUMBER, phoneNumber); 117 118 // features 119 String features = getFeatures(); 120 addResult(FEATURES, features); 121 122 // processes 123 String processes = getProcesses(); 124 addResult(PROCESSES, processes); 125 126 // OpenGL ES version 127 String openGlEsVersion = getOpenGlEsVersion(); 128 addResult(OPEN_GL_ES_VERSION, openGlEsVersion); 129 130 // partitions 131 String partitions = getPartitions(); 132 addResult(PARTITIONS, partitions); 133 134 // System libraries 135 String sysLibraries = getSystemLibraries(); 136 addResult(SYS_LIBRARIES, sysLibraries); 137 138 finish(Activity.RESULT_OK, mResults); 139 } 140 141 /** 142 * Add string result. 143 * 144 * @param key the string of the key name. 145 * @param value string value. 146 */ 147 static void addResult(final String key, final String value){ 148 mResults.putString(key, value); 149 } 150 151 /** 152 * Add integer result. 153 * 154 * @param key the string of the key name. 155 * @param value integer value. 156 */ 157 private void addResult(final String key, final int value){ 158 mResults.putInt(key, value); 159 } 160 161 /** 162 * Add float result. 163 * 164 * @param key the string of the key name. 165 * @param value float value. 166 */ 167 private void addResult(final String key, final float value){ 168 mResults.putFloat(key, value); 169 } 170 171 private String getScreenSize() { 172 Configuration config = getContext().getResources().getConfiguration(); 173 int screenLayout = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK; 174 String screenSize = String.format("0x%x", screenLayout); 175 switch (screenLayout) { 176 case Configuration.SCREENLAYOUT_SIZE_SMALL: 177 screenSize = "small"; 178 break; 179 180 case Configuration.SCREENLAYOUT_SIZE_NORMAL: 181 screenSize = "normal"; 182 break; 183 184 case Configuration.SCREENLAYOUT_SIZE_LARGE: 185 screenSize = "large"; 186 break; 187 188 case Configuration.SCREENLAYOUT_SIZE_XLARGE: 189 screenSize = "xlarge"; 190 break; 191 192 case Configuration.SCREENLAYOUT_SIZE_UNDEFINED: 193 screenSize = "undefined"; 194 break; 195 } 196 return screenSize; 197 } 198 199 private String getScreenDensityBucket(DisplayMetrics metrics) { 200 switch (metrics.densityDpi) { 201 case DisplayMetrics.DENSITY_LOW: 202 return "ldpi"; 203 204 case DisplayMetrics.DENSITY_MEDIUM: 205 return "mdpi"; 206 207 case DisplayMetrics.DENSITY_TV: 208 return "tvdpi"; 209 210 case DisplayMetrics.DENSITY_HIGH: 211 return "hdpi"; 212 213 case DisplayMetrics.DENSITY_XHIGH: 214 return "xdpi"; 215 216 default: 217 return "" + metrics.densityDpi; 218 } 219 } 220 221 /** 222 * Return a summary of the device's feature as a semi-colon-delimited list of colon separated 223 * name and availability pairs like "feature1:sdk:true;feature2:sdk:false;feature3:other:true;". 224 */ 225 private String getFeatures() { 226 StringBuilder features = new StringBuilder(); 227 228 try { 229 Set<String> checkedFeatures = new HashSet<String>(); 230 231 PackageManager packageManager = getContext().getPackageManager(); 232 for (String featureName : getPackageManagerFeatures()) { 233 checkedFeatures.add(featureName); 234 boolean hasFeature = packageManager.hasSystemFeature(featureName); 235 addFeature(features, featureName, "sdk", hasFeature); 236 } 237 238 FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures(); 239 if (featureInfos != null) { 240 for (FeatureInfo featureInfo : featureInfos) { 241 if (featureInfo.name != null && !checkedFeatures.contains(featureInfo.name)) { 242 addFeature(features, featureInfo.name, "other", true); 243 } 244 } 245 } 246 } catch (Exception exception) { 247 Log.e(TAG, "Error getting features: " + exception.getMessage(), exception); 248 } 249 250 return features.toString(); 251 } 252 253 private static void addFeature(StringBuilder features, String name, String type, 254 boolean available) { 255 features.append(name).append(':').append(type).append(':').append(available).append(';'); 256 } 257 258 /** 259 * Use reflection to get the features defined by the SDK. If there are features that do not fit 260 * the convention of starting with "FEATURE_" then they will still be shown under the 261 * "Other Features" section. 262 * 263 * @return list of feature names from sdk 264 */ 265 private List<String> getPackageManagerFeatures() { 266 try { 267 List<String> features = new ArrayList<String>(); 268 Field[] fields = PackageManager.class.getFields(); 269 for (Field field : fields) { 270 if (field.getName().startsWith("FEATURE_")) { 271 String feature = (String) field.get(null); 272 features.add(feature); 273 } 274 } 275 return features; 276 } catch (IllegalAccessException illegalAccess) { 277 throw new RuntimeException(illegalAccess); 278 } 279 } 280 281 /** 282 * Return a semi-colon-delimited list of the root processes that were running on the phone 283 * or an error message. 284 */ 285 private static String getProcesses() { 286 StringBuilder builder = new StringBuilder(); 287 288 try { 289 String[] rootProcesses = RootProcessScanner.getRootProcesses(); 290 for (String rootProcess : rootProcesses) { 291 builder.append(rootProcess).append(':').append(0).append(';'); 292 } 293 } catch (Exception exception) { 294 Log.e(TAG, "Error getting processes: " + exception.getMessage(), exception); 295 builder.append(exception.getMessage()); 296 } 297 298 return builder.toString(); 299 } 300 301 /** @return a string containing the Open GL ES version number or an error message */ 302 private String getOpenGlEsVersion() { 303 PackageManager packageManager = getContext().getPackageManager(); 304 FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures(); 305 if (featureInfos != null && featureInfos.length > 0) { 306 for (FeatureInfo featureInfo : featureInfos) { 307 // Null feature name means this feature is the open gl es version feature. 308 if (featureInfo.name == null) { 309 return featureInfo.getGlEsVersion(); 310 } 311 } 312 } 313 return "No feature for Open GL ES version."; 314 } 315 316 private String getPartitions() { 317 try { 318 StringBuilder builder = new StringBuilder(); 319 Process df = new ProcessBuilder("df").start(); 320 Scanner scanner = new Scanner(df.getInputStream()); 321 try { 322 while (scanner.hasNextLine()) { 323 builder.append(scanner.nextLine()).append(';'); 324 } 325 return builder.toString(); 326 } finally { 327 scanner.close(); 328 } 329 } catch (IOException e) { 330 return "Not able to run df for partition information."; 331 } 332 } 333 334 private String getSystemLibraries() { 335 PackageManager pm = getContext().getPackageManager(); 336 String list[] = pm.getSystemSharedLibraryNames(); 337 338 StringBuilder builder = new StringBuilder(); 339 for (String lib : list) { 340 builder.append(lib); 341 builder.append(";"); 342 } 343 344 return builder.toString(); 345 } 346 } 347