OSDN Git Service

Fix wifi tile animating full-dark when slashing/unslashing
authorEvan Laird <evanlaird@google.com>
Thu, 21 Sep 2017 18:11:00 +0000 (14:11 -0400)
committerEvan Laird <evanlaird@google.com>
Thu, 21 Sep 2017 18:11:00 +0000 (14:11 -0400)
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

packages/SystemUI/src/com/android/systemui/qs/AlphaControlledSignalTileView.java [new file with mode: 0644]
packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java
packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java
packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
packages/SystemUI/tests/src/com/android/systemui/qs/AlphaControlledSignalTileViewTest.java [new file with mode: 0644]

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 (file)
index 0000000..2c7ec70
--- /dev/null
@@ -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);
+        }
+    }
+}
+
index b300e4a..9ee40cc 100644 (file)
@@ -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);
index c356148..a9b2376 100644 (file)
@@ -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;
index 8074cb9..e8c8b90 100644 (file)
@@ -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);
index 13912fe..62bc61e 100644 (file)
@@ -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);
index 33b1512..2370273 100644 (file)
@@ -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<SignalState> {
 
     @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 (file)
index 0000000..3e677c0
--- /dev/null
@@ -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);
+        }
+    }
+}