Sync and cleanup pass over support-v4

* Add missing annotations on one TextViewCompat method and its
implementations
* Tighten annotation from IdRes to StyleRes on TextViewCompat's
setTextAppearance
* Switch a few v4 tests to JUnit4, activity rules and Espresso

Change-Id: Ia235b9c527173f0403432c59ba9206a174bf043f
diff --git a/v4/api23/android/support/v4/widget/TextViewCompatApi23.java b/v4/api23/android/support/v4/widget/TextViewCompatApi23.java
index 8370bfc..ad21409 100644
--- a/v4/api23/android/support/v4/widget/TextViewCompatApi23.java
+++ b/v4/api23/android/support/v4/widget/TextViewCompatApi23.java
@@ -18,10 +18,11 @@
 
 import android.support.annotation.IdRes;
 import android.support.annotation.NonNull;
+import android.support.annotation.StyleRes;
 import android.widget.TextView;
 
 class TextViewCompatApi23 {
-    public static void setTextAppearance(@NonNull TextView textView, @IdRes int resId) {
+    public static void setTextAppearance(@NonNull TextView textView, @StyleRes int resId) {
         textView.setTextAppearance(resId);
     }
 }
diff --git a/v4/build.gradle b/v4/build.gradle
index 5abdbb9..8b26642 100644
--- a/v4/build.gradle
+++ b/v4/build.gradle
@@ -65,8 +65,12 @@
     // when manipulating the libraryVariants.
     compile files(internalJar.archivePath)
 
-    androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
-    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
+    androidTestCompile ('com.android.support.test:runner:0.4.1') {
+        exclude module: 'support-annotations'
+    }
+    androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2.1') {
+        exclude module: 'support-annotations'
+    }
     testCompile 'junit:junit:4.12'
 }
 
diff --git a/v4/java/android/support/v4/widget/TextViewCompat.java b/v4/java/android/support/v4/widget/TextViewCompat.java
index 5df1ae6..7af3087 100644
--- a/v4/java/android/support/v4/widget/TextViewCompat.java
+++ b/v4/java/android/support/v4/widget/TextViewCompat.java
@@ -18,9 +18,11 @@
 
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.DrawableRes;
 import android.support.annotation.IdRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.StyleRes;
 import android.widget.TextView;
 
 /**
@@ -40,10 +42,11 @@
                 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end,
                 @Nullable Drawable bottom);
         void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
-                int start, int top, int end, int bottom);
+                @DrawableRes int start, @DrawableRes int top, @DrawableRes int end,
+                @DrawableRes int bottom);
         int getMaxLines(TextView textView);
         int getMinLines(TextView textView);
-        void setTextAppearance(@NonNull TextView textView, @IdRes int resId);
+        void setTextAppearance(@NonNull TextView textView, @StyleRes int resId);
     }
 
     static class BaseTextViewCompatImpl implements TextViewCompatImpl {
@@ -63,7 +66,8 @@
 
         @Override
         public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
-                int start, int top, int end, int bottom) {
+                @DrawableRes int start, @DrawableRes int top, @DrawableRes int end,
+                @DrawableRes int bottom) {
             textView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom);
         }
 
@@ -78,7 +82,7 @@
         }
 
         @Override
-        public void setTextAppearance(TextView textView, int resId) {
+        public void setTextAppearance(TextView textView, @StyleRes int resId) {
             TextViewCompatDonut.setTextAppearance(textView, resId);
         }
     }
@@ -113,7 +117,8 @@
 
         @Override
         public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
-                int start, int top, int end, int bottom) {
+                @DrawableRes int start, @DrawableRes int top, @DrawableRes int end,
+                @DrawableRes int bottom) {
             TextViewCompatJbMr1.setCompoundDrawablesRelativeWithIntrinsicBounds(textView,
                     start, top, end, bottom);
         }
@@ -138,7 +143,8 @@
 
         @Override
         public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
-                int start, int top, int end, int bottom) {
+                @DrawableRes int start, @DrawableRes int top, @DrawableRes int end,
+                @DrawableRes int bottom) {
             TextViewCompatJbMr2.setCompoundDrawablesRelativeWithIntrinsicBounds(textView,
                     start, top, end, bottom);
         }
@@ -146,7 +152,7 @@
 
     static class Api23TextViewCompatImpl extends JbMr2TextViewCompatImpl {
         @Override
-        public void setTextAppearance(@NonNull TextView textView, @IdRes int resId) {
+        public void setTextAppearance(@NonNull TextView textView, @StyleRes int resId) {
             TextViewCompatApi23.setTextAppearance(textView, resId);
         }
     }
@@ -228,7 +234,8 @@
      * @attr ref android.R.styleable#TextView_drawableBottom
      */
     public static void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
