Home | History | Annotate | Download | only in getinfo
      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.ActivityManager;
     21 import android.app.ActivityManager.MemoryInfo;
     22 import android.app.Instrumentation;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.pm.FeatureInfo;
     26 import android.content.pm.PackageManager;
     27 import android.content.res.Configuration;
     28 import android.os.Build;
     29 import android.os.Bundle;
     30 import android.os.Environment;
     31 import android.os.UserManager;
     32 import android.os.SystemProperties;
     33 import android.telephony.TelephonyManager;
     34 import android.text.TextUtils;
     35 import android.util.DisplayMetrics;
     36 import android.util.Log;
     37 import android.view.Display;
     38 import android.view.WindowManager;
     39 
     40 import java.io.IOException;
     41 import java.lang.reflect.Field;
     42 import java.lang.reflect.InvocationTargetException;
     43 import java.lang.reflect.Method;
     44 import java.util.ArrayList;
     45 import java.util.Arrays;
     46 import java.util.HashSet;
     47 import java.util.List;
     48 import java.util.Scanner;
     49 import java.util.Set;
     50 
     51 public class DeviceInfoInstrument extends Instrumentation implements DeviceInfoConstants {
     52 
     53     private static final String TAG = "DeviceInfoInstrument";
     54 
     55     private static Bundle mResults = new Bundle();
     56 
     57     public DeviceInfoInstrument() {
     58         super();
     59     }
     60 
     61     @Override
     62     public void onCreate(Bundle arguments) {
     63         start();
     64     }
     65 
     66     @Override
     67     public void onStart() {
     68         addResult(BUILD_ID, Build.ID);
     69         addResult(PRODUCT_NAME, Build.PRODUCT);
     70         addResult(BUILD_DEVICE, Build.DEVICE);
     71         addResult(BUILD_BOARD, Build.BOARD);
     72         addResult(BUILD_MANUFACTURER, Build.MANUFACTURER);
     73         addResult(BUILD_BRAND, Build.BRAND);
     74         addResult(BUILD_MODEL, Build.MODEL);
     75         addResult(BUILD_TYPE, Build.TYPE);
     76         addResult(BUILD_FINGERPRINT, Build.FINGERPRINT);
     77         addResult(BUILD_ABI, Build.CPU_ABI);
     78         addResult(BUILD_ABI2, Build.CPU_ABI2);
     79         addResult(BUILD_ABIS, TextUtils.join(",", Build.SUPPORTED_ABIS));
     80         addResult(BUILD_ABIS_32, TextUtils.join(",", Build.SUPPORTED_32_BIT_ABIS));
     81         addResult(BUILD_ABIS_64, TextUtils.join(",", Build.SUPPORTED_64_BIT_ABIS));
     82         addResult(SERIAL_NUMBER, Build.SERIAL);
     83 
     84         addResult(REFERENCE_BUILD_FINGERPRINT,
     85             SystemProperties.get("ro.build.reference.fingerprint", ""));
     86 
     87         addResult(VERSION_RELEASE, Build.VERSION.RELEASE);
     88         addResult(VERSION_SDK, Build.VERSION.SDK);
     89         addResult(VERSION_BASE_OS, Build.VERSION.BASE_OS);
     90         addResult(VERSION_SECURITY_PATCH, Build.VERSION.SECURITY_PATCH);
     91 
     92         DisplayMetrics metrics = new DisplayMetrics();
     93         WindowManager wm = (WindowManager) getContext().getSystemService(
     94                 Context.WINDOW_SERVICE);
     95         Display d = wm.getDefaultDisplay();
     96         d.getRealMetrics(metrics);
     97         addResult(RESOLUTION, String.format("%sx%s", metrics.widthPixels, metrics.heightPixels));
     98         addResult(SCREEN_DENSITY, metrics.density);
     99         addResult(SCREEN_X_DENSITY, metrics.xdpi);
    100         addResult(SCREEN_Y_DENSITY, metrics.ydpi);
    101 
    102         String screenDensityBucket = getScreenDensityBucket(metrics);
    103         addResult(SCREEN_DENSITY_BUCKET, screenDensityBucket);
    104 
    105         String screenSize = getScreenSize();
    106         addResult(SCREEN_SIZE, screenSize);
    107 
    108         Configuration configuration = getContext().getResources().getConfiguration();
    109         addResult(SMALLEST_SCREEN_WIDTH_DP, configuration.smallestScreenWidthDp);
    110 
    111         Intent intent = new Intent();
    112         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    113         intent.setClass(this.getContext(), DeviceInfoActivity.class);
    114 
    115         DeviceInfoActivity activity = (DeviceInfoActivity) startActivitySync(intent);
    116         waitForIdleSync();
    117         activity.waitForAcitityToFinish();
    118 
    119         TelephonyManager tm = (TelephonyManager) getContext().getSystemService(
    120                 Context.TELEPHONY_SERVICE);
    121         // network
    122         String network = tm.getNetworkOperatorName();
    123         addResult(NETWORK, network.trim());
    124 
    125         // imei
    126         String imei = tm.getDeviceId();
    127         addResult(IMEI, imei);
    128 
    129         // imsi
    130         String imsi = tm.getSubscriberId();
    131         addResult(IMSI, imsi);
    132 
    133         // phone number
    134         String phoneNumber = tm.getLine1Number();
    135         addResult(PHONE_NUMBER, phoneNumber);
    136 
    137         // features
    138         String features = getFeatures();
    139         addResult(FEATURES, features);
    140 
    141         // processes
    142         String processes = getProcesses();
    143         addResult(PROCESSES, processes);
    144 
    145         // OpenGL ES version
    146         String openGlEsVersion = getOpenGlEsVersion();
    147         addResult(OPEN_GL_ES_VERSION, openGlEsVersion);
    148 
    149         // partitions
    150         String partitions = getPartitions();
    151         addResult(PARTITIONS, partitions);
    152 
    153         // System libraries
    154         String sysLibraries = getSystemLibraries();
    155         addResult(SYS_LIBRARIES, sysLibraries);
    156 
    157         // Storage devices
    158         addResult(STORAGE_DEVICES, getStorageDevices());
    159 
    160         // Multi-user support
    161         addResult(MULTI_USER, getMultiUserInfo());
    162 
    163         // Encrypted
    164         addResult(ENCRYPTED, getEncrypted());
    165 
    166         // Memory Info
    167         addResult(IS_LOW_RAM_DEVICE, isLowRamDevice());
    168         addResult(MEMORY_CLASS, getMemoryClass());
    169         addResult(LARGE_MEMORY_CLASS, getLargeMemoryClass());
    170         addResult(TOTAL_MEMORY, getTotalMemory());
    171 
    172         // CPU Info
    173         addResult(AVAILABLE_PROCESSORS, Runtime.getRuntime().availableProcessors());
    174 
    175         finish(Activity.RESULT_OK, mResults);
    176     }
    177 
    178     /**
    179      * Add string result.
    180      *
    181      * @param key the string of the key name.
    182      * @param value string value.
    183      */
    184     static void addResult(final String key, final String value){
    185         mResults.putString(key, value);
    186     }
    187 
    188     /**
    189      * Add integer result.
    190      *
    191      * @param key the string of the key name.
    192      * @param value integer value.
    193      */
    194     static void addResult(final String key, final int value){
    195         mResults.putInt(key, value);
    196     }
    197 
    198     /**
    199      * Add float result.
    200      *
    201      * @param key the string of the key name.
    202      * @param value float value.
    203      */
    204     static void addResult(final String key, final float value){
    205         mResults.putFloat(key, value);
    206     }
    207 
    208     private String getScreenSize() {
    209         Configuration config = getContext().getResources().getConfiguration();
    210         int screenLayout = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
    211         String screenSize = String.format("0x%x", screenLayout);
    212         switch (screenLayout) {
    213             case Configuration.SCREENLAYOUT_SIZE_SMALL:
    214                 screenSize = "small";
    215                 break;
    216 
    217             case Configuration.SCREENLAYOUT_SIZE_NORMAL:
    218                 screenSize = "normal";
    219                 break;
    220 
    221             case Configuration.SCREENLAYOUT_SIZE_LARGE:
    222                 screenSize = "large";
    223                 break;
    224 
    225             case Configuration.SCREENLAYOUT_SIZE_XLARGE:
    226                 screenSize = "xlarge";
    227                 break;
    228 
    229             case Configuration.SCREENLAYOUT_SIZE_UNDEFINED:
    230                 screenSize = "undefined";
    231                 break;
    232         }
    233         return screenSize;
    234     }
    235 
    236     private String getScreenDensityBucket(DisplayMetrics metrics) {
    237         switch (metrics.densityDpi) {
    238             case DisplayMetrics.DENSITY_LOW:
    239                 return "ldpi";
    240 
    241             case DisplayMetrics.DENSITY_MEDIUM:
    242                 return "mdpi";
    243 
    244             case DisplayMetrics.DENSITY_TV:
    245                 return "tvdpi";
    246 
    247             case DisplayMetrics.DENSITY_HIGH:
    248                 return "hdpi";
    249 
    250             case DisplayMetrics.DENSITY_XHIGH:
    251                 return "xdpi";
    252 
    253             default:
    254                 return "" + metrics.densityDpi;
    255         }
    256     }
    257 
    258     /**
    259      * Return a summary of the device's feature as a semi-colon-delimited list of colon separated
    260      * name and availability pairs like "feature1:sdk:true;feature2:sdk:false;feature3:other:true;".
    261      */
    262     private String getFeatures() {
    263         StringBuilder features = new StringBuilder();
    264 
    265         try {
    266             Set<String> checkedFeatures = new HashSet<String>();
    267 
    268             PackageManager packageManager = getContext().getPackageManager();
    269             for (String featureName : getPackageManagerFeatures()) {
    270                 checkedFeatures.add(featureName);
    271                 boolean hasFeature = packageManager.hasSystemFeature(featureName);
    272                 addFeature(features, featureName, "sdk", hasFeature);
    273             }
    274 
    275             FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
    276             if (featureInfos != null) {
    277                 for (FeatureInfo featureInfo : featureInfos) {
    278                     if (featureInfo.name != null && !checkedFeatures.contains(featureInfo.name)) {
    279                         addFeature(features, featureInfo.name, "other", true);
    280                     }
    281                 }
    282             }
    283         } catch (Exception exception) {
    284             Log.e(TAG, "Error getting features: " + exception.getMessage(), exception);
    285         }
    286 
    287         return features.toString();
    288     }
    289 
    290     private static void addFeature(StringBuilder features, String name, String type,
    291             boolean available) {
    292         features.append(name).append(':').append(type).append(':').append(available).append(';');
    293     }
    294 
    295     /**
    296      * Use reflection to get the features defined by the SDK. If there are features that do not fit
    297      * the convention of starting with "FEATURE_" then they will still be shown under the
    298      * "Other Features" section.
    299      *
    300      * @return list of feature names from sdk
    301      */
    302     private List<String> getPackageManagerFeatures() {
    303         try {
    304             List<String> features = new ArrayList<String>();
    305             Field[] fields = PackageManager.class.getFields();
    306             for (Field field : fields) {
    307                 if (field.getName().startsWith("FEATURE_")) {
    308                     String feature = (String) field.get(null);
    309                     features.add(feature);
    310                 }
    311             }
    312             return features;
    313         } catch (IllegalAccessException illegalAccess) {
    314             throw new RuntimeException(illegalAccess);
    315         }
    316     }
    317 
    318     /**
    319      * Return a semi-colon-delimited list of the root processes that were running on the phone
    320      * or an error message.
    321      */
    322     private static String getProcesses() {
    323         StringBuilder builder = new StringBuilder();
    324 
    325         try {
    326             String[] rootProcesses = RootProcessScanner.getRootProcesses();
    327             for (String rootProcess : rootProcesses) {
    328                 builder.append(rootProcess).append(':').append(0).append(';');
    329             }
    330         } catch (Exception exception) {
    331             Log.e(TAG, "Error getting processes: " + exception.getMessage(), exception);
    332             builder.append(exception.getMessage());
    333         }
    334 
    335         return builder.toString();
    336     }
    337 
    338     /** @return a string containing the Open GL ES version number or an error message */
    339     private String getOpenGlEsVersion() {
    340         PackageManager packageManager = getContext().getPackageManager();
    341         FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
    342         if (featureInfos != null && featureInfos.length > 0) {
    343             for (FeatureInfo featureInfo : featureInfos) {
    344                 // Null feature name means this feature is the open gl es version feature.
    345                 if (featureInfo.name == null) {
    346                     return featureInfo.getGlEsVersion();
    347                 }
    348             }
    349         }
    350         return "No feature for Open GL ES version.";
    351     }
    352 
    353     private String getPartitions() {
    354         try {
    355             StringBuilder builder = new StringBuilder();
    356             Process df = new ProcessBuilder("df").start();
    357             Scanner scanner = new Scanner(df.getInputStream());
    358             try {
    359                 while (scanner.hasNextLine()) {
    360                     builder.append(scanner.nextLine()).append(';');
    361                 }
    362                 return builder.toString();
    363             } finally {
    364                 scanner.close();
    365             }
    366         } catch (IOException e) {
    367             return "Not able to run df for partition information.";
    368         }
    369     }
    370 
    371     private String getSystemLibraries() {
    372         PackageManager pm = getContext().getPackageManager();
    373         String list[] = pm.getSystemSharedLibraryNames();
    374 
    375         StringBuilder builder = new StringBuilder();
    376         for (String lib : list) {
    377             builder.append(lib);
    378             builder.append(";");
    379         }
    380 
    381         return builder.toString();
    382     }
    383 
    384     private String getStorageDevices() {
    385         int count = 0;
    386         count = Math.max(count, getContext().getExternalCacheDirs().length);
    387         count = Math.max(count, getContext().getExternalFilesDirs(null).length);
    388         count = Math.max(
    389                 count, getContext().getExternalFilesDirs(Environment.DIRECTORY_PICTURES).length);
    390         count = Math.max(count, getContext().getObbDirs().length);
    391 
    392         if (Environment.isExternalStorageEmulated()) {
    393             if (count == 1) {
    394                 return "1 emulated";
    395             } else {
    396                 return "1 emulated, " + (count - 1) + " physical media";
    397             }
    398         } else {
    399             return count + " physical media";
    400         }
    401     }
    402 
    403     private String getMultiUserInfo() {
    404         try {
    405             final Method method = UserManager.class.getMethod("getMaxSupportedUsers");
    406             final Integer maxUsers = (Integer) method.invoke(null);
    407             if (maxUsers == 1) {
    408                 return "single user";
    409             } else {
    410                 return maxUsers + " users supported";
    411             }
    412         } catch (ClassCastException e) {
    413         } catch (NoSuchMethodException e) {
    414         } catch (InvocationTargetException e) {
    415         } catch (IllegalAccessException e) {
    416         }
    417 
    418         return "unknown";
    419     }
    420 
    421     private static String getProperty(String property)
    422             throws IOException {
    423         Process process = new ProcessBuilder("getprop", property).start();
    424         Scanner scanner = null;
    425         String line = "";
    426         try {
    427             scanner = new Scanner(process.getInputStream());
    428             line = scanner.nextLine();
    429         } finally {
    430             if (scanner != null) {
    431                 scanner.close();
    432             }
    433         }
    434         return line;
    435     }
    436 
    437     private int getEncrypted() {
    438         try {
    439             return "encrypted".equals(getProperty("ro.crypto.state")) ? 1 : 0;
    440         } catch (IOException e) {
    441         }
    442 
    443         return 0;
    444     }
    445 
    446     private String isLowRamDevice() {
    447         ActivityManager activityManager = (ActivityManager) getContext()
    448                 .getSystemService(Context.ACTIVITY_SERVICE);
    449         return activityManager.isLowRamDevice() ? "true" : "false";
    450     }
    451 
    452     private String getMemoryClass() {
    453         ActivityManager activityManager = (ActivityManager) getContext()
    454                 .getSystemService(Context.ACTIVITY_SERVICE);
    455         return String.valueOf(activityManager.getMemoryClass());
    456     }
    457 
    458     private String getLargeMemoryClass() {
    459         ActivityManager activityManager = (ActivityManager) getContext()
    460                 .getSystemService(Context.ACTIVITY_SERVICE);
    461         return String.valueOf(activityManager.getLargeMemoryClass());
    462     }
    463 
    464     private String getTotalMemory() {
    465         ActivityManager activityManager = (ActivityManager) getContext()
    466                 .getSystemService(Context.ACTIVITY_SERVICE);
    467 
    468         MemoryInfo memoryInfo = new MemoryInfo();
    469         activityManager.getMemoryInfo(memoryInfo);
    470         return String.valueOf(memoryInfo.totalMem);
    471     }
    472 }
    473