blob: cdf1df31e7785f41ba426b0e1131fb7eff4f9467 [file] [log] [blame]
The Android Open Source Projectf8057102009-03-15 16:47:16 -07001/*
Brian Muramatsu40bdc5e2010-08-13 16:20:15 -07002 * Copyright (C) 2008 The Android Open Source Project
The Android Open Source Projectf8057102009-03-15 16:47:16 -07003 *
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
17package android.tests.getinfo;
18
19import android.app.Activity;
20import android.app.Instrumentation;
21import android.content.Context;
22import android.content.Intent;
Brian Muramatsu4af6c4e2010-06-21 16:57:12 -070023import android.content.pm.FeatureInfo;
Brian Muramatsua61d3232010-06-08 12:29:36 -070024import android.content.pm.PackageManager;
Brian Muramatsue6b12dc2010-11-08 14:56:40 -080025import android.content.res.Configuration;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070026import android.os.Build;
27import android.os.Bundle;
Jeff Sharkey4f24dc52013-10-11 13:33:13 -070028import android.os.Environment;
29import android.os.UserManager;
Brett Chabot62a17ce2009-11-12 13:35:13 -080030import android.telephony.TelephonyManager;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070031import android.util.DisplayMetrics;
Brian Muramatsu73799892010-06-23 17:42:52 -070032import android.util.Log;
The Android Open Source Projectf8057102009-03-15 16:47:16 -070033import android.view.Display;
34import android.view.WindowManager;
35
Brian Muramatsu570acf72011-03-10 17:21:07 -080036import java.io.IOException;
Brian Muramatsu73799892010-06-23 17:42:52 -070037import java.lang.reflect.Field;
Jeff Sharkey4f24dc52013-10-11 13:33:13 -070038import java.lang.reflect.InvocationTargetException;
39import java.lang.reflect.Method;
Brian Muramatsu73799892010-06-23 17:42:52 -070040import java.util.ArrayList;
Brian Muramatsu4af6c4e2010-06-21 16:57:12 -070041import java.util.HashSet;
Brian Muramatsu73799892010-06-23 17:42:52 -070042import java.util.List;
Brian Muramatsu570acf72011-03-10 17:21:07 -080043import java.util.Scanner;
Brian Muramatsu4af6c4e2010-06-21 16:57:12 -070044import java.util.Set;
Brian Muramatsu55790392010-06-14 14:45:42 -070045
Brett Chabot2f903ad2011-02-02 18:22:18 -080046public class DeviceInfoInstrument extends Instrumentation implements DeviceInfoConstants {
Brian Muramatsua61d3232010-06-08 12:29:36 -070047
Brian Muramatsu73799892010-06-23 17:42:52 -070048 private static final String TAG = "DeviceInfoInstrument";
Brian Muramatsua61d3232010-06-08 12:29:36 -070049
The Android Open Source Projectf8057102009-03-15 16:47:16 -070050 private static Bundle mResults = new Bundle();
51
The Android Open Source Projectf8057102009-03-15 16:47:16 -070052 public DeviceInfoInstrument() {
53 super();
54 }
55
56 @Override
57 public void onCreate(Bundle arguments) {
58 start();
59 }
60
61 @Override
62 public void onStart() {
The Android Open Source Projectf8057102009-03-15 16:47:16 -070063 addResult(BUILD_ID, Build.ID);
64 addResult(PRODUCT_NAME, Build.PRODUCT);
65 addResult(BUILD_DEVICE, Build.DEVICE);
66 addResult(BUILD_BOARD, Build.BOARD);
Brian Muramatsud6445ae2010-10-27 13:31:28 -070067 addResult(BUILD_MANUFACTURER, Build.MANUFACTURER);
The Android Open Source Projectf8057102009-03-15 16:47:16 -070068 addResult(BUILD_BRAND, Build.BRAND);
69 addResult(BUILD_MODEL, Build.MODEL);
70 addResult(BUILD_TYPE, Build.TYPE);
The Android Open Source Projectf8057102009-03-15 16:47:16 -070071 addResult(BUILD_FINGERPRINT, Build.FINGERPRINT);
Brian Muramatsu722008e2010-05-25 16:44:48 -070072 addResult(BUILD_ABI, Build.CPU_ABI);
73 addResult(BUILD_ABI2, Build.CPU_ABI2);
Brett Chabot770358e2011-10-28 17:27:35 -070074 addResult(SERIAL_NUMBER, Build.SERIAL);
The Android Open Source Projectf8057102009-03-15 16:47:16 -070075
The Android Open Source Projectf8057102009-03-15 16:47:16 -070076 addResult(VERSION_RELEASE, Build.VERSION.RELEASE);
77 addResult(VERSION_SDK, Build.VERSION.SDK);
78
79 DisplayMetrics metrics = new DisplayMetrics();
80 WindowManager wm = (WindowManager) getContext().getSystemService(
81 Context.WINDOW_SERVICE);
82 Display d = wm.getDefaultDisplay();
Madan Ankapura56c756f2013-05-10 10:10:27 -070083 d.getRealMetrics(metrics);
Brett Chabot770358e2011-10-28 17:27:35 -070084 addResult(RESOLUTION, String.format("%sx%s", metrics.widthPixels, metrics.heightPixels));
Brian Muramatsu647277e2010-11-16 13:58:42 -080085 addResult(SCREEN_DENSITY, metrics.density);
The Android Open Source Projectf8057102009-03-15 16:47:16 -070086 addResult(SCREEN_X_DENSITY, metrics.xdpi);
87 addResult(SCREEN_Y_DENSITY, metrics.ydpi);
88
Brian Muramatsue6b12dc2010-11-08 14:56:40 -080089 String screenDensityBucket = getScreenDensityBucket(metrics);
90 addResult(SCREEN_DENSITY_BUCKET, screenDensityBucket);
91
92 String screenSize = getScreenSize();
93 addResult(SCREEN_SIZE, screenSize);
94
The Android Open Source Projectf8057102009-03-15 16:47:16 -070095 Intent intent = new Intent();
96 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
97 intent.setClass(this.getContext(), DeviceInfoActivity.class);
98
Bill Napier6c12b462009-05-14 11:07:39 -070099 DeviceInfoActivity activity = (DeviceInfoActivity) startActivitySync(intent);
100 waitForIdleSync();
101 activity.waitForAcitityToFinish();
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700102
Brett Chabot62a17ce2009-11-12 13:35:13 -0800103 TelephonyManager tm = (TelephonyManager) getContext().getSystemService(
104 Context.TELEPHONY_SERVICE);
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700105 // network
Brett Chabot62a17ce2009-11-12 13:35:13 -0800106 String network = tm.getNetworkOperatorName();
Brett Chabot51b9caa2011-09-07 18:44:22 -0700107 addResult(NETWORK, network.trim());
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700108
109 // imei
Brett Chabot62a17ce2009-11-12 13:35:13 -0800110 String imei = tm.getDeviceId();
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700111 addResult(IMEI, imei);
112
113 // imsi
Brett Chabot62a17ce2009-11-12 13:35:13 -0800114 String imsi = tm.getSubscriberId();
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700115 addResult(IMSI, imsi);
116
117 // phone number
Brett Chabot62a17ce2009-11-12 13:35:13 -0800118 String phoneNumber = tm.getLine1Number();
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700119 addResult(PHONE_NUMBER, phoneNumber);
120
Brian Muramatsua61d3232010-06-08 12:29:36 -0700121 // features
122 String features = getFeatures();
123 addResult(FEATURES, features);
124
Brian Muramatsu55790392010-06-14 14:45:42 -0700125 // processes
126 String processes = getProcesses();
127 addResult(PROCESSES, processes);
128
Brian Muramatsud89a48b2010-07-29 12:03:49 -0700129 // OpenGL ES version
130 String openGlEsVersion = getOpenGlEsVersion();
131 addResult(OPEN_GL_ES_VERSION, openGlEsVersion);
132
Brian Muramatsu570acf72011-03-10 17:21:07 -0800133 // partitions
134 String partitions = getPartitions();
135 addResult(PARTITIONS, partitions);
Brian Muramatsud89a48b2010-07-29 12:03:49 -0700136
Keun young Parkabed8862011-12-09 10:57:33 -0800137 // System libraries
138 String sysLibraries = getSystemLibraries();
139 addResult(SYS_LIBRARIES, sysLibraries);
140
Jeff Sharkey4f24dc52013-10-11 13:33:13 -0700141 // Storage devices
142 addResult(STORAGE_DEVICES, getStorageDevices());
143
144 // Multi-user support
145 addResult(MULTI_USER, getMultiUserInfo());
146
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700147 finish(Activity.RESULT_OK, mResults);
148 }
149
150 /**
151 * Add string result.
152 *
153 * @param key the string of the key name.
154 * @param value string value.
155 */
156 static void addResult(final String key, final String value){
157 mResults.putString(key, value);
158 }
159
160 /**
161 * Add integer result.
162 *
163 * @param key the string of the key name.
164 * @param value integer value.
165 */
166 private void addResult(final String key, final int value){
167 mResults.putInt(key, value);
168 }
169
170 /**
171 * Add float result.
172 *
173 * @param key the string of the key name.
174 * @param value float value.
175 */
176 private void addResult(final String key, final float value){
177 mResults.putFloat(key, value);
178 }
Brian Muramatsua61d3232010-06-08 12:29:36 -0700179
Brian Muramatsue6b12dc2010-11-08 14:56:40 -0800180 private String getScreenSize() {
181 Configuration config = getContext().getResources().getConfiguration();
182 int screenLayout = config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
183 String screenSize = String.format("0x%x", screenLayout);
184 switch (screenLayout) {
185 case Configuration.SCREENLAYOUT_SIZE_SMALL:
186 screenSize = "small";
187 break;
188
189 case Configuration.SCREENLAYOUT_SIZE_NORMAL:
190 screenSize = "normal";
191 break;
192
193 case Configuration.SCREENLAYOUT_SIZE_LARGE:
194 screenSize = "large";
195 break;
196
Guru Nagarajan63c59832012-01-13 21:33:05 -0800197 case Configuration.SCREENLAYOUT_SIZE_XLARGE:
198 screenSize = "xlarge";
199 break;
200
Brian Muramatsue6b12dc2010-11-08 14:56:40 -0800201 case Configuration.SCREENLAYOUT_SIZE_UNDEFINED:
202 screenSize = "undefined";
203 break;
204 }
205 return screenSize;
206 }
207
208 private String getScreenDensityBucket(DisplayMetrics metrics) {
209 switch (metrics.densityDpi) {
210 case DisplayMetrics.DENSITY_LOW:
211 return "ldpi";
212
213 case DisplayMetrics.DENSITY_MEDIUM:
214 return "mdpi";
215
Guru Nagarajan63c59832012-01-13 21:33:05 -0800216 case DisplayMetrics.DENSITY_TV:
217 return "tvdpi";
218
Brian Muramatsue6b12dc2010-11-08 14:56:40 -0800219 case DisplayMetrics.DENSITY_HIGH:
220 return "hdpi";
221
Guru Nagarajan63c59832012-01-13 21:33:05 -0800222 case DisplayMetrics.DENSITY_XHIGH:
Brian Muramatsue6b12dc2010-11-08 14:56:40 -0800223 return "xdpi";
224
225 default:
226 return "" + metrics.densityDpi;
227 }
228 }
229
Brian Muramatsua61d3232010-06-08 12:29:36 -0700230 /**
231 * Return a summary of the device's feature as a semi-colon-delimited list of colon separated
Brian Muramatsu4af6c4e2010-06-21 16:57:12 -0700232 * name and availability pairs like "feature1:sdk:true;feature2:sdk:false;feature3:other:true;".
Brian Muramatsua61d3232010-06-08 12:29:36 -0700233 */
234 private String getFeatures() {
Brian Muramatsu4af6c4e2010-06-21 16:57:12 -0700235 StringBuilder features = new StringBuilder();
236
Brian Muramatsu73799892010-06-23 17:42:52 -0700237 try {
238 Set<String> checkedFeatures = new HashSet<String>();
Brian Muramatsua61d3232010-06-08 12:29:36 -0700239
Brian Muramatsu73799892010-06-23 17:42:52 -0700240 PackageManager packageManager = getContext().getPackageManager();
241 for (String featureName : getPackageManagerFeatures()) {
242 checkedFeatures.add(featureName);
243 boolean hasFeature = packageManager.hasSystemFeature(featureName);
244 addFeature(features, featureName, "sdk", hasFeature);
Brian Muramatsu4af6c4e2010-06-21 16:57:12 -0700245 }
Brian Muramatsu73799892010-06-23 17:42:52 -0700246
247 FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
248 if (featureInfos != null) {
249 for (FeatureInfo featureInfo : featureInfos) {
250 if (featureInfo.name != null && !checkedFeatures.contains(featureInfo.name)) {
251 addFeature(features, featureInfo.name, "other", true);
252 }
253 }
254 }
255 } catch (Exception exception) {
256 Log.e(TAG, "Error getting features: " + exception.getMessage(), exception);
Brian Muramatsu4af6c4e2010-06-21 16:57:12 -0700257 }
258
259 return features.toString();
260 }
261
262 private static void addFeature(StringBuilder features, String name, String type,
263 boolean available) {
264 features.append(name).append(':').append(type).append(':').append(available).append(';');
Brian Muramatsua61d3232010-06-08 12:29:36 -0700265 }
Brian Muramatsu55790392010-06-14 14:45:42 -0700266
267 /**
Brian Muramatsu73799892010-06-23 17:42:52 -0700268 * Use reflection to get the features defined by the SDK. If there are features that do not fit
269 * the convention of starting with "FEATURE_" then they will still be shown under the
270 * "Other Features" section.
271 *
272 * @return list of feature names from sdk
273 */
274 private List<String> getPackageManagerFeatures() {
275 try {
276 List<String> features = new ArrayList<String>();
277 Field[] fields = PackageManager.class.getFields();
278 for (Field field : fields) {
279 if (field.getName().startsWith("FEATURE_")) {
280 String feature = (String) field.get(null);
281 features.add(feature);
282 }
283 }
284 return features;
285 } catch (IllegalAccessException illegalAccess) {
286 throw new RuntimeException(illegalAccess);
287 }
288 }
289
290 /**
Brian Muramatsu55790392010-06-14 14:45:42 -0700291 * Return a semi-colon-delimited list of the root processes that were running on the phone
292 * or an error message.
293 */
294 private static String getProcesses() {
295 StringBuilder builder = new StringBuilder();
296
297 try {
298 String[] rootProcesses = RootProcessScanner.getRootProcesses();
299 for (String rootProcess : rootProcesses) {
Brian Muramatsu1d67e192012-01-18 15:24:23 -0800300 builder.append(rootProcess).append(':').append(0).append(';');
Brian Muramatsu55790392010-06-14 14:45:42 -0700301 }
Brian Muramatsu73799892010-06-23 17:42:52 -0700302 } catch (Exception exception) {
303 Log.e(TAG, "Error getting processes: " + exception.getMessage(), exception);
304 builder.append(exception.getMessage());
Brian Muramatsu55790392010-06-14 14:45:42 -0700305 }
306
307 return builder.toString();
308 }
Brian Muramatsud89a48b2010-07-29 12:03:49 -0700309
310 /** @return a string containing the Open GL ES version number or an error message */
311 private String getOpenGlEsVersion() {
312 PackageManager packageManager = getContext().getPackageManager();
313 FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
314 if (featureInfos != null && featureInfos.length > 0) {
315 for (FeatureInfo featureInfo : featureInfos) {
316 // Null feature name means this feature is the open gl es version feature.
317 if (featureInfo.name == null) {
318 return featureInfo.getGlEsVersion();
319 }
320 }
321 }
322 return "No feature for Open GL ES version.";
323 }
Brian Muramatsu570acf72011-03-10 17:21:07 -0800324
325 private String getPartitions() {
326 try {
327 StringBuilder builder = new StringBuilder();
328 Process df = new ProcessBuilder("df").start();
329 Scanner scanner = new Scanner(df.getInputStream());
330 try {
331 while (scanner.hasNextLine()) {
332 builder.append(scanner.nextLine()).append(';');
333 }
334 return builder.toString();
335 } finally {
336 scanner.close();
337 }
338 } catch (IOException e) {
339 return "Not able to run df for partition information.";
340 }
341 }
Keun young Parkabed8862011-12-09 10:57:33 -0800342
343 private String getSystemLibraries() {
344 PackageManager pm = getContext().getPackageManager();
345 String list[] = pm.getSystemSharedLibraryNames();
346
347 StringBuilder builder = new StringBuilder();
348 for (String lib : list) {
349 builder.append(lib);
350 builder.append(";");
351 }
352
353 return builder.toString();
354 }
Jeff Sharkey4f24dc52013-10-11 13:33:13 -0700355
356 private String getStorageDevices() {
357 int count = 0;
358 count = Math.max(count, getContext().getExternalCacheDirs().length);
359 count = Math.max(count, getContext().getExternalFilesDirs(null).length);
360 count = Math.max(
361 count, getContext().getExternalFilesDirs(Environment.DIRECTORY_PICTURES).length);
362 count = Math.max(count, getContext().getObbDirs().length);
363
364 final String result;
365 if (Environment.isExternalStorageEmulated()) {
366 if (count == 1) {
367 return "1 emulated";
368 } else {
369 return "1 emulated, " + (count - 1) + " physical media";
370 }
371 } else {
372 return count + " physical media";
373 }
374 }
375
376 private String getMultiUserInfo() {
377 try {
378 final Method method = UserManager.class.getMethod("getMaxSupportedUsers");
379 final Integer maxUsers = (Integer) method.invoke(null);
380 if (maxUsers == 1) {
381 return "single user";
382 } else {
383 return maxUsers + " users supported";
384 }
385 } catch (ClassCastException e) {
386 } catch (NoSuchMethodException e) {
387 } catch (InvocationTargetException e) {
388 } catch (IllegalAccessException e) {
389 }
390
391 return "unknown";
392 }
The Android Open Source Projectf8057102009-03-15 16:47:16 -0700393}