Merge "Move to gradle 3.0, tools 2.2-beta1" into nyc-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 044a6ee..b30851b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6317,6 +6317,7 @@
     method public static android.content.res.ColorStateList getBackgroundTintList(android.view.View);
     method public static android.graphics.PorterDuff.Mode getBackgroundTintMode(android.view.View);
     method public static android.graphics.Rect getClipBounds(android.view.View);
+    method public static android.view.Display getDisplay(android.view.View);
     method public static float getElevation(android.view.View);
     method public static boolean getFitsSystemWindows(android.view.View);
     method public static int getImportantForAccessibility(android.view.View);
diff --git a/compat/gingerbread/android/support/v4/view/ViewCompatBase.java b/compat/gingerbread/android/support/v4/view/ViewCompatBase.java
index f4e113e..e7882bd 100644
--- a/compat/gingerbread/android/support/v4/view/ViewCompatBase.java
+++ b/compat/gingerbread/android/support/v4/view/ViewCompatBase.java
@@ -16,10 +16,13 @@
 
 package android.support.v4.view;
 
+import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
+import android.view.Display;
 import android.view.View;
 import android.view.ViewParent;
+import android.view.WindowManager;
 
 import java.lang.reflect.Field;
 
@@ -149,4 +152,14 @@
             }
         }
     }
+
+    static Display getDisplay(View view) {
+        if (isAttachedToWindow(view)) {
+            final WindowManager wm = (WindowManager) view.getContext().getSystemService(
+                    Context.WINDOW_SERVICE);
+            return wm.getDefaultDisplay();
+        }
+        return null;
+    }
+
 }
diff --git a/compat/java/android/support/v4/net/ConnectivityManagerCompat.java b/compat/java/android/support/v4/net/ConnectivityManagerCompat.java
index b7e0daa..90479c1 100644
--- a/compat/java/android/support/v4/net/ConnectivityManagerCompat.java
+++ b/compat/java/android/support/v4/net/ConnectivityManagerCompat.java
@@ -153,9 +153,15 @@
     /**
      * Returns if the currently active data network is metered. A network is
      * classified as metered when the user is sensitive to heavy data usage on
-     * that connection. You should check this before doing large data transfers,
-     * and warn the user or delay the operation until another network is
-     * available.
+     * that connection due to monetary costs, data limitations or
+     * battery/performance issues. You should check this before doing large
+     * data transfers, and warn the user or delay the operation until another
+     * network is available.
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+     *
+     * @return {@code true} if large transfers should be avoided, otherwise
+     *        {@code false}.
      */
     public static boolean isActiveNetworkMetered(ConnectivityManager cm) {
         return IMPL.isActiveNetworkMetered(cm);
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/java/android/support/v4/view/ViewCompat.java
index 4e14ec0..7af945d 100644
--- a/compat/java/android/support/v4/view/ViewCompat.java
+++ b/compat/java/android/support/v4/view/ViewCompat.java
@@ -31,6 +31,7 @@
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
 import android.util.Log;
+import android.view.Display;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -484,6 +485,7 @@
         void offsetTopAndBottom(View view, int offset);
         void offsetLeftAndRight(View view, int offset);
         void setPointerIcon(View view, PointerIconCompat pointerIcon);
+        Display getDisplay(View view);
     }
 
     static class BaseViewCompatImpl implements ViewCompatImpl {
@@ -1147,6 +1149,11 @@
         public void setPointerIcon(View view, PointerIconCompat pointerIcon) {
             // no-op
         }
+
+        @Override
+        public Display getDisplay(View view) {
+            return ViewCompatBase.getDisplay(view);
+        }
     }
 
     static class HCViewCompatImpl extends BaseViewCompatImpl {
@@ -1539,6 +1546,11 @@
         public boolean isPaddingRelative(View view) {
             return ViewCompatJellybeanMr1.isPaddingRelative(view);
         }
+
+        @Override
+        public Display getDisplay(View view) {
+            return ViewCompatJellybeanMr1.getDisplay(view);
+        }
     }
 
     static class JbMr2ViewCompatImpl extends JbMr1ViewCompatImpl {
@@ -3342,7 +3354,7 @@
      * <p>
      * Compatibility:
      * <ul>
-     *     <li>API < 18: Always returns {@code false}</li>
+     *     <li>API &lt; 18: Always returns {@code false}</li>
      * </ul>
      *
      * @return whether the view hierarchy is currently undergoing a layout pass
@@ -3364,7 +3376,7 @@
      * <p>
      * Compatibility:
      * <ul>
-     *     <li>API < 19: Always returns {@code false}</li>
+     *     <li>API &lt; 19: Always returns {@code false}</li>
      * </ul>
      *
      * @return true if layout direction has been resolved.
@@ -3391,7 +3403,7 @@
      * <p>
      * Compatibility:
      * <ul>
-     *     <li>API < 21: No-op
+     *     <li>API &lt; 21: No-op
      * </ul>
      *
      * @param z The visual z position of this view, in pixels.
@@ -3532,5 +3544,19 @@
         IMPL.setPointerIcon(view, pointerIcon);
     }
 
+    /**
+     * Gets the logical display to which the view's window has been attached.
+     * <p>
+     * Compatibility:
+     * <ul>
+     * <li>API &lt; 17: Returns the default display when the view is attached. Otherwise, null.
+     * </ul>
+     *
+     * @return The logical display, or null if the view is not currently attached to a window.
+     */
+    public static Display getDisplay(@NonNull View view) {
+        return IMPL.getDisplay(view);
+    }
+
     protected ViewCompat() {}
 }
diff --git a/compat/jellybean-mr1/android/support/v4/view/ViewCompatJellybeanMr1.java b/compat/jellybean-mr1/android/support/v4/view/ViewCompatJellybeanMr1.java
index 4865a8b..c39ef2a 100644
--- a/compat/jellybean-mr1/android/support/v4/view/ViewCompatJellybeanMr1.java
+++ b/compat/jellybean-mr1/android/support/v4/view/ViewCompatJellybeanMr1.java
@@ -17,6 +17,7 @@
 package android.support.v4.view;
 
 import android.graphics.Paint;
