Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4d195d2 authored by Dave Mankoff's avatar Dave Mankoff Committed by Fabian Kozynski
Browse files

Refactor ExpandableView to maintain its own ExpandableViewState.

Bug: 119282834
Test: atest SystemUITests (and manual)
Change-Id: I2067488482d9f48767d8e2c9b37c69a40c3b0d88
parent 18b665d4
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.widget.TextView;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.StackScrollState;

public class EmptyShadeView extends StackScrollerDecorView {

@@ -74,7 +73,7 @@ public class EmptyShadeView extends StackScrollerDecorView {
    }

    @Override
    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
    public ExpandableViewState createExpandableViewState() {
        return new EmptyShadeViewState();
    }

+27 −29
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.StackScrollState;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.phone.NotificationIconContainer;

@@ -68,7 +67,6 @@ public class NotificationShelf extends ActivatableNotificationView implements

    private boolean mDark;
    private NotificationIconContainer mShelfIcons;
    private ShelfState mShelfState;
    private int[] mTmp = new int[2];
    private boolean mHideBackground;
    private int mIconAppearTopPadding;
@@ -115,7 +113,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
        setClipChildren(false);
        setClipToPadding(false);
        mShelfIcons.setIsStaticLayout(false);
        mShelfState = new ShelfState();
        setBottomRoundness(1.0f, false /* animate */);
        initDimens();
    }
@@ -187,52 +184,53 @@ public class NotificationShelf extends ActivatableNotificationView implements
    }

    @Override
    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
        return mShelfState;
    public ExpandableViewState createExpandableViewState() {
        return new ShelfState();
    }

    public void updateState(StackScrollState resultState,
            AmbientState ambientState) {
        View lastView = ambientState.getLastVisibleBackgroundChild();
    /** Update the state of the shelf. */
    public void updateState(AmbientState ambientState) {
        ExpandableView lastView = ambientState.getLastVisibleBackgroundChild();
        ShelfState viewState = (ShelfState) getViewState();
        if (mShowNotificationShelf && lastView != null) {
            float maxShelfEnd = ambientState.getInnerHeight() + ambientState.getTopPadding()
                    + ambientState.getStackTranslation();
            ExpandableViewState lastViewState = resultState.getViewStateForView(lastView);
            ExpandableViewState lastViewState = lastView.getViewState();
            float viewEnd = lastViewState.yTranslation + lastViewState.height;
            mShelfState.copyFrom(lastViewState);
            mShelfState.height = getIntrinsicHeight();
            viewState.copyFrom(lastViewState);
            viewState.height = getIntrinsicHeight();

            float awakenTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - mShelfState.height,
            float awakenTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height,
                    getFullyClosedTranslation());
            float darkTranslation = mAmbientState.getDarkTopPadding();
            float yRatio = mAmbientState.hasPulsingNotifications() ?
                    0 : mAmbientState.getDarkAmount();
            mShelfState.yTranslation = MathUtils.lerp(awakenTranslation, darkTranslation, yRatio);
            mShelfState.zTranslation = ambientState.getBaseZHeight();
            viewState.yTranslation = MathUtils.lerp(awakenTranslation, darkTranslation, yRatio);
            viewState.zTranslation = ambientState.getBaseZHeight();
            // For the small display size, it's not enough to make the icon not covered by
            // the top cutout so the denominator add the height of cutout.
            // Totally, (getIntrinsicHeight() * 2 + mCutoutHeight) should be smaller then
            // mAmbientState.getTopPadding().
            float openedAmount = (mShelfState.yTranslation - getFullyClosedTranslation())
            float openedAmount = (viewState.yTranslation - getFullyClosedTranslation())
                    / (getIntrinsicHeight() * 2 + mCutoutHeight);
            openedAmount = Math.min(1.0f, openedAmount);
            mShelfState.openedAmount = openedAmount;
            mShelfState.clipTopAmount = 0;
            mShelfState.alpha = mAmbientState.hasPulsingNotifications() ? 0 : 1;
            mShelfState.belowSpeedBump = mAmbientState.getSpeedBumpIndex() == 0;
            mShelfState.hideSensitive = false;
            mShelfState.xTranslation = getTranslationX();
            viewState.openedAmount = openedAmount;
            viewState.clipTopAmount = 0;
            viewState.alpha = mAmbientState.hasPulsingNotifications() ? 0 : 1;
            viewState.belowSpeedBump = mAmbientState.getSpeedBumpIndex() == 0;
            viewState.hideSensitive = false;
            viewState.xTranslation = getTranslationX();
            if (mNotGoneIndex != -1) {
                mShelfState.notGoneIndex = Math.min(mShelfState.notGoneIndex, mNotGoneIndex);
                viewState.notGoneIndex = Math.min(viewState.notGoneIndex, mNotGoneIndex);
            }
            mShelfState.hasItemsInStableShelf = lastViewState.inShelf;
            mShelfState.hidden = !mAmbientState.isShadeExpanded()
            viewState.hasItemsInStableShelf = lastViewState.inShelf;
            viewState.hidden = !mAmbientState.isShadeExpanded()
                    || mAmbientState.isQsCustomizerShowing();
            mShelfState.maxShelfEnd = maxShelfEnd;
            viewState.maxShelfEnd = maxShelfEnd;
        } else {
            mShelfState.hidden = true;
            mShelfState.location = ExpandableViewState.LOCATION_GONE;
            mShelfState.hasItemsInStableShelf = false;
            viewState.hidden = true;
            viewState.location = ExpandableViewState.LOCATION_GONE;
            viewState.hasItemsInStableShelf = false;
        }
    }

