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 {