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

Commit 29aab967 authored by Selim Cinek's avatar Selim Cinek
Browse files

Ensured that the heads-up notifications are always rounded

Previously they would have a random rounding. We're now introducing
a roundness manager that isolates this from the notification list.

Bug: 72748440
Test: runtest systemui
Change-Id: I5e9e7528a55536c802b5262168664e47fbec310e
parent 7924167a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1046,6 +1046,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
        return calculateBgColor(false /* withTint */, false /* withOverride */);
    }

    public boolean isPinned() {
        return false;
    }

    public boolean isHeadsUpAnimatingAway() {
        return false;
    }

    public interface OnActivatedListener {
        void onActivated(ActivatableNotificationView view);
        void onActivationReset(ActivatableNotificationView view);
+2 −0
Original line number Diff line number Diff line
@@ -722,6 +722,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        }
    }

    @Override
    public boolean isPinned() {
        return mIsPinned;
    }
@@ -1101,6 +1102,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
     * @return if the view was just heads upped and is now animating away. During such a time the
     * layout needs to be kept consistent
     */
    @Override
    public boolean isHeadsUpAnimatingAway() {
        return mHeadsupDisappearRunning;
    }
+14 −2
Original line number Diff line number Diff line
@@ -276,12 +276,18 @@ public abstract class ExpandableOutlineView extends ExpandableView {
        setClipToOutline(mAlwaysRoundBothCorners);
    }

    public void setTopRoundness(float topRoundness, boolean animate) {
    /**
     * Set the topRoundness of this view.
     * @return Whether the roundness was changed.
     */
    public boolean setTopRoundness(float topRoundness, boolean animate) {
        if (mTopRoundness != topRoundness) {
            mTopRoundness = topRoundness;
            PropertyAnimator.setProperty(this, TOP_ROUNDNESS, topRoundness,
                    ROUNDNESS_PROPERTIES, animate);
            return true;
        }
        return false;
    }

    protected void applyRoundness() {
@@ -305,12 +311,18 @@ public abstract class ExpandableOutlineView extends ExpandableView {
        return mCurrentBottomRoundness * mOutlineRadius;
    }

    public void setBottomRoundness(float bottomRoundness, boolean animate) {
    /**
     * Set the bottom roundness of this view.
     * @return Whether the roundness was changed.
     */
    public boolean setBottomRoundness(float bottomRoundness, boolean animate) {
        if (mBottomRoundness != bottomRoundness) {
            mBottomRoundness = bottomRoundness;
            PropertyAnimator.setProperty(this, BOTTOM_ROUNDNESS, bottomRoundness,
                    ROUNDNESS_PROPERTIES, animate);
            return true;
        }
        return false;
    }

    protected void setBackgroundTop(int backgroundTop) {
+109 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui.statusbar.stack;

import android.view.View;

import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;

import java.util.HashSet;

/**
 * A class that manages the roundness for notification views
 */
class NotificationRoundnessManager implements OnHeadsUpChangedListener {

    private boolean mExpanded;
    private ActivatableNotificationView mFirst;
    private ActivatableNotificationView mLast;
    private HashSet<View> mAnimatedChildren;
    private Runnable mRoundingChangedCallback;

    @Override
    public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
        updateRounding(headsUp, false /* animate */);
    }

    @Override
    public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
        updateRounding(headsUp, true /* animate */);
    }

    private void updateRounding(ActivatableNotificationView view, boolean animate) {
        float topRoundness = getRoundness(view, true /* top */);
        float bottomRoundness = getRoundness(view, false /* top */);
        boolean firstChanged = view.setTopRoundness(topRoundness, animate);
        boolean secondChanged = view.setBottomRoundness(bottomRoundness, animate);
        if ((view == mFirst || view == mLast) && (firstChanged || secondChanged)) {
            mRoundingChangedCallback.run();
        }
    }

    private float getRoundness(ActivatableNotificationView view, boolean top) {
        if ((view.isPinned() || view.isHeadsUpAnimatingAway()) && !mExpanded) {
            return 1.0f;
        }
        if (view == mFirst && top) {
            return 1.0f;
        }
        if (view == mLast && !top) {
            return 1.0f;
        }
        return 0.0f;
    }

    public void setExpanded(boolean expanded) {
        mExpanded = expanded;
    }

    public void setFirstAndLastBackgroundChild(ActivatableNotificationView first,
            ActivatableNotificationView last) {
        boolean firstChanged = mFirst != first;
        boolean lastChanged = mLast != last;
        if (!firstChanged && !lastChanged) {
            return;
        }
        ActivatableNotificationView oldFirst = mFirst;
        ActivatableNotificationView oldLast = mLast;
        mFirst = first;
        mLast = last;
        if (firstChanged && oldFirst != null && !oldFirst.isRemoved()) {
            updateRounding(oldFirst, oldFirst.isShown());
        }
        if (lastChanged && oldLast != null && !oldLast.isRemoved()) {
            updateRounding(oldLast, oldLast.isShown());
        }
        if (mFirst != null) {
            updateRounding(mFirst, mFirst.isShown() && !mAnimatedChildren.contains(mFirst));
        }
        if (mLast != null) {
            updateRounding(mLast, mLast.isShown() && !mAnimatedChildren.contains(mLast));
        }
        mRoundingChangedCallback.run();
    }

    public void setAnimatedChildren(HashSet<View> animatedChildren) {
        mAnimatedChildren = animatedChildren;
    }

    public void setOnRoundingChangedCallback(Runnable roundingChangedCallback) {
        mRoundingChangedCallback = roundingChangedCallback;
    }
}
+9 −28
Original line number Diff line number Diff line
@@ -289,6 +289,7 @@ public class NotificationStackScrollLayout extends ViewGroup
    private HashSet<Pair<ExpandableNotificationRow, Boolean>> mHeadsUpChangeAnimations
            = new HashSet<>();
    private HeadsUpManagerPhone mHeadsUpManager;
    private NotificationRoundnessManager mRoundnessManager = new NotificationRoundnessManager();
    private boolean mTrackingHeadsUp;
    private ScrimController mScrimController;
    private boolean mForceNoOverlappingRendering;
@@ -440,6 +441,8 @@ public class NotificationStackScrollLayout extends ViewGroup
        mSeparatorWidth = res.getDimensionPixelSize(R.dimen.widget_separator_width);
        mSeparatorThickness = res.getDimensionPixelSize(R.dimen.widget_separator_thickness);
        mDarkSeparatorPadding = res.getDimensionPixelSize(R.dimen.widget_bottom_separator_padding);
        mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
        mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);

        updateWillNotDraw();
        mBackgroundPaint.setAntiAlias(true);
@@ -2929,42 +2932,18 @@ public class NotificationStackScrollLayout extends ViewGroup
    private void updateFirstAndLastBackgroundViews() {
        ActivatableNotificationView firstChild = getFirstChildWithBackground();
        ActivatableNotificationView lastChild = getLastChildWithBackground();
        boolean firstChanged = firstChild != mFirstVisibleBackgroundChild;
        boolean lastChanged = lastChild != mLastVisibleBackgroundChild;
        if (mAnimationsEnabled && mIsExpanded) {
            mAnimateNextBackgroundTop = firstChanged;
            mAnimateNextBackgroundBottom = lastChanged;
            mAnimateNextBackgroundTop = firstChild != mFirstVisibleBackgroundChild;
            mAnimateNextBackgroundBottom = lastChild != mLastVisibleBackgroundChild;
        } else {
            mAnimateNextBackgroundTop = false;
            mAnimateNextBackgroundBottom = false;
        }
        if (firstChanged && mFirstVisibleBackgroundChild != null
                && !mFirstVisibleBackgroundChild.isRemoved()) {
            mFirstVisibleBackgroundChild.setTopRoundness(0.0f,
                    mFirstVisibleBackgroundChild.isShown());
        }
        if (lastChanged && mLastVisibleBackgroundChild != null
                && !mLastVisibleBackgroundChild.isRemoved()) {
            mLastVisibleBackgroundChild.setBottomRoundness(0.0f,
                    mLastVisibleBackgroundChild.isShown());
        }
        mFirstVisibleBackgroundChild = firstChild;
        mLastVisibleBackgroundChild = lastChild;
        mAmbientState.setLastVisibleBackgroundChild(lastChild);
        applyRoundedNess();
    }

    private void applyRoundedNess() {
        if (mFirstVisibleBackgroundChild != null) {
            mFirstVisibleBackgroundChild.setTopRoundness(1.0f,
                    mFirstVisibleBackgroundChild.isShown()
                            && !mChildrenToAddAnimated.contains(mFirstVisibleBackgroundChild));
        }
        if (mLastVisibleBackgroundChild != null) {
            mLastVisibleBackgroundChild.setBottomRoundness(1.0f,
                    mLastVisibleBackgroundChild.isShown()
                            && !mChildrenToAddAnimated.contains(mLastVisibleBackgroundChild));
        }
        mRoundnessManager.setFirstAndLastBackgroundChild(mFirstVisibleBackgroundChild,
                mLastVisibleBackgroundChild);
        invalidate();
    }

@@ -3572,6 +3551,7 @@ public class NotificationStackScrollLayout extends ViewGroup
    private void setIsExpanded(boolean isExpanded) {
        boolean changed = isExpanded != mIsExpanded;
        mIsExpanded = isExpanded;
        mRoundnessManager.setExpanded(isExpanded);
        mStackScrollAlgorithm.setIsExpanded(isExpanded);
        if (changed) {
            if (!mIsExpanded) {
@@ -4288,6 +4268,7 @@ public class NotificationStackScrollLayout extends ViewGroup
    public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
        mHeadsUpManager = headsUpManager;
        mAmbientState.setHeadsUpManager(headsUpManager);
        mHeadsUpManager.addListener(mRoundnessManager);
    }

    public void generateHeadsUpAnimation(ExpandableNotificationRow row, boolean isHeadsUp) {
Loading