Home | History | Annotate | Download | only in base
      1 // Copyright 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 package org.chromium.base;
      6 
      7 import android.content.Context;
      8 import android.content.pm.ApplicationInfo;
      9 import android.content.pm.PackageInfo;
     10 import android.content.pm.PackageManager;
     11 import android.content.pm.PackageManager.NameNotFoundException;
     12 import android.os.Build;
     13 import android.os.StrictMode;
     14 
     15 import org.chromium.base.annotations.CalledByNative;
     16 
     17 /**
     18  * BuildInfo is a utility class providing easy access to {@link PackageInfo} information. This is
     19  * primarily of use for accessing package information from native code.
     20  */
     21 public class BuildInfo {
     22     private static final String TAG = "BuildInfo";
     23     private static final int MAX_FINGERPRINT_LENGTH = 128;
     24 
     25     /**
     26      * BuildInfo is a static utility class and therefore shouldn't be instantiated.
     27      */
     28     private BuildInfo() {}
     29 
     30     @CalledByNative
     31     public static String getDevice() {
     32         return Build.DEVICE;
     33     }
     34 
     35     @CalledByNative
     36     public static String getBrand() {
     37         return Build.BRAND;
     38     }
     39 
     40     @CalledByNative
     41     public static String getAndroidBuildId() {
     42         return Build.ID;
     43     }
     44 
     45     /**
     46      * @return The build fingerprint for the current Android install.  The value is truncated to a
     47      *         128 characters as this is used for crash and UMA reporting, which should avoid huge
     48      *         strings.
     49      */
     50     @CalledByNative
     51     public static String getAndroidBuildFingerprint() {
     52         return Build.FINGERPRINT.substring(
     53                 0, Math.min(Build.FINGERPRINT.length(), MAX_FINGERPRINT_LENGTH));
     54     }
     55 
     56     @CalledByNative
     57     public static String getDeviceManufacturer() {
     58         return Build.MANUFACTURER;
     59     }
     60 
     61     @CalledByNative
     62     public static String getDeviceModel() {
     63         return Build.MODEL;
     64     }
     65 
     66     @CalledByNative
     67     public static String getGMSVersionCode(Context context) {
     68         String msg = "gms versionCode not available.";
     69         try {
     70             PackageManager packageManager = context.getPackageManager();
     71             PackageInfo packageInfo = packageManager.getPackageInfo("com.google.android.gms", 0);
     72             msg = Integer.toString(packageInfo.versionCode);
     73         } catch (NameNotFoundException e) {
     74             Log.d(TAG, "GMS package is not found.", e);
     75         }
     76         return msg;
     77     }
     78 
     79     @CalledByNative
     80     public static String getPackageVersionCode(Context context) {
     81         String msg = "versionCode not available.";
     82         try {
     83             PackageManager pm = context.getPackageManager();
     84             PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
     85             msg = "";
     86             if (pi.versionCode > 0) {
     87                 msg = Integer.toString(pi.versionCode);
     88             }
     89         } catch (NameNotFoundException e) {
     90             Log.d(TAG, msg);
     91         }
     92         return msg;
     93     }
     94 
     95     @CalledByNative
     96     public static String getPackageVersionName(Context context) {
     97         String msg = "versionName not available";
     98         try {
     99             PackageManager pm = context.getPackageManager();
    100             PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
    101             msg = "";
    102             if (pi.versionName != null) {
    103                 msg = pi.versionName;
    104             }
    105         } catch (NameNotFoundException e) {
    106             Log.d(TAG, msg);
    107         }
    108         return msg;
    109     }
    110 
    111     @CalledByNative
    112     public static String getPackageLabel(Context context) {
    113         // Third-party code does disk read on the getApplicationInfo call. http://crbug.com/614343
    114         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
    115         try {
    116             PackageManager packageManager = context.getPackageManager();
    117             ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(),
    118                     PackageManager.GET_META_DATA);
    119             CharSequence label = packageManager.getApplicationLabel(appInfo);
    120             return  label != null ? label.toString() : "";
    121         } catch (NameNotFoundException e) {
    122             return "";
    123         } finally {
    124             StrictMode.setThreadPolicy(oldPolicy);
    125         }
    126     }
    127 
    128     @CalledByNative
    129     public static String getPackageName(Context context) {
    130         String packageName = context != null ? context.getPackageName() : null;
    131         return packageName != null ? packageName : "";
    132     }
    133 
    134     @CalledByNative
    135     public static String getBuildType() {
    136         return Build.TYPE;
    137     }
    138 
    139     /**
    140      * Check if this is a debuggable build of Android. Use this to enable developer-only features.
    141      */
    142     public static boolean isDebugAndroid() {
    143         return "eng".equals(Build.TYPE) || "userdebug".equals(Build.TYPE);
    144     }
    145 
    146     @CalledByNative
    147     public static int getSdkInt() {
    148         return Build.VERSION.SDK_INT;
    149     }
    150 
    151     /**
    152      * @return Whether the current build version is greater than Android N.
    153      */
    154     public static boolean isGreaterThanN() {
    155         return Build.VERSION.SDK_INT > 24 || Build.VERSION.CODENAME.equals("NMR1");
    156     }
    157 
    158     /**
    159      * @return Whether the current device is running Android O release or newer.
    160      */
    161     public static boolean isAtLeastO() {
    162         return !"REL".equals(Build.VERSION.CODENAME)
    163                 && ("O".equals(Build.VERSION.CODENAME) || Build.VERSION.CODENAME.startsWith("OMR"));
    164     }
    165 
    166     /**
    167      * @return Whether the current app targets the SDK for at least O
    168      */
    169     public static boolean targetsAtLeastO(Context appContext) {
    170         return isAtLeastO()
    171                 && appContext.getApplicationInfo().targetSdkVersion
    172                 == Build.VERSION_CODES.CUR_DEVELOPMENT;
    173     }
    174 }
    175