1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 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 package com.android.compatibility.common.deviceinfo; 17 18 import android.app.Activity; 19 import android.app.Instrumentation; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.ActivityInfo; 23 import android.content.pm.PackageManager; 24 import android.os.Bundle; 25 import android.text.TextUtils; 26 import android.util.Log; 27 28 import java.util.Arrays; 29 import java.util.HashSet; 30 import java.util.Set; 31 32 /** 33 * An instrumentation that runs all activities that extends DeviceInfoActivity. 34 */ 35 public class DeviceInfoInstrument extends Instrumentation { 36 37 private static final String LOG_TAG = "ExtendedDeviceInfo"; 38 private static final String COLLECTOR = "collector"; 39 40 // List of collectors to run. If null or empty, all collectors will run. 41 private Set<String> mCollectorSet = new HashSet<String>(); 42 43 // Results sent to the caller when this istrumentation completes. 44 private Bundle mBundle = new Bundle(); 45 46 @Override onCreate(Bundle savedInstanceState)47 public void onCreate(Bundle savedInstanceState) { 48 super.onCreate(savedInstanceState); 49 if (savedInstanceState != null) { 50 String collectorList = savedInstanceState.getString(COLLECTOR); 51 if (!TextUtils.isEmpty(collectorList)) { 52 for (String collector : TextUtils.split(collectorList, ",")) { 53 if (!TextUtils.isEmpty(collector)) { 54 mCollectorSet.add(collector); 55 } 56 } 57 } 58 } 59 start(); 60 } 61 62 @Override onStart()63 public void onStart() { 64 try { 65 Context context = getContext(); 66 ActivityInfo[] activities = context.getPackageManager().getPackageInfo( 67 context.getPackageName(), PackageManager.GET_ACTIVITIES).activities; 68 for (ActivityInfo activityInfo : activities) { 69 runActivity(activityInfo.name); 70 } 71 } catch (Exception e) { 72 Log.e(LOG_TAG, "Exception occurred while running activities.", e); 73 // Returns INSTRUMENTATION_CODE: 0 74 finish(Activity.RESULT_CANCELED, mBundle); 75 } 76 // Returns INSTRUMENTATION_CODE: -1 77 finish(Activity.RESULT_OK, mBundle); 78 } 79 80 /** 81 * Returns true if the activity meets the criteria to run; otherwise, false. 82 */ isActivityRunnable(Class activityClass)83 private boolean isActivityRunnable(Class activityClass) { 84 // Don't run the base DeviceInfoActivity class. 85 if (DeviceInfoActivity.class == activityClass) { 86 return false; 87 } 88 // Don't run anything that doesn't extends DeviceInfoActivity. 89 if (!DeviceInfoActivity.class.isAssignableFrom(activityClass)) { 90 return false; 91 } 92 // Only run activity if mCollectorSet is empty or contains it. 93 if (mCollectorSet != null && mCollectorSet.size() > 0) { 94 return mCollectorSet.contains(activityClass.getName()); 95 } 96 // Run anything that makes it here. 97 return true; 98 } 99 100 /** 101 * Runs a device info activity and return the file path where the results are written to. 102 */ runActivity(String activityName)103 private void runActivity(String activityName) throws Exception { 104 Class activityClass = null; 105 try { 106 activityClass = Class.forName(activityName); 107 } catch (ClassNotFoundException e) { 108 return; 109 } 110 111 if (activityClass == null || !isActivityRunnable(activityClass)) { 112 return; 113 } 114 115 Intent intent = new Intent(); 116 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 117 intent.setClassName(this.getContext(), activityName); 118 119 DeviceInfoActivity activity = (DeviceInfoActivity) startActivitySync(intent); 120 waitForIdleSync(); 121 activity.waitForActivityToFinish(); 122 123 String className = activityClass.getSimpleName(); 124 String errorMessage = activity.getErrorMessage(); 125 if (TextUtils.isEmpty(errorMessage)) { 126 mBundle.putString(className, activity.getResultFilePath()); 127 } else { 128 mBundle.putString(className, errorMessage); 129 throw new Exception(errorMessage); 130 } 131 } 132 } 133 134