-            int start, int top, int end, int bottom) {
+            @DrawableRes int start, @DrawableRes int top, @DrawableRes int end,
+            @DrawableRes int bottom) {
         IMPL.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, start, top, end, bottom);
     }
 
@@ -259,7 +266,7 @@
      * @param textView The TextView against which to invoke the method.
      * @param resId    The resource identifier of the style to apply.
      */
-    public static void setTextAppearance(@NonNull TextView textView, @IdRes int resId) {
+    public static void setTextAppearance(@NonNull TextView textView, @StyleRes int resId) {
         IMPL.setTextAppearance(textView, resId);
     }
 }
diff --git a/v4/jellybean-mr2/android/support/v4/widget/TextViewCompatJbMr2.java b/v4/jellybean-mr2/android/support/v4/widget/TextViewCompatJbMr2.java
index ec9fe61..73f9666 100644
--- a/v4/jellybean-mr2/android/support/v4/widget/TextViewCompatJbMr2.java
+++ b/v4/jellybean-mr2/android/support/v4/widget/TextViewCompatJbMr2.java
@@ -17,6 +17,7 @@
 package android.support.v4.widget;
 
 import android.graphics.drawable.Drawable;
+import android.support.annotation.DrawableRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.widget.TextView;
@@ -36,7 +37,8 @@
     }
 
     public static void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView,
-            int start, int top, int end, int bottom) {
+            @DrawableRes int start, @DrawableRes int top, @DrawableRes int end,
+            @DrawableRes int bottom) {
         textView.setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
     }
 
diff --git a/v4/tests/AndroidManifest.xml b/v4/tests/AndroidManifest.xml
index f99c5d1..85ffd7d 100644
--- a/v4/tests/AndroidManifest.xml
+++ b/v4/tests/AndroidManifest.xml
@@ -20,7 +20,8 @@
     <uses-sdk
             android:minSdkVersion="4"
             android:targetSdkVersion="23"
-            tools:overrideLibrary="android.support.test,android.support.test.espresso, android.support.test.espresso.idling"/>
+            tools:overrideLibrary="android.support.test, android.app, android.support.test.rule,
+                      android.support.test.espresso, android.support.test.espresso.idling"/>
 
     <uses-permission android:name="android.permission.VIBRATE"/>
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
@@ -29,7 +30,7 @@
 
     <application android:supportsRtl="true">
         <uses-library android:name="android.test.runner" />
-        <activity android:name="android.support.v4.widget.test.TextViewTestActivity"/>
+        <activity android:name="android.support.v4.widget.TextViewTestActivity"/>
 
         <activity android:name="android.support.v4.view.ViewPagerWithTitleStripActivity"/>
 
