diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 56298fa155fae..920f4634abe22 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -16,6 +16,7 @@ package com.android.systemui.qs;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
+import android.annotation.NonNull;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
@@ -30,15 +31,11 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTileView;
-import com.android.systemui.qs.PagedTileLayout.PageListener;
-import com.android.systemui.qs.QSHost.Callback;
import com.android.systemui.qs.QSPanel.QSTileLayout;
import com.android.systemui.qs.TouchAnimator.Builder;
-import com.android.systemui.qs.TouchAnimator.Listener;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.qs.tileimpl.HeightOverrideable;
import com.android.systemui.tuner.TunerService;
-import com.android.systemui.tuner.TunerService.Tunable;
import java.util.ArrayList;
import java.util.Collection;
@@ -47,16 +44,26 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
-/** */
+/**
+ * Performs the animated transition between the QQS and QS views.
+ *
+ *
The transition is driven externally via {@link #setPosition(float)}, where 0 is a fully
+ * collapsed QQS and one a fully expanded QS.
+ *
+ *
This implementation maintains a set of {@code TouchAnimator} to transition the properties of
+ * views both in QQS and QS. These {@code TouchAnimator} are re-created lazily if contents of either
+ * view change, see {@link #requestAnimatorUpdate()}.
+ *
+ *
During the transition, both QS and QQS are visible. For overlapping tiles (Whenever the QS
+ * shows the first page), the corresponding QS tiles are hidden until QS is fully expanded.
+ */
@QSScope
-public class QSAnimator implements Callback, PageListener, Listener, OnLayoutChangeListener,
- OnAttachStateChangeListener, Tunable {
+public class QSAnimator implements QSHost.Callback, PagedTileLayout.PageListener,
+ TouchAnimator.Listener, OnLayoutChangeListener,
+ OnAttachStateChangeListener {
private static final String TAG = "QSAnimator";
- private static final String ALLOW_FANCY_ANIMATION = "sysui_qs_fancy_anim";
- private static final String MOVE_FULL_ROWS = "sysui_qs_move_whole_rows";
-
private static final float EXPANDED_TILE_DELAY = .86f;
//Non first page delays
private static final float QS_TILE_LABEL_FADE_OUT_START = 0.15f;
@@ -65,7 +72,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
public static final float SHORT_PARALLAX_AMOUNT = 0.1f;
-
/**
* List of all views that will be reset when clearing animation state
* see {@link #clearAnimationState()} }
@@ -125,14 +131,11 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private boolean mNeedsAnimatorUpdate = false;
private boolean mOnKeyguard;
- private boolean mAllowFancy;
- private boolean mFullRows;
private int mNumQuickTiles;
private int mLastQQSTileHeight;
private float mLastPosition;
private final QSTileHost mHost;
private final Executor mExecutor;
- private final TunerService mTunerService;
private boolean mShowCollapsedOnKeyguard;
private boolean mTranslateWhileExpanding;
private int mQQSTop;
@@ -153,7 +156,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
mQuickStatusBarHeader = quickStatusBarHeader;
mHost = qsTileHost;
mExecutor = executor;
- mTunerService = tunerService;
mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
mHost.addCallback(this);
mQsPanelController.addOnAttachStateChangeListener(this);
@@ -199,7 +201,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
setCurrentPosition();
}
-
private void setCurrentPosition() {
setPosition(mLastPosition);
}
@@ -210,30 +211,15 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
}
@Override
- public void onViewAttachedToWindow(@Nullable View v) {
- mTunerService.addTunable(this, ALLOW_FANCY_ANIMATION,
- MOVE_FULL_ROWS);
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- mHost.removeCallback(this);
- mTunerService.removeTunable(this);
- }
-
- @Override
- public void onTuningChanged(String key, String newValue) {
- if (ALLOW_FANCY_ANIMATION.equals(key)) {
- mAllowFancy = TunerService.parseIntegerSwitch(newValue, true);
- if (!mAllowFancy) {
- clearAnimationState();
- }
- } else if (MOVE_FULL_ROWS.equals(key)) {
- mFullRows = TunerService.parseIntegerSwitch(newValue, true);
- }
+ public void onViewAttachedToWindow(@NonNull View view) {
updateAnimators();
}
+ @Override
+ public void onViewDetachedFromWindow(@NonNull View v) {
+ mHost.removeCallback(this);
+ }
+
private void addNonFirstPageAnimators(int page) {
Pair pair = createSecondaryPageAnimators(page);
if (pair != null) {
@@ -339,8 +325,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
View view = mQs.getView();
// This case: less tiles to animate in small displays.
- if (count < mQuickQSPanelController.getTileLayout().getNumVisibleTiles()
- && mAllowFancy) {
+ if (count < mQuickQSPanelController.getTileLayout().getNumVisibleTiles()) {
// Quick tiles.
QSTileView quickTileView = mQuickQSPanelController.getTileView(tile);
if (quickTileView == null) continue;
@@ -422,7 +407,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
mAnimatedQsViews.add(tileView);
mAllViews.add(quickTileView);
mAllViews.add(quickTileView.getSecondaryLabel());
- } else if (mFullRows && isIconInAnimatedRow(count)) {
+ } else if (isIconInAnimatedRow(count)) {
firstPageBuilder.addFloat(tileView, "translationY", -heightDiff, 0);
@@ -457,44 +442,42 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
}
}
- if (mAllowFancy) {
- animateBrightnessSlider(firstPageBuilder);
+ animateBrightnessSlider(firstPageBuilder);
- mFirstPageAnimator = firstPageBuilder
- // Fade in the tiles/labels as we reach the final position.
- .addFloat(tileLayout, "alpha", 0, 1)
- .addFloat(quadraticInterpolatorBuilder.build(), "position", 0, 1)
- .setListener(this)
- .build();
+ mFirstPageAnimator = firstPageBuilder
+ // Fade in the tiles/labels as we reach the final position.
+ .addFloat(tileLayout, "alpha", 0, 1)
+ .addFloat(quadraticInterpolatorBuilder.build(), "position", 0, 1)
+ .setListener(this)
+ .build();
- // Fade in the media player as we reach the final position
- Builder builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY);
- if (mQsPanelController.shouldUseHorizontalLayout()
- && mQsPanelController.mMediaHost.hostView != null) {
- builder.addFloat(mQsPanelController.mMediaHost.hostView, "alpha", 0, 1);
- } else {
- // In portrait, media view should always be visible
- mQsPanelController.mMediaHost.hostView.setAlpha(1.0f);
- }
- mAllPagesDelayedAnimator = builder.build();
- translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
- qqsTranslationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
- translationXBuilder.setInterpolator(mQSExpansionPathInterpolator.getXInterpolator());
- if (mOnFirstPage) {
- // Only recreate this animator if we're in the first page. That way we know that
- // the first page is attached and has the proper positions/measures.
- mQQSTranslationYAnimator = qqsTranslationYBuilder.build();
- }
- mTranslationYAnimator = translationYBuilder.build();
- mTranslationXAnimator = translationXBuilder.build();
- if (mQQSTileHeightAnimator != null) {
- mQQSTileHeightAnimator.setInterpolator(
- mQSExpansionPathInterpolator.getYInterpolator());
- }
- if (mOtherFirstPageTilesHeightAnimator != null) {
- mOtherFirstPageTilesHeightAnimator.setInterpolator(
- mQSExpansionPathInterpolator.getYInterpolator());
- }
+ // Fade in the media player as we reach the final position
+ Builder builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY);
+ if (mQsPanelController.shouldUseHorizontalLayout()
+ && mQsPanelController.mMediaHost.hostView != null) {
+ builder.addFloat(mQsPanelController.mMediaHost.hostView, "alpha", 0, 1);
+ } else {
+ // In portrait, media view should always be visible
+ mQsPanelController.mMediaHost.hostView.setAlpha(1.0f);
+ }
+ mAllPagesDelayedAnimator = builder.build();
+ translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
+ qqsTranslationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
+ translationXBuilder.setInterpolator(mQSExpansionPathInterpolator.getXInterpolator());
+ if (mOnFirstPage) {
+ // Only recreate this animator if we're in the first page. That way we know that
+ // the first page is attached and has the proper positions/measures.
+ mQQSTranslationYAnimator = qqsTranslationYBuilder.build();
+ }
+ mTranslationYAnimator = translationYBuilder.build();
+ mTranslationXAnimator = translationXBuilder.build();
+ if (mQQSTileHeightAnimator != null) {
+ mQQSTileHeightAnimator.setInterpolator(
+ mQSExpansionPathInterpolator.getYInterpolator());
+ }
+ if (mOtherFirstPageTilesHeightAnimator != null) {
+ mOtherFirstPageTilesHeightAnimator.setInterpolator(
+ mQSExpansionPathInterpolator.getYInterpolator());
}
mNonfirstPageAlphaAnimator = nonFirstPageAlphaBuilder
.addFloat(mQuickQsPanel, "alpha", 1, 0)
@@ -568,7 +551,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
if (animator == null) {
animator = new HeightExpansionAnimator(
- this, mLastQQSTileHeight, tileView.getMeasuredHeight());
+ this, mLastQQSTileHeight, tileView.getMeasuredHeight());
animator.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
}
animator.addView(tileView);
@@ -639,7 +622,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
}
private void getRelativePositionInt(int[] loc1, View view, View parent) {
- if(view == parent || view == null) return;
+ if (view == parent || view == null) return;
// Ignore tile pages as they can have some offset we don't want to take into account in
// RTL.
if (!isAPage(view)) {
@@ -672,7 +655,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
}
}
mLastPosition = position;
- if (!mAllowFancy) return;
if (mOnFirstPage) {
mQuickQsPanel.setAlpha(1);
mFirstPageAnimator.setPosition(position);
@@ -806,30 +788,31 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private final ValueAnimator.AnimatorUpdateListener mUpdateListener =
new ValueAnimator.AnimatorUpdateListener() {
- float mLastT = -1;
- @Override
- public void onAnimationUpdate(ValueAnimator valueAnimator) {
- float t = valueAnimator.getAnimatedFraction();
- final int viewCount = mViews.size();
- int height = (Integer) valueAnimator.getAnimatedValue();
- for (int i = 0; i < viewCount; i++) {
- View v = mViews.get(i);
- if (v instanceof HeightOverrideable) {
- ((HeightOverrideable) v).setHeightOverride(height);
- } else {
- v.setBottom(v.getTop() + height);
+ float mLastT = -1;
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ float t = valueAnimator.getAnimatedFraction();
+ final int viewCount = mViews.size();
+ int height = (Integer) valueAnimator.getAnimatedValue();
+ for (int i = 0; i < viewCount; i++) {
+ View v = mViews.get(i);
+ if (v instanceof HeightOverrideable) {
+ ((HeightOverrideable) v).setHeightOverride(height);
+ } else {
+ v.setBottom(v.getTop() + height);
+ }
+ }
+ if (t == 0f) {
+ mListener.onAnimationAtStart();
+ } else if (t == 1f) {
+ mListener.onAnimationAtEnd();
+ } else if (mLastT <= 0 || mLastT == 1) {
+ mListener.onAnimationStarted();
+ }
+ mLastT = t;
}
- }
- if (t == 0f) {
- mListener.onAnimationAtStart();
- } else if (t == 1f) {
- mListener.onAnimationAtEnd();
- } else if (mLastT <= 0 || mLastT == 1) {
- mListener.onAnimationStarted();
- }
- mLastT = t;
- }
- };
+ };
HeightExpansionAnimator(TouchAnimator.Listener listener, int startHeight, int endHeight) {
mListener = listener;