From b9f2751f50af0e134f854237ef5ebd82b4d123c8 Mon Sep 17 00:00:00 2001 From: Silin Huang Date: Tue, 24 Aug 2021 10:33:18 -0700 Subject: [PATCH] Mutate the drawable when updating QS icon. This fixes an issue that same drawable could be tinted in different places at the same time. Test: manual Test: atest QSIconViewImplTest Fixes: 196886638 Change-Id: Ib1d53b6b843c35406e50eec7975ee0e34dada640 --- .../systemui/qs/tileimpl/QSIconViewImpl.java | 3 ++ .../qs/tileimpl/QSIconViewImplTest.java | 33 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java index 2e771d6fb6691..b1cd03c4a2f28 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java @@ -116,6 +116,9 @@ public class QSIconViewImpl extends QSIconView { : icon.getInvisibleDrawable(mContext) : null; int padding = icon != null ? icon.getPadding() : 0; if (d != null) { + if (d.getConstantState() != null) { + d = d.getConstantState().newDrawable(); + } d.setAutoMirrored(false); d.setLayoutDirection(getLayoutDirection()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java index 63ebe9290f64e..23e51687f9e10 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSIconViewImplTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -73,6 +74,24 @@ public class QSIconViewImplTest extends SysuiTestCase { verify(s.icon, never()).getInvisibleDrawable(any()); } + @Test + public void testMutateIconDrawable() { + SlashImageView iv = mock(SlashImageView.class); + Drawable originalDrawable = mock(Drawable.class); + Drawable otherDrawable = mock(Drawable.class); + State s = new State(); + s.icon = mock(Icon.class); + when(s.icon.getInvisibleDrawable(eq(mContext))).thenReturn(originalDrawable); + when(s.icon.getDrawable(eq(mContext))).thenReturn(originalDrawable); + when(iv.isShown()).thenReturn(true); + when(originalDrawable.getConstantState()).thenReturn(fakeConstantState(otherDrawable)); + + + mIconView.updateIcon(iv, s, /* allowAnimations= */true); + + verify(iv).setState(any(), eq(otherDrawable)); + } + @Test public void testNoFirstFade() { ImageView iv = mock(ImageView.class); @@ -104,4 +123,18 @@ public class QSIconViewImplTest extends SysuiTestCase { public void testIconNotSet_toString() { assertFalse(mIconView.toString().contains("lastIcon")); } + + private static Drawable.ConstantState fakeConstantState(Drawable otherDrawable) { + return new Drawable.ConstantState() { + @Override + public Drawable newDrawable() { + return otherDrawable; + } + + @Override + public int getChangingConfigurations() { + return 1; + } + }; + } }