diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java index 98ef9e20ac3b8..de2eca2b655cd 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java @@ -23,6 +23,8 @@ import com.android.systemui.plugins.annotations.DependsOn; import com.android.systemui.plugins.annotations.ProvidesInterface; import com.android.systemui.plugins.qs.QS.HeightListener; +import java.util.function.Consumer; + /** * Fragment that contains QS in the notification shade. Most of the interface is for * handling the expand/collapsing of the view interaction. @@ -33,7 +35,7 @@ public interface QS extends FragmentBase { String ACTION = "com.android.systemui.action.PLUGIN_QS"; - int VERSION = 9; + int VERSION = 10; String TAG = "QS"; @@ -101,6 +103,11 @@ public interface QS extends FragmentBase { return true; } + /** + * Add a listener for when the collapsed media visibility changes. + */ + void setCollapsedMediaVisibilityChangedListener(Consumer listener); + @ProvidesInterface(version = HeightListener.VERSION) interface HeightListener { int VERSION = 1; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index 6660081006cdc..74550f26b6e94 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -28,12 +28,8 @@ import android.view.View; import android.view.WindowInsets; import android.widget.FrameLayout; -import androidx.dynamicanimation.animation.FloatPropertyCompat; -import androidx.dynamicanimation.animation.SpringForce; - import com.android.systemui.R; import com.android.systemui.qs.customize.QSCustomizer; -import com.android.wm.shell.animation.PhysicsAnimator; /** * Wrapper view with background which contains {@link QSPanel} and {@link QuickStatusBarHeader} @@ -41,26 +37,10 @@ import com.android.wm.shell.animation.PhysicsAnimator; public class QSContainerImpl extends FrameLayout { private final Point mSizePoint = new Point(); - private static final FloatPropertyCompat BACKGROUND_BOTTOM = - new FloatPropertyCompat("backgroundBottom") { - @Override - public float getValue(QSContainerImpl qsImpl) { - return qsImpl.getBackgroundBottom(); - } - - @Override - public void setValue(QSContainerImpl background, float value) { - background.setBackgroundBottom((int) value); - } - }; - private static final PhysicsAnimator.SpringConfig BACKGROUND_SPRING - = new PhysicsAnimator.SpringConfig(SpringForce.STIFFNESS_MEDIUM, - SpringForce.DAMPING_RATIO_LOW_BOUNCY); private int mFancyClippingTop; private int mFancyClippingBottom; private final float[] mFancyClippingRadii = new float[] {0, 0, 0, 0, 0, 0, 0, 0}; private final Path mFancyClippingPath = new Path(); - private int mBackgroundBottom = 0; private int mHeightOverride = -1; private View mQSDetail; private QuickStatusBarHeader mHeader; @@ -71,7 +51,6 @@ public class QSContainerImpl extends FrameLayout { private int mSideMargins; private boolean mQsDisabled; private int mContentPadding = -1; - private boolean mAnimateBottomOnNextLayout; private int mNavBarInset = 0; private boolean mClippingEnabled; @@ -86,11 +65,6 @@ public class QSContainerImpl extends FrameLayout { mQSDetail = findViewById(R.id.qs_detail); mHeader = findViewById(R.id.header); mQSCustomizer = findViewById(R.id.qs_customize); - mHeader.getHeaderQsPanel().setMediaVisibilityChangedListener((visible) -> { - if (mHeader.getHeaderQsPanel().isShown()) { - mAnimateBottomOnNextLayout = true; - } - }); setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); } @@ -99,20 +73,6 @@ public class QSContainerImpl extends FrameLayout { return false; } - void onMediaVisibilityChanged(boolean qsVisible) { - mAnimateBottomOnNextLayout = qsVisible; - } - - private void setBackgroundBottom(int value) { - // We're saving the bottom separately since otherwise the bottom would be overridden in - // the layout and the animation wouldn't properly start at the old position. - mBackgroundBottom = value; - } - - private float getBackgroundBottom() { - return mBackgroundBottom; - } - @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -186,8 +146,7 @@ public class QSContainerImpl extends FrameLayout { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - updateExpansion(mAnimateBottomOnNextLayout /* animate */); - mAnimateBottomOnNextLayout = false; + updateExpansion(); updateClippingPath(); } @@ -230,31 +189,12 @@ public class QSContainerImpl extends FrameLayout { } public void updateExpansion() { - updateExpansion(false /* animate */); - } - - public void updateExpansion(boolean animate) { int height = calculateContainerHeight(); int scrollBottom = calculateContainerBottom(); setBottom(getTop() + height); mQSDetail.setBottom(getTop() + scrollBottom); int qsDetailBottomMargin = ((MarginLayoutParams) mQSDetail.getLayoutParams()).bottomMargin; mQSDetail.setBottom(getTop() + scrollBottom - qsDetailBottomMargin); - updateBackgroundBottom(scrollBottom, animate); - } - - private void updateBackgroundBottom(int height, boolean animated) { - PhysicsAnimator physicsAnimator = PhysicsAnimator.getInstance(this); - if (physicsAnimator.isPropertyAnimating(BACKGROUND_BOTTOM) || animated) { - // An animation is running or we want to animate - // Let's make sure to set the currentValue again, since the call below might only - // start in the next frame and otherwise we'd flicker - BACKGROUND_BOTTOM.setValue(this, BACKGROUND_BOTTOM.getValue(this)); - physicsAnimator.spring(BACKGROUND_BOTTOM, height, BACKGROUND_SPRING).start(); - } else { - BACKGROUND_BOTTOM.setValue(this, height); - } - } protected int calculateContainerHeight() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java index 3638395be29e2..7d61991c910a6 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImplController.java @@ -61,12 +61,6 @@ public class QSContainerImplController extends ViewController { @Override protected void onViewAttached() { mView.updateResources(mQsPanelController, mQuickStatusBarHeaderController); - mQsPanelController.setMediaVisibilityChangedListener((visible) -> { - if (mQsPanelController.isShown()) { - mView.onMediaVisibilityChanged(true); - } - }); - mConfigurationController.addCallback(mConfigurationListener); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java index c28c649b0306a..998cff2bb1fdd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java @@ -53,6 +53,8 @@ import com.android.systemui.util.InjectionInflationController; import com.android.systemui.util.LifecycleFragment; import com.android.systemui.util.Utils; +import java.util.function.Consumer; + import javax.inject.Inject; import javax.inject.Named; @@ -281,6 +283,11 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca return mLastQSExpansion == 0.0f || mLastQSExpansion == -1; } + @Override + public void setCollapsedMediaVisibilityChangedListener(Consumer listener) { + mQuickQSPanelController.setMediaVisibilityChangedListener(listener); + } + private void setEditLocation(View view) { View edit = view.findViewById(android.R.id.edit); int[] loc = edit.getLocationOnScreen(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index c70eaffcaeb6a..db8efd5301952 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -46,7 +46,6 @@ import com.android.systemui.util.animation.UniqueObjectHostView; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; /** View that represents the quick settings tile panel (when expanded/pulled down). **/ public class QSPanel extends LinearLayout implements Tunable { @@ -105,7 +104,6 @@ public class QSPanel extends LinearLayout implements Tunable { protected QSTileLayout mTileLayout; private int mLastOrientation = -1; private int mMediaTotalBottomMargin; - private Consumer mMediaVisibilityChangedListener; public QSPanel(Context context, AttributeSet attrs) { super(context, attrs); @@ -148,12 +146,6 @@ public class QSPanel extends LinearLayout implements Tunable { } } - protected void onMediaVisibilityChanged(Boolean visible) { - if (mMediaVisibilityChangedListener != null) { - mMediaVisibilityChangedListener.accept(visible); - } - } - /** * Add brightness view above the tile layout. * @@ -667,10 +659,6 @@ public class QSPanel extends LinearLayout implements Tunable { mHeaderContainer = headerContainer; } - public void setMediaVisibilityChangedListener(Consumer visibilityChangedListener) { - mMediaVisibilityChangedListener = visibilityChangedListener; - } - public boolean isListening() { return mListening; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java index ac92d4fe44e2f..9810e96ed199c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java @@ -45,8 +45,6 @@ import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.policy.BrightnessMirrorController; import com.android.systemui.tuner.TunerService; -import java.util.function.Consumer; - import javax.inject.Inject; import javax.inject.Named; @@ -289,11 +287,6 @@ public class QSPanelController extends QSPanelControllerBase { mView.setPageListener(listener); } - /** */ - public void setMediaVisibilityChangedListener(Consumer visibilityChangedListener) { - mView.setMediaVisibilityChangedListener(visibilityChangedListener); - } - public boolean isShown() { return mView.isShown(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java index 170785ca7aabc..77591b50c1038 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java @@ -19,6 +19,8 @@ package com.android.systemui.qs; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent; import static com.android.systemui.qs.dagger.QSFragmentModule.QS_USING_MEDIA_PLAYER; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.ComponentName; import android.content.res.Configuration; import android.metrics.LogMaker; @@ -42,6 +44,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; +import java.util.function.Consumer; import java.util.stream.Collectors; import javax.inject.Named; @@ -68,6 +71,8 @@ public abstract class QSPanelControllerBase extends ViewContr protected final ArrayList mRecords = new ArrayList<>(); private boolean mShouldUseSplitNotificationShade; + @Nullable + private Consumer mMediaVisibilityChangedListener; private int mLastOrientation; private String mCachedSpecs = ""; private QSTileRevealController mQsTileRevealController; @@ -89,7 +94,9 @@ public abstract class QSPanelControllerBase extends ViewContr }; private final Function1 mMediaHostVisibilityListener = (visible) -> { - mView.onMediaVisibilityChanged(visible); + if (mMediaVisibilityChangedListener != null) { + mMediaVisibilityChangedListener.accept(visible); + } switchTileLayout(false); return null; }; @@ -136,7 +143,6 @@ public abstract class QSPanelControllerBase extends ViewContr } mMediaHost.addVisibilityChangeListener(mMediaHostVisibilityListener); - mView.onMediaVisibilityChanged(mMediaHost.getVisible()); mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener); mHost.addCallback(mQSHostCallback); setTiles(); @@ -381,6 +387,13 @@ public abstract class QSPanelControllerBase extends ViewContr return mView.getTileLayout(); } + /** + * Add a listener for when the media visibility changes. + */ + public void setMediaVisibilityChangedListener(@NonNull Consumer listener) { + mMediaVisibilityChangedListener = listener; + } + /** */ public static final class TileRecord extends QSPanel.Record { public QSTile tile; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index bc6db245879c5..47e83fbd17ee4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -77,7 +77,6 @@ import com.android.settingslib.Utils; import com.android.systemui.Dumpable; import com.android.systemui.ExpandHelper; import com.android.systemui.R; -import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.Interpolators; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.statusbar.CommandQueue; @@ -201,6 +200,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private int mPaddingBetweenElements; private int mMaxTopPadding; private int mTopPadding; + private boolean mAnimateNextTopPaddingChange; private int mBottomMargin; private int mBottomInset = 0; private float mQsExpansionFraction; @@ -1212,16 +1212,18 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) private void setTopPadding(int topPadding, boolean animate) { if (mTopPadding != topPadding) { + boolean shouldAnimate = animate || mAnimateNextTopPaddingChange; mTopPadding = topPadding; updateAlgorithmHeightAndPadding(); updateContentHeight(); - if (animate && mAnimationsEnabled && mIsExpanded) { + if (shouldAnimate && mAnimationsEnabled && mIsExpanded) { mTopPaddingNeedsAnimation = true; mNeedsAnimation = true; } updateStackPosition(); requestChildrenUpdate(); - notifyHeightChangeListener(null, animate); + notifyHeightChangeListener(null, shouldAnimate); + mAnimateNextTopPaddingChange = false; } } @@ -5551,6 +5553,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable return mIsExpanded ? mQsScrollBoundaryPosition : 0; } + /** + * Request an animation whenever the toppadding changes next + */ + public void animateNextTopPaddingChange() { + mAnimateNextTopPaddingChange = true; + } + /** * A listener that is notified when the empty space below the notifications is clicked on */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index a4bffd4f223a0..a92682a76a9ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -1463,6 +1463,13 @@ public class NotificationStackScrollLayoutController { mView.setRoundedClippingBounds(left, top, right, bottom, topRadius, bottomRadius); } + /** + * Request an animation whenever the toppadding changes next + */ + public void animateNextTopPaddingChange() { + mView.animateNextTopPaddingChange(); + } + /** * Enum for UiEvent logged from this class */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index ff8b4be17eb05..2b37c6418647e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -558,6 +558,11 @@ public class NotificationPanelViewController extends PanelViewController { */ private long mNotificationBoundsAnimationDelay; + /** + * The duration of the notification bounds animation + */ + private long mNotificationBoundsAnimationDuration; + /** * Is this a collapse that started on the panel where we should allow the panel to intercept */ @@ -2227,7 +2232,8 @@ public class NotificationPanelViewController extends PanelViewController { private void onStackYChanged(boolean shouldAnimate) { if (mQs != null) { if (shouldAnimate) { - mAnimateNextNotificationBounds = true; + animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD, + 0 /* delay */); mNotificationBoundsAnimationDelay = 0; } setQSClippingBounds(); @@ -2307,8 +2313,7 @@ public class NotificationPanelViewController extends PanelViewController { final int startBottom = mKeyguardStatusAreaClipBounds.bottom; mQsClippingAnimation = ValueAnimator.ofFloat(0.0f, 1.0f); mQsClippingAnimation.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mQsClippingAnimation.setDuration( - StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE); + mQsClippingAnimation.setDuration(mNotificationBoundsAnimationDuration); mQsClippingAnimation.setStartDelay(mNotificationBoundsAnimationDelay); mQsClippingAnimation.addUpdateListener(animation -> { float fraction = animation.getAnimatedFraction(); @@ -2484,8 +2489,10 @@ public class NotificationPanelViewController extends PanelViewController { * shade. 0.0f means we're not transitioning yet. */ public void setTransitionToFullShadeAmount(float pxAmount, boolean animate, long delay) { - mAnimateNextNotificationBounds = animate && !mShouldUseSplitNotificationShade; - mNotificationBoundsAnimationDelay = delay; + if (animate && !mShouldUseSplitNotificationShade) { + animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, + delay); + } float endPosition = 0; if (pxAmount > 0.0f) { @@ -3484,7 +3491,6 @@ public class NotificationPanelViewController extends PanelViewController { mQs.setPanelView(mHeightListener); mQs.setExpandClickListener(mOnClickListener); mQs.setHeaderClickable(mQsExpansionEnabled); - mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade); updateQSPulseExpansion(); mQs.setOverscrolling(mStackScrollerOverscrolling); mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade); @@ -3498,6 +3504,13 @@ public class NotificationPanelViewController extends PanelViewController { mHeightListener.onQsHeightChanged(); } }); + mQs.setCollapsedMediaVisibilityChangedListener((visible) -> { + if (mQs.getHeader().isShown()) { + animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_STANDARD, + 0 /* delay */); + mNotificationStackScrollLayoutController.animateNextTopPaddingChange(); + } + }); mLockscreenShadeTransitionController.setQS(mQs); mNotificationStackScrollLayoutController.setQsContainer((ViewGroup) mQs.getView()); updateQsExpansion(); @@ -3514,6 +3527,12 @@ public class NotificationPanelViewController extends PanelViewController { } }; + private void animateNextNotificationBounds(long duration, long delay) { + mAnimateNextNotificationBounds = true; + mNotificationBoundsAnimationDuration = duration; + mNotificationBoundsAnimationDelay = delay; + } + @Override public void setTouchAndAnimationDisabled(boolean disabled) { super.setTouchAndAnimationDisabled(disabled);