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; |
8 import android.content.pm.PackageInfo; | 9 import android.content.pm.PackageInfo; |
9 import android.content.pm.PackageManager; | 10 import android.content.pm.PackageManager; |
10 import android.content.pm.PackageManager.NameNotFoundException; | 11 import android.content.pm.PackageManager.NameNotFoundException; |
11 import android.os.Build; | 12 import android.os.Build; |
| 13 import android.os.StrictMode; |
12 | 14 |
13 import org.chromium.base.annotations.CalledByNative; | 15 import org.chromium.base.annotations.CalledByNative; |
14 | 16 |
15 /** | 17 /** |
16 * BuildInfo is a utility class providing easy access to {@link PackageInfo} inf
ormation. This is | 18 * BuildInfo is a utility class providing easy access to {@link PackageInfo} inf
ormation. This is |
17 * primarily of use for accessing package information from native code. | 19 * primarily of use for accessing package information from native code. |
18 */ | 20 */ |
19 public class BuildInfo { | 21 public class BuildInfo { |
20 private static final String TAG = "BuildInfo"; | 22 private static final String TAG = "BuildInfo"; |
21 private static final int MAX_FINGERPRINT_LENGTH = 128; | 23 private static final int MAX_FINGERPRINT_LENGTH = 128; |
22 | 24 |
23 /** | 25 /** |
24 * BuildInfo is a static utility class and therefore shouldn't be instantiat
ed. | 26 * BuildInfo is a static utility class and therefore shouldn't be instantiat
ed. |
25 */ | 27 */ |
26 private BuildInfo() {} | 28 private BuildInfo() {} |
27 | 29 |
28 @CalledByNative | 30 @CalledByNative |
29 private static String[] getAll() { | 31 public static String getDevice() { |
30 try { | 32 return Build.DEVICE; |
31 String packageName = ContextUtils.getApplicationContext().getPackage
Name(); | 33 } |
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; | |
36 | 34 |
37 CharSequence label = pm.getApplicationLabel(pi.applicationInfo); | 35 @CalledByNative |
38 String packageLabel = label == null ? "" : label.toString(); | 36 public static String getBrand() { |
| 37 return Build.BRAND; |
| 38 } |
39 | 39 |
40 // Use lastUpdateTime when developing locally, since versionCode doe
s not normally | 40 @CalledByNative |
41 // change in this case. | 41 public static String getAndroidBuildId() { |
42 long version = pi.versionCode > 10 ? pi.versionCode : pi.lastUpdateT
ime; | 42 return Build.ID; |
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 } | |
55 } | 43 } |
56 | 44 |
57 /** | 45 /** |
58 * @return The build fingerprint for the current Android install. The value
is truncated to a | 46 * @return The build fingerprint for the current Android install. The value
is truncated to a |
59 * 128 characters as this is used for crash and UMA reporting, which should
avoid huge | 47 * 128 characters as this is used for crash and UMA reporting, which should
avoid huge |
60 * strings. | 48 * strings. |
61 */ | 49 */ |
62 private static String getAndroidBuildFingerprint() { | 50 @CalledByNative |
| 51 public static String getAndroidBuildFingerprint() { |
63 return Build.FINGERPRINT.substring( | 52 return Build.FINGERPRINT.substring( |
64 0, Math.min(Build.FINGERPRINT.length(), MAX_FINGERPRINT_LENGTH))
; | 53 0, Math.min(Build.FINGERPRINT.length(), MAX_FINGERPRINT_LENGTH))
; |
65 } | 54 } |
66 | 55 |
67 private static String getGMSVersionCode(PackageManager packageManager) { | 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() { |
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(); |
70 PackageInfo packageInfo = packageManager.getPackageInfo("com.google.
android.gms", 0); | 72 PackageInfo packageInfo = packageManager.getPackageInfo("com.google.
android.gms", 0); |
71 msg = Integer.toString(packageInfo.versionCode); | 73 msg = Integer.toString(packageInfo.versionCode); |
72 } catch (NameNotFoundException e) { | 74 } catch (NameNotFoundException e) { |
73 Log.d(TAG, "GMS package is not found.", e); | 75 Log.d(TAG, "GMS package is not found.", e); |
74 } | 76 } |
75 return msg; | 77 return msg; |
76 } | 78 } |
77 | 79 |
| 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 |
78 public static String getPackageVersionName() { | 97 public static String getPackageVersionName() { |
79 return getAll()[10]; | 98 String msg = "versionName not available"; |
| 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; |
80 } | 110 } |
81 | 111 |
82 /** Returns a string that is different each time the apk changes. */ | 112 /** Returns a string that is different each time the apk changes. */ |
| 113 @CalledByNative |
83 public static String getExtractedFileSuffix() { | 114 public static String getExtractedFileSuffix() { |
84 return getAll()[13]; | 115 PackageManager pm = ContextUtils.getApplicationContext().getPackageManag
er(); |
| 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 } |
85 } | 126 } |
86 | 127 |
| 128 @CalledByNative |
87 public static String getPackageLabel() { | 129 public static String getPackageLabel() { |
88 return getAll()[7]; | 130 // Third-party code does disk read on the getApplicationInfo call. http:
//crbug.com/614343 |
| 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 } |
89 } | 144 } |
90 | 145 |
| 146 @CalledByNative |
91 public static String getPackageName() { | 147 public static String getPackageName() { |
| 148 if (ContextUtils.getApplicationContext() == null) { |
| 149 return ""; |
| 150 } |
92 return ContextUtils.getApplicationContext().getPackageName(); | 151 return ContextUtils.getApplicationContext().getPackageName(); |
93 } | 152 } |
94 | 153 |
| 154 @CalledByNative |
| 155 public static String getBuildType() { |
| 156 return Build.TYPE; |
| 157 } |
| 158 |
95 /** | 159 /** |
96 * Check if this is a debuggable build of Android. Use this to enable develo
per-only features. | 160 * Check if this is a debuggable build of Android. Use this to enable develo
per-only features. |
97 */ | 161 */ |
98 public static boolean isDebugAndroid() { | 162 public static boolean isDebugAndroid() { |
99 return "eng".equals(Build.TYPE) || "userdebug".equals(Build.TYPE); | 163 return "eng".equals(Build.TYPE) || "userdebug".equals(Build.TYPE); |
100 } | 164 } |
101 | 165 |
| 166 @CalledByNative |
| 167 public static int getSdkInt() { |
| 168 return Build.VERSION.SDK_INT; |
| 169 } |
| 170 |
102 /** | 171 /** |
103 * @return Whether the current device is running Android O release or newer. | 172 * @return Whether the current device is running Android O release or newer. |
104 */ | 173 */ |
105 public static boolean isAtLeastO() { | 174 public static boolean isAtLeastO() { |
106 return !"REL".equals(Build.VERSION.CODENAME) | 175 return !"REL".equals(Build.VERSION.CODENAME) |
107 && ("O".equals(Build.VERSION.CODENAME) || Build.VERSION.CODENAME
.startsWith("OMR")); | 176 && ("O".equals(Build.VERSION.CODENAME) || Build.VERSION.CODENAME
.startsWith("OMR")); |
108 } | 177 } |
109 | 178 |
110 /** | 179 /** |
111 * @return Whether the current app targets the SDK for at least O | 180 * @return Whether the current app targets the SDK for at least O |
112 */ | 181 */ |
113 public static boolean targetsAtLeastO(Context appContext) { | 182 public static boolean targetsAtLeastO(Context appContext) { |
114 return isAtLeastO() | 183 return isAtLeastO() |
115 && appContext.getApplicationInfo().targetSdkVersion | 184 && appContext.getApplicationInfo().targetSdkVersion |
116 == Build.VERSION_CODES.CUR_DEVELOPMENT; | 185 == Build.VERSION_CODES.CUR_DEVELOPMENT; |
117 } | 186 } |
118 } | 187 } |
OLD | NEW |