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
17package android.test;
18
19import android.app.ListActivity;
20import android.content.Intent;
21import android.database.MatrixCursor;
22import android.net.Uri;
23import android.os.Bundle;
24import android.view.Menu;
25import android.view.MenuItem;
26import android.view.View;
27import android.widget.CursorAdapter;
28import android.widget.ListView;
29import android.widget.SimpleCursorAdapter;
30
31import java.util.Arrays;
32import java.util.Comparator;
33
34/**
35 * Activity base class to use to implement your application's tests.
36 *
37 * <p>Implement the getTestSuite() method to return the name of your
38 * test suite class.
39 *
40 * <p>See the android.test package documentation (click the more... link)
41 * for a full description
42 *
43 * {@hide} Not needed for SDK
44 */
45public abstract class TestListActivity extends ListActivity {
46    /** Supplied in the intent extras if we are running performance tests. */
47    public static final String PERFORMANCE_TESTS = "android.test.performance";
48
49    /** "Mode" group in the menu. */
50    static final int MODE_GROUP = Menu.FIRST;
51
52    /** Our suite */
53    String mSuite;
54
55    /** Our children tests */
56    String[] mTests;
57
58    /** which mode, REGRESSION, PERFORMANCE or PROFILING */
59    private int mMode = TestRunner.REGRESSION;
60
61    /** "Regression" menu item */
62    private MenuItem mRegressionItem;
63
64    /** "Performance" menu item */
65    private MenuItem mPerformanceItem;
66
67    /** "Profiling" menu item */
68    private MenuItem mProfilingItem;
69
70    private final Comparator<String> sComparator = new Comparator<String>() {
71        public final int compare(String a, String b) {
72            String s1 = makeCompareName(a);
73            String s2 = makeCompareName(b);
74
75            return s1.compareToIgnoreCase(s2);
76        }
77    };
78
79    /**
80     * Constructor that doesn't do much.
81     */
82    public TestListActivity() {
83        super();
84    }
85
86    /**
87     * Subclasses should implement this to return the names of the classes
88     * of their tests.
89     *
90     * @return test suite class name
91     */
92    public abstract String getTestSuite();
93
94    /**
95     * Typical onCreate(Bundle icicle) implementation.
96     */
97    public void onCreate(Bundle icicle) {
98        super.onCreate(icicle);
99
100        Intent intent = getIntent();
101
102        mMode = intent.getIntExtra(TestListActivity.PERFORMANCE_TESTS, mMode);
103
104
105        if (intent.getAction().equals(Intent.ACTION_MAIN)) {
106            // if we were called as MAIN, get the test suites,
107            mSuite = getTestSuite();
108        } else if (intent.getAction().equals(Intent.ACTION_RUN)) {
109            // We should have been provided a status channel.  Bail out and
110            // run the test instead.  This is how the TestHarness gets us
111            // loaded in our process for "Run All Tests."
112            Intent ntent = new Intent(Intent.ACTION_RUN,
113                    intent.getData() != null
114                            ? intent.getData()
115                            : Uri.parse(getTestSuite()));
116            ntent.setClassName("com.android.testharness",
117                    "com.android.testharness.RunTest");
118            ntent.putExtras(intent);
119            ntent.putExtra("package", getPackageName());
120            startActivity(ntent);
121            finish();
122            return;
123        } else if (intent.getAction().equals(Intent.ACTION_VIEW)) {
124            // otherwise use the one in the intent
125            mSuite = intent.getData() != null ? intent.getData().toString()
126                    : null;
127        }
128
129        String[] children = TestRunner.getChildren(this, mSuite);
130
131        Arrays.sort(children, sComparator);
132
133        int len = children.length;
134        mTests = new String[len];
135        System.arraycopy(children, 0, mTests, 0, len);
136
137        setTitle(TestRunner.getTitle(mSuite));
138
139        MatrixCursor cursor = new MatrixCursor(new String[] { "name", "_id" });
140        addTestRows(cursor);
141
142        CursorAdapter adapter = new SimpleCursorAdapter(
143                this,
144                com.android.internal.R.layout.simple_list_item_1,
145                cursor,
146                new String[] {"name"},
147                new int[] {com.android.internal.R.id.text1});
148
149        setListAdapter(adapter);
150    }
151
152    private void addTestRows(MatrixCursor cursor) {
153        int id = 0;
154        cursor.newRow().add("Run All").add(id++);
155        for (String test : mTests) {
156            String title = TestRunner.getTitle(test);
157            String prefix = TestRunner.isTestSuite(this, test)
158                    ? "Browse " : "Run ";
159
160            // I'd rather do this with an icon column, but I don't know how
161            cursor.newRow().add(prefix + title).add(id++);
162        }
163    }
164
165    @Override
166    protected void onResume() {
167        super.onResume();
168    }
169
170    @Override
171    public boolean onCreateOptionsMenu(Menu menu) {
172        super.onCreateOptionsMenu(menu);
173        mRegressionItem = menu.add(MODE_GROUP, -1, 0, "Regression Mode");
174        mPerformanceItem = menu.add(MODE_GROUP, -1, 0, "Performance Mode");
175        mProfilingItem = menu.add(MODE_GROUP, -1, 0, "Profiling Mode");
176        menu.setGroupCheckable(MODE_GROUP, true, true);
177        return true;
178    }
179
180    @Override
181    public boolean onOptionsItemSelected(MenuItem item) {
182        if (item == mRegressionItem) {
183            mMode = TestRunner.REGRESSION;
184        } else if (item == mPerformanceItem) {
185            mMode = TestRunner.PERFORMANCE;
186        } else if (item == mProfilingItem) {
187            mMode = TestRunner.PROFILING;
188        }
189
190        return true;
191    }
192
193    @Override
194    public boolean onPrepareOptionsMenu(Menu menu) {
195        super.onPrepareOptionsMenu(menu);
196        switch (mMode) {
197        case TestRunner.REGRESSION:
198            mRegressionItem.setChecked(true);
199            break;
200
201        case TestRunner.PERFORMANCE:
202            mPerformanceItem.setChecked(true);
203            break;
204
205        case TestRunner.PROFILING:
206            mProfilingItem.setChecked(true);
207            break;
208        }
209        return true;
210    }
211
212    @Override
213    protected void onListItemClick(ListView l, View v, int position, long id) {
214        Intent intent = new Intent();
215
216        if (position == 0) {
217            if (false) {
218                intent.setClassName("com.android.testharness",
219                        "com.android.testharness.RunAll");
220                intent.putExtra("tests", new String[]{mSuite});
221            } else {
222                intent.setClassName("com.android.testharness",
223                        "com.android.testharness.RunTest");
224                intent.setAction(Intent.ACTION_RUN);
225                intent.setData(Uri.parse(mSuite));
226            }
227        } else {
228            String test = mTests[position - 1];
229            if (TestRunner.isTestSuite(this, test)) {
230                intent.setClassName(getPackageName(), this.getClass().getName());
231                intent.setAction(Intent.ACTION_VIEW);
232            } else {
233                intent.setClassName("com.android.testharness",
234                        "com.android.testharness.RunTest");
235            }
236            intent.setData(Uri.parse(test));
237        }
238
239        intent.putExtra(PERFORMANCE_TESTS, mMode);
240        intent.putExtra("package", getPackageName());
241        startActivity(intent);
242    }
243
244    private String makeCompareName(String s) {
245        int index = s.lastIndexOf('.');
246
247        if (index == -1) {
248            return s;
249        }
250
251        return s.substring(index + 1);
252    }
253}
254