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 |