+import android.view.Display;
 import android.view.View;
 
 /**
@@ -63,4 +64,8 @@
     public static boolean isPaddingRelative(View view) {
         return view.isPaddingRelative();
     }
+
+    public static Display getDisplay(View view) {
+        return view.getDisplay();
+    }
 }
diff --git a/compat/tests/AndroidManifest.xml b/compat/tests/AndroidManifest.xml
index a46860a..8228476 100644
--- a/compat/tests/AndroidManifest.xml
+++ b/compat/tests/AndroidManifest.xml
@@ -37,6 +37,8 @@
         <activity
             android:name="android.support.v4.ThemedYellowActivity"
             android:theme="@style/YellowTheme" />
+
+        <activity android:name="android.support.v4.view.ViewCompatActivity"/>
     </application>
 
     <instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java b/compat/tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java
similarity index 98%
rename from tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java
rename to compat/tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java
index ea67375..8c1abcc 100644
--- a/tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java
+++ b/compat/tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java
@@ -20,15 +20,16 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.os.Bundle;
-import android.support.tests.R;
+import android.support.compat.test.R;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
 
-import java.util.Arrays;
 import java.util.List;
 
 /**
  * Tests for {@link android.support.v4.app.NotificationCompat.Action.WearableExtender}.
  */