diff --git a/v4/tests/java/android/support/v4/BaseInstrumentationTestCase.java b/v4/tests/java/android/support/v4/BaseInstrumentationTestCase.java
new file mode 100644
index 0000000..5f9ce85
--- /dev/null
+++ b/v4/tests/java/android/support/v4/BaseInstrumentationTestCase.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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.support.v4;
+
+import android.app.Activity;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public abstract class BaseInstrumentationTestCase<A extends Activity> {
+    @Rule
+    public final ActivityTestRule<A> mActivityTestRule;
+
+    protected BaseInstrumentationTestCase(Class<A> activityClass) {
+        mActivityTestRule = new ActivityTestRule<A>(activityClass);
+    }
+}
diff --git a/v4/tests/java/android/support/v4/BaseTestActivity.java b/v4/tests/java/android/support/v4/BaseTestActivity.java
new file mode 100755
index 0000000..e0682ce
--- /dev/null
+++ b/v4/tests/java/android/support/v4/BaseTestActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 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.support.v4;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public abstract class BaseTestActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        final int contentView = getContentViewLayoutResId();
+        if (contentView > 0) {
+            setContentView(contentView);
+        }
+        onContentViewSet();
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+
+    protected abstract int getContentViewLayoutResId();
+
+    protected void onContentViewSet() {}
+}
diff --git a/v4/tests/java/android/support/v4/testutils/LayoutDirectionActions.java b/v4/tests/java/android/support/v4/testutils/LayoutDirectionActions.java
new file mode 100755
index 0000000..25ae971
--- /dev/null
+++ b/v4/tests/java/android/support/v4/testutils/LayoutDirectionActions.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 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.support.v4.testutils;
+
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.v4.view.ViewCompat;
+import android.view.View;
+import org.hamcrest.Matcher;
+
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+
+public class LayoutDirectionActions {
+    /**
+     * Sets layout direction on the view.
+     */
+    public static ViewAction setLayoutDirection(final int layoutDirection) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isDisplayed();
+            }
+
+            @Override
+            public String getDescription() {
+                return "set layout direction";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                ViewCompat.setLayoutDirection(view, layoutDirection);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+}
diff --git a/v4/tests/java/android/support/v4/testutils/TextViewActions.java b/v4/tests/java/android/support/v4/testutils/TextViewActions.java
new file mode 100644
index 0000000..f67e8c0
--- /dev/null
+++ b/v4/tests/java/android/support/v4/testutils/TextViewActions.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2016 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.support.v4.testutils;
+
+import android.graphics.drawable.Drawable;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.annotation.StyleRes;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.v4.widget.TextViewCompat;
+import android.view.View;
+import android.widget.TextView;
+import org.hamcrest.Matcher;
+
+import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+
+public class TextViewActions {
+    /**
+     * Sets max lines count on <code>TextView</code>.
+     */
+    public static ViewAction setMaxLines(final int maxLines) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(TextView.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "TextView set max lines";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                TextView textView = (TextView) view;
+                textView.setMaxLines(maxLines);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    /**
+     * Sets min lines count on <code>TextView</code>.
+     */
+    public static ViewAction setMinLines(final int minLines) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(TextView.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "TextView set min lines";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                TextView textView = (TextView) view;
+                textView.setMinLines(minLines);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    /**
+     * Sets text content on <code>TextView</code>.
+     */
+    public static ViewAction setText(final @StringRes int stringResId) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(TextView.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "TextView set text";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                TextView textView = (TextView) view;
+                textView.setText(stringResId);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    /**
+     * Sets text appearance on <code>TextView</code>.
+     */
+    public static ViewAction setTextAppearance(final @StyleRes int styleResId) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(TextView.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "TextView set text appearance";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                TextView textView = (TextView) view;
+                TextViewCompat.setTextAppearance(textView, styleResId);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    /**
+     * Sets compound drawables on <code>TextView</code>.
+     */
+    public static ViewAction setCompoundDrawablesRelative(final @Nullable Drawable start,
+            final @Nullable Drawable top, final @Nullable Drawable end,
+            final @Nullable Drawable bottom) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(TextView.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "TextView set compound drawables";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                TextView textView = (TextView) view;
+                TextViewCompat.setCompoundDrawablesRelative(textView, start, top, end, bottom);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    /**
+     * Sets compound drawables on <code>TextView</code>.
+     */
+    public static ViewAction setCompoundDrawablesRelativeWithIntrinsicBounds(
+            final @Nullable Drawable start, final @Nullable Drawable top,
+            final @Nullable Drawable end, final @Nullable Drawable bottom) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(TextView.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "TextView set compound drawables";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                TextView textView = (TextView) view;
+                TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(
+                        textView, start, top, end, bottom);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    /**
+     * Sets compound drawables on <code>TextView</code>.
+     */
+    public static ViewAction setCompoundDrawablesRelativeWithIntrinsicBounds(
+            final @DrawableRes int start, final @DrawableRes int top, final @DrawableRes int end,
+            final @DrawableRes int bottom) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(TextView.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "TextView set compound drawables";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                TextView textView = (TextView) view;
+                TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(
+                        textView, start, top, end, bottom);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+}
diff --git a/v4/tests/java/android/support/v4/view/BaseViewPagerTest.java b/v4/tests/java/android/support/v4/view/BaseViewPagerTest.java
index 166fb1e..13d8372 100644
--- a/v4/tests/java/android/support/v4/view/BaseViewPagerTest.java
+++ b/v4/tests/java/android/support/v4/view/BaseViewPagerTest.java
@@ -17,47 +17,32 @@
 
 import android.app.Activity;
 import android.graphics.Color;
+import android.support.v4.BaseInstrumentationTestCase;
+import android.support.v4.test.R;
+import android.support.v4.testutils.TestUtilsAssertions;
+import android.support.v4.testutils.TestUtilsMatchers;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
 import android.util.Pair;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
-
-import android.support.test.espresso.Espresso;
-import android.support.test.espresso.UiController;
-import android.support.v4.test.R;
-import android.support.v4.testutils.TestUtilsAssertions;
-import android.support.v4.testutils.TestUtilsMatchers;
-import android.support.v4.view.ViewPager;
-import android.support.v4.view.PagerTitleStrip;
-import android.support.v4.widget.TestActivity;
-
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.SmallTest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 import java.util.ArrayList;
 
-import org.hamcrest.Matcher;
-
 import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.action.ViewActions.click;
 import static android.support.test.espresso.action.ViewActions.swipeLeft;
 import static android.support.test.espresso.action.ViewActions.swipeRight;
+import static android.support.test.espresso.assertion.PositionAssertions.*;
 import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.assertion.PositionAssertions.isBelow;
-import static android.support.test.espresso.assertion.PositionAssertions.isBottomAlignedWith;
-import static android.support.test.espresso.assertion.PositionAssertions.isLeftAlignedWith;
-import static android.support.test.espresso.assertion.PositionAssertions.isRightAlignedWith;
-import static android.support.test.espresso.assertion.PositionAssertions.isTopAlignedWith;
-import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
-
+import static android.support.test.espresso.matcher.ViewMatchers.*;
 import static org.hamcrest.Matchers.allOf;
 import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertEquals;
 
 /**
  * Base class for testing <code>ViewPager</code>. Most of the testing logic should be in this
@@ -67,8 +52,7 @@
  * Testing logic that does depend on the specific pager title implementation is pushed into the
  * extending classes in <code>assertStripInteraction()</code> method.
  */
-public abstract class BaseViewPagerTest<T extends Activity>
-        extends ActivityInstrumentationTestCase2<T> {
+public abstract class BaseViewPagerTest<T extends Activity> extends BaseInstrumentationTestCase<T> {
     protected ViewPager mViewPager;
 
     protected static class BasePagerAdapter<Q> extends PagerAdapter {
@@ -181,14 +165,12 @@
     }
 
     public BaseViewPagerTest(Class<T> activityClass) {
-        super("android.support.v4.view", activityClass);
+        super(activityClass);
     }
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-
-        final T activity = getActivity();
+        final T activity = mActivityTestRule.getActivity();
         mViewPager = (ViewPager) activity.findViewById(R.id.pager);
 
         ColorPagerAdapter adapter = new ColorPagerAdapter();
@@ -199,13 +181,12 @@
                 ViewPagerActions.scrollToPage(0));
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         onView(withId(R.id.pager)).perform(ViewPagerActions.setAdapter(null));
-
-        super.tearDown();
     }
 
+    @Test
     @SmallTest
     public void testPageSelections() {
         assertEquals("Initial state", 0, mViewPager.getCurrentItem());
@@ -232,6 +213,7 @@
 
     }
 
+    @Test
     @SmallTest
     public void testPageSwipes() {
         assertEquals("Initial state", 0, mViewPager.getCurrentItem());
@@ -257,6 +239,7 @@
         assertEquals("Swipe right beyond first page", 0, mViewPager.getCurrentItem());
     }
 
+    @Test
     @SmallTest
     public void testPageSwipesComposite() {
         assertEquals("Initial state", 0, mViewPager.getCurrentItem());
@@ -275,6 +258,7 @@
         assertEquals("Swipe right beyond first page and then left", 1, mViewPager.getCurrentItem());
     }
 
+    @Test
     @SmallTest
     public void testPageContent() {
         assertEquals("Initial state", 0, mViewPager.getCurrentItem());
@@ -315,6 +299,7 @@
                 TestUtilsMatchers.backgroundColor(Color.BLUE))));
     }
 
+    @Test
     @SmallTest
     public void testAdapterChange() {
         // Verify that we have the expected initial adapter
@@ -427,6 +412,7 @@
         }
     }
 
+    @Test
     @SmallTest
     public void testPagerStrip() {
         // Set an adapter with 5 pages
diff --git a/v4/tests/java/android/support/v4/view/GravityCompatTest.java b/v4/tests/java/android/support/v4/view/GravityCompatTest.java
index db62b0c..2e2f180 100644
--- a/v4/tests/java/android/support/v4/view/GravityCompatTest.java
+++ b/v4/tests/java/android/support/v4/view/GravityCompatTest.java
@@ -17,15 +17,10 @@
 
 import android.graphics.Rect;
 import android.os.Build;
-import android.view.Gravity;
-import android.view.View;
-
 import android.support.v4.testutils.TestUtils;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.view.ViewCompat;
-
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.view.Gravity;
 
 public class GravityCompatTest extends AndroidTestCase {
     @SmallTest
diff --git a/v4/tests/java/android/support/v4/view/MarginLayoutParamsCompatTest.java b/v4/tests/java/android/support/v4/view/MarginLayoutParamsCompatTest.java
index db08a1a..057db99 100644
--- a/v4/tests/java/android/support/v4/view/MarginLayoutParamsCompatTest.java
+++ b/v4/tests/java/android/support/v4/view/MarginLayoutParamsCompatTest.java
@@ -15,16 +15,10 @@
  */
 package android.support.v4.view;
 
-import android.view.View;
-
-import android.support.v4.view.MarginLayoutParamsCompat;
-import android.support.v4.view.ViewCompat;
-
 import android.os.Build;
-import android.view.ViewGroup;
-
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.view.ViewGroup;
 
 public class MarginLayoutParamsCompatTest extends AndroidTestCase {
     @SmallTest
diff --git a/v4/tests/java/android/support/v4/view/ViewCompatTest.java b/v4/tests/java/android/support/v4/view/ViewCompatTest.java
index 483d16b..29a0f5a 100644
--- a/v4/tests/java/android/support/v4/view/ViewCompatTest.java
+++ b/v4/tests/java/android/support/v4/view/ViewCompatTest.java
@@ -15,12 +15,9 @@
  */
 package android.support.v4.view;
 
-import android.view.View;
-
-import android.support.v4.view.ViewCompat;
-
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.view.View;
 
 public class ViewCompatTest extends AndroidTestCase {
     @SmallTest
diff --git a/v4/tests/java/android/support/v4/view/ViewPagerActions.java b/v4/tests/java/android/support/v4/view/ViewPagerActions.java
index b1e1a76..2b37e6f 100644
--- a/v4/tests/java/android/support/v4/view/ViewPagerActions.java
+++ b/v4/tests/java/android/support/v4/view/ViewPagerActions.java
@@ -22,20 +22,12 @@
 import android.support.test.espresso.action.GeneralClickAction;
 import android.support.test.espresso.action.Press;
 import android.support.test.espresso.action.Tap;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
 import android.view.View;
 import android.widget.TextView;
-
 import org.hamcrest.Matcher;
 
-import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
 import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
-import static android.support.test.espresso.matcher.ViewMatchers.withText;
-
-import static org.hamcrest.Matchers.allOf;
 
 public class ViewPagerActions {
     /**
diff --git a/v4/tests/java/android/support/v4/view/ViewPagerWithTabStripActivity.java b/v4/tests/java/android/support/v4/view/ViewPagerWithTabStripActivity.java
index edc4da9..2cb3048 100644
--- a/v4/tests/java/android/support/v4/view/ViewPagerWithTabStripActivity.java
+++ b/v4/tests/java/android/support/v4/view/ViewPagerWithTabStripActivity.java
@@ -21,8 +21,6 @@
 import android.support.v4.test.R;
 import android.view.WindowManager;
 
-import java.util.ArrayList;
-
 public class ViewPagerWithTabStripActivity extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/v4/tests/java/android/support/v4/view/ViewPagerWithTabStripTest.java b/v4/tests/java/android/support/v4/view/ViewPagerWithTabStripTest.java
index 706d2e2..3e4a82f 100644
--- a/v4/tests/java/android/support/v4/view/ViewPagerWithTabStripTest.java
+++ b/v4/tests/java/android/support/v4/view/ViewPagerWithTabStripTest.java
@@ -15,7 +15,6 @@
  */
 package android.support.v4.view;
 
-import android.support.v4.view.PagerTitleStrip;
 import android.support.v4.test.R;
 
 import static android.support.test.espresso.Espresso.onView;
@@ -23,8 +22,8 @@
 import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
-
 import static org.hamcrest.Matchers.allOf;
+import static org.junit.Assert.assertEquals;
 
 /**
  * Provides assertions that depend on the interactive nature of <code>PagerTabStrip</code>.
diff --git a/v4/tests/java/android/support/v4/view/ViewPagerWithTitleStripActivity.java b/v4/tests/java/android/support/v4/view/ViewPagerWithTitleStripActivity.java
index 28dcb07..49d6e76 100644
--- a/v4/tests/java/android/support/v4/view/ViewPagerWithTitleStripActivity.java
+++ b/v4/tests/java/android/support/v4/view/ViewPagerWithTitleStripActivity.java
@@ -21,8 +21,6 @@
 import android.support.v4.test.R;
 import android.view.WindowManager;
 
-import java.util.ArrayList;
-
 public class ViewPagerWithTitleStripActivity extends Activity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/v4/tests/java/android/support/v4/view/ViewPagerWithTitleStripTest.java b/v4/tests/java/android/support/v4/view/ViewPagerWithTitleStripTest.java
index 528db86..8d831dc 100644
--- a/v4/tests/java/android/support/v4/view/ViewPagerWithTitleStripTest.java
+++ b/v4/tests/java/android/support/v4/view/ViewPagerWithTitleStripTest.java
@@ -15,7 +15,6 @@
  */
 package android.support.v4.view;
 
-import android.support.v4.view.PagerTitleStrip;
 import android.support.v4.test.R;
 
 import static android.support.test.espresso.Espresso.onView;
@@ -23,8 +22,8 @@
 import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
-
 import static org.hamcrest.Matchers.allOf;
+import static org.junit.Assert.assertEquals;
 
 /**
  * Provides assertions that depend on the non-interactive nature of <code>PagerTabStrip</code>.
diff --git a/v4/tests/java/android/support/v4/widget/TextViewCompatTest.java b/v4/tests/java/android/support/v4/widget/TextViewCompatTest.java
index d0f5b00..3ef236f 100644
--- a/v4/tests/java/android/support/v4/widget/TextViewCompatTest.java
+++ b/v4/tests/java/android/support/v4/widget/TextViewCompatTest.java
@@ -17,35 +17,27 @@
 
 package android.support.v4.widget;
 
-import org.junit.After;
+import android.content.res.Resources;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
+import android.support.v4.BaseInstrumentationTestCase;
+import android.support.v4.test.R;
+import android.support.v4.testutils.TestUtils;
+import android.support.v4.view.ViewCompat;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.widget.TextView;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
-import android.app.Instrumentation;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Looper;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.UiThreadTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.support.annotation.ColorInt;
-import android.support.annotation.LayoutRes;
-import android.support.test.InstrumentationRegistry;
-import android.support.v4.test.R;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.widget.TextViewCompat;
-import android.support.v4.testutils.TestUtils;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.v4.testutils.LayoutDirectionActions.setLayoutDirection;
+import static android.support.v4.testutils.TextViewActions.*;
+import static org.junit.Assert.*;
 
-public class TextViewCompatTest extends ActivityInstrumentationTestCase2<TestActivity> {
+public class TextViewCompatTest extends BaseInstrumentationTestCase<TextViewTestActivity> {
     private static final String TAG = "TextViewCompatTest";
 
     private TextView mTextView;
@@ -72,127 +64,75 @@
     }
 
     public TextViewCompatTest() {
-        super("android.support.v4.widget", TestActivity.class);
+        super(TextViewTestActivity.class);
     }
 
-    @Override
-    public void tearDown() throws Exception {
-        if (mTextView != null) {
-            removeTextView();
-        }
-
-        getInstrumentation().waitForIdleSync();
-        super.tearDown();
+    @Before
+    public void setUp() {
+        mTextView = (TextView) mActivityTestRule.getActivity().findViewById(R.id.text_view);
     }
 
-    private boolean isMainThread() {
-        return Looper.myLooper() == Looper.getMainLooper();
-    }
-
-    private void removeTextView() {
-        if (mTextView == null) {
-            return;
-        }
-        if (!isMainThread()) {
-            getInstrumentation().waitForIdleSync();
-        }
-        try {
-            runTestOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    getActivity().mContainer.removeAllViews();
-                }
-            });
-        } catch (Throwable throwable) {
-            Log.e(TAG, "", throwable);
-        }
-        mTextView = null;
-    }
-
-    private void createAndAddTextView() {
-        final TestActivity activity = getActivity();
-        mTextView = new TextView(activity);
-        activity.mContainer.addView(mTextView);
-
-        // Explicitly measure and layout the text view. This way the core TextView updates its
-        // internal tracking of various visual facets so those can be tested in the relevant
-        // tests - such as, for example, where each drawable is positioned relative to the text.
-        final DisplayMetrics metrics = getActivity().getResources().getDisplayMetrics();
-        int textViewWidthPx = TestUtils.convertSizeDipsToPixels(metrics, 200);
-        int textViewHeightPx = TestUtils.convertSizeDipsToPixels(metrics, 60);
-        mTextView.measure(
-                View.MeasureSpec.makeMeasureSpec(textViewWidthPx, View.MeasureSpec.EXACTLY),
-                View.MeasureSpec.makeMeasureSpec(textViewHeightPx, View.MeasureSpec.EXACTLY));
-        mTextView.layout(0, 0, textViewWidthPx, textViewHeightPx);
-    }
-
-    @UiThreadTest
+    @Test
     @SmallTest
     public void testMaxLines() throws Throwable {
-        createAndAddTextView();
         final int maxLinesCount = 4;
-        mTextView.setMaxLines(maxLinesCount);
+        onView(withId(R.id.text_view)).perform(setMaxLines(maxLinesCount));
 
         assertEquals("Empty view: Max lines must match", TextViewCompat.getMaxLines(mTextView),
                 maxLinesCount);
 
-        mTextView.setText(R.string.test_text_short);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_short));
         assertEquals("Short text: Max lines must match", TextViewCompat.getMaxLines(mTextView),
                 maxLinesCount);
 
-        mTextView.setText(R.string.test_text_medium);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_medium));
         assertEquals("Medium text: Max lines must match", TextViewCompat.getMaxLines(mTextView),
                 maxLinesCount);
 
-        mTextView.setText(R.string.test_text_long);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
         assertEquals("Long text: Max lines must match", TextViewCompat.getMaxLines(mTextView),
                 maxLinesCount);
     }
 
-    @UiThreadTest
+    @Test
     @SmallTest
     public void testMinLines() throws Throwable {
-        createAndAddTextView();
         final int minLinesCount = 3;
-        mTextView.setMinLines(minLinesCount);
+        onView(withId(R.id.text_view)).perform(setMinLines(minLinesCount));
 
         assertEquals("Empty view: Min lines must match", TextViewCompat.getMinLines(mTextView),
                 minLinesCount);
 
-        mTextView.setText(R.string.test_text_short);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_short));
         assertEquals("Short text: Min lines must match", TextViewCompat.getMinLines(mTextView),
                 minLinesCount);
 
-        mTextView.setText(R.string.test_text_medium);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_medium));
         assertEquals("Medium text: Min lines must match", TextViewCompat.getMinLines(mTextView),
                 minLinesCount);
 
-        mTextView.setText(R.string.test_text_long);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
         assertEquals("Long text: Min lines must match", TextViewCompat.getMinLines(mTextView),
                 minLinesCount);
     }
 
-    @UiThreadTest
+    @Test
     @SmallTest
     public void testStyle() throws Throwable {
-        createAndAddTextView();
+        onView(withId(R.id.text_view)).perform(setTextAppearance(R.style.TextMediumStyle));
 
-        TextViewCompat.setTextAppearance(mTextView, R.style.TextMediumStyle);
-
-        final Resources res = getActivity().getResources();
+        final Resources res = mActivityTestRule.getActivity().getResources();
         assertTrue("Styled text view: style",
                 mTextView.getTypeface().isItalic() || (mTextView.getPaint().getTextSkewX() < 0));
         assertEquals("Styled text view: color", mTextView.getTextColors().getDefaultColor(),
                 res.getColor(R.color.text_color));
         assertEquals("Styled text view: size", mTextView.getTextSize(),
-                (float) res.getDimensionPixelSize(R.dimen.text_medium_size));
+                (float) res.getDimensionPixelSize(R.dimen.text_medium_size), 1.0f);
     }
 
-    @UiThreadTest
+    @Test
     @SmallTest
     public void testCompoundDrawablesRelative() throws Throwable {
-        createAndAddTextView();
-
         final Drawable drawableStart = new ColorDrawable(0xFFFF0000);
         drawableStart.setBounds(0, 0, 20, 20);
         final Drawable drawableTop = new ColorDrawable(0xFF00FF00);
@@ -200,9 +140,9 @@
         final Drawable drawableEnd = new ColorDrawable(0xFF0000FF);
         drawableEnd.setBounds(0, 0, 25, 20);
 
-        mTextView.setText(R.string.test_text_medium);
-        TextViewCompat.setCompoundDrawablesRelative(mTextView, drawableStart, drawableTop,
-                drawableEnd, null);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_medium));
+        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelative(drawableStart,
+                drawableTop, drawableEnd, null));
 
         final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
 
@@ -227,12 +167,10 @@
         assertNull("Compound drawable: bottom", drawablesAbsolute[3]);
     }
 
-    @UiThreadTest
+    @Test
     @SmallTest
     public void testCompoundDrawablesRelativeRtl() throws Throwable {
-        createAndAddTextView();
-
-        ViewCompat.setLayoutDirection(mTextView, ViewCompat.LAYOUT_DIRECTION_RTL);
+        onView(withId(R.id.text_view)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL));
 
         final Drawable drawableStart = new ColorDrawable(0xFFFF0000);
         drawableStart.setBounds(0, 0, 20, 20);
@@ -241,9 +179,9 @@
         final Drawable drawableEnd = new ColorDrawable(0xFF0000FF);
         drawableEnd.setBounds(0, 0, 25, 20);
 
-        mTextView.setText(R.string.test_text_medium);
-        TextViewCompat.setCompoundDrawablesRelative(mTextView, drawableStart, drawableTop,
-                drawableEnd, null);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_medium));
+        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelative(drawableStart,
+                drawableTop, drawableEnd, null));
 
         // Check to see whether our text view is under RTL mode
         if (ViewCompat.getLayoutDirection(mTextView) != ViewCompat.LAYOUT_DIRECTION_RTL) {
@@ -276,18 +214,16 @@
         assertNull("Compound drawable: bottom", drawablesAbsolute[3]);
     }
 
-    @UiThreadTest
+    @Test
     @SmallTest
     public void testCompoundDrawablesRelativeWithIntrinsicBounds() throws Throwable {
-        createAndAddTextView();
-
         final Drawable drawableStart = new TestDrawable(0xFFFF0000, 30, 20);
         final Drawable drawableEnd = new TestDrawable(0xFF0000FF, 25, 45);
         final Drawable drawableBottom = new TestDrawable(0xFF00FF00, 15, 35);
 
-        mTextView.setText(R.string.test_text_long);
-        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mTextView, drawableStart,
-                null, drawableEnd, drawableBottom);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
+        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelativeWithIntrinsicBounds(
+                drawableStart, null, drawableEnd, drawableBottom));
 
         final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
 
@@ -312,20 +248,18 @@
                 drawablesAbsolute[3].getBounds().height(), 35);
     }
 
-    @UiThreadTest
+    @Test
     @SmallTest
     public void testCompoundDrawablesRelativeWithIntrinsicBoundsRtl() throws Throwable {
-        createAndAddTextView();
-
-        ViewCompat.setLayoutDirection(mTextView, ViewCompat.LAYOUT_DIRECTION_RTL);
+        onView(withId(R.id.text_view)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL));
 
         final Drawable drawableStart = new TestDrawable(0xFFFF0000, 30, 20);
         final Drawable drawableEnd = new TestDrawable(0xFF0000FF, 25, 45);
         final Drawable drawableBottom = new TestDrawable(0xFF00FF00, 15, 35);
 
-        mTextView.setText(R.string.test_text_long);
-        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mTextView, drawableStart,
-                null, drawableEnd, drawableBottom);
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
+        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelativeWithIntrinsicBounds(
+                drawableStart, null, drawableEnd, drawableBottom));
 
         // Check to see whether our text view is under RTL mode
         if (ViewCompat.getLayoutDirection(mTextView) != ViewCompat.LAYOUT_DIRECTION_RTL) {
@@ -358,18 +292,16 @@
                 drawablesAbsolute[3].getBounds().height(), 35);
     }
 
-    @UiThreadTest
+    @Test
     @MediumTest
     public void testCompoundDrawablesRelativeWithIntrinsicBoundsById() throws Throwable {
-        createAndAddTextView();
-
-        mTextView.setText(R.string.test_text_long);
-        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mTextView,
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
+        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelativeWithIntrinsicBounds(
                 R.drawable.test_drawable_red, 0,
-                R.drawable.test_drawable_green, R.drawable.test_drawable_blue);
+                R.drawable.test_drawable_green, R.drawable.test_drawable_blue));
 
         final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
-        final Resources res = getActivity().getResources();
+        final Resources res = mActivityTestRule.getActivity().getResources();
 
         // The entire left drawable should be the specific red color
         TestUtils.assertAllPixelsOfColor("Compound drawable: left color",
@@ -404,17 +336,15 @@
                 res.getDimensionPixelSize(R.dimen.drawable_small_size));
     }
 
-    @UiThreadTest
+    @Test
     @MediumTest
     public void testCompoundDrawablesRelativeWithIntrinsicBoundsByIdRtl() throws Throwable {
-        createAndAddTextView();
+        onView(withId(R.id.text_view)).perform(setLayoutDirection(ViewCompat.LAYOUT_DIRECTION_RTL));
 
-        ViewCompat.setLayoutDirection(mTextView, ViewCompat.LAYOUT_DIRECTION_RTL);
-
-        mTextView.setText(R.string.test_text_long);
-        TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(mTextView,
+        onView(withId(R.id.text_view)).perform(setText(R.string.test_text_long));
+        onView(withId(R.id.text_view)).perform(setCompoundDrawablesRelativeWithIntrinsicBounds(
                 R.drawable.test_drawable_red, 0,
-                R.drawable.test_drawable_green, R.drawable.test_drawable_blue);
+                R.drawable.test_drawable_green, R.drawable.test_drawable_blue));
 
         // Check to see whether our text view is under RTL mode
         if (ViewCompat.getLayoutDirection(mTextView) != ViewCompat.LAYOUT_DIRECTION_RTL) {
@@ -423,7 +353,7 @@
         }
 
         final Drawable[] drawablesAbsolute = mTextView.getCompoundDrawables();
-        final Resources res = getActivity().getResources();
+        final Resources res = mActivityTestRule.getActivity().getResources();
 
         // The entire left / end drawable should be the specific green color
         TestUtils.assertAllPixelsOfColor("Compound drawable: left color",
diff --git a/v4/tests/java/android/support/v4/widget/test/TextViewTestActivity.java b/v4/tests/java/android/support/v4/widget/TextViewTestActivity.java
similarity index 68%
rename from v4/tests/java/android/support/v4/widget/test/TextViewTestActivity.java
rename to v4/tests/java/android/support/v4/widget/TextViewTestActivity.java
index 7366127..dcaab70 100644
--- a/v4/tests/java/android/support/v4/widget/test/TextViewTestActivity.java
+++ b/v4/tests/java/android/support/v4/widget/TextViewTestActivity.java
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
-package android.support.v4.widget.test;
+package android.support.v4.widget;
 
+import android.support.v4.BaseTestActivity;
+import android.support.v4.test.R;
 
-import android.app.Activity;
-
-public class TextViewTestActivity extends Activity {
-
+public class TextViewTestActivity extends BaseTestActivity {
+    @Override
+    protected int getContentViewLayoutResId() {
+        return R.layout.text_view_activity;
+    }
 }
diff --git a/v4/tests/res/layout/text_view_activity.xml b/v4/tests/res/layout/text_view_activity.xml
new file mode 100644
index 0000000..ba5d688
--- /dev/null
+++ b/v4/tests/res/layout/text_view_activity.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <TextView
+        android:id="@+id/text_view"
+        android:layout_width="200dip"
+        android:layout_height="60dip" />
+</FrameLayout>