|  | /* | 
|  | * Copyright (C) 2008 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | package android.test; | 
|  |  | 
|  | import android.app.Activity; | 
|  | import android.content.Intent; | 
|  |  | 
|  | import java.lang.reflect.Method; | 
|  |  | 
|  | /** | 
|  | * This class provides functional testing of a single activity.  The activity under test will | 
|  | * be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity()) | 
|  | * and you will then be able to manipulate your Activity directly. | 
|  | * | 
|  | * <p>Other options supported by this test case include: | 
|  | * <ul> | 
|  | * <li>You can run any test method on the UI thread (see {@link android.test.UiThreadTest}).</li> | 
|  | * <li>You can inject custom Intents into your Activity (see | 
|  | * {@link #setActivityIntent(Intent)}).</li> | 
|  | * </ul> | 
|  | * | 
|  | * <p>This class replaces {@link android.test.ActivityInstrumentationTestCase}, which is deprecated. | 
|  | * New tests should be written using this base class. | 
|  | * | 
|  | * <p>If you prefer an isolated unit test, see {@link android.test.ActivityUnitTestCase}. | 
|  | * | 
|  | * @deprecated Use | 
|  | * <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html"> | 
|  | * ActivityTestRule</a> instead. New tests should be written using the | 
|  | * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>. | 
|  | */ | 
|  | @Deprecated | 
|  | public abstract class ActivityInstrumentationTestCase2<T extends Activity> | 
|  | extends ActivityTestCase { | 
|  | Class<T> mActivityClass; | 
|  | boolean mInitialTouchMode = false; | 
|  | Intent mActivityIntent = null; | 
|  |  | 
|  | /** | 
|  | * Creates an {@link ActivityInstrumentationTestCase2}. | 
|  | * | 
|  | * @param pkg ignored - no longer in use. | 
|  | * @param activityClass The activity to test. This must be a class in the instrumentation | 
|  | * targetPackage specified in the AndroidManifest.xml | 
|  | * | 
|  | * @deprecated use {@link #ActivityInstrumentationTestCase2(Class)} instead | 
|  | */ | 
|  | @Deprecated | 
|  | public ActivityInstrumentationTestCase2(String pkg, Class<T> activityClass) { | 
|  | this(activityClass); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Creates an {@link ActivityInstrumentationTestCase2}. | 
|  | * | 
|  | * @param activityClass The activity to test. This must be a class in the instrumentation | 
|  | * targetPackage specified in the AndroidManifest.xml | 
|  | */ | 
|  | public ActivityInstrumentationTestCase2(Class<T> activityClass) { | 
|  | mActivityClass = activityClass; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Get the Activity under test, starting it if necessary. | 
|  | * | 
|  | * For each test method invocation, the Activity will not actually be created until the first | 
|  | * time this method is called. | 
|  | * | 
|  | * <p>If you wish to provide custom setup values to your Activity, you may call | 
|  | * {@link #setActivityIntent(Intent)} and/or {@link #setActivityInitialTouchMode(boolean)} | 
|  | * before your first call to getActivity().  Calling them after your Activity has | 
|  | * started will have no effect. | 
|  | * | 
|  | * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread. | 
|  | * If your test method is annotated with {@link android.test.UiThreadTest}, then your Activity | 
|  | * will be started automatically just before your test method is run.  You still call this | 
|  | * method in order to get the Activity under test. | 
|  | * | 
|  | * @return the Activity under test | 
|  | */ | 
|  | @Override | 
|  | public T getActivity() { | 
|  | Activity a = super.getActivity(); | 
|  | if (a == null) { | 
|  | // set initial touch mode | 
|  | getInstrumentation().setInTouchMode(mInitialTouchMode); | 
|  | final String targetPackage = getInstrumentation().getTargetContext().getPackageName(); | 
|  | // inject custom intent, if provided | 
|  | if (mActivityIntent == null) { | 
|  | a = launchActivity(targetPackage, mActivityClass, null); | 
|  | } else { | 
|  | a = launchActivityWithIntent(targetPackage, mActivityClass, mActivityIntent); | 
|  | } | 
|  | setActivity(a); | 
|  | } | 
|  | return (T) a; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Call this method before the first call to {@link #getActivity} to inject a customized Intent | 
|  | * into the Activity under test. | 
|  | * | 
|  | * <p>If you do not call this, the default intent will be provided.  If you call this after | 
|  | * your Activity has been started, it will have no effect. | 
|  | * | 
|  | * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread. | 
|  | * If your test method is annotated with {@link android.test.UiThreadTest}, then you must call | 
|  | * {@link #setActivityIntent(Intent)} from {@link #setUp()}. | 
|  | * | 
|  | * <p>The default Intent (if this method is not called) is: | 
|  | *  action = {@link Intent#ACTION_MAIN} | 
|  | *  flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK} | 
|  | * All other fields are null or empty. | 
|  | * | 
|  | * @param i The Intent to start the Activity with, or null to reset to the default Intent. | 
|  | */ | 
|  | public void setActivityIntent(Intent i) { | 
|  | mActivityIntent = i; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Call this method before the first call to {@link #getActivity} to set the initial touch | 
|  | * mode for the Activity under test. | 
|  | * | 
|  | * <p>If you do not call this, the touch mode will be false.  If you call this after | 
|  | * your Activity has been started, it will have no effect. | 
|  | * | 
|  | * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread. | 
|  | * If your test method is annotated with {@link android.test.UiThreadTest}, then you must call | 
|  | * {@link #setActivityInitialTouchMode(boolean)} from {@link #setUp()}. | 
|  | * | 
|  | * @param initialTouchMode true if the Activity should be placed into "touch mode" when started | 
|  | */ | 
|  | public void setActivityInitialTouchMode(boolean initialTouchMode) { | 
|  | mInitialTouchMode = initialTouchMode; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | protected void setUp() throws Exception { | 
|  | super.setUp(); | 
|  |  | 
|  | mInitialTouchMode = false; | 
|  | mActivityIntent = null; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | protected void tearDown() throws Exception { | 
|  | // Finish the Activity off (unless was never launched anyway) | 
|  | Activity a = super.getActivity(); | 
|  | if (a != null) { | 
|  | a.finish(); | 
|  | setActivity(null); | 
|  | } | 
|  |  | 
|  | // Scrub out members - protects against memory leaks in the case where someone | 
|  | // creates a non-static inner class (thus referencing the test case) and gives it to | 
|  | // someone else to hold onto | 
|  | scrubClass(ActivityInstrumentationTestCase2.class); | 
|  |  | 
|  | super.tearDown(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Runs the current unit test. If the unit test is annotated with | 
|  | * {@link android.test.UiThreadTest}, force the Activity to be created before switching to | 
|  | * the UI thread. | 
|  | */ | 
|  | @Override | 
|  | protected void runTest() throws Throwable { | 
|  | try { | 
|  | Method method = getClass().getMethod(getName(), (Class[]) null); | 
|  | if (method.isAnnotationPresent(UiThreadTest.class)) { | 
|  | getActivity(); | 
|  | } | 
|  | } catch (Exception e) { | 
|  | // eat the exception here; super.runTest() will catch it again and handle it properly | 
|  | } | 
|  | super.runTest(); | 
|  | } | 
|  |  | 
|  | } |