Merge "Do not animate QS state changes when not in view."
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSIconView.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSIconView.java
index c268d32..0cdb509 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSIconView.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSIconView.java
@@ -29,7 +29,7 @@
super(context);
}
- public abstract void setIcon(State state);
+ public abstract void setIcon(State state, boolean allowAnimations);
public abstract void disableAnimation();
public abstract View getIconView();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
index e7eefe8..376e6ae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/CellTileView.java
@@ -43,9 +43,9 @@
R.dimen.qs_tile_icon_size));
}
- protected void updateIcon(ImageView iv, State state) {
+ protected void updateIcon(ImageView iv, State state, boolean allowAnimations) {
if (!(state.icon instanceof SignalIcon)) {
- super.updateIcon(iv, state);
+ super.updateIcon(iv, state, allowAnimations);
return;
} else if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
mSignalDrawable.setLevel(((SignalIcon) state.icon).getState());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index d9583af..ce90fc1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -18,14 +18,13 @@
import android.animation.ValueAnimator;
import android.content.Context;
-import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.systemui.R;
-import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.SignalState;
+import com.android.systemui.plugins.qs.QSTile.State;
import com.android.systemui.qs.tileimpl.QSIconViewImpl;
import com.android.systemui.qs.tileimpl.SlashImageView;
@@ -119,9 +118,9 @@
}
@Override
- public void setIcon(QSTile.State state) {
+ public void setIcon(State state, boolean allowAnimations) {
final SignalState s = (SignalState) state;
- setIcon(mSignal, s);
+ setIcon(mSignal, s, allowAnimations);
if (s.overlayIconId > 0) {
mOverlay.setVisibility(VISIBLE);
@@ -134,9 +133,9 @@
} else {
mSignal.setPaddingRelative(0, 0, 0, 0);
}
- final boolean shown = isShown();
- setVisibility(mIn, shown, s.activityIn);
- setVisibility(mOut, shown, s.activityOut);
+ final boolean shouldAnimate = allowAnimations && isShown();
+ setVisibility(mIn, shouldAnimate, s.activityIn);
+ setVisibility(mOut, shouldAnimate, s.activityOut);
}
private void setVisibility(View view, boolean shown, boolean visible) {
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 e7e756f..9dd5d8f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -84,16 +84,15 @@
layout(mIcon, iconLeft, top);
}
- public void setIcon(QSTile.State state) {
- setIcon((ImageView) mIcon, state);
+ public void setIcon(State state, boolean allowAnimations) {
+ setIcon((ImageView) mIcon, state, allowAnimations);
}
- protected void updateIcon(ImageView iv, State state) {
+ protected void updateIcon(ImageView iv, State state, boolean allowAnimations) {
final QSTile.Icon icon = state.iconSupplier != null ? state.iconSupplier.get() : state.icon;
if (!Objects.equals(icon, iv.getTag(R.id.qs_icon_tag))
|| !Objects.equals(state.slash, iv.getTag(R.id.qs_slash_tag))) {
- boolean shouldAnimate = iv.isShown() && mAnimationEnabled
- && iv.getDrawable() != null;
+ boolean shouldAnimate = allowAnimations && shouldAnimate(iv);
Drawable d = icon != null
? shouldAnimate ? icon.getDrawable(mContext)
: icon.getInvisibleDrawable(mContext) : null;
@@ -128,7 +127,11 @@
}
}
- protected void setIcon(ImageView iv, QSTile.State state) {
+ private boolean shouldAnimate(ImageView iv) {
+ return mAnimationEnabled && iv.isShown() && iv.getDrawable() != null;
+ }
+
+ protected void setIcon(ImageView iv, QSTile.State state, boolean allowAnimations) {
if (state.disabledByPolicy) {
iv.setColorFilter(getContext().getColor(R.color.qs_tile_disabled_color));
} else {
@@ -137,8 +140,8 @@
if (state.state != mState) {
int color = getColor(state.state);
mState = state.state;
- if (iv.isShown() && mTint != 0) {
- animateGrayScale(mTint, color, iv, () -> updateIcon(iv, state));
+ if (mTint != 0 && allowAnimations && shouldAnimate(iv)) {
+ animateGrayScale(mTint, color, iv, () -> updateIcon(iv, state, allowAnimations));
mTint = color;
} else {
if (iv instanceof AlphaControlledSlashImageView) {
@@ -148,10 +151,10 @@
setTint(iv, color);
}
mTint = color;
- updateIcon(iv, state);
+ updateIcon(iv, state, allowAnimations);
}
} else {
- updateIcon(iv, state);
+ updateIcon(iv, state, allowAnimations);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index 91afef02..d42127e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -47,6 +47,7 @@
private static final String TAG = "QSTileBaseView";
private final H mHandler = new H();
+ private final int[] mLocInScreen = new int[2];
private final FrameLayout mIconFrame;
protected QSIconView mIcon;
protected RippleDrawable mRipple;
@@ -178,8 +179,9 @@
protected void handleStateChanged(QSTile.State state) {
int circleColor = getCircleColor(state.state);
+ boolean allowAnimations = animationsEnabled();
if (circleColor != mCircleColor) {
- if (mBg.isShown() && animationsEnabled()) {
+ if (allowAnimations) {
ValueAnimator animator = ValueAnimator.ofArgb(mCircleColor, circleColor)
.setDuration(QS_ANIM_LENGTH);
animator.addUpdateListener(animation -> mBg.setImageTintList(ColorStateList.valueOf(
@@ -192,7 +194,7 @@
}
setClickable(state.state != Tile.STATE_UNAVAILABLE);
- mIcon.setIcon(state);
+ mIcon.setIcon(state, allowAnimations);
setContentDescription(state.contentDescription);
mAccessibilityClass = state.expandedAccessibilityClassName;
@@ -205,8 +207,17 @@
}
}
+ /* The view should not be animated if it's not on screen and no part of it is visible.
+ */
protected boolean animationsEnabled() {
- return true;
+ if (!isShown()) {
+ return false;
+ }
+ if (getAlpha() != 1f) {
+ return false;
+ }
+ getLocationOnScreen(mLocInScreen);
+ return mLocInScreen[1] >= -getHeight();
}
private int getCircleColor(int state) {
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 f9f4f497..c5e4043 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
@@ -59,14 +59,14 @@
// No current icon, only the static drawable should be used.
s.icon = mock(Icon.class);
when(iv.getDrawable()).thenReturn(null);
- mIconView.updateIcon(iv, s);
+ mIconView.updateIcon(iv, s, true);
verify(s.icon, never()).getDrawable(any());
verify(s.icon).getInvisibleDrawable(any());
// Has icon, should use the standard (animated) form.
s.icon = mock(Icon.class);
when(iv.getDrawable()).thenReturn(mock(Drawable.class));
- mIconView.updateIcon(iv, s);
+ mIconView.updateIcon(iv, s, true);
verify(s.icon).getDrawable(any());
verify(s.icon, never()).getInvisibleDrawable(any());
}
@@ -79,7 +79,7 @@
int desiredColor = mIconView.getColor(s.state);
when(iv.isShown()).thenReturn(true);
- mIconView.setIcon(iv, s);
+ mIconView.setIcon(iv, s, true);
verify(iv).setImageTintList(argThat(stateList -> stateList.getColors()[0] == desiredColor));
}
}