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