Merge "Animating the qs / notification bounds now when dismissing media" into sc-dev am: 5b4a42f6db
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15105255 Change-Id: I462706014650abd8c8b2124d573eb321496b01a8
This commit is contained in:
@@ -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<Boolean> listener);
|
||||
|
||||
@ProvidesInterface(version = HeightListener.VERSION)
|
||||
interface HeightListener {
|
||||
int VERSION = 1;
|
||||
|
||||
@@ -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<QSContainerImpl> BACKGROUND_BOTTOM =
|
||||
new FloatPropertyCompat<QSContainerImpl>("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<QSContainerImpl> 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() {
|
||||
|
||||
@@ -61,12 +61,6 @@ public class QSContainerImplController extends ViewController<QSContainerImpl> {
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
mView.updateResources(mQsPanelController, mQuickStatusBarHeaderController);
|
||||
mQsPanelController.setMediaVisibilityChangedListener((visible) -> {
|
||||
if (mQsPanelController.isShown()) {
|
||||
mView.onMediaVisibilityChanged(true);
|
||||
}
|
||||
});
|
||||
|
||||
mConfigurationController.addCallback(mConfigurationListener);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Boolean> listener) {
|
||||
mQuickQSPanelController.setMediaVisibilityChangedListener(listener);
|
||||
}
|
||||
|
||||
private void setEditLocation(View view) {
|
||||
View edit = view.findViewById(android.R.id.edit);
|
||||
int[] loc = edit.getLocationOnScreen();
|
||||
|
||||
@@ -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<Boolean> 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<Boolean> visibilityChangedListener) {
|
||||
mMediaVisibilityChangedListener = visibilityChangedListener;
|
||||
}
|
||||
|
||||
public boolean isListening() {
|
||||
return mListening;
|
||||
}
|
||||
|
||||
@@ -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<QSPanel> {
|
||||
mView.setPageListener(listener);
|
||||
}
|
||||
|
||||
/** */
|
||||
public void setMediaVisibilityChangedListener(Consumer<Boolean> visibilityChangedListener) {
|
||||
mView.setMediaVisibilityChangedListener(visibilityChangedListener);
|
||||
}
|
||||
|
||||
public boolean isShown() {
|
||||
return mView.isShown();
|
||||
}
|
||||
|
||||
@@ -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<T extends QSPanel> extends ViewContr
|
||||
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
|
||||
private boolean mShouldUseSplitNotificationShade;
|
||||
|
||||
@Nullable
|
||||
private Consumer<Boolean> mMediaVisibilityChangedListener;
|
||||
private int mLastOrientation;
|
||||
private String mCachedSpecs = "";
|
||||
private QSTileRevealController mQsTileRevealController;
|
||||
@@ -89,7 +94,9 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
|
||||
};
|
||||
|
||||
private final Function1<Boolean, Unit> mMediaHostVisibilityListener = (visible) -> {
|
||||
mView.onMediaVisibilityChanged(visible);
|
||||
if (mMediaVisibilityChangedListener != null) {
|
||||
mMediaVisibilityChangedListener.accept(visible);
|
||||
}
|
||||
switchTileLayout(false);
|
||||
return null;
|
||||
};
|
||||
@@ -136,7 +143,6 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
|
||||
}
|
||||
|
||||
mMediaHost.addVisibilityChangeListener(mMediaHostVisibilityListener);
|
||||
mView.onMediaVisibilityChanged(mMediaHost.getVisible());
|
||||
mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
|
||||
mHost.addCallback(mQSHostCallback);
|
||||
setTiles();
|
||||
@@ -381,6 +387,13 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
|
||||
return mView.getTileLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for when the media visibility changes.
|
||||
*/
|
||||
public void setMediaVisibilityChangedListener(@NonNull Consumer<Boolean> listener) {
|
||||
mMediaVisibilityChangedListener = listener;
|
||||
}
|
||||
|
||||
/** */
|
||||
public static final class TileRecord extends QSPanel.Record {
|
||||
public QSTile tile;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -1458,6 +1458,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
|
||||
*/
|
||||
|
||||
@@ -556,6 +556,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
|
||||
*/
|
||||
@@ -2214,7 +2219,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();
|
||||
@@ -2293,8 +2299,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();
|
||||
@@ -2470,8 +2475,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) {
|
||||
@@ -3470,7 +3477,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);
|
||||
@@ -3484,6 +3490,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();
|
||||
@@ -3500,6 +3513,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);
|
||||
|
||||
Reference in New Issue
Block a user