1 /* 2 * Copyright (C) 2007 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 17 package com.android.development; 18 19 import android.app.ActivityManager; 20 import android.app.IInstrumentationWatcher; 21 import android.app.ListActivity; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.pm.InstrumentationInfo; 25 import android.content.pm.PackageManager; 26 import android.os.Bundle; 27 import android.os.RemoteException; 28 import android.os.UserHandle; 29 import android.util.Log; 30 import android.view.Menu; 31 import android.view.MenuItem; 32 import android.view.View; 33 import android.view.ViewGroup; 34 import android.view.LayoutInflater; 35 import android.widget.BaseAdapter; 36 import android.widget.ListView; 37 import android.widget.TextView; 38 39 import java.util.Collections; 40 import java.util.List; 41 42 class InstrumentationAdapter extends BaseAdapter 43 { 44 private PackageManager mPM; 45 46 public InstrumentationAdapter(Context context, String targetPackage) 47 { 48 mContext = context; 49 mTargetPackage = targetPackage; 50 mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 51 mPM = context.getPackageManager(); 52 53 mList = context.getPackageManager().queryInstrumentation(mTargetPackage, 0); 54 if (mList != null) { 55 Collections.sort(mList, new InstrumentationInfo.DisplayNameComparator(mPM)); 56 } 57 } 58 59 public ComponentName instrumentationForPosition(int position) 60 { 61 if (mList == null) { 62 return null; 63 } 64 InstrumentationInfo ii = mList.get(position); 65 return new ComponentName(ii.packageName, ii.name); 66 } 67 68 public int getCount() 69 { 70 return mList != null ? mList.size() : 0; 71 } 72 73 public Object getItem(int position) 74 { 75 return position; 76 } 77 78 public long getItemId(int position) 79 { 80 return position; 81 } 82 83 public View getView(int position, View convertView, ViewGroup parent) 84 { 85 View view; 86 if (convertView == null) { 87 view = mInflater.inflate( 88 android.R.layout.simple_list_item_1, parent, false); 89 } else { 90 view = convertView; 91 } 92 bindView(view, mList.get(position)); 93 return view; 94 } 95 96 private final void bindView(View view, InstrumentationInfo info) 97 { 98 TextView text = (TextView)view.findViewById(android.R.id.text1); 99 CharSequence label = info.loadLabel(mPM); 100 text.setText(label != null ? label : info.name); 101 } 102 103 protected final Context mContext; 104 protected final String mTargetPackage; 105 protected final LayoutInflater mInflater; 106 107 protected List<InstrumentationInfo> mList; 108 } 109 110 public class InstrumentationList extends ListActivity 111 { 112 @Override 113 protected void onCreate(Bundle icicle) { 114 super.onCreate(icicle); 115 116 mProfilingMode = icicle != null && icicle.containsKey("profiling"); 117 setListAdapter(new InstrumentationAdapter(this, null)); 118 } 119 120 @Override 121 public boolean onCreateOptionsMenu(Menu menu) 122 { 123 super.onCreateOptionsMenu(menu); 124 mProfilingItem = menu.add(0, 0, 0, "Profiling Mode") 125 .setOnMenuItemClickListener(mProfilingCallback); 126 mProfilingItem.setCheckable(true); 127 return true; 128 } 129 130 @Override 131 public boolean onPrepareOptionsMenu(Menu menu) 132 { 133 super.onPrepareOptionsMenu(menu); 134 mProfilingItem.setChecked(mProfilingMode); 135 return true; 136 } 137 138 @Override 139 protected void onSaveInstanceState(Bundle outState) 140 { 141 if (mProfilingMode) { 142 outState.putBoolean("profiling", true); 143 } 144 } 145 146 @Override 147 protected void onListItemClick(ListView l, View v, int position, long id) 148 { 149 ComponentName className = ((InstrumentationAdapter)getListAdapter()). 150 instrumentationForPosition(position); 151 if (className != null) { 152 String profilingFile = null; 153 if (mProfilingMode) { 154 profilingFile = "/tmp/trace/" + className + ".dmtrace"; 155 } 156 try { 157 ActivityManager.getService(). 158 startInstrumentation(className, profilingFile, 0, null, mWatcher, null, 159 UserHandle.myUserId(), null); 160 } catch (RemoteException ex) { 161 } 162 } 163 } 164 165 private MenuItem.OnMenuItemClickListener mProfilingCallback = 166 new MenuItem.OnMenuItemClickListener() 167 { 168 public boolean onMenuItemClick(MenuItem item) { 169 mProfilingMode = !mProfilingMode; 170 return true; 171 } 172 }; 173 174 private IInstrumentationWatcher mWatcher = new IInstrumentationWatcher.Stub() { 175 176 public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) { 177 if (results != null) { 178 for (String key : results.keySet()) { 179 Log.i("instrumentation", 180 "INSTRUMENTATION_STATUS_RESULT: " + key + "=" + results.get(key)); 181 } 182 } 183 Log.i("instrumentation", "INSTRUMENTATION_STATUS_CODE: " + resultCode); 184 } 185 public void instrumentationFinished(ComponentName name, 186 int resultCode, Bundle results) { 187 if (results != null) { 188 for (String key : results.keySet()) { 189 Log.i("instrumentation", 190 "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key)); 191 } 192 } 193 Log.i("instrumentation", "INSTRUMENTATION_CODE: " + resultCode); 194 } 195 }; 196 197 private MenuItem mProfilingItem; 198 private boolean mProfilingMode; 199 } 200