@@ -261,7 +259,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
        int notGoneIndex = 0;
        int colorOfViewBeforeLast = NO_COLOR;
        boolean backgroundForceHidden = false;
        if (mHideBackground && !mShelfState.hasItemsInStableShelf) {
        if (mHideBackground && !((ShelfState) getViewState()).hasItemsInStableShelf) {
            backgroundForceHidden = true;
        }
        int colorTwoBefore = NO_COLOR;
+29 −48
Original line number Diff line number Diff line
@@ -17,22 +17,14 @@
package com.android.systemui.statusbar.notification.row;

import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator
        .ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.row.NotificationContentView
        .VISIBLE_TYPE_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentView
        .VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView
        .VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.notification.row.NotificationInflater
        .FLAG_CONTENT_VIEW_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationInflater
        .FLAG_CONTENT_VIEW_HEADS_UP;
import static com.android.systemui.statusbar.notification.row.NotificationInflater
        .FLAG_CONTENT_VIEW_PUBLIC;
import static com.android.systemui.statusbar.notification.row.NotificationInflater
        .InflationCallback;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_PUBLIC;
import static com.android.systemui.statusbar.notification.row.NotificationInflater.InflationCallback;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -105,7 +97,6 @@ import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.StackScrollState;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -337,7 +328,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    private float mTranslationWhenRemoved;
    private boolean mWasChildInGroupWhenRemoved;
    private int mNotificationColorAmbient;
    private NotificationViewState mNotificationViewState;

    private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
            new SystemNotificationAsyncTask();
@@ -894,29 +884,32 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
                visualStabilityManager, callback);
    }

    public void getChildrenStates(StackScrollState resultState,
            AmbientState ambientState) {
    /** Updates states of all children. */
    public void updateChildrenStates(AmbientState ambientState) {
        if (mIsSummaryWithChildren) {
            ExpandableViewState parentState = resultState.getViewStateForView(this);
            mChildrenContainer.getState(resultState, parentState, ambientState);
            ExpandableViewState parentState = getViewState();
            mChildrenContainer.updateState(parentState, ambientState);
        }
    }

    public void applyChildrenState(StackScrollState state) {
    /** Applies children states. */
    public void applyChildrenState() {
        if (mIsSummaryWithChildren) {
            mChildrenContainer.applyState(state);
            mChildrenContainer.applyState();
        }
    }

    public void prepareExpansionChanged(StackScrollState state) {
    /** Prepares expansion changed. */
    public void prepareExpansionChanged() {
        if (mIsSummaryWithChildren) {
            mChildrenContainer.prepareExpansionChanged(state);
            mChildrenContainer.prepareExpansionChanged();
        }
    }

    public void startChildAnimation(StackScrollState finalState, AnimationProperties properties) {
    /** Starts child animations. */
    public void startChildAnimation(AnimationProperties properties) {
        if (mIsSummaryWithChildren) {
            mChildrenContainer.startAnimationToState(finalState, properties);
            mChildrenContainer.startAnimationToState(properties);
        }
    }

@@ -2047,7 +2040,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
                    .setInterpolator(Interpolators.ALPHA_OUT);
            setAboveShelf(true);
            mExpandAnimationRunning = true;
            mNotificationViewState.cancelAnimations(this);
            getViewState().cancelAnimations(this);
            mNotificationLaunchHeight = AmbientState.getNotificationLaunchHeight(getContext());
        } else {
            mExpandAnimationRunning = false;
@@ -2924,13 +2917,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    }

    @Override
    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
        mNotificationViewState = new NotificationViewState(stackScrollState);
        return mNotificationViewState;
    }

    public NotificationViewState getViewState() {
        return mNotificationViewState;
    public ExpandableViewState createExpandableViewState() {
        return new NotificationViewState();
    }

    @Override
@@ -3040,14 +3028,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        }
    }

    public static class NotificationViewState extends ExpandableViewState {

        private final StackScrollState mOverallState;


        private NotificationViewState(StackScrollState stackScrollState) {
            mOverallState = stackScrollState;
        }
    private static class NotificationViewState extends ExpandableViewState {

        @Override
        public void applyToView(View view) {
@@ -3058,7 +3039,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
                }
                handleFixedTranslationZ(row);
                super.applyToView(view);
                row.applyChildrenState(mOverallState);
                row.applyChildrenState();
            }
        }

@@ -3089,7 +3070,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
                }
                handleFixedTranslationZ(row);
                super.animateTo(child, properties);
                row.startChildAnimation(mOverallState, properties);
                row.startChildAnimation(properties);
            }
        }
    }
