Merge "Rework background manager and add TestCases"
diff --git a/fragment/java/android/support/v4/app/BackStackRecord.java b/fragment/java/android/support/v4/app/BackStackRecord.java
index 19f949c..85ded71 100644
--- a/fragment/java/android/support/v4/app/BackStackRecord.java
+++ b/fragment/java/android/support/v4/app/BackStackRecord.java
@@ -748,7 +748,7 @@
}
if (!mAllowOptimization) {
// Added fragments are added at the end to comply with prior behavior.
- mManager.moveToState(mManager.mCurState);
+ mManager.moveToState(mManager.mCurState, true);
}
}
@@ -794,7 +794,7 @@
}
}
if (!mAllowOptimization) {
- mManager.moveToState(mManager.mCurState);
+ mManager.moveToState(mManager.mCurState, true);
}
}
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/java/android/support/v4/app/FragmentManager.java
index 6ef6ed1..77325cb 100644
--- a/fragment/java/android/support/v4/app/FragmentManager.java
+++ b/fragment/java/android/support/v4/app/FragmentManager.java
@@ -16,6 +16,8 @@
package android.support.v4.app;
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources.NotFoundException;
@@ -62,8 +64,6 @@
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
-import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
-
/**
* Static library support version of the framework's {@link android.app.FragmentManager}.
* Used to write apps that run on platforms prior to Android 3.0. When running
@@ -1554,11 +1554,24 @@
}
}
- void moveToState(int newState) {
+ /**
+ * Changes the state of the fragment manager to {@code newState}. If the fragment manager
+ * changes state or {@code always} is {@code true}, any fragments within it have their
+ * states updated as well.
+ *
+ * @param newState The new state for the fragment manager
+ * @param always If {@code true}, all fragments update their state, even
+ * if {@code newState} matches the current fragment manager's state.
+ */
+ void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
+ if (!always && newState == mCurState) {
+ return;
+ }
+
mCurState = newState;
if (mActive != null) {
@@ -2129,7 +2142,7 @@
// need to run something now
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
postponeIndex, true);
- moveToState(mCurState);
+ moveToState(mCurState, true);
}
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
@@ -2221,7 +2234,7 @@
FragmentTransition.startTransitions(this, records, isRecordPop, 0, 1, true);
}
if (moveToState) {
- moveToState(mCurState);
+ moveToState(mCurState, true);
} else if (mActive != null) {
final int numActive = mActive.size();
for (int i = 0; i < numActive; i++) {
@@ -2811,26 +2824,26 @@
public void dispatchCreate() {
mStateSaved = false;
- moveToState(Fragment.CREATED);
+ moveToState(Fragment.CREATED, false);
}
public void dispatchActivityCreated() {
mStateSaved = false;
- moveToState(Fragment.ACTIVITY_CREATED);
+ moveToState(Fragment.ACTIVITY_CREATED, false);
}
public void dispatchStart() {
mStateSaved = false;
- moveToState(Fragment.STARTED);
+ moveToState(Fragment.STARTED, false);
}
public void dispatchResume() {
mStateSaved = false;
- moveToState(Fragment.RESUMED);
+ moveToState(Fragment.RESUMED, false);
}
public void dispatchPause() {
- moveToState(Fragment.STARTED);
+ moveToState(Fragment.STARTED, false);
}
public void dispatchStop() {
@@ -2839,21 +2852,21 @@
// them.
mStateSaved = true;
- moveToState(Fragment.STOPPED);
+ moveToState(Fragment.STOPPED, false);
}
public void dispatchReallyStop() {
- moveToState(Fragment.ACTIVITY_CREATED);
+ moveToState(Fragment.ACTIVITY_CREATED, false);
}
public void dispatchDestroyView() {
- moveToState(Fragment.CREATED);
+ moveToState(Fragment.CREATED, false);
}
public void dispatchDestroy() {
mDestroyed = true;
execPendingActions();
- moveToState(Fragment.INITIALIZING);
+ moveToState(Fragment.INITIALIZING, false);
mHost = null;
mContainer = null;
mParent = null;
diff --git a/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java b/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
index 94d0445..4c0c0a4 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
@@ -17,6 +17,19 @@
package android.support.v4.app;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNotSame;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -36,6 +49,7 @@
import android.view.ViewGroup;
import android.view.Window;
import android.widget.TextView;
+
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
@@ -44,10 +58,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import static junit.framework.Assert.*;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.Mockito.*;
-
@RunWith(AndroidJUnit4.class)
@MediumTest
public class FragmentLifecycleTest {
@@ -540,6 +550,42 @@
assertTrue(fragmentA.mCalledOnDestroy);
}
+ /**
+ * Test to ensure that when dispatch* is called that the fragment manager
+ * doesn't cause the contained fragment states to change even if no state changes.
+ */
+ @Test
+ @UiThreadTest
+ public void noPrematureStateChange() throws Throwable {
+ FragmentController fc = startupFragmentController(null);
+ FragmentManager fm = fc.getSupportFragmentManager();
+
+ fm.beginTransaction()
+ .add(new StrictFragment(), "1")
+ .commitNow();
+
+ Parcelable savedState = shutdownFragmentController(fc);
+ fc = FragmentController.createController(
+ new HostCallbacks(mActivityRule.getActivity()));
+
+ fc.attachHost(null);
+ fc.dispatchCreate();
+ fc.dispatchActivityCreated();
+ fc.noteStateNotSaved();
+ fc.execPendingActions();
+ fc.doLoaderStart();
+ fc.dispatchStart();
+ fc.reportLoaderStart();
+ fc.dispatchResume();
+ fc.restoreAllState(savedState, (FragmentManagerNonConfig) null);
+ fc.dispatchResume();
+ fm = fc.getSupportFragmentManager();
+
+ StrictFragment fragment1 = (StrictFragment) fm.findFragmentByTag("1");
+
+ assertFalse(fragment1.mCalledOnResume);
+ }
+
private void assertAnimationsMatch(FragmentManager fm, int enter, int exit, int popEnter,
int popExit) {
FragmentManagerImpl fmImpl = (FragmentManagerImpl) fm;
diff --git a/samples/Support7Demos/res/layout/appcompat_widgets_buttons.xml b/samples/Support7Demos/res/layout/appcompat_widgets_buttons.xml
index aa07328..1c60d90 100644
--- a/samples/Support7Demos/res/layout/appcompat_widgets_buttons.xml
+++ b/samples/Support7Demos/res/layout/appcompat_widgets_buttons.xml
@@ -16,8 +16,9 @@
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
@@ -77,6 +78,19 @@
android:text="Button (borderless + colored)"
style="@style/Widget.AppCompat.Button.Borderless.Colored"/>
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button (colored)"
+ style="@style/Widget.AppCompat.Button.Colored"/>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button (colored + tinted)"
+ app:backgroundTint="#00FF00"
+ style="@style/Widget.AppCompat.Button.Colored"/>
+
<RatingBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
index 09e4a28..3fffb9f 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
@@ -155,10 +155,9 @@
void applySupportBackgroundTint() {
final Drawable background = mView.getBackground();
if (background != null) {
- if (Build.VERSION.SDK_INT == 21 && applyFrameworkTintUsingColorFilter(background)) {
- // GradientDrawable doesn't implement setTintList on API 21, and since there is
- // no nice way to unwrap DrawableContainers we have to blanket apply this
- // on API 21. This needs to be called before the internal tints below so it takes
+ if (shouldApplyFrameworkTintUsingColorFilter()
+ && applyFrameworkTintUsingColorFilter(background)) {
+ // This needs to be called before the internal tints below so it takes
// effect on any widgets using the compat tint on API 21 (EditText)
return;
}
@@ -186,6 +185,23 @@
applySupportBackgroundTint();
}
+ private boolean shouldApplyFrameworkTintUsingColorFilter() {
+ final int sdk = Build.VERSION.SDK_INT;
+ if (sdk < 21) {
+ // API 19 and below doesn't have framework tint
+ return false;
+ } else if (sdk == 21) {
+ // GradientDrawable doesn't implement setTintList on API 21, and since there is
+ // no nice way to unwrap DrawableContainers we have to blanket apply this
+ // on API 21
+ return true;
+ } else {
+ // On API 22+, if we're using an internal compat background tint, we're also
+ // responsible for applying any custom tint set via the framework impl
+ return mInternalBackgroundTint != null;
+ }
+ }
+
/**
* Applies the framework background tint to a view, but using the compat method (ColorFilter)
*
diff --git a/v7/appcompat/tests/res/layout/appcompat_button_activity.xml b/v7/appcompat/tests/res/layout/appcompat_button_activity.xml
index 72d6500..7708d0c 100644
--- a/v7/appcompat/tests/res/layout/appcompat_button_activity.xml
+++ b/v7/appcompat/tests/res/layout/appcompat_button_activity.xml
@@ -76,6 +76,13 @@
android:text="@string/sample_text2"
android:background="@drawable/test_background_green" />
+ <android.support.v7.widget.AppCompatButton
+ android:id="@+id/button_colored_untinted"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/sample_text2"
+ style="@style/Widget.AppCompat.Button.Colored"/>
+
</LinearLayout>
</ScrollView>
diff --git a/v7/appcompat/tests/src/android/support/v7/testutils/TestUtils.java b/v7/appcompat/tests/src/android/support/v7/testutils/TestUtils.java
index 6c1f167..5080252 100644
--- a/v7/appcompat/tests/src/android/support/v7/testutils/TestUtils.java
+++ b/v7/appcompat/tests/src/android/support/v7/testutils/TestUtils.java
@@ -169,6 +169,36 @@
}
/**
+ * Checks whether the center pixel in the specified drawable is of the same specified color.
+ *
+ * In case there is a color mismatch, the behavior of this method depends on the
+ * <code>throwExceptionIfFails</code> parameter. If it is <code>true</code>, this method will
+ * throw an <code>Exception</code> describing the mismatch. Otherwise this method will call
+ * <code>Assert.fail</code> with detailed description of the mismatch.
+ */
+ public static void assertCenterPixelOfColor(String failMessagePrefix, @NonNull Drawable drawable,
+ int drawableWidth, int drawableHeight, boolean callSetBounds, @ColorInt int color,
+ int allowedComponentVariance, boolean throwExceptionIfFails) {
+ // Create a bitmap
+ Bitmap bitmap = Bitmap.createBitmap(drawableWidth, drawableHeight, Bitmap.Config.ARGB_8888);
+ // Create a canvas that wraps the bitmap
+ Canvas canvas = new Canvas(bitmap);
+ if (callSetBounds) {
+ // Configure the drawable to have bounds that match the passed size
+ drawable.setBounds(0, 0, drawableWidth, drawableHeight);
+ }
+ // And ask the drawable to draw itself to the canvas / bitmap
+ drawable.draw(canvas);
+
+ try {
+ assertCenterPixelOfColor(failMessagePrefix, bitmap, color, allowedComponentVariance,
+ throwExceptionIfFails);
+ } finally {
+ bitmap.recycle();
+ }
+ }
+
+ /**
* Checks whether the center pixel in the specified bitmap is of the same specified color.
*
* In case there is a color mismatch, the behavior of this method depends on the
@@ -177,8 +207,7 @@
* <code>Assert.fail</code> with detailed description of the mismatch.
*/
public static void assertCenterPixelOfColor(String failMessagePrefix, @NonNull Bitmap bitmap,
- @ColorInt int color,
- int allowedComponentVariance, boolean throwExceptionIfFails) {
+ @ColorInt int color, int allowedComponentVariance, boolean throwExceptionIfFails) {
final int centerX = bitmap.getWidth() / 2;
final int centerY = bitmap.getHeight() / 2;
final @ColorInt int colorAtCenterPixel = bitmap.getPixel(centerX, centerY);
diff --git a/v7/appcompat/tests/src/android/support/v7/testutils/TestUtilsMatchers.java b/v7/appcompat/tests/src/android/support/v7/testutils/TestUtilsMatchers.java
index ac10d3b..3e092c4 100644
--- a/v7/appcompat/tests/src/android/support/v7/testutils/TestUtilsMatchers.java
+++ b/v7/appcompat/tests/src/android/support/v7/testutils/TestUtilsMatchers.java
@@ -81,6 +81,14 @@
* with the specific color.
*/
public static Matcher isBackground(@ColorInt final int color) {
+ return isBackground(color, false);
+ }
+
+ /**
+ * Returns a matcher that matches <code>View</code>s which have background flat-filled
+ * with the specific color.
+ */
+ public static Matcher isBackground(@ColorInt final int color, final boolean onlyTestCenter) {
return new BoundedMatcher<View, View>(View.class) {
private String failedComparisonDescription;
@@ -97,10 +105,14 @@
if (drawable == null) {
return false;
}
-
try {
- TestUtils.assertAllPixelsOfColor("", drawable, view.getWidth(),
- view.getHeight(), false, color, 0, true);
+ if (onlyTestCenter) {
+ TestUtils.assertCenterPixelOfColor("", drawable, view.getWidth(),
+ view.getHeight(), false, color, 0, true);
+ } else {
+ TestUtils.assertAllPixelsOfColor("", drawable, view.getWidth(),
+ view.getHeight(), false, color, 0, true);
+ }
// If we are here, the color comparison has passed.
failedComparisonDescription = null;
return true;
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java
index e721ebd..dca0f2a 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java
@@ -16,7 +16,15 @@
package android.support.v7.widget;
import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.v7.testutils.AppCompatTintableViewActions.setBackgroundResource;
+import static android.support.v7.testutils.AppCompatTintableViewActions.setBackgroundTintList;
+import static android.support.v7.testutils.AppCompatTintableViewActions.setBackgroundTintMode;
+import static android.support.v7.testutils.AppCompatTintableViewActions.setEnabled;
+import static android.support.v7.testutils.TestUtilsActions.setBackgroundTintListViewCompat;
+import static android.support.v7.testutils.TestUtilsActions.setBackgroundTintModeViewCompat;
+import static android.support.v7.testutils.TestUtilsMatchers.isBackground;
import static org.junit.Assert.assertNull;
@@ -27,7 +35,6 @@
import android.support.annotation.ColorInt;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
-import android.support.test.filters.SmallTest;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.ColorUtils;
import android.support.v7.app.BaseInstrumentationTestCase;
@@ -35,7 +42,7 @@
import android.support.v7.testutils.AppCompatTintableViewActions;
import android.support.v7.testutils.BaseTestActivity;
import android.support.v7.testutils.TestUtils;
-import android.support.v7.testutils.TestUtilsActions;
+import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;
import android.view.ViewGroup;
@@ -102,11 +109,11 @@
assertNull("No background after XML loading", view.getBackground());
// Disable the view and check that the background is still null.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
assertNull("No background after disabling", view.getBackground());
// Enable the view and check that the background is still null.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
assertNull("No background after re-enabling", view.getBackground());
// Load a new color state list, set it on the view and check that the background
@@ -114,14 +121,14 @@
final ColorStateList sandColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_sand, null);
onView(withId(viewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(sandColor));
+ setBackgroundTintList(sandColor));
// Disable the view and check that the background is still null.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
assertNull("No background after disabling", view.getBackground());
// Enable the view and check that the background is still null.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
assertNull("No background after re-enabling", view.getBackground());
}
@@ -146,26 +153,25 @@
assertNull("No background after XML loading", view.getBackground());
// Disable the view and check that the background is still null.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
assertNull("No background after disabling", view.getBackground());
// Enable the view and check that the background is still null.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
assertNull("No background after re-enabling", view.getBackground());
// Load a new color state list, set it on the view and check that the background
// is still null.
final ColorStateList lilacColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_lilac, null);
- onView(withId(viewId)).perform(
- TestUtilsActions.setBackgroundTintListViewCompat(lilacColor));
+ onView(withId(viewId)).perform(setBackgroundTintListViewCompat(lilacColor));
// Disable the view and check that the background is still null.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
assertNull("No background after disabling", view.getBackground());
// Enable the view and check that the background is still null.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
assertNull("No background after re-enabling", view.getBackground());
}
@@ -199,13 +205,13 @@
// Disable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("Default lilac tinting in disabled state", view,
lilacDisabled, 0);
// Enable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state", view,
lilacDefault, 0);
@@ -214,19 +220,19 @@
final ColorStateList sandColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_sand, null);
onView(withId(viewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(sandColor));
+ setBackgroundTintList(sandColor));
verifyBackgroundIsColoredAs("New sand tinting in enabled state", view,
sandDefault, 0);
// Disable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("New sand tinting in disabled state", view,
sandDisabled, 0);
// Enable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("New sand tinting in re-enabled state", view,
sandDefault, 0);
@@ -234,20 +240,19 @@
// switched to the matching entry in newly set color state list.
final ColorStateList oceanColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_ocean, null);
- onView(withId(viewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(oceanColor));
+ onView(withId(viewId)).perform(setBackgroundTintList(oceanColor));
verifyBackgroundIsColoredAs("New ocean tinting in enabled state", view,
oceanDefault, 0);
// Disable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("New ocean tinting in disabled state", view,
oceanDisabled, 0);
// Enable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("New ocean tinting in re-enabled state", view,
oceanDefault, 0);
}
@@ -282,13 +287,13 @@
// Disable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("Default lilac tinting in disabled state", view,
lilacDisabled, 0);
// Enable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state", view,
lilacDefault, 0);
@@ -296,20 +301,19 @@
// switched to the matching entry in newly set color state list.
final ColorStateList sandColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_sand, null);
- onView(withId(viewId)).perform(
- TestUtilsActions.setBackgroundTintListViewCompat(sandColor));
+ onView(withId(viewId)).perform(setBackgroundTintListViewCompat(sandColor));
verifyBackgroundIsColoredAs("New sand tinting in enabled state", view,
sandDefault, 0);
// Disable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("New sand tinting in disabled state", view,
sandDisabled, 0);
// Enable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("New sand tinting in re-enabled state", view,
sandDefault, 0);
@@ -318,19 +322,19 @@
final ColorStateList oceanColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_ocean, null);
onView(withId(viewId)).perform(
- TestUtilsActions.setBackgroundTintListViewCompat(oceanColor));
+ setBackgroundTintListViewCompat(oceanColor));
verifyBackgroundIsColoredAs("New ocean tinting in enabled state", view,
oceanDefault, 0);
// Disable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("New ocean tinting in disabled state", view,
oceanDisabled, 0);
// Enable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("New ocean tinting in re-enabled state", view,
oceanDefault, 0);
}
@@ -367,21 +371,19 @@
final int allowedComponentVariance = 2;
// Set src_in tint mode on our view
- onView(withId(viewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_IN));
+ onView(withId(viewId)).perform(setBackgroundTintMode(PorterDuff.Mode.SRC_IN));
// Load a new color state list, set it on the view and check that the background has
// switched to the matching entry in newly set color state list.
final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_emerald_translucent, null);
- onView(withId(viewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(emeraldColor));
+ onView(withId(viewId)).perform(setBackgroundTintList(emeraldColor));
verifyBackgroundIsColoredAs("New emerald tinting in enabled state under src_in", view,
emeraldDefault, allowedComponentVariance);
// Disable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_in", view,
emeraldDisabled, allowedComponentVariance);
@@ -389,19 +391,18 @@
// translucent colors, we expect the actual background of the view to be different under
// this new mode (unlike src_in and src_over that behave identically when the destination is
// a fully filled rectangle and the source is an opaque color).
- onView(withId(viewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
+ onView(withId(viewId)).perform(setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
// Enable the view and check that the background has switched to the matching entry
// in the color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("New emerald tinting in enabled state under src_over", view,
ColorUtils.compositeColors(emeraldDefault, backgroundColor),
allowedComponentVariance);
// Disable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_over",
view, ColorUtils.compositeColors(emeraldDisabled, backgroundColor),
allowedComponentVariance);
@@ -439,21 +440,19 @@
final int allowedComponentVariance = 2;
// Set src_in tint mode on our view
- onView(withId(viewId)).perform(
- TestUtilsActions.setBackgroundTintModeViewCompat(PorterDuff.Mode.SRC_IN));
+ onView(withId(viewId)).perform(setBackgroundTintModeViewCompat(PorterDuff.Mode.SRC_IN));
// Load a new color state list, set it on the view and check that the background has
// switched to the matching entry in newly set color state list.
final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_emerald_translucent, null);
- onView(withId(viewId)).perform(
- TestUtilsActions.setBackgroundTintListViewCompat(emeraldColor));
+ onView(withId(viewId)).perform(setBackgroundTintListViewCompat(emeraldColor));
verifyBackgroundIsColoredAs("New emerald tinting in enabled state under src_in", view,
emeraldDefault, allowedComponentVariance);
// Disable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_in", view,
emeraldDisabled, allowedComponentVariance);
@@ -461,19 +460,18 @@
// translucent colors, we expect the actual background of the view to be different under
// this new mode (unlike src_in and src_over that behave identically when the destination is
// a fully filled rectangle and the source is an opaque color).
- onView(withId(viewId)).perform(
- TestUtilsActions.setBackgroundTintModeViewCompat(PorterDuff.Mode.SRC_OVER));
+ onView(withId(viewId)).perform(setBackgroundTintModeViewCompat(PorterDuff.Mode.SRC_OVER));
// Enable the view and check that the background has switched to the matching entry
// in the color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("New emerald tinting in enabled state under src_over", view,
ColorUtils.compositeColors(emeraldDefault, backgroundColor),
allowedComponentVariance);
// Disable the view and check that the background has switched to the matching entry
// in the newly set color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("New emerald tinting in disabled state under src_over",
view, ColorUtils.compositeColors(emeraldDisabled, backgroundColor),
allowedComponentVariance);
@@ -499,8 +497,7 @@
}
// Set background on our view
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setBackgroundDrawable(
- ResourcesCompat.getDrawable(mResources, R.drawable.test_background_green, null)));
+ onView(withId(viewId)).perform(setBackgroundResource(R.drawable.test_background_green));
// Test the default state for tinting set up in the layout XML file.
verifyBackgroundIsColoredAs("Default lilac tinting in enabled state on green background",
@@ -508,13 +505,13 @@
// Disable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("Default lilac tinting in disabled state on green background",
view, lilacDisabled, 0);
// Enable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state on green background",
view, lilacDefault, 0);
@@ -528,13 +525,13 @@
// Disable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("Default lilac tinting in disabled state on red background",
view, lilacDisabled, 0);
// Enable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("Default lilac tinting in re-enabled state on red background",
view, lilacDefault, 0);
}
@@ -568,17 +565,15 @@
// translucent colors, we expect the actual background of the view to be different under
// this new mode (unlike src_in and src_over that behave identically when the destination is
// a fully filled rectangle and the source is an opaque color).
- onView(withId(viewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
+ onView(withId(viewId)).perform(setBackgroundTintMode(PorterDuff.Mode.SRC_OVER));
// Load and set a translucent color state list as the background tint list
final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
mResources, R.color.color_state_list_emerald_translucent, null);
onView(withId(viewId)).perform(
- AppCompatTintableViewActions.setBackgroundTintList(emeraldColor));
+ setBackgroundTintList(emeraldColor));
// Set background on our view
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setBackgroundDrawable(
- ResourcesCompat.getDrawable(mResources, R.drawable.test_background_green, null)));
+ onView(withId(viewId)).perform(setBackgroundResource(R.drawable.test_background_green));
// From this point on in this method we're allowing a margin of error in checking the
// color of the view background. This is due to both translucent colors being used
@@ -594,14 +589,14 @@
// Disable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("Emerald tinting in disabled state on green background",
view, ColorUtils.compositeColors(emeraldDisabled, backgroundColorGreen),
allowedComponentVariance);
// Enable the view and check that the background has switched to the matching entry
// in the default color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("Emerald tinting in re-enabled state on green background",
view, ColorUtils.compositeColors(emeraldDefault, backgroundColorGreen),
allowedComponentVariance);
@@ -617,16 +612,39 @@
// Disable the view and check that the background has switched to the matching entry
// in our current color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(false));
+ onView(withId(viewId)).perform(setEnabled(false));
verifyBackgroundIsColoredAs("Emerald tinting in disabled state on red background",
view, ColorUtils.compositeColors(emeraldDisabled, backgroundColorRed),
allowedComponentVariance);
// Enable the view and check that the background has switched to the matching entry
// in our current color state list.
- onView(withId(viewId)).perform(AppCompatTintableViewActions.setEnabled(true));
+ onView(withId(viewId)).perform(setEnabled(true));
verifyBackgroundIsColoredAs("Emerald tinting in re-enabled state on red background",
view, ColorUtils.compositeColors(emeraldDefault, backgroundColorRed),
allowedComponentVariance);
}
+
+ protected void testUntintedBackgroundTintingViewCompatAcrossStateChange(@IdRes int viewId) {
+ final T view = (T) mContainer.findViewById(viewId);
+
+ final @ColorInt int oceanDefault = ResourcesCompat.getColor(
+ mResources, R.color.ocean_default, null);
+ final @ColorInt int oceanDisabled = ResourcesCompat.getColor(
+ mResources, R.color.ocean_disabled, null);
+
+ final ColorStateList oceanColor = ResourcesCompat.getColorStateList(
+ mResources, R.color.color_state_list_ocean, null);
+ onView(withId(viewId)).perform(setBackgroundTintListViewCompat(oceanColor));
+
+ // Disable the view and check that the background has switched to the matching entry
+ // in the newly set color state list.
+ onView(withId(viewId)).perform(setEnabled(false))
+ .check(matches(isBackground(oceanDisabled, true)));
+
+ // Enable the view and check that the background has switched to the matching entry
+ // in the newly set color state list.
+ onView(withId(viewId)).perform(setEnabled(true))
+ .check(matches(isBackground(oceanDefault, true)));
+ }
}
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatButtonTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatButtonTest.java
index 1ea0468..2e5a952 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatButtonTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatButtonTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertEquals;
+import android.support.test.filters.SdkSuppress;
import android.support.test.filters.SmallTest;
import android.support.v7.appcompat.test.R;
@@ -81,4 +82,13 @@
assertEquals("Button is not in all caps", text, button.getLayout().getText());
}
+
+ /**
+ * Currently only runs on API 22+ due to http://b.android.com/221469
+ */
+ @Test
+ @SdkSuppress(minSdkVersion = 22)
+ public void testBackgroundTintListOnColoredButton() {
+ testUntintedBackgroundTintingViewCompatAcrossStateChange(R.id.button_colored_untinted);
+ }
}