Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.base; | 5 package org.chromium.base; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.content.pm.ApplicationInfo; | |
| 9 import android.content.pm.PackageInfo; | 8 import android.content.pm.PackageInfo; |
| 10 import android.content.pm.PackageManager; | 9 import android.content.pm.PackageManager; |
| 11 import android.content.pm.PackageManager.NameNotFoundException; | 10 import android.content.pm.PackageManager.NameNotFoundException; |
| 12 import android.os.Build; | 11 import android.os.Build; |
| 13 import android.os.StrictMode; | |
| 14 | 12 |
| 15 import org.chromium.base.annotations.CalledByNative; | 13 import org.chromium.base.annotations.CalledByNative; |
| 16 | 14 |
| 17 /** | 15 /** |
| 18 * BuildInfo is a utility class providing easy access to {@link PackageInfo} inf ormation. This is | 16 * BuildInfo is a utility class providing easy access to {@link PackageInfo} inf ormation. This is |
| 19 * primarily of use for accessing package information from native code. | 17 * primarily of use for accessing package information from native code. |
| 20 */ | 18 */ |
| 21 public class BuildInfo { | 19 public class BuildInfo { |
| 22 private static final String TAG = "BuildInfo"; | 20 private static final String TAG = "BuildInfo"; |
| 23 private static final int MAX_FINGERPRINT_LENGTH = 128; | 21 private static final int MAX_FINGERPRINT_LENGTH = 128; |
| 24 | 22 |
| 25 /** | 23 /** |
| 26 * BuildInfo is a static utility class and therefore shouldn't be instantiat ed. | 24 * BuildInfo is a static utility class and therefore shouldn't be instantiat ed. |
| 27 */ | 25 */ |
| 28 private BuildInfo() {} | 26 private BuildInfo() {} |
| 29 | 27 |
| 30 @CalledByNative | 28 @CalledByNative |
| 31 public static String getDevice() { | 29 private static String[] getAll() { |
| 32 return Build.DEVICE; | 30 try { |
| 33 } | 31 String packageName = ContextUtils.getApplicationContext().getPackage Name(); |
| 32 PackageManager pm = ContextUtils.getApplicationContext().getPackageM anager(); | |
| 33 PackageInfo pi = pm.getPackageInfo(packageName, 0); | |
| 34 String versionCode = pi.versionCode <= 0 ? "" : Integer.toString(pi. versionCode); | |
| 35 String versionName = pi.versionName == null ? "" : pi.versionName; | |
| 34 | 36 |
| 35 @CalledByNative | 37 CharSequence label = pm.getApplicationLabel(pi.applicationInfo); |
| 36 public static String getBrand() { | 38 String packageLabel = label == null ? "" : label.toString(); |
| 37 return Build.BRAND; | |
| 38 } | |
| 39 | 39 |
| 40 @CalledByNative | 40 // Use lastUpdateTime when developing locally, since versionCode doe s not normally |
| 41 public static String getAndroidBuildId() { | 41 // change in this case. |
| 42 return Build.ID; | 42 long version = pi.versionCode > 10 ? pi.versionCode : pi.lastUpdateT ime; |
| 43 String extractedFileSuffix = String.format("@%s", Long.toHexString(v ersion)); | |
| 44 | |
| 45 // Do not alter this list without updating callers of it. | |
| 46 return new String[] { | |
| 47 Build.BRAND, Build.DEVICE, Build.ID, Build.MANUFACTURER, Bui ld.MODEL, | |
| 48 String.valueOf(Build.VERSION.SDK_INT), Build.TYPE, packageLa bel, packageName, | |
| 49 versionCode, versionName, getAndroidBuildFingerprint(), getG MSVersionCode(pm), | |
| 50 extractedFileSuffix, | |
| 51 }; | |
| 52 } catch (NameNotFoundException e) { | |
| 53 throw new RuntimeException(e); | |
| 54 } | |
| 43 } | 55 } |
| 44 | 56 |
| 45 /** | 57 /** |
| 46 * @return The build fingerprint for the current Android install. The value is truncated to a | 58 * @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 | 59 * 128 characters as this is used for crash and UMA reporting, which should avoid huge |
| 48 * strings. | 60 * strings. |
| 49 */ | 61 */ |
| 50 @CalledByNative | 62 private static String getAndroidBuildFingerprint() { |
| 51 public static String getAndroidBuildFingerprint() { | |
| 52 return Build.FINGERPRINT.substring( | 63 return Build.FINGERPRINT.substring( |
| 53 0, Math.min(Build.FINGERPRINT.length(), MAX_FINGERPRINT_LENGTH)) ; | 64 0, Math.min(Build.FINGERPRINT.length(), MAX_FINGERPRINT_LENGTH)) ; |
| 54 } | 65 } |
| 55 | 66 |
| 56 @CalledByNative | 67 private static String getGMSVersionCode(PackageManager packageManager) { |
| 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() { | |
| 68 String msg = "gms versionCode not available."; | 68 String msg = "gms versionCode not available."; |
| 69 try { | 69 try { |
| 70 PackageManager packageManager = | |
| 71 ContextUtils.getApplicationContext().getPackageManager(); | |
| 72 PackageInfo packageInfo = packageManager.getPackageInfo("com.google. android.gms", 0); | 70 PackageInfo packageInfo = packageManager.getPackageInfo("com.google. android.gms", 0); |
| 73 msg = Integer.toString(packageInfo.versionCode); | 71 msg = Integer.toString(packageInfo.versionCode); |
| 74 } catch (NameNotFoundException e) { | 72 } catch (NameNotFoundException e) { |
| 75 Log.d(TAG, "GMS package is not found.", e); | 73 Log.d(TAG, "GMS package is not found.", e); |
| 76 } | 74 } |
| 77 return msg; | 75 return msg; |
| 78 } | 76 } |
| 79 | 77 |
| 80 @CalledByNative | |
| 81 public static String getPackageVersionCode() { | |
| 82 String msg = "versionCode not available."; | |
| 83 try { | |
| 84 PackageManager pm = ContextUtils.getApplicationContext().getPackageM anager(); | |
| 85 PackageInfo pi = pm.getPackageInfo(getPackageName(), 0); | |
| 86 msg = ""; | |
| 87 if (pi.versionCode > 0) { | |
| 88 msg = Integer.toString(pi.versionCode); | |
| 89 } | |
| 90 } catch (NameNotFoundException e) { | |
| 91 Log.d(TAG, msg); | |
| 92 } | |
| 93 return msg; | |
| 94 } | |
| 95 | |
| 96 @CalledByNative | |
| 97 public static String getPackageVersionName() { | 78 public static String getPackageVersionName() { |
| 98 String msg = "versionName not available"; | 79 return getAll()[10]; |
|
Torne
2017/04/21 19:41:25
Can we just retrieve all the values once and save
agrieve
2017/04/21 20:00:33
We could cache them, but we'd still need to call g
| |
| 99 try { | |
| 100 PackageManager pm = ContextUtils.getApplicationContext().getPackageM anager(); | |
| 101 PackageInfo pi = pm.getPackageInfo(getPackageName(), 0); | |
| 102 msg = ""; | |
| 103 if (pi.versionName != null) { | |
| 104 msg = pi.versionName; | |
| 105 } | |
| 106 } catch (NameNotFoundException e) { | |
| 107 Log.d(TAG, msg); | |
| 108 } | |
| 109 return msg; | |
| 110 } | 80 } |
| 111 | 81 |
| 112 /** Returns a string that is different each time the apk changes. */ | 82 /** Returns a string that is different each time the apk changes. */ |
| 113 @CalledByNative | |
| 114 public static String getExtractedFileSuffix() { | 83 public static String getExtractedFileSuffix() { |
| 115 PackageManager pm = ContextUtils.getApplicationContext().getPackageManag er(); | 84 return getAll()[13]; |
| 116 try { | |
| 117 PackageInfo pi = | |
| 118 pm.getPackageInfo(ContextUtils.getApplicationContext().getPa ckageName(), 0); | |
| 119 // Use lastUpdateTime when developing locally, since versionCode doe s not normally | |
| 120 // change in this case. | |
| 121 long version = pi.versionCode > 10 ? pi.versionCode : pi.lastUpdateT ime; | |
| 122 return "@" + Long.toHexString(version); | |
| 123 } catch (PackageManager.NameNotFoundException e) { | |
| 124 throw new RuntimeException(e); | |
| 125 } | |
| 126 } | 85 } |
| 127 | 86 |
| 128 @CalledByNative | |
| 129 public static String getPackageLabel() { | 87 public static String getPackageLabel() { |
| 130 // Third-party code does disk read on the getApplicationInfo call. http: //crbug.com/614343 | 88 return getAll()[7]; |
| 131 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); | |
| 132 try { | |
| 133 PackageManager packageManager = | |
| 134 ContextUtils.getApplicationContext().getPackageManager(); | |
| 135 ApplicationInfo appInfo = packageManager.getApplicationInfo( | |
| 136 getPackageName(), PackageManager.GET_META_DATA); | |
| 137 CharSequence label = packageManager.getApplicationLabel(appInfo); | |
| 138 return label != null ? label.toString() : ""; | |
| 139 } catch (NameNotFoundException e) { | |
| 140 return ""; | |
| 141 } finally { | |
| 142 StrictMode.setThreadPolicy(oldPolicy); | |
| 143 } | |
| 144 } | 89 } |
| 145 | 90 |
| 146 @CalledByNative | |
| 147 public static String getPackageName() { | 91 public static String getPackageName() { |
| 148 if (ContextUtils.getApplicationContext() == null) { | |
| 149 return ""; | |
| 150 } | |
| 151 return ContextUtils.getApplicationContext().getPackageName(); | 92 return ContextUtils.getApplicationContext().getPackageName(); |
| 152 } | 93 } |
| 153 | 94 |
| 154 @CalledByNative | |
| 155 public static String getBuildType() { | |
| 156 return Build.TYPE; | |
| 157 } | |
| 158 | |
| 159 /** | 95 /** |
| 160 * Check if this is a debuggable build of Android. Use this to enable develo per-only features. | 96 * Check if this is a debuggable build of Android. Use this to enable develo per-only features. |
| 161 */ | 97 */ |
| 162 public static boolean isDebugAndroid() { | 98 public static boolean isDebugAndroid() { |
| 163 return "eng".equals(Build.TYPE) || "userdebug".equals(Build.TYPE); | 99 return "eng".equals(Build.TYPE) || "userdebug".equals(Build.TYPE); |
| 164 } | 100 } |
| 165 | 101 |
| 166 @CalledByNative | |
| 167 public static int getSdkInt() { | |
| 168 return Build.VERSION.SDK_INT; | |
| 169 } | |
| 170 | |
| 171 /** | 102 /** |
| 172 * @return Whether the current device is running Android O release or newer. | 103 * @return Whether the current device is running Android O release or newer. |
| 173 */ | 104 */ |
| 174 public static boolean isAtLeastO() { | 105 public static boolean isAtLeastO() { |
| 175 return !"REL".equals(Build.VERSION.CODENAME) | 106 return !"REL".equals(Build.VERSION.CODENAME) |
| 176 && ("O".equals(Build.VERSION.CODENAME) || Build.VERSION.CODENAME .startsWith("OMR")); | 107 && ("O".equals(Build.VERSION.CODENAME) || Build.VERSION.CODENAME .startsWith("OMR")); |
| 177 } | 108 } |
| 178 | 109 |
| 179 /** | 110 /** |
| 180 * @return Whether the current app targets the SDK for at least O | 111 * @return Whether the current app targets the SDK for at least O |
| 181 */ | 112 */ |
| 182 public static boolean targetsAtLeastO(Context appContext) { | 113 public static boolean targetsAtLeastO(Context appContext) { |
| 183 return isAtLeastO() | 114 return isAtLeastO() |
| 184 && appContext.getApplicationInfo().targetSdkVersion | 115 && appContext.getApplicationInfo().targetSdkVersion |
| 185 == Build.VERSION_CODES.CUR_DEVELOPMENT; | 116 == Build.VERSION_CODES.CUR_DEVELOPMENT; |
| 186 } | 117 } |
| 187 } | 118 } |
| OLD | NEW |