+@MediumTest
 public class NotificationCompatActionWearableExtenderTest extends AndroidTestCase {
 
     private int mIcon;
diff --git a/tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java b/compat/tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java
similarity index 98%
rename from tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java
rename to compat/tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java
index 2a988ed..4e945dd 100644
--- a/tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java
+++ b/compat/tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java
@@ -20,8 +20,9 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.os.Bundle;
-import android.support.tests.R;
+import android.support.compat.test.R;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.Gravity;
 
 import java.util.Arrays;
@@ -30,6 +31,7 @@
 /**
  * Tests for {@link android.support.v4.app.NotificationCompat.WearableExtender}.
  */
+@MediumTest
 public class NotificationCompatWearableExtenderTest extends AndroidTestCase {
     public static final int CUSTOM_CONTENT_HEIGHT_DP = 256;
 
diff --git a/compat/tests/java/android/support/v4/content/ModernAsyncTaskTest.java b/compat/tests/java/android/support/v4/content/ModernAsyncTaskTest.java
index 2905df0..fc144c5 100644
--- a/compat/tests/java/android/support/v4/content/ModernAsyncTaskTest.java
+++ b/compat/tests/java/android/support/v4/content/ModernAsyncTaskTest.java
@@ -16,8 +16,11 @@
 
 package android.support.v4.content;
 
+import static org.junit.Assert.fail;
+
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -25,8 +28,6 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-import static org.junit.Assert.*;
-
 @RunWith(AndroidJUnit4.class)
 public class ModernAsyncTaskTest {
 
@@ -37,6 +38,7 @@
      *
      * @throws Throwable
      */
+    @LargeTest
     @Test
     public void testCancellationWithException() throws Throwable {
         final CountDownLatch readyToCancel = new CountDownLatch(1);
diff --git a/tests/java/android/support/v4/text/IcuCompatTest.java b/compat/tests/java/android/support/v4/text/IcuCompatTest.java
similarity index 93%
rename from tests/java/android/support/v4/text/IcuCompatTest.java
rename to compat/tests/java/android/support/v4/text/IcuCompatTest.java
index 6f7f459..0eb4ba1b 100644
--- a/tests/java/android/support/v4/text/IcuCompatTest.java
+++ b/compat/tests/java/android/support/v4/text/IcuCompatTest.java
@@ -16,10 +16,13 @@
 
 package android.support.v4.text;
 
+import android.test.suitebuilder.annotation.SmallTest;
+
 import junit.framework.TestCase;
 
 import java.util.Locale;
 
+@SmallTest
 public class IcuCompatTest extends TestCase {
     public void testMaximizeAndGetScript() {
         assertEquals("Latn", ICUCompat.maximizeAndGetScript(new Locale("en", "US")));
diff --git a/compat/tests/java/android/support/v4/view/ViewCompatActivity.java b/compat/tests/java/android/support/v4/view/ViewCompatActivity.java
new file mode 100644
index 0000000..28ff642
--- /dev/null
+++ b/compat/tests/java/android/support/v4/view/ViewCompatActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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.view;
+
+import android.support.compat.test.R;
+import android.support.v4.BaseTestActivity;
+
+public class ViewCompatActivity extends BaseTestActivity {
+
+    @Override
+    protected int getContentViewLayoutResId() {
+        return R.layout.view_compat_activity;
+    }
+
+}
diff --git a/compat/tests/java/android/support/v4/view/ViewCompatTest.java b/compat/tests/java/android/support/v4/view/ViewCompatTest.java
index c4217a5..0b102a6 100644
--- a/compat/tests/java/android/support/v4/view/ViewCompatTest.java
+++ b/compat/tests/java/android/support/v4/view/ViewCompatTest.java
@@ -15,18 +15,39 @@
  */
 package android.support.v4.view;
 
+import android.app.Activity;
 import android.support.test.runner.AndroidJUnit4;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.Display;
 import android.view.View;
+import android.support.v4.BaseInstrumentationTestCase;
+import android.support.compat.test.R;
+
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
 
 @RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ViewCompatTest {
+@MediumTest
+public class ViewCompatTest extends BaseInstrumentationTestCase<ViewCompatActivity> {
+
+    private View mView;
+
+    public ViewCompatTest() {
+        super(ViewCompatActivity.class);
+    }
+
+    @Before
+    public void setUp() {
+        final Activity activity = mActivityTestRule.getActivity();
+        mView = activity.findViewById(R.id.view);
+    }
+
     @Test
     public void testConstants() {
         // Compat constants must match core constants since they can be used interchangeably
@@ -34,4 +55,18 @@
         assertEquals("LTR constants", View.LAYOUT_DIRECTION_LTR, ViewCompat.LAYOUT_DIRECTION_LTR);
         assertEquals("RTL constants", View.LAYOUT_DIRECTION_RTL, ViewCompat.LAYOUT_DIRECTION_RTL);
     }
+
+    @Test
+    public void testGetDisplay() {
+        final Display display = ViewCompat.getDisplay(mView);
+        assertNotNull(display);
+    }
+
+    @Test
+    public void testGetDisplay_returnsNullForUnattachedView() {
+        final View view = new View(mActivityTestRule.getActivity());
+        final Display display = ViewCompat.getDisplay(view);
+        assertNull(display);
+    }
+
 }
diff --git a/tests/res/drawable/action_icon.xml b/compat/tests/res/drawable/action_icon.xml
similarity index 100%
rename from tests/res/drawable/action_icon.xml
rename to compat/tests/res/drawable/action_icon.xml
diff --git a/tests/res/drawable/action_icon2.xml b/compat/tests/res/drawable/action_icon2.xml
similarity index 100%
rename from tests/res/drawable/action_icon2.xml
rename to compat/tests/res/drawable/action_icon2.xml
diff --git a/tests/res/drawable/content_icon.xml b/compat/tests/res/drawable/content_icon.xml
similarity index 100%
rename from tests/res/drawable/content_icon.xml
rename to compat/tests/res/drawable/content_icon.xml
diff --git a/tests/res/drawable/content_icon2.xml b/compat/tests/res/drawable/content_icon2.xml
similarity index 100%
rename from tests/res/drawable/content_icon2.xml
rename to compat/tests/res/drawable/content_icon2.xml
diff --git a/compat/tests/res/layout/view_compat_activity.xml b/compat/tests/res/layout/view_compat_activity.xml
new file mode 100644
index 0000000..2a8acac
--- /dev/null
+++ b/compat/tests/res/layout/view_compat_activity.xml
@@ -0,0 +1,29 @@
+<?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
+    android:id="@+id/container"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <View
+        android:id="@+id/view"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:background="#f00"/>
+
+</FrameLayout>
diff --git a/core-utils/tests/AndroidManifest.xml b/core-utils/tests/AndroidManifest.xml
index d80e735..8a30a93 100644
--- a/core-utils/tests/AndroidManifest.xml
+++ b/core-utils/tests/AndroidManifest.xml
@@ -35,7 +35,13 @@
         <uses-library android:name="android.test.runner" />
         <activity android:name="android.support.v4.widget.test.TextViewTestActivity"/>
         <activity android:name="android.support.v4.widget.TestActivity"/>
-
+        <activity android:name="android.support.v4.provider.GrantActivity"
+                  android:label="_GrantActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
         <provider
             android:name="android.support.v4.content.FileProvider"
             android:authorities="moocow"
diff --git a/tests/java/android/support/v4/provider/DocumentFileTest.java b/core-utils/tests/java/android/support/v4/provider/DocumentFileTest.java
similarity index 98%
rename from tests/java/android/support/v4/provider/DocumentFileTest.java
rename to core-utils/tests/java/android/support/v4/provider/DocumentFileTest.java
index 26c10a4..9dd5a51 100644
--- a/tests/java/android/support/v4/provider/DocumentFileTest.java
+++ b/core-utils/tests/java/android/support/v4/provider/DocumentFileTest.java
@@ -22,7 +22,8 @@
 import android.os.Environment;
 import android.os.SystemClock;
 import android.test.AndroidTestCase;
-import android.util.Log;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -34,7 +35,11 @@
 
 /**
  * Tests for {@link DocumentFile}
+ *
  */
+// These tests fail so it is marked @Suppress. Fix is tracked in b/27168036
+@Suppress
+@MediumTest
 public class DocumentFileTest extends AndroidTestCase {
 
     private Uri treeUri;
diff --git a/tests/java/android/support/tests/GrantActivity.java b/core-utils/tests/java/android/support/v4/provider/GrantActivity.java
similarity index 97%
rename from tests/java/android/support/tests/GrantActivity.java
rename to core-utils/tests/java/android/support/v4/provider/GrantActivity.java
index 854357f..c4dbb27 100644
--- a/tests/java/android/support/tests/GrantActivity.java
+++ b/core-utils/tests/java/android/support/v4/provider/GrantActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.support.tests;
+package android.support.v4.provider;
 
 import android.app.Activity;
 import android.content.ContentResolver;
diff --git a/design/src/android/support/design/widget/CoordinatorLayout.java b/design/src/android/support/design/widget/CoordinatorLayout.java
index 201ed9b..268dbe3 100644
--- a/design/src/android/support/design/widget/CoordinatorLayout.java
+++ b/design/src/android/support/design/widget/CoordinatorLayout.java
@@ -624,13 +624,7 @@
         return result;
     }
 
-    private void prepareChildren(final boolean forceRefresh) {
-        if (!forceRefresh && mChildDag.size() == getChildCount()
-                && mChildDag.size() == mDependencySortedChildren.size()) {
-            // If we're not being forced and everything looks good, lets skip the call
-            return;
-        }
-
+    private void prepareChildren() {
         mDependencySortedChildren.clear();
         mChildDag.clear();
 
@@ -709,7 +703,7 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        prepareChildren(true);
+        prepareChildren();
         ensurePreDrawListener();
 
         final int paddingLeft = getPaddingLeft();
@@ -1395,12 +1389,10 @@
      * @param view the View to find dependents of to dispatch the call.
      */
     public void dispatchDependentViewsChanged(View view) {
-        prepareChildren(false);
-
         final List<View> dependents = mChildDag.getIncomingEdges(view);
         if (dependents != null && !dependents.isEmpty()) {
             for (int i = 0; i < dependents.size(); i++) {
-                final View child = (View) dependents.get(i);
+                final View child = dependents.get(i);
                 CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)
                         child.getLayoutParams();
                 CoordinatorLayout.Behavior b = lp.getBehavior();
@@ -1421,8 +1413,6 @@
      */
     @NonNull
     public List<View> getDependencies(@NonNull View child) {
-        prepareChildren(false);
-
         final List<View> dependencies = mChildDag.getOutgoingEdges(child);
         mTempDependenciesList.clear();
         if (dependencies != null) {
@@ -1441,8 +1431,6 @@
      */
     @NonNull
     public List<View> getDependents(@NonNull View child) {
-        prepareChildren(false);
-
         final List<View> edges = mChildDag.getIncomingEdges(child);
         mTempDependenciesList.clear();
         if (edges != null) {
@@ -1453,7 +1441,7 @@
 
     @VisibleForTesting
     final List<View> getDependencySortedChildren() {
-        prepareChildren(true);
+        prepareChildren();
         return Collections.unmodifiableList(mDependencySortedChildren);
     }
 
@@ -1483,8 +1471,7 @@
     /**
      * Check if the given child has any layout dependencies on other child views.
      */
-    boolean hasDependencies(View child) {
-        prepareChildren(false);
+    private boolean hasDependencies(View child) {
         return mChildDag.hasOutgoingEdges(child);
     }
 
diff --git a/design/tests/src/android/support/design/widget/BottomSheetBehaviorInitialStateTest.java b/design/tests/src/android/support/design/widget/BottomSheetBehaviorInitialStateTest.java
index 050739b..7cfce3d 100644
--- a/design/tests/src/android/support/design/widget/BottomSheetBehaviorInitialStateTest.java
+++ b/design/tests/src/android/support/design/widget/BottomSheetBehaviorInitialStateTest.java
@@ -24,11 +24,13 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class BottomSheetBehaviorInitialStateTest {
 
diff --git a/design/tests/src/android/support/design/widget/BottomSheetBehaviorTouchTest.java b/design/tests/src/android/support/design/widget/BottomSheetBehaviorTouchTest.java
index ea5872e..fe62e441 100644
--- a/design/tests/src/android/support/design/widget/BottomSheetBehaviorTouchTest.java
+++ b/design/tests/src/android/support/design/widget/BottomSheetBehaviorTouchTest.java
@@ -28,6 +28,7 @@
 import android.support.test.espresso.ViewAssertion;
 import android.support.test.espresso.action.ViewActions;
 import android.support.v4.view.MotionEventCompat;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.FrameLayout;
@@ -35,6 +36,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
+@MediumTest
 public class BottomSheetBehaviorTouchTest extends
         BaseInstrumentationTestCase<CoordinatorLayoutActivity> {
 
diff --git a/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java b/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
index 5471c38..f6350c1 100644
--- a/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
+++ b/design/tests/src/android/support/design/widget/CoordinatorLayoutTest.java
@@ -293,4 +293,45 @@
         // And assert that View B's Behavior was called appropriately
         verify(behavior, times(1)).onDependentViewRemoved(col, viewB, viewA);
     }
+
+    @Test
+    public void testGetDependenciesAfterDependentViewRemoved() {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        final CoordinatorLayout col = mActivityTestRule.getActivity().mCoordinatorLayout;
+
+        // Add two views, A & B, where B depends on A
+        final View viewA = new View(col.getContext());
+        final View viewB = new View(col.getContext());
+        final CoordinatorLayout.LayoutParams lpB = col.generateDefaultLayoutParams();
+        final CoordinatorLayout.Behavior behavior
+                = new CoordinatorLayoutUtils.DependentBehavior(viewA) {
+            @Override
+            public void onDependentViewRemoved(CoordinatorLayout parent, View child,
+                    View dependency) {
+                parent.getDependencies(child);
+            }
+        };
+        lpB.setBehavior(behavior);
+
+        // Now add views
+        instrumentation.runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                col.addView(viewA);
+                col.addView(viewB, lpB);
+            }
+        });
+
+        // Wait for a layout
+        instrumentation.waitForIdleSync();
+
+        // Now remove view A, which will trigger onDependentViewRemoved() on view B's behavior
+        instrumentation.runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                col.removeView(viewA);
+            }
+        });
+    }
+
 }
diff --git a/fragment/tests/java/android/support/v4/app/ChildFragmentStateTest.java b/fragment/tests/java/android/support/v4/app/ChildFragmentStateTest.java
index 78c3e28..188c3b1 100644
--- a/fragment/tests/java/android/support/v4/app/ChildFragmentStateTest.java
+++ b/fragment/tests/java/android/support/v4/app/ChildFragmentStateTest.java
@@ -21,7 +21,9 @@
 import android.support.v4.app.test.FragmentTestActivity.ParentFragment;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.SmallTest;
 
+@SmallTest
 public class ChildFragmentStateTest extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
     public ChildFragmentStateTest() {
         super(FragmentTestActivity.class);
diff --git a/fragment/tests/java/android/support/v4/app/NestedFragmentTest.java b/fragment/tests/java/android/support/v4/app/NestedFragmentTest.java
index cc884f99..84700ff 100644
--- a/fragment/tests/java/android/support/v4/app/NestedFragmentTest.java
+++ b/fragment/tests/java/android/support/v4/app/NestedFragmentTest.java
@@ -26,10 +26,12 @@
 import android.support.v4.app.test.FragmentTestActivity.ParentFragment;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.LargeTest;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+@LargeTest
 public class NestedFragmentTest extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
 
     ParentFragment mParentFragment;
diff --git a/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/AnimatedVectorDrawableTest.java b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/AnimatedVectorDrawableTest.java
index b2b720c..4105d82 100644
--- a/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/AnimatedVectorDrawableTest.java
+++ b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/AnimatedVectorDrawableTest.java
@@ -27,6 +27,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
@@ -47,6 +48,7 @@
 
 import static org.junit.Assert.*;
 
+@MediumTest
 @RunWith(AndroidJUnit4.class)
 public class AnimatedVectorDrawableTest {
     @Rule public final ActivityTestRule<DrawableStubActivity> mActivityTestRule;
diff --git a/samples/SupportTransitionDemos/Android.mk b/samples/SupportTransitionDemos/Android.mk
index 1d077a2..abc1ad9 100644
--- a/samples/SupportTransitionDemos/Android.mk
+++ b/samples/SupportTransitionDemos/Android.mk
@@ -21,6 +21,8 @@
 LOCAL_PACKAGE_NAME := SupportTransitionDemos
 LOCAL_MODULE_TAGS := samples
 LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 14
+LOCAL_DEX_PREOPT := false
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_STATIC_JAVA_LIBRARIES := \
         android-support-v4 \
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index bfdb396..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-LOCAL_SDK_VERSION := $(SUPPORT_CURRENT_SDK_VERSION)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-test \
-    android-support-v4 \
-    mockito-target
-
-LOCAL_PACKAGE_NAME := AndroidSupportTests
-
-include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
deleted file mode 100644
index 35314ae..0000000
--- a/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.support.tests">
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-
-        <activity android:name="android.support.tests.GrantActivity" android:label="_GrantActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
-    </application>
-
-    <instrumentation
-        android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="android.support.tests" />
-
-</manifest>
diff --git a/transition/ics/android/support/transition/TransitionManagerPort.java b/transition/ics/android/support/transition/TransitionManagerPort.java
index 7857f57..d6ca154 100644
--- a/transition/ics/android/support/transition/TransitionManagerPort.java
+++ b/transition/ics/android/support/transition/TransitionManagerPort.java
@@ -132,7 +132,7 @@
 
         if (runningTransitions != null && runningTransitions.size() > 0) {
             for (TransitionPort runningTransition : runningTransitions) {
-                runningTransition.pause();
+                runningTransition.pause(sceneRoot);
             }
         }
 
@@ -397,7 +397,7 @@
             ArrayList<TransitionPort> runningTransitions = getRunningTransitions().get(mSceneRoot);
             if (runningTransitions != null && runningTransitions.size() > 0) {
                 for (TransitionPort runningTransition : runningTransitions) {
-                    runningTransition.resume();
+                    runningTransition.resume(mSceneRoot);
                 }
             }
             mTransition.clearValues(true);
@@ -430,7 +430,7 @@
             mTransition.captureValues(mSceneRoot, false);
             if (previousRunningTransitions != null) {
                 for (TransitionPort runningTransition : previousRunningTransitions) {
-                    runningTransition.resume();
+                    runningTransition.resume(mSceneRoot);
                 }
             }
             mTransition.playTransition(mSceneRoot);
diff --git a/transition/ics/android/support/transition/TransitionPort.java b/transition/ics/android/support/transition/TransitionPort.java
index 31b4221..f6c3346 100644
--- a/transition/ics/android/support/transition/TransitionPort.java
+++ b/transition/ics/android/support/transition/TransitionPort.java
@@ -343,7 +343,8 @@
                             view = start.view;
                         }
                         if (animator != null) {
-                            AnimationInfo info = new AnimationInfo(view, getName(), infoValues);
+                            AnimationInfo info = new AnimationInfo(view, getName(),
+                                    WindowIdPort.getWindowId(sceneRoot), infoValues);
                             runningAnimators.put(animator, info);
                             mAnimators.add(animator);
                         }
@@ -788,13 +789,17 @@
      *
      * @hide
      */
-    public void pause() {
+    public void pause(View sceneRoot) {
         if (!mEnded) {
             ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
             int numOldAnims = runningAnimators.size();
+            WindowIdPort windowId = WindowIdPort.getWindowId(sceneRoot);
             for (int i = numOldAnims - 1; i >= 0; i--) {
-                Animator anim = runningAnimators.keyAt(i);
-//                anim.pause();
+                AnimationInfo info = runningAnimators.valueAt(i);
+                if (info.view != null && windowId.equals(info.windowId)) {
+                    Animator anim = runningAnimators.keyAt(i);
+                    anim.cancel(); // pause() is API Level 19
+                }
             }
             if (mListeners != null && mListeners.size() > 0) {
                 ArrayList<TransitionListener> tmpListeners =
@@ -815,14 +820,18 @@
      *
      * @hide
      */
-    public void resume() {
+    public void resume(View sceneRoot) {
         if (mPaused) {
             if (!mEnded) {
                 ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
                 int numOldAnims = runningAnimators.size();
+                WindowIdPort windowId = WindowIdPort.getWindowId(sceneRoot);
                 for (int i = numOldAnims - 1; i >= 0; i--) {
-                    Animator anim = runningAnimators.keyAt(i);
-//                    anim.resume();
+                    AnimationInfo info = runningAnimators.valueAt(i);
+                    if (info.view != null && windowId.equals(info.windowId)) {
+                        Animator anim = runningAnimators.keyAt(i);
+                        anim.end(); // resume() is API Level 19
+                    }
                 }
                 if (mListeners != null && mListeners.size() > 0) {
                     ArrayList<TransitionListener> tmpListeners =
@@ -1211,10 +1220,13 @@
 
         TransitionValues values;
 
-        AnimationInfo(View view, String name, TransitionValues values) {
+        WindowIdPort windowId;
+
+        AnimationInfo(View view, String name, WindowIdPort windowId, TransitionValues values) {
             this.view = view;
             this.name = name;
             this.values = values;
+            this.windowId = windowId;
         }
     }
 
diff --git a/transition/ics/android/support/transition/TransitionSetPort.java b/transition/ics/android/support/transition/TransitionSetPort.java
index eab84c9..97985a5 100644
--- a/transition/ics/android/support/transition/TransitionSetPort.java
+++ b/transition/ics/android/support/transition/TransitionSetPort.java
@@ -232,21 +232,21 @@
 
     /** @hide */
     @Override
-    public void pause() {
-        super.pause();
+    public void pause(View sceneRoot) {
+        super.pause(sceneRoot);
         int numTransitions = mTransitions.size();
         for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).pause();
+            mTransitions.get(i).pause(sceneRoot);
         }
     }
 
     /** @hide */
     @Override
-    public void resume() {
-        super.resume();
+    public void resume(View sceneRoot) {
+        super.resume(sceneRoot);
         int numTransitions = mTransitions.size();
         for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).resume();
+            mTransitions.get(i).resume(sceneRoot);
         }
     }
 
diff --git a/transition/ics/android/support/transition/WindowIdPort.java b/transition/ics/android/support/transition/WindowIdPort.java
new file mode 100644
index 0000000..f768b2e
--- /dev/null
+++ b/transition/ics/android/support/transition/WindowIdPort.java
@@ -0,0 +1,47 @@
+/*
+ * 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.transition;
+
+import android.os.IBinder;
+import android.support.annotation.NonNull;
+import android.view.View;
+
+
+/**
+ * Backport of WindowId.
+ *
+ * <p>Since the use of WindowId in Transition API is limited to identifying windows, we can just
+ * wrap a window token and use it as an identifier.</p>
+ */
+class WindowIdPort {
+
+    private final IBinder mToken;
+
+    private WindowIdPort(IBinder token) {
+        mToken = token;
+    }
+
+    static WindowIdPort getWindowId(@NonNull View view) {
+        return new WindowIdPort(view.getWindowToken());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof WindowIdPort && ((WindowIdPort) obj).mToken.equals(this.mToken);
+    }
+
+}
diff --git a/v17/leanback/res/values-bs-rBA/strings.xml b/v17/leanback/res/values-bs-rBA/strings.xml
index cdfe434..63a76e2 100644
--- a/v17/leanback/res/values-bs-rBA/strings.xml
+++ b/v17/leanback/res/values-bs-rBA/strings.xml
@@ -53,5 +53,5 @@
     <string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
     <string name="lb_time_separator" msgid="2763247350845477227">":"</string>
     <string name="lb_onboarding_get_started" msgid="6961440391306351139">"ZAPOČNITE"</string>
-    <string name="lb_onboarding_accessibility_next" msgid="2918313444257732434">"Sljedeća"</string>
+    <string name="lb_onboarding_accessibility_next" msgid="2918313444257732434">"Naprijed"</string>
 </resources>
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
index e804a5a..cca25db 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
@@ -16,6 +16,7 @@
 package android.support.v17.leanback.app;
 
 import android.support.v17.leanback.test.R;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.KeyEvent;
 
 import android.support.v17.leanback.widget.Presenter;
@@ -40,6 +41,7 @@
 /**
  * @hide from javadoc
  */
+@MediumTest
 @RunWith(AndroidJUnit4.class)
 public class BrowseFragmentTest {
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
index 1c007c6..5f362a3 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
@@ -18,6 +18,7 @@
 package android.support.v17.leanback.app;
 
 import android.support.v17.leanback.test.R;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.KeyEvent;
 
 import android.support.v17.leanback.widget.Presenter;
@@ -42,6 +43,7 @@
 /**
  * @hide from javadoc
  */
+@MediumTest
 @RunWith(AndroidJUnit4.class)
 public class BrowseSupportFragmentTest {
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedDatePickerTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedDatePickerTest.java
index 72f4f448..9cab5a1 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedDatePickerTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedDatePickerTest.java
@@ -25,6 +25,7 @@
 import android.support.v17.leanback.widget.VerticalGridView;
 import android.support.v17.leanback.widget.picker.DatePicker;
 import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
@@ -37,6 +38,7 @@
 import java.util.Date;
 import java.util.List;
 
+@MediumTest
 public class GuidedDatePickerTest extends
         ActivityInstrumentationTestCase2<GuidedStepAttributesTestActivity> {
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTest.java
index 72391d1..8387dbd 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/wizard/GuidedStepAttributesTest.java
@@ -22,6 +22,7 @@
 import android.support.v17.leanback.widget.GuidanceStylist;
 import android.support.v17.leanback.widget.GuidedAction;
 import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.util.Log;
 import android.view.KeyEvent;
 
@@ -30,9 +31,9 @@
 import java.util.Collections;
 import java.util.List;
 
+@MediumTest
 public class GuidedStepAttributesTest extends
-        ActivityInstrumentationTestCase2<GuidedStepAttributesTestActivity>
-{
+        ActivityInstrumentationTestCase2<GuidedStepAttributesTestActivity> {
     static final long TRANSITION_LENGTH = 1000;
 
     static final String TAG = "GuidedStepAttributesTest";
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
index 5fbcb0e..e1739ff 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetTest.java
@@ -27,6 +27,7 @@
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerViewAccessibilityDelegate;
 import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.text.Selection;
 import android.text.Spannable;
 import android.util.SparseArray;
@@ -44,6 +45,7 @@
 /**
  * @hide from javadoc
  */
+@MediumTest
 public class GridWidgetTest extends ActivityInstrumentationTestCase2<GridActivity> {
 
     private static final boolean HUMAN_DELAY = false;
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/PresenterTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/PresenterTest.java
index ba5ddda..b9a230a 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/PresenterTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/PresenterTest.java
@@ -19,6 +19,7 @@
 import android.support.v17.leanback.app.HeadersFragment;
 import android.support.v17.leanback.R;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.ContextThemeWrapper;
 import android.widget.FrameLayout;
 import android.view.View;
@@ -28,6 +29,7 @@
 import android.support.v17.leanback.widget.DividerPresenter;
 import android.view.ContextThemeWrapper;
 
+@MediumTest
 public class PresenterTest extends AndroidTestCase {
 
     public void testZoomFactors() throws Throwable {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ShadowOverlayContainerTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ShadowOverlayContainerTest.java
index e7ec4bf..3b99486 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ShadowOverlayContainerTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ShadowOverlayContainerTest.java
@@ -16,12 +16,13 @@
 package android.support.v17.leanback.widget;
 
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup.LayoutParams;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-
+@MediumTest
 public class ShadowOverlayContainerTest extends AndroidTestCase {
 
     public void testWrapContent() {
diff --git a/v7/appcompat/tests/res/layout/toolbar_decor_content.xml b/v7/appcompat/tests/res/layout/toolbar_decor_content.xml
index 91d93ca..db9935d 100644
--- a/v7/appcompat/tests/res/layout/toolbar_decor_content.xml
+++ b/v7/appcompat/tests/res/layout/toolbar_decor_content.xml
@@ -32,7 +32,8 @@
         <EditText
                 android:id="@+id/editText"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"/>
+                android:layout_height="wrap_content"
+                android:imeOptions="flagNoExtractUi"/>
 
     </android.support.v7.custom.FitWindowsContentLayout>
 
diff --git a/v7/appcompat/tests/src/android/support/v7/app/BaseKeyboardShortcutsTestCase.java b/v7/appcompat/tests/src/android/support/v7/app/BaseKeyboardShortcutsTestCase.java
index 97383c3..9c50144 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/BaseKeyboardShortcutsTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/BaseKeyboardShortcutsTestCase.java
@@ -16,7 +16,10 @@
 
 package android.support.v7.app;
 
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import android.os.SystemClock;
 import android.support.v7.appcompat.test.R;
@@ -27,10 +30,7 @@
 import android.view.MenuItem;
 import android.view.View;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import org.junit.Test;
 
 public abstract class BaseKeyboardShortcutsTestCase<A extends BaseTestActivity>
         extends BaseInstrumentationTestCase<A> {
@@ -63,66 +63,4 @@
         assertNotNull("Options item selected", selectedItem);
         assertEquals("Correct options item selected", selectedItem.getItemId(), expectedId);
     }
-
-    @Test
-    @SmallTest
-    public void testAccessActionBar() throws Throwable {
-        final BaseTestActivity activity = getActivity();
-
-        final View editText = activity.findViewById(R.id.editText);
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                editText.requestFocus();
-            }
-        });
-
-        getInstrumentation().waitForIdleSync();
-        sendControlChar('<');
-        getInstrumentation().waitForIdleSync();
-
-        // Should jump to the action bar after control-<
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                assertFalse(editText.hasFocus());
-                final View toolbar = activity.findViewById(R.id.toolbar);
-                assertTrue(toolbar.hasFocus());
-            }
-        });
-        getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
-        getInstrumentation().waitForIdleSync();
-
-        // Should jump to the first view again.
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                assertTrue(editText.hasFocus());
-            }
-        });
-        getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
-        getInstrumentation().waitForIdleSync();
-
-        // Now it shouldn't go up to action bar -- it doesn't allow taking focus once left
-        runTestOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                assertTrue(editText.hasFocus());
-            }
-        });
-    }
-
-    private void sendControlChar(char key) throws Throwable {
-        KeyEvent tempEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
-        KeyCharacterMap map = tempEvent.getKeyCharacterMap();
-        KeyEvent[] events = map.getEvents(new char[] {key});
-        for (int i = 0; i < events.length; i++) {
-            long time = SystemClock.uptimeMillis();
-            KeyEvent event = events[i];
-            KeyEvent controlKey = new KeyEvent(time, time, event.getAction(), event.getKeyCode(),
-                    event.getRepeatCount(), event.getMetaState() | KeyEvent.META_CTRL_ON);
-            getInstrumentation().sendKeySync(controlKey);
-        }
-    }
-
 }
diff --git a/v7/appcompat/tests/src/android/support/v7/app/DialogTestCase.java b/v7/appcompat/tests/src/android/support/v7/app/DialogTestCase.java
index 2381821..a165d53 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/DialogTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/DialogTestCase.java
@@ -20,10 +20,12 @@
 
 import android.app.Dialog;
 import android.os.Bundle;
+import android.test.suitebuilder.annotation.MediumTest;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+@MediumTest
 public class DialogTestCase extends BaseInstrumentationTestCase<WindowDecorActionBarActivity> {
 
     public DialogTestCase() {
diff --git a/v7/appcompat/tests/src/android/support/v7/app/KeyboardShortcutsTestCaseWithToolbar.java b/v7/appcompat/tests/src/android/support/v7/app/KeyboardShortcutsTestCaseWithToolbar.java
index 16c37a2..a27b20b 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/KeyboardShortcutsTestCaseWithToolbar.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/KeyboardShortcutsTestCaseWithToolbar.java
@@ -16,9 +16,74 @@
 
 package android.support.v7.app;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.SystemClock;
+import android.support.v7.testutils.BaseTestActivity;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.View;
+
+import org.junit.Test;
+
 public class KeyboardShortcutsTestCaseWithToolbar
         extends BaseKeyboardShortcutsTestCase<ToolbarActionBarActivity> {
     public KeyboardShortcutsTestCaseWithToolbar() {
         super(ToolbarActionBarActivity.class);
     }
+
+    @Test
+    @SmallTest
+    public void testAccessActionBar() throws Throwable {
+        final BaseTestActivity activity = getActivity();
+
+        final View editText = activity.findViewById(android.support.v7.appcompat.test.R.id.editText);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                editText.requestFocus();
+            }
+        });
+
+        getInstrumentation().waitForIdleSync();
+        sendControlChar('<');
+        getInstrumentation().waitForIdleSync();
+
+        // Should jump to the action bar after control-<
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(editText.hasFocus());
+                final View toolbar = activity.findViewById(android.support.v7.appcompat.test.R.id.toolbar);
+                assertTrue(toolbar.hasFocus());
+            }
+        });
+        getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
+        getInstrumentation().waitForIdleSync();
+
+        // Should jump to the first view again.
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(editText.hasFocus());
+            }
+        });
+        getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
+        getInstrumentation().waitForIdleSync();
+    }
+
+    private void sendControlChar(char key) throws Throwable {
+        KeyEvent tempEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
+        KeyCharacterMap map = tempEvent.getKeyCharacterMap();
+        KeyEvent[] events = map.getEvents(new char[] {key});
+        for (int i = 0; i < events.length; i++) {
+            long time = SystemClock.uptimeMillis();
+            KeyEvent event = events[i];
+            KeyEvent controlKey = new KeyEvent(time, time, event.getAction(), event.getKeyCode(),
+                    event.getRepeatCount(), event.getMetaState() | KeyEvent.META_CTRL_ON);
+            getInstrumentation().sendKeySync(controlKey);
+        }
+    }
 }
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
index 55d0d39..bb712d1 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
@@ -23,6 +23,8 @@
 import android.support.test.espresso.ViewInteraction;
 import android.support.v7.appcompat.test.R;
 import android.support.v7.testutils.TestUtilsMatchers;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.widget.ImageView;
 
 import org.junit.Test;
@@ -31,6 +33,7 @@
  * In addition to all tinting-related tests done by the base class, this class provides
  * tests specific to {@link AppCompatImageView} class.
  */
+@SmallTest
 public class AppCompatImageViewTest
         extends AppCompatBaseViewTest<AppCompatImageViewActivity, AppCompatImageView> {
     public AppCompatImageViewTest() {
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/TintResourcesTest.java b/v7/appcompat/tests/src/android/support/v7/widget/TintResourcesTest.java
index 81cac576..673a6aa 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/TintResourcesTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/TintResourcesTest.java
@@ -23,9 +23,11 @@
 import android.graphics.drawable.Drawable;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.app.BaseInstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import org.junit.Test;
 
+@SmallTest
 public class TintResourcesTest extends BaseInstrumentationTestCase<AppCompatActivity> {
 
     public TintResourcesTest() {
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
index 5f7f244..7a7a4d4 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
@@ -1107,11 +1107,21 @@
         return Looper.myLooper() == Looper.getMainLooper();
     }
 
-    public void runTestOnUiThread(Runnable r) throws Throwable {
+    public void runTestOnUiThread(final Runnable r) throws Throwable {
         if (Looper.myLooper() == Looper.getMainLooper()) {
             r.run();
         } else {
-            InstrumentationRegistry.getInstrumentation().runOnMainSync(r);
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        r.run();
+                    } catch (Throwable t) {
+                        postExceptionToInstrumentation(t);
+                    }
+                }
+            });
+            checkForMainThreadException();
         }
     }
 
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/DefaultItemAnimatorTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/DefaultItemAnimatorTest.java
index 4ace4ca..1ebd17f 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/DefaultItemAnimatorTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/DefaultItemAnimatorTest.java
@@ -440,13 +440,4 @@
     private interface ThrowingRunnable {
         void run() throws Throwable;
     }
-
-    @Override
-    public void runTestOnUiThread(Runnable r) throws Throwable {
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            r.run();
-        } else {
-            super.runTestOnUiThread(r);
-        }
-    }
 }
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerWrapContentTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerWrapContentTest.java
index 6f77867..1703dcd 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerWrapContentTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerWrapContentTest.java
@@ -27,6 +27,7 @@
 import android.graphics.Rect;
 import android.os.Build;
 import android.support.test.filters.SdkSuppress;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.Gravity;
 import android.view.View;
 
@@ -37,6 +38,7 @@
 import java.util.Arrays;
 import java.util.List;
 
+@MediumTest
 @RunWith(Parameterized.class)
 public class GridLayoutManagerWrapContentTest extends BaseWrapContentTest {
     private boolean mHorizontal = false;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewFocusRecoveryTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewFocusRecoveryTest.java
index ea1573d3..768f2f1 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewFocusRecoveryTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewFocusRecoveryTest.java
@@ -25,6 +25,7 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v7.recyclerview.test.R;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -43,6 +44,7 @@
  * represent the same item in the adapter. Keeping a focused view visible is up-to-the
  * LayoutManager and all FW LayoutManagers already have tests for it.
  */
+@MediumTest
 @RunWith(Parameterized.class)
 public class RecyclerViewFocusRecoveryTest extends BaseRecyclerViewInstrumentationTest {
     TestLayoutManager mLayoutManager;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerWrapContentTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerWrapContentTest.java
index 5e07dca..5021ecb 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerWrapContentTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerWrapContentTest.java
@@ -25,6 +25,7 @@
 import android.graphics.Rect;
 import android.os.Build;
 import android.support.test.filters.SdkSuppress;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.Gravity;
 import android.view.View;
 
@@ -35,6 +36,7 @@
 import java.util.Arrays;
 import java.util.List;
 
+@MediumTest
 @RunWith(Parameterized.class)
 public class StaggeredGridLayoutManagerWrapContentTest extends BaseWrapContentTest {
     int mOrientation = StaggeredGridLayoutManager.VERTICAL;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/WrapContentBasicTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/WrapContentBasicTest.java
index b485fa6..56cd024 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/WrapContentBasicTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/WrapContentBasicTest.java
@@ -26,6 +26,7 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.view.Display;
 import android.view.View;
 import android.view.ViewGroup;
@@ -40,6 +41,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+@MediumTest
 @RunWith(AndroidJUnit4.class)
 public class WrapContentBasicTest extends AndroidTestCase {