Merge "Add ViewCompat.getDisplay" into nyc-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index d23b9e9..b30851b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -157,6 +157,8 @@
   public final class CustomTabsIntent {
     method public static int getMaxToolbarItems();
     method public void launchUrl(android.app.Activity, android.net.Uri);
+    method public static android.content.Intent setAlwaysUseBrowserUI(android.content.Intent);
+    method public static boolean shouldAlwaysUseBrowserUI(android.content.Intent);
     field public static final java.lang.String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
     field public static final java.lang.String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
     field public static final java.lang.String EXTRA_DEFAULT_SHARE_MENU_ITEM = "android.support.customtabs.extra.SHARE_MENU_ITEM";
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/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
index 123333c..02fd3dd 100644
--- a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -233,6 +233,10 @@
      * near the top of the refreshing content. This position is a consistent
      * location, but can be adjusted in either direction based on whether or not
      * there is a toolbar or actionbar present.
+     * <p>
+     * <strong>Note:</strong> Calling this will reset the position of the refresh indicator to
+     * <code>start</code>.
+     * </p>
      *
      * @param scale Set to true if there is no view at a higher z-order than where the progress
      *              spinner is set to appear. Setting it to true will cause indicator to be scaled
@@ -245,11 +249,11 @@
      */
     public void setProgressViewOffset(boolean scale, int start, int end) {
         mScale = scale;
-        mCircleView.setVisibility(View.GONE);
-        mOriginalOffsetTop = mCurrentTargetOffsetTop = start;
+        mOriginalOffsetTop = start;
         mSpinnerFinalOffset = end;
         mUsingCustomStart = true;
-        mCircleView.invalidate();
+        reset();
+        mRefreshing = false;
     }
 
     /**
diff --git a/customtabs/src/android/support/customtabs/CustomTabsIntent.java b/customtabs/src/android/support/customtabs/CustomTabsIntent.java
index d2aabbe..75214ee 100644
--- a/customtabs/src/android/support/customtabs/CustomTabsIntent.java
+++ b/customtabs/src/android/support/customtabs/CustomTabsIntent.java
@@ -46,6 +46,19 @@
 public final class CustomTabsIntent {
 
     /**
+     * Indicates that the user explicitly opted out of Custom Tabs in the calling application.
+     * <p>
+     * If an application provides a mechanism for users to opt out of Custom Tabs, this extra should
+     * be provided with {@link Intent#FLAG_ACTIVITY_NEW_TASK} to ensure the browser does not attempt
+     * to trigger any Custom Tab-like experiences as a result of the VIEW intent.
+     * <p>
+     * If this extra is present with {@link Intent#FLAG_ACTIVITY_NEW_TASK}, all Custom Tabs
+     * customizations will be ignored.
+     */
+    private static final String EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS =
+            "android.support.customtabs.extra.user_opt_out";
+
+    /**
      * Extra used to match the session. This has to be included in the intent to open in
      * a custom tab. This is the same IBinder that gets passed to ICustomTabsService#newSession.
      * Null if there is no need to match any service side sessions with the intent.
@@ -520,4 +533,30 @@
     public static int getMaxToolbarItems() {
         return MAX_TOOLBAR_ITEMS;
     }
+
+    /**
+     * Adds the necessary flags and extras to signal any browser supporting custom tabs to use the
+     * browser UI at all times and avoid showing custom tab like UI. Calling this with an intent
+     * will override any custom tabs related customizations.
+     * @param intent The intent to modify for always showing browser UI.
+     * @return The same intent with the necessary flags and extras added.
+     */
+    public static Intent setAlwaysUseBrowserUI(Intent intent) {
+        if (intent == null) intent = new Intent(Intent.ACTION_VIEW);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.putExtra(EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, true);
+        return intent;
+    }
+
+    /**
+     * Whether a browser receiving the given intent should always use browser UI and avoid using any
+     * custom tabs UI.
+     *
+     * @param intent The intent to check for the required flags and extras.
+     * @return Whether the browser UI should be used exclusively.
+     */
+    public static boolean shouldAlwaysUseBrowserUI(Intent intent) {
+        return intent.getBooleanExtra(EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, false)
+                && (intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0;
+    }
 }
diff --git a/design/src/android/support/design/widget/TabLayout.java b/design/src/android/support/design/widget/TabLayout.java
index 74092a0..35d59ff 100755
--- a/design/src/android/support/design/widget/TabLayout.java
+++ b/design/src/android/support/design/widget/TabLayout.java
@@ -1135,9 +1135,13 @@
                     setSelectedTabView(newPosition);
                 }
             }
-            dispatchTabUnselected(currentTab);
+            if (currentTab != null) {
+                dispatchTabUnselected(currentTab);
+            }
             mSelectedTab = tab;
-            dispatchTabSelected(tab);
+            if (tab != null) {
+                dispatchTabSelected(tab);
+            }
         }
     }
 
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/TabLayoutTest.java b/design/tests/src/android/support/design/widget/TabLayoutTest.java
index 2f3ad60..69bf429 100755
--- a/design/tests/src/android/support/design/widget/TabLayoutTest.java
+++ b/design/tests/src/android/support/design/widget/TabLayoutTest.java
@@ -20,6 +20,12 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.support.design.test.R;
 import android.support.test.annotation.UiThreadTest;
@@ -82,12 +88,17 @@
     @Test
     @UiThreadTest
     public void testTabWithCustomLayoutSelection1() {
+        final TabLayout.OnTabSelectedListener mockListener =
+                mock(TabLayout.OnTabSelectedListener.class);
         final LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
 
         final TabLayout tabLayout = (TabLayout) inflater.inflate(R.layout.design_tabs, null);
+        tabLayout.addOnTabSelectedListener(mockListener);
         final TabLayout.Tab tab = tabLayout.newTab();
         tab.setCustomView(R.layout.design_tab_item_custom);
         tabLayout.addTab(tab);
+        verify(mockListener, times(1)).onTabSelected(eq(tab));
+        verify(mockListener, times(0)).onTabUnselected(any(TabLayout.Tab.class));
 
         assertNotNull("Tab has custom view", tab.getCustomView());
         assertEquals("First tab is selected", 0, tabLayout.getSelectedTabPosition());
@@ -97,11 +108,16 @@
     @Test
     @UiThreadTest
     public void testTabWithCustomLayoutSelection2() {
+        final TabLayout.OnTabSelectedListener mockListener =
+                mock(TabLayout.OnTabSelectedListener.class);
         final LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
 
         final TabLayout tabLayout = (TabLayout) inflater.inflate(R.layout.design_tabs, null);
+        tabLayout.addOnTabSelectedListener(mockListener);
         final TabLayout.Tab tab = tabLayout.newTab();
         tabLayout.addTab(tab);
+        verify(mockListener, times(1)).onTabSelected(eq(tab));
+        verify(mockListener, times(0)).onTabUnselected(any(TabLayout.Tab.class));
         tab.setCustomView(R.layout.design_tab_item_custom);
 
         assertNotNull("Tab has custom view", tab.getCustomView());
@@ -112,12 +128,23 @@
     @Test
     @UiThreadTest
     public void testMultipleTabsWithCustomLayoutSelection1() {
+        final TabLayout.OnTabSelectedListener mockListener =
+                mock(TabLayout.OnTabSelectedListener.class);
         final LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
         final TabLayout tabs = (TabLayout) inflater.inflate(R.layout.design_tabs, null);
+        tabs.addOnTabSelectedListener(mockListener);
 
-        tabs.addTab(tabs.newTab().setCustomView(R.layout.design_tab_item_custom));
-        tabs.addTab(tabs.newTab().setCustomView(R.layout.design_tab_item_custom), true);
-        tabs.addTab(tabs.newTab().setCustomView(R.layout.design_tab_item_custom));
+        final TabLayout.Tab tab1 = tabs.newTab().setCustomView(R.layout.design_tab_item_custom);
+        tabs.addTab(tab1);
+        verify(mockListener, times(1)).onTabSelected(eq(tab1));
+        verify(mockListener, times(0)).onTabUnselected(any(TabLayout.Tab.class));
+        final TabLayout.Tab tab2 = tabs.newTab().setCustomView(R.layout.design_tab_item_custom);
+        tabs.addTab(tab2, true);
+        verify(mockListener, times(1)).onTabSelected(eq(tab2));
+        verify(mockListener, times(1)).onTabUnselected(eq(tab1));
+        final TabLayout.Tab tab3 = tabs.newTab().setCustomView(R.layout.design_tab_item_custom);
+        tabs.addTab(tab3);
+        verifyNoMoreInteractions(mockListener);
 
         assertEquals("Second tab is selected", 1, tabs.getSelectedTabPosition());
         assertTabCustomViewSelected(tabs);
@@ -126,12 +153,23 @@
     @Test
     @UiThreadTest
     public void testMultipleTabsWithCustomLayoutSelection2() {
+        final TabLayout.OnTabSelectedListener mockListener =
+                mock(TabLayout.OnTabSelectedListener.class);
         final LayoutInflater inflater = LayoutInflater.from(mActivityTestRule.getActivity());
         final TabLayout tabs = (TabLayout) inflater.inflate(R.layout.design_tabs, null);
+        tabs.addOnTabSelectedListener(mockListener);
 
-        tabs.addTab(tabs.newTab());
-        tabs.addTab(tabs.newTab(), true);
-        tabs.addTab(tabs.newTab());
+        final TabLayout.Tab tab1 = tabs.newTab();
+        tabs.addTab(tab1);
+        verify(mockListener, times(1)).onTabSelected(eq(tab1));
+        verify(mockListener, times(0)).onTabUnselected(any(TabLayout.Tab.class));
+        final TabLayout.Tab tab2 = tabs.newTab();
+        tabs.addTab(tab2, true);
+        verify(mockListener, times(1)).onTabSelected(eq(tab2));
+        verify(mockListener, times(1)).onTabUnselected(eq(tab1));
+        final TabLayout.Tab tab3 = tabs.newTab();
+        tabs.addTab(tab3);
+        verifyNoMoreInteractions(mockListener);
 
         tabs.getTabAt(0).setCustomView(R.layout.design_tab_item_custom);
         tabs.getTabAt(1).setCustomView(R.layout.design_tab_item_custom);
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/Support13Demos/AndroidManifest.xml b/samples/Support13Demos/AndroidManifest.xml
index dfa4e64..01bab26 100644
--- a/samples/Support13Demos/AndroidManifest.xml
+++ b/samples/Support13Demos/AndroidManifest.xml
@@ -87,5 +87,13 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.inputmethod.CommitContentSupport"
+                 android:label="@string/commit_content_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv13.SUPPORT13_SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
     </application>
 </manifest>
diff --git a/samples/Support13Demos/res/layout/commit_content.xml b/samples/Support13Demos/res/layout/commit_content.xml
new file mode 100644
index 0000000..414df18
--- /dev/null
+++ b/samples/Support13Demos/res/layout/commit_content.xml
@@ -0,0 +1,142 @@
+<?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:layout_width="match_parent"
+             android:layout_height="match_parent"
+             android:background="@android:color/black">
+
+    <WebView
+        android:id="@+id/commit_content_webview"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:background="@android:color/transparent" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="#77000000"
+        android:orientation="vertical">
+
+        <HorizontalScrollView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:fadeScrollbars="false"
+            android:scrollbars="horizontal">
+
+            <TableLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <TableRow>
+
+                    <TextView
+                        android:layout_column="1"
+                        android:gravity="end"
+                        android:padding="3dip"
+                        android:text="MIME"
+                        android:textColor="@android:color/white"
+                        android:textStyle="bold" />
+
+                    <TextView
+                        android:id="@+id/text_commit_content_mime_types"
+                        android:padding="3dip"
+                        android:textColor="@android:color/white" />
+                </TableRow>
+
+                <TableRow>
+
+                    <TextView
+                        android:layout_column="1"
+                        android:gravity="end"
+                        android:padding="3dip"
+                        android:text="Label"
+                        android:textColor="@android:color/white"
+                        android:textStyle="bold" />
+
+                    <TextView
+                        android:id="@+id/text_commit_content_label"
+                        android:padding="3dip"
+                        android:textColor="@android:color/white" />
+                </TableRow>
+
+                <TableRow>
+
+                    <TextView
+                        android:layout_column="1"
+                        android:gravity="end"
+                        android:padding="3dip"
+                        android:text="URI"
+                        android:textColor="@android:color/white"
+                        android:textStyle="bold" />
+
+                    <TextView
+                        android:id="@+id/text_commit_content_content_uri"
+                        android:padding="3dip"
+                        android:textColor="@android:color/white" />
+                </TableRow>
+
+                <TableRow>
+
+                    <TextView
+                        android:layout_column="1"
+                        android:gravity="end"
+                        android:padding="3dip"
+                        android:text="Link"
+                        android:textColor="@android:color/white"
+                        android:textStyle="bold" />
+
+                    <TextView
+                        android:id="@+id/text_commit_content_link_uri"
+                        android:padding="3dip"
+                        android:textColor="@android:color/white" />
+                </TableRow>
+
+                <TableRow>
+
+                    <TextView
+                        android:layout_column="1"
+                        android:gravity="end"
+                        android:padding="3dip"
+                        android:text="Flags"
+                        android:textColor="@android:color/white"
+                        android:textStyle="bold" />
+
+                    <TextView
+                        android:id="@+id/text_commit_content_link_flags"
+                        android:padding="3dip"
+                        android:textColor="@android:color/white" />
+                </TableRow>
+            </TableLayout>
+        </HorizontalScrollView>
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:fadeScrollbars="false"
+            android:scrollbars="vertical">
+
+            <LinearLayout
+                android:id="@+id/commit_content_sample_edit_boxes"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical" />
+        </ScrollView>
+
+    </LinearLayout>
+
+</FrameLayout>
diff --git a/samples/Support13Demos/res/values/strings.xml b/samples/Support13Demos/res/values/strings.xml
index 92316d0..30b6a18 100644
--- a/samples/Support13Demos/res/values/strings.xml
+++ b/samples/Support13Demos/res/values/strings.xml
@@ -36,4 +36,7 @@
     <string name="fragment_state_pager_support">Fragment/State Pager</string>
 
     <string name="action_bar_tabs_pager">Fragment/Action Bar Tabs Pager</string>
+
+    <string name="commit_content_support">View/Input Method/Commit Content</string>
+
 </resources>
diff --git a/samples/Support13Demos/src/com/example/android/supportv13/view/inputmethod/CommitContentSupport.java b/samples/Support13Demos/src/com/example/android/supportv13/view/inputmethod/CommitContentSupport.java
new file mode 100644
index 0000000..29f8a91f
--- /dev/null
+++ b/samples/Support13Demos/src/com/example/android/supportv13/view/inputmethod/CommitContentSupport.java
@@ -0,0 +1,258 @@
+/*
+ * 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 com.example.android.supportv13.view.inputmethod;
+
+import com.example.android.supportv13.R;
+
+import android.support.v13.view.inputmethod.EditorInfoCompat;
+import android.support.v13.view.inputmethod.InputConnectionCompat;
+import android.support.v13.view.inputmethod.InputContentInfoCompat;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.webkit.WebView;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import static android.widget.LinearLayout.VERTICAL;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class CommitContentSupport extends Activity {
+    private static final String INPUT_CONTENT_INFO_KEY = "COMMIT_CONTENT_INPUT_CONTENT_INFO";
+    private static final String COMMIT_CONTENT_FLAGS_KEY = "COMMIT_CONTENT_FLAGS";
+
+    private static String TAG = "CommitContentSupport";
+
+    private WebView mWebView;
+    private TextView mLabel;
+    private TextView mContentUri;
+    private TextView mLinkUri;
+    private TextView mMimeTypes;
+    private TextView mFlags;
+
+    private InputContentInfoCompat mCurrentInputContentInfo;
+    private int mCurrentFlags;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.commit_content);
+
+        final LinearLayout layout =
+                (LinearLayout) findViewById(R.id.commit_content_sample_edit_boxes);
+
+        // This declares that the IME cannot commit any content with
+        // InputConnectionCompat#commitContent().
+        layout.addView(createEditTextWithContentMimeTypes(null));
+
+        // This declares that the IME can commit contents with
+        // InputConnectionCompat#commitContent() if they match "image/gif".
+        layout.addView(createEditTextWithContentMimeTypes(new String[]{"image/gif"}));
+
+        // This declares that the IME can commit contents with
+        // InputConnectionCompat#commitContent() if they match "image/png".
+        layout.addView(createEditTextWithContentMimeTypes(new String[]{"image/png"}));
+
+        // This declares that the IME can commit contents with
+        // InputConnectionCompat#commitContent() if they match "image/jpeg".
+        layout.addView(createEditTextWithContentMimeTypes(new String[]{"image/jpeg"}));
+
+        // This declares that the IME can commit contents with
+        // InputConnectionCompat#commitContent() if they match "image/webp".
+        layout.addView(createEditTextWithContentMimeTypes(new String[]{"image/webp"}));
+
+        // This declares that the IME can commit contents with
+        // InputConnectionCompat#commitContent() if they match "image/png", "image/gif",
+        // "image/jpeg", or "image/webp".
+        layout.addView(createEditTextWithContentMimeTypes(
+                new String[]{"image/png", "image/gif", "image/jpeg", "image/webp"}));
+
+        mWebView = (WebView) findViewById(R.id.commit_content_webview);
+        mMimeTypes = (TextView) findViewById(R.id.text_commit_content_mime_types);
+        mLabel = (TextView) findViewById(R.id.text_commit_content_label);
+        mContentUri = (TextView) findViewById(R.id.text_commit_content_content_uri);
+        mLinkUri = (TextView) findViewById(R.id.text_commit_content_link_uri);
+        mFlags = (TextView) findViewById(R.id.text_commit_content_link_flags);
+
+        if (savedInstanceState != null) {
+            final InputContentInfoCompat previousInputContentInfo = InputContentInfoCompat.wrap(
+                    savedInstanceState.getParcelable(INPUT_CONTENT_INFO_KEY));
+            final int previousFlags = savedInstanceState.getInt(COMMIT_CONTENT_FLAGS_KEY);
+            if (previousInputContentInfo != null) {
+                onCommitContentInternal(previousInputContentInfo, previousFlags);
+            }
+        }
+    }
+
+    private boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags,
+            Bundle opts, String[] contentMimeTypes) {
+        // Clear the temporary permission (if any).  See below about why we do this here.
+        try {
+            if (mCurrentInputContentInfo != null) {
+                mCurrentInputContentInfo.releasePermission();
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "InputContentInfo#releasePermission() failed.", e);
+        } finally {
+            mCurrentInputContentInfo = null;
+        }
+
+        mWebView.loadUrl("about:blank");
+        mMimeTypes.setText("");
+        mContentUri.setText("");
+        mLabel.setText("");
+        mLinkUri.setText("");
+        mFlags.setText("");
+
+        boolean supported = false;
+        for (final String mimeType : contentMimeTypes) {
+            if (inputContentInfo.getDescription().hasMimeType(mimeType)) {
+                supported = true;
+                break;
+            }
+        }
+        if (!supported) {
+            return false;
+        }
+
+        return onCommitContentInternal(inputContentInfo, flags);
+    }
+
+    private boolean onCommitContentInternal(InputContentInfoCompat inputContentInfo, int flags) {
+        if ((flags & InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
+            try {
+                inputContentInfo.requestPermission();
+            } catch (Exception e) {
+                Log.e(TAG, "InputContentInfo#requestPermission() failed.", e);
+                return false;
+            }
+        }
+
+        mMimeTypes.setText(
+                Arrays.toString(inputContentInfo.getDescription().filterMimeTypes("*/*")));
+        mContentUri.setText(inputContentInfo.getContentUri().toString());
+        mLabel.setText(inputContentInfo.getDescription().getLabel());
+        Uri linkUri = inputContentInfo.getLinkUri();
+        mLinkUri.setText(linkUri != null ? linkUri.toString() : "null");
+        mFlags.setText(flagsToString(flags));
+        mWebView.loadUrl(inputContentInfo.getContentUri().toString());
+        mWebView.setBackgroundColor(Color.TRANSPARENT);
+
+        // Due to the asynchronous nature of WebView, it is a bit too early to call
+        // inputContentInfo.releasePermission() here. Hence we call IC#releasePermission() when this
+        // method is called next time.  Note that calling IC#releasePermission() is just to be a
+        // good citizen. Even if we failed to call that method, the system would eventually revoke
+        // the permission sometime after inputContentInfo object gets garbage-collected.
+        mCurrentInputContentInfo = inputContentInfo;
+        mCurrentFlags = flags;
+
+        return true;
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle savedInstanceState) {
+        if (mCurrentInputContentInfo != null) {
+            savedInstanceState.putParcelable(INPUT_CONTENT_INFO_KEY,
+                    (Parcelable) mCurrentInputContentInfo.unwrap());
+            savedInstanceState.putInt(COMMIT_CONTENT_FLAGS_KEY, mCurrentFlags);
+        }
+        mCurrentInputContentInfo = null;
+        mCurrentFlags = 0;
+        super.onSaveInstanceState(savedInstanceState);
+    }
+
+    /**
+     * Creates a new instance of {@link EditText} that is configured to specify the given content
+     * MIME types to {@link EditorInfo#contentMimeTypes} so that developers
+     * can locally test how the current input method behaves for such content MIME types.
+     *
+     * @param contentMimeTypes A {@link String} array that indicates the supported content MIME
+     *                         types
+     * @return a new instance of {@link EditText}, which specifies
+     * {@link EditorInfo#contentMimeTypes} with the given content
+     * MIME types
+     */
+    private EditText createEditTextWithContentMimeTypes(String[] contentMimeTypes) {
+        final CharSequence hintText;
+        final String[] mimeTypes;  // our own copy of contentMimeTypes.
+        if (contentMimeTypes == null || contentMimeTypes.length == 0) {
+            hintText = "MIME: []";
+            mimeTypes = new String[0];
+        } else {
+            hintText = "MIME: " + Arrays.toString(contentMimeTypes);
+            mimeTypes = Arrays.copyOf(contentMimeTypes, contentMimeTypes.length);
+        }
+        EditText exitText = new EditText(this) {
+            @Override
+            public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
+                final InputConnection ic = super.onCreateInputConnection(editorInfo);
+                EditorInfoCompat.setContentMimeTypes(editorInfo, mimeTypes);
+                final InputConnectionCompat.OnCommitContentListener callback =
+                        new InputConnectionCompat.OnCommitContentListener() {
+                            @Override
+                            public boolean onCommitContent(InputContentInfoCompat inputContentInfo,
+                                    int flags, Bundle opts) {
+                                return CommitContentSupport.this.onCommitContent(
+                                        inputContentInfo, flags, opts, mimeTypes);
+                            }
+                        };
+                return InputConnectionCompat.createWrapper(ic, editorInfo, callback);
+            }
+        };
+        exitText.setHint(hintText);
+        exitText.setTextColor(Color.WHITE);
+        exitText.setHintTextColor(Color.WHITE);
+        return exitText;
+    }
+
+    /**
+     * Converts {@code flags} specified in {@link InputConnectionCompat#commitContent(
+     *InputConnection, EditorInfo, InputContentInfoCompat, int, Bundle)} to a human readable
+     * string.
+     *
+     * @param flags the 2nd parameter of
+     *              {@link InputConnectionCompat#commitContent(InputConnection, EditorInfo,
+     *              InputContentInfoCompat, int, Bundle)}
+     * @return a human readable string that corresponds to the given {@code flags}
+     */
+    private static String flagsToString(int flags) {
+        final ArrayList<String> tokens = new ArrayList<>();
+        if ((flags & InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
+            tokens.add("INPUT_CONTENT_GRANT_READ_URI_PERMISSION");
+            flags &= ~InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION;
+        }
+        if (flags != 0) {
+            tokens.add("0x" + Integer.toHexString(flags));
+        }
+        return TextUtils.join(" | ", tokens);
+    }
+
+}
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/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java b/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
index a144081..b740502 100644
--- a/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
+++ b/v13/java/android/support/v13/view/inputmethod/InputConnectionCompat.java
@@ -114,7 +114,7 @@
                 final ClipDescription description = data.getParcelable(
                         COMMIT_CONTENT_DESCRIPTION_KEY);
                 final Uri linkUri = data.getParcelable(COMMIT_CONTENT_LINK_URI_KEY);
-                final int flags = data.getParcelable(COMMIT_CONTENT_FLAGS_KEY);
+                final int flags = data.getInt(COMMIT_CONTENT_FLAGS_KEY);
                 final Bundle opts = data.getParcelable(COMMIT_CONTENT_OPTS_KEY);
                 final InputContentInfoCompat inputContentInfo =
                         new InputContentInfoCompat(contentUri, description, linkUri);
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/res-public/values/public_styles.xml b/v7/appcompat/res-public/values/public_styles.xml
index 38efc46..9e6df30 100644
--- a/v7/appcompat/res-public/values/public_styles.xml
+++ b/v7/appcompat/res-public/values/public_styles.xml
@@ -54,8 +54,6 @@
     <public type="style" name="TextAppearance.AppCompat.Widget.ActionMode.Title"/>
     <public type="style" name="TextAppearance.AppCompat.Widget.ActionMode.Title.Inverse"/>
     <public type="style" name="TextAppearance.AppCompat.Widget.Button"/>
-    <public type="style" name="TextAppearance.AppCompat.Widget.Button.Borderless.Colored"/>
-    <public type="style" name="TextAppearance.AppCompat.Widget.Button.Colored"/>
     <public type="style" name="TextAppearance.AppCompat.Widget.Button.Inverse"/>
     <public type="style" name="TextAppearance.AppCompat.Widget.DropDownItem"/>
     <public type="style" name="TextAppearance.AppCompat.Widget.PopupMenu.Header"/>
diff --git a/v7/appcompat/res/color-v23/abc_btn_colored_text_material.xml b/v7/appcompat/res/color-v23/abc_btn_colored_text_material.xml
deleted file mode 100644
index 74170d6..0000000
--- a/v7/appcompat/res/color-v23/abc_btn_colored_text_material.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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.
--->
-
-<!-- Used for the text of a bordered colored button. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="false"
-          android:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/textColorPrimary" />
-    <item android:color="?android:attr/textColorPrimaryInverse" />
-</selector>
\ No newline at end of file
diff --git a/v7/appcompat/res/color/abc_btn_colored_text_material.xml b/v7/appcompat/res/color/abc_btn_colored_text_material.xml
deleted file mode 100644
index 897a3f7..0000000
--- a/v7/appcompat/res/color/abc_btn_colored_text_material.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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.
--->
-
-<!-- Used for the text of a bordered colored button. -->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:app="http://schemas.android.com/apk/res-auto">
-    <item android:state_enabled="false"
-          app:alpha="?android:attr/disabledAlpha"
-          android:color="?android:attr/textColorPrimary" />
-    <item android:color="?android:attr/textColorPrimaryInverse" />
-</selector>
\ No newline at end of file
diff --git a/v7/appcompat/res/values-v24/styles_base_text.xml b/v7/appcompat/res/values-v24/styles_base_text.xml
deleted file mode 100644
index 2e6182d..0000000
--- a/v7/appcompat/res/values-v24/styles_base_text.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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.
--->
-<resources>
-
-    <style name="Base.TextAppearance.AppCompat.Widget.Button.Colored" parent="android:TextAppearance.Material.Widget.Button.Colored" />
-
-    <style name="Base.TextAppearance.AppCompat.Widget.Button.Borderless.Colored" parent="android:TextAppearance.Material.Widget.Button.Borderless.Colored" />
-
-</resources>
\ No newline at end of file
diff --git a/v7/appcompat/res/values/styles.xml b/v7/appcompat/res/values/styles.xml
index 7595d74..ec8bbe1 100644
--- a/v7/appcompat/res/values/styles.xml
+++ b/v7/appcompat/res/values/styles.xml
@@ -298,10 +298,6 @@
 
     <style name="TextAppearance.AppCompat.Widget.TextView.SpinnerItem" parent="Base.TextAppearance.AppCompat.Widget.TextView.SpinnerItem" />
 
-    <style name="TextAppearance.AppCompat.Widget.Button.Colored" parent="Base.TextAppearance.AppCompat.Widget.Button.Colored" />
-
-    <style name="TextAppearance.AppCompat.Widget.Button.Borderless.Colored" parent="Base.TextAppearance.AppCompat.Widget.Button.Borderless.Colored" />
-
     <!--
          The following themes are deprecated.
     -->
diff --git a/v7/appcompat/res/values/styles_base.xml b/v7/appcompat/res/values/styles_base.xml
index b8c1f29..b1d6c95 100644
--- a/v7/appcompat/res/values/styles_base.xml
+++ b/v7/appcompat/res/values/styles_base.xml
@@ -453,7 +453,7 @@
     <!-- Colored bordered ink button -->
     <style name="Base.Widget.AppCompat.Button.Colored">
         <item name="android:background">@drawable/abc_btn_colored_material</item>
-        <item name="android:textAppearance">@style/TextAppearance.AppCompat.Widget.Button.Colored</item>
+        <item name="android:textAppearance">@style/TextAppearance.AppCompat.Widget.Button.Inverse</item>
     </style>
 
     <!-- Borderless ink button -->
@@ -463,7 +463,7 @@
 
     <!-- Colored borderless ink button -->
     <style name="Base.Widget.AppCompat.Button.Borderless.Colored">
-        <item name="android:textAppearance">@style/TextAppearance.AppCompat.Widget.Button.Borderless.Colored</item>
+        <item name="android:textColor">@color/abc_btn_colored_borderless_text_material</item>
     </style>
 
     <style name="Base.Widget.AppCompat.Button.ButtonBar.AlertDialog" parent="Widget.AppCompat.Button.Borderless.Colored">
diff --git a/v7/appcompat/res/values/styles_base_text.xml b/v7/appcompat/res/values/styles_base_text.xml
index 6a43144..8597179 100644
--- a/v7/appcompat/res/values/styles_base_text.xml
+++ b/v7/appcompat/res/values/styles_base_text.xml
@@ -139,12 +139,4 @@
         <item name="android:textColorHint">?android:attr/textColorHintInverse</item>
     </style>
 
-    <style name="Base.TextAppearance.AppCompat.Widget.Button.Colored">
-        <item name="android:textColor">@color/abc_btn_colored_text_material</item>
-    </style>
-
-    <style name="Base.TextAppearance.AppCompat.Widget.Button.Borderless.Colored" parent="Base.TextAppearance.AppCompat.Widget.Button">
-        <item name="android:textColor">@color/abc_btn_colored_borderless_text_material</item>
-    </style>
-
 </resources>
\ No newline at end of file
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/widget/AppCompatImageViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
index 55d0d39d..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/PopupMenuTest.java b/v7/appcompat/tests/src/android/support/v7/widget/PopupMenuTest.java
index 09590bd..ba27a88 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/PopupMenuTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/PopupMenuTest.java
@@ -278,7 +278,8 @@
         // Allow for off-by-one mismatch in anchoring
         assertEquals("Anchoring X", anchorOnScreenXY[0] + popupInWindowXY[0],
                 popupOnScreenXY[0], 1);
-        assertEquals("Anchoring Y", anchorOnScreenXY[1] + popupInWindowXY[1] + mButton.getHeight(),
+        assertEquals("Anchoring Y",
+                anchorOnScreenXY[1] + popupInWindowXY[1] + mButton.getHeight() - popupPadding.top,
                 popupOnScreenXY[1], 1);
     }
 
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/src/android/support/v7/widget/LinearLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
index 848d910..5ee2537 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
@@ -137,6 +137,11 @@
     final AnchorInfo mAnchorInfo = new AnchorInfo();
 
     /**
+     * Stashed to avoid allocation, currently only used in #fill()
+     */
+    private final LayoutChunkResult mLayoutChunkResult = new LayoutChunkResult();
+
+    /**
      * Creates a vertical LinearLayoutManager
      *
      * @param context Current context, will be used to access resources.
@@ -1366,7 +1371,7 @@
             recycleByLayoutState(recycler, layoutState);
         }
         int remainingSpace = layoutState.mAvailable + layoutState.mExtra;
-        LayoutChunkResult layoutChunkResult = new LayoutChunkResult();
+        LayoutChunkResult layoutChunkResult = mLayoutChunkResult;
         while ((layoutState.mInfinite || remainingSpace > 0) && layoutState.hasMore(state)) {
             layoutChunkResult.resetInternal();
             layoutChunk(recycler, state, layoutState, layoutChunkResult);
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index b1d1dfd5..a90cf7c 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -4277,6 +4277,10 @@
             return lp.mDecorInsets;
         }
 
+        if (mState.isPreLayout() && (lp.isItemChanged() || lp.isViewInvalid())) {
+            // changed/invalid items should not be updated until they are rebound.
+            return lp.mDecorInsets;
+        }
         final Rect insets = lp.mDecorInsets;
         insets.set(0, 0, 0, 0);
         final int decorCount = mItemDecorations.size();
@@ -5886,6 +5890,10 @@
             TraceCompat.beginSection(TRACE_BIND_VIEW_TAG);
             onBindViewHolder(holder, position, holder.getUnmodifiedPayloads());
             holder.clearPayload();
+            final ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
+            if (layoutParams instanceof RecyclerView.LayoutParams) {
+                ((LayoutParams) layoutParams).mInsetsDirty = true;
+            }
             TraceCompat.endSection();
         }
 
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 8377874..5f7f244 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
@@ -527,6 +527,7 @@
     public class TestViewHolder extends RecyclerView.ViewHolder {
 
         Item mBoundItem;
+        Object mData;
 
         public TestViewHolder(View itemView) {
             super(itemView);
@@ -535,7 +536,15 @@
 
         @Override
         public String toString() {
-            return super.toString() + " item:" + mBoundItem;
+            return super.toString() + " item:" + mBoundItem + ", data:" + mData;
+        }
+
+        public Object getData() {
+            return mData;
+        }
+
+        public void setData(Object data) {
+            mData = data;
         }
     }
     class DumbLayoutManager extends TestLayoutManager {
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/RecyclerViewLayoutTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
index e9e92a1..770ab71 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
@@ -24,6 +24,7 @@
 import static android.support.v7.widget.RecyclerView.getChildViewHolderInt;
 
 import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.sameInstance;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -2596,6 +2597,67 @@
     }
 
     @Test
+    public void itemDecorsWithPredictive() throws Throwable {
+        LayoutAllLayoutManager lm = new LayoutAllLayoutManager(true);
+        lm.setSupportsPredictive(true);
+        final Object changePayload = new Object();
+        final TestAdapter adapter = new TestAdapter(10) {
+            @Override
+            public void onBindViewHolder(TestViewHolder holder,
+                    int position, List<Object> payloads) {
+                super.onBindViewHolder(holder, position);
+                holder.setData(payloads.isEmpty() ? null : payloads.get(0));
+            }
+        };
+        final Map<Integer, Object> preLayoutData = new HashMap<>();
+        final Map<Integer, Object> postLayoutData = new HashMap<>();
+
+        final RecyclerView.ItemDecoration decoration = new RecyclerView.ItemDecoration() {
+            @Override
+            public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
+                    RecyclerView.State state) {
+                try {
+                    TestViewHolder tvh = (TestViewHolder) parent.getChildViewHolder(view);
+                    Object data = tvh.getData();
+                    int adapterPos = tvh.getAdapterPosition();
+                    assertThat(adapterPos, is(not(NO_POSITION)));
+                    if (state.isPreLayout()) {
+                        preLayoutData.put(adapterPos, data);
+                    } else {
+                        postLayoutData.put(adapterPos, data);
+                    }
+                } catch (Throwable t) {
+                    postExceptionToInstrumentation(t);
+                }
+
+            }
+        };
+        RecyclerView rv = new RecyclerView(getActivity());
+        rv.addItemDecoration(decoration);
+        rv.setAdapter(adapter);
+        rv.setLayoutManager(lm);
+        lm.expectLayouts(1);
+        setRecyclerView(rv);
+        lm.waitForLayout(2);
+
+        preLayoutData.clear();
+        postLayoutData.clear();
+        lm.expectLayouts(2);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                adapter.notifyItemChanged(3, changePayload);
+            }
+        });
+        lm.waitForLayout(2);
+        assertThat(preLayoutData.containsKey(3), is(false));
+        assertThat(postLayoutData.get(3), is(changePayload));
+        assertThat(preLayoutData.size(), is(0));
+        assertThat(postLayoutData.size(), is(1));
+        checkForMainThreadException();
+    }
+
+    @Test
     public void invalidateAllDecorOffsets() throws Throwable {
         final TestAdapter adapter = new TestAdapter(10);
         final RecyclerView recyclerView = new RecyclerView(getActivity());
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 {