From 6026b057e7e81a8e54e1986007360b2f97bf454f Mon Sep 17 00:00:00 2001 From: Evan Laird Date: Thu, 21 Sep 2017 14:11:00 -0400 Subject: [PATCH] Fix wifi tile animating full-dark when slashing/unslashing WifiTile now owns a specific tile view that will animate the tint/alpha of the slash but not the underlying drawable. Becasue we always animate from the disconnected icon <-> disabled icon, this fixes the problem where the disabled icon will start off as full-dark and appear to flash. Fixes: 63534380 Test: turn wifi on/off; runtest -x tests/src/com/android/systemui/qs/AlphaControlledSignalTileViewTest.java Change-Id: I824572fdf00e122b7c17104b727171d81ff104c5 --- .../qs/AlphaControlledSignalTileView.java | 86 +++++++++++++++++ .../android/systemui/qs/SignalTileView.java | 6 +- .../android/systemui/qs/SlashDrawable.java | 6 +- .../systemui/qs/tileimpl/QSIconViewImpl.java | 12 ++- .../systemui/qs/tileimpl/SlashImageView.java | 18 +++- .../android/systemui/qs/tiles/WifiTile.java | 4 +- .../qs/AlphaControlledSignalTileViewTest.java | 93 +++++++++++++++++++ 7 files changed, 219 insertions(+), 6 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java create mode 100644 packages/SystemUI/tests/src/com/android/systemui/qs/AlphaControlledSignalTileViewTest.java diff --git a/packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java new file mode 100644 index 0000000000000..2c7ec70a5fff8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2017 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.android.systemui.qs; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import com.android.systemui.qs.tileimpl.SlashImageView; + + +/** + * Creates AlphaControlledSlashImageView instead of SlashImageView + */ +public class AlphaControlledSignalTileView extends SignalTileView { + public AlphaControlledSignalTileView(Context context) { + super(context); + } + + @Override + protected SlashImageView createSlashImageView(Context context) { + return new AlphaControlledSlashImageView(context); + } + + /** + * Creates AlphaControlledSlashDrawable instead of regular SlashDrawables + */ + public static class AlphaControlledSlashImageView extends SlashImageView { + public AlphaControlledSlashImageView(Context context) { + super(context); + } + + public void setFinalImageTintList(ColorStateList tint) { + super.setImageTintList(tint); + final SlashDrawable slash = getSlash(); + if (slash != null) { + ((AlphaControlledSlashDrawable)slash).setFinalTintList(tint); + } + } + + @Override + protected void ensureSlashDrawable() { + if (getSlash() == null) { + final SlashDrawable slash = new AlphaControlledSlashDrawable(getDrawable()); + setSlash(slash); + slash.setAnimationEnabled(getAnimationEnabled()); + setImageViewDrawable(slash); + } + } + } + + /** + * SlashDrawable that disobeys orders to change its drawable's tint except when you tell + * it not to disobey. The slash still will animate its alpha. + */ + public static class AlphaControlledSlashDrawable extends SlashDrawable { + AlphaControlledSlashDrawable(Drawable d) { + super(d); + } + + @Override + protected void setDrawableTintList(ColorStateList tint) { + } + + /** + * Set a target tint list instead of + */ + public void setFinalTintList(ColorStateList tint) { + super.setDrawableTintList(tint); + } + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java index b300e4a35a5ae..9ee40ccf88935 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java @@ -63,13 +63,17 @@ public class SignalTileView extends QSIconViewImpl { @Override protected View createIcon() { mIconFrame = new FrameLayout(mContext); - mSignal = new SlashImageView(mContext); + mSignal = createSlashImageView(mContext); mIconFrame.addView(mSignal); mOverlay = new ImageView(mContext); mIconFrame.addView(mOverlay, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); return mIconFrame; } + protected SlashImageView createSlashImageView(Context context) { + return new SlashImageView(context); + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); diff --git a/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java index c356148930986..a9b2376e46e5d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java @@ -197,11 +197,15 @@ public class SlashDrawable extends Drawable { public void setTintList(@Nullable ColorStateList tint) { mTintList = tint; super.setTintList(tint); - mDrawable.setTintList(tint); + setDrawableTintList(tint); mPaint.setColor(tint.getDefaultColor()); invalidateSelf(); } + protected void setDrawableTintList(@Nullable ColorStateList tint) { + mDrawable.setTintList(tint); + } + @Override public void setTintMode(@NonNull Mode tintMode) { mTintMode = tintMode; 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 8074cb9b04438..e8c8b90757921 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java @@ -33,6 +33,7 @@ import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.State; +import com.android.systemui.qs.AlphaControlledSignalTileView.AlphaControlledSlashImageView; import java.util.Objects; public class QSIconViewImpl extends QSIconView { @@ -138,7 +139,12 @@ public class QSIconViewImpl extends QSIconView { animateGrayScale(mTint, color, iv); mTint = color; } else { - setTint(iv, color); + if (iv instanceof AlphaControlledSlashImageView) { + ((AlphaControlledSlashImageView)iv) + .setFinalImageTintList(ColorStateList.valueOf(color)); + } else { + setTint(iv, color); + } mTint = color; } } @@ -149,6 +155,10 @@ public class QSIconViewImpl extends QSIconView { } public static void animateGrayScale(int fromColor, int toColor, ImageView iv) { + if (iv instanceof AlphaControlledSlashImageView) { + ((AlphaControlledSlashImageView)iv) + .setFinalImageTintList(ColorStateList.valueOf(toColor)); + } if (ValueAnimator.areAnimatorsEnabled()) { final float fromAlpha = Color.alpha(fromColor); final float toAlpha = Color.alpha(toColor); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java index 13912fe0c16d9..62bc61e188949 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java @@ -34,7 +34,15 @@ public class SlashImageView extends ImageView { super(context); } - private void ensureSlashDrawable() { + protected SlashDrawable getSlash() { + return mSlash; + } + + protected void setSlash(SlashDrawable slash) { + mSlash = slash; + } + + protected void ensureSlashDrawable() { if (mSlash == null) { mSlash = new SlashDrawable(getDrawable()); mSlash.setAnimationEnabled(mAnimationEnabled); @@ -55,10 +63,18 @@ public class SlashImageView extends ImageView { } } + protected void setImageViewDrawable(SlashDrawable slash) { + super.setImageDrawable(slash); + } + public void setAnimationEnabled(boolean enabled) { mAnimationEnabled = enabled; } + public boolean getAnimationEnabled() { + return mAnimationEnabled; + } + private void setSlashState(@NonNull SlashState slashState) { ensureSlashDrawable(); mSlash.setRotation(slashState.rotation); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 33b15121b47e7..23702736b0db2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -37,10 +37,10 @@ import com.android.systemui.plugins.qs.DetailAdapter; import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.plugins.qs.QSTile.SignalState; +import com.android.systemui.qs.AlphaControlledSignalTileView; import com.android.systemui.qs.QSDetailItems; import com.android.systemui.qs.QSDetailItems.Item; import com.android.systemui.qs.QSHost; -import com.android.systemui.qs.SignalTileView; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.AccessPointController; @@ -104,7 +104,7 @@ public class WifiTile extends QSTileImpl { @Override public QSIconView createTileView(Context context) { - return new SignalTileView(context); + return new AlphaControlledSignalTileView(context); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/AlphaControlledSignalTileViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/AlphaControlledSignalTileViewTest.java new file mode 100644 index 0000000000000..3e677c01fd57d --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/AlphaControlledSignalTileViewTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2017 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.android.systemui.qs; + + +import static org.junit.Assert.assertTrue; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import android.test.suitebuilder.annotation.SmallTest; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.qs.AlphaControlledSignalTileView.AlphaControlledSlashDrawable; +import com.android.systemui.qs.AlphaControlledSignalTileView.AlphaControlledSlashImageView; +import org.junit.Test; + +@SmallTest +public class AlphaControlledSignalTileViewTest extends SysuiTestCase { + + private AlphaControlledSignalTileView mTileView; + + @Test + public void testTileView_createsAlphaControlledSlashImageView() { + mTileView = new AlphaControlledSignalTileView(mContext); + + assertTrue(mTileView.createSlashImageView(mContext) + instanceof AlphaControlledSlashImageView); + } + + /// AlphaControlledSlashImageView tests + @Test + public void testSlashImageView_createsAlphaControlledSlashDrawable() { + TestableSlashImageView iv = new TestableSlashImageView(mContext); + + iv.ensureSlashDrawable(); + assertTrue(iv.getSlashDrawable() instanceof AlphaControlledSlashDrawable); + } + + /// AlphaControlledSlashDrawable tests + @Test + public void testSlashDrawable_doesNotSetTintList() { + Drawable mockDrawable = mock(Drawable.class); + AlphaControlledSlashDrawable drawable = new AlphaControlledSlashDrawable(mockDrawable); + ColorStateList list = ColorStateList.valueOf(0xffffff); + drawable.setTintList(list); + verify(mockDrawable, never()).setTintList(any()); + } + + @Test + public void testSlashDrawable_setsFinalTintList() { + Drawable mockDrawable = mock(Drawable.class); + AlphaControlledSlashDrawable drawable = new AlphaControlledSlashDrawable(mockDrawable); + ColorStateList list = ColorStateList.valueOf(0xffffff); + drawable.setFinalTintList(list); + verify(mockDrawable, atLeastOnce()).setTintList(list); + } + + // Expose getSlashDrawable + private static class TestableSlashImageView extends AlphaControlledSlashImageView { + TestableSlashImageView(Context c) { + super(c); + } + + private SlashDrawable getSlashDrawable() { + return mSlash; + } + + @Override + protected void setSlash(SlashDrawable slash) { + super.setSlash(slash); + } + } +}