DirListActivity.java revision 6fd7112e5cde88f805fcd2a62db5164edadb7dd6
1/* 2 * Copyright (C) 2010 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 17package com.android.dumprendertree2.ui; 18 19import com.android.dumprendertree2.FileFilter; 20import com.android.dumprendertree2.R; 21 22import android.app.Activity; 23import android.app.ListActivity; 24import android.content.res.Configuration; 25import android.os.Bundle; 26import android.os.Environment; 27import android.view.LayoutInflater; 28import android.view.View; 29import android.view.ViewGroup; 30import android.widget.AdapterView; 31import android.widget.ArrayAdapter; 32import android.widget.ImageView; 33import android.widget.ListView; 34import android.widget.TextView; 35 36import java.io.File; 37import java.util.ArrayList; 38import java.util.Collections; 39import java.util.List; 40 41/** 42 * An Activity that allows navigating through tests folders and choosing folders or tests to run. 43 */ 44public class DirListActivity extends ListActivity { 45 46 private static final String LOG_TAG = "DirListActivity"; 47 private static final String ROOT_DIR_PATH = 48 Environment.getExternalStorageDirectory() + 49 File.separator + "android" + 50 File.separator + "LayoutTests"; 51 52 /** TODO: This is just a guess - think of a better way to achieve it */ 53 private static final int MEAN_TITLE_CHAR_SIZE = 12; 54 55 private ListView mListView; 56 57 /** This is a relative path! */ 58 private String mCurrentDirPath; 59 60 /** 61 * TODO: This should not be a constant, but rather be configurable from somewhere. 62 */ 63 private String mRootDirPath = ROOT_DIR_PATH; 64 65 /** 66 * Very simple object to use inside ListView as an item. 67 */ 68 private static class ListItem implements Comparable<ListItem> { 69 private String mRelativePath; 70 private String mName; 71 private boolean mIsDirectory; 72 73 public ListItem(String relativePath, boolean isDirectory) { 74 mRelativePath = relativePath; 75 mName = new File(relativePath).getName(); 76 mIsDirectory = isDirectory; 77 } 78 79 public boolean isDirectory() { 80 return mIsDirectory; 81 } 82 83 public String getRelativePath() { 84 return mRelativePath; 85 } 86 87 public String getName() { 88 return mName; 89 } 90 91 @Override 92 public int compareTo(ListItem another) { 93 return mRelativePath.compareTo(another.getRelativePath()); 94 } 95 96 @Override 97 public boolean equals(Object o) { 98 if (!(o instanceof ListItem)) { 99 return false; 100 } 101 102 return mRelativePath.equals(((ListItem) o).getRelativePath()); 103 } 104 105 @Override 106 public int hashCode() { 107 return mRelativePath.hashCode(); 108 } 109 110 } 111 112 /** 113 * A custom adapter that sets the proper icon and label in the list view. 114 */ 115 private static class DirListAdapter extends ArrayAdapter<ListItem> { 116 private Activity mContext; 117 private ListItem[] mItems; 118 119 public DirListAdapter(Activity context, ListItem[] items) { 120 super(context, R.layout.dirlist_row, items); 121 122 mContext = context; 123 mItems = items; 124 } 125 126 @Override 127 public View getView(int position, View convertView, ViewGroup parent) { 128 LayoutInflater inflater = mContext.getLayoutInflater(); 129 View row = inflater.inflate(R.layout.dirlist_row, null); 130 131 TextView label = (TextView) row.findViewById(R.id.label); 132 label.setText(mItems[position].getName()); 133 134 ImageView icon = (ImageView) row.findViewById(R.id.icon); 135 if (mItems[position].isDirectory()) { 136 icon.setImageResource(R.drawable.folder); 137 } else { 138 icon.setImageResource(R.drawable.runtest); 139 } 140 141 return row; 142 } 143 } 144 145 @Override 146 protected void onCreate(Bundle savedInstanceState) { 147 super.onCreate(savedInstanceState); 148 149 mListView = getListView(); 150 151 mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 152 public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { 153 ListItem item = (ListItem) adapterView.getItemAtPosition(position); 154 155 if (item.isDirectory()) { 156 showDir(item.getRelativePath()); 157 } else { 158 /** TODO: run the test */ 159 } 160 } 161 }); 162 163 /** All the paths are relative to test root dir where possible */ 164 showDir(""); 165 } 166 167 @Override 168 /** 169 * Moves to the parent directory if one exists. Does not allow to move above 170 * the test 'root' directory. 171 */ 172 public void onBackPressed() { 173 File currentDirParent = new File(mCurrentDirPath).getParentFile(); 174 if (currentDirParent != null) { 175 showDir(currentDirParent.getPath()); 176 } else { 177 showDir(""); 178 } 179 } 180 181 /** 182 * Prevents the activity from recreating on change of orientation. The title needs to 183 * be recalculated. 184 */ 185 @Override 186 public void onConfigurationChanged(Configuration newConfig) { 187 super.onConfigurationChanged(newConfig); 188 189 setTitle(shortenTitle(mCurrentDirPath)); 190 } 191 192 /** 193 * Loads the contents of dir into the list view. 194 * 195 * @param dirPath 196 * directory to load into list view 197 */ 198 private void showDir(String dirPath) { 199 mCurrentDirPath = dirPath; 200 setTitle(shortenTitle(dirPath)); 201 setListAdapter(new DirListAdapter(this, getDirList(dirPath))); 202 } 203 204 /** 205 * TODO: find a neat way to determine number of characters that fit in the title 206 * bar. 207 * */ 208 private String shortenTitle(String title) { 209 if (title.equals("")) { 210 return "Tests' root dir:"; 211 } 212 int charCount = mListView.getWidth() / MEAN_TITLE_CHAR_SIZE; 213 214 if (title.length() > charCount) { 215 return "..." + title.substring(title.length() - charCount); 216 } else { 217 return title; 218 } 219 } 220 221 /** 222 * Return the array with contents of the given directory. 223 * First it contains the subfolders, then the files. Both sorted 224 * alphabetically. 225 */ 226 private ListItem[] getDirList(String dirPath) { 227 File dir = new File(mRootDirPath, dirPath); 228 229 List<ListItem> subDirs = new ArrayList<ListItem>(); 230 List<ListItem> subFiles = new ArrayList<ListItem>(); 231 232 for (File item : dir.listFiles()) { 233 if (item.isDirectory() && FileFilter.isTestDir(item.getName())) { 234 subDirs.add(new ListItem(getRelativePath(item), true)); 235 } else if (FileFilter.isTestFile(item.getName())) { 236 subFiles.add(new ListItem(getRelativePath(item), false)); 237 } 238 } 239 240 Collections.sort(subDirs); 241 Collections.sort(subFiles); 242 243 /** Concatenate the two lists */ 244 subDirs.addAll(subFiles); 245 246 return subDirs.toArray(new ListItem[subDirs.size()]); 247 } 248 249 private String getRelativePath(File file) { 250 File rootDir = new File(mRootDirPath); 251 return file.getAbsolutePath().replaceFirst(rootDir.getPath() + File.separator, ""); 252 } 253}