@@ -3144,8 +3125,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        pw.println();
        showingLayout.dump(fd, pw, args);
        pw.print("    ");
        if (mNotificationViewState != null) {
            mNotificationViewState.dump(fd, pw, args);
        if (getViewState() != null) {
            getViewState().dump(fd, pw, args);
        } else {
            pw.print("no viewState!!!");
        }
+53 −2
Original line number Diff line number Diff line
@@ -21,23 +21,27 @@ import android.content.Context;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.annotation.Nullable;

import com.android.systemui.Dumpable;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.StackScrollState;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * An abstract view for expandable views.
 */
public abstract class ExpandableView extends FrameLayout implements Dumpable {
    private static final String TAG = "ExpandableView";

    public static final float NO_ROUNDNESS = -1;
    protected OnHeightChangedListener mOnHeightChangedListener;
@@ -54,6 +58,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
    private ViewGroup mTransientContainer;
    private boolean mInShelf;
    private boolean mTransformingInShelf;
    @Nullable private ExpandableViewState mViewState;

    public ExpandableView(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -511,10 +516,56 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {

    public void setActualHeightAnimating(boolean animating) {}

    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
    protected ExpandableViewState createExpandableViewState() {
        return new ExpandableViewState();
    }

    /** Sets {@link ExpandableViewState} to default state. */
    public ExpandableViewState resetViewState() {
        // TODO(http://b/119762423): Move the null check to getViewState().
        if (mViewState == null) {
            mViewState = createExpandableViewState();
        }

        // initialize with the default values of the view
        mViewState.height = getIntrinsicHeight();
        mViewState.gone = getVisibility() == View.GONE;
        mViewState.alpha = 1f;
        mViewState.notGoneIndex = -1;
        mViewState.xTranslation = getTranslationX();
        mViewState.hidden = false;
        mViewState.scaleX = getScaleX();
        mViewState.scaleY = getScaleY();
        mViewState.inShelf = false;
        mViewState.headsUpIsVisible = false;

        // handling reset for child notifications
        if (this instanceof ExpandableNotificationRow) {
            ExpandableNotificationRow row = (ExpandableNotificationRow) this;
            List<ExpandableNotificationRow> children = row.getNotificationChildren();
            if (row.isSummaryWithChildren() && children != null) {
                for (ExpandableNotificationRow childRow : children) {
                    childRow.resetViewState();
                }
            }
        }

        return mViewState;
    }

    @Nullable public ExpandableViewState getViewState() {
        return mViewState;
    }

    /** Applies internal {@link ExpandableViewState} to this view. */
    public void applyViewState() {
        if (mViewState == null) {
            Log.wtf(TAG, "No child state was found when applying this state to the hostView");
        } else if (!mViewState.gone) {
            mViewState.applyToView(this);
        }
    }

    /**
     * @return whether the current view doesn't add height to the overall content. This means that
     * if it is added to a list of items, it's content will still have the same height.
+1 −2
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.view.View;

import com.android.systemui.R;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.StackScrollState;

public class FooterView extends StackScrollerDecorView {
    private final int mClearAllTopPadding;
@@ -87,7 +86,7 @@ public class FooterView extends StackScrollerDecorView {
    }

    @Override
    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
    public ExpandableViewState createExpandableViewState() {
        return new FooterViewState();
    }

Loading