Loading packages/SystemUI/res/values/dimens.xml +3 −0 Original line number Diff line number Diff line Loading @@ -478,6 +478,9 @@ <!-- The height of the divider between the individual notifications when the notification wants it to be increased. This is currently the case for notification groups --> <dimen name="notification_divider_height_increased">6dp</dimen> <!-- The height of the gap between adjacent notification sections. --> <dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen> <!-- The minimum amount of top overscroll to go to the quick settings. --> <dimen name="min_top_overscroll_to_qs">36dp</dimen> Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +22 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ public class NotificationShelf extends ActivatableNotificationView implements private float mFirstElementRoundness; private Rect mClipRect = new Rect(); private int mCutoutHeight; private int mGapHeight; private final StateListener mStateListener = this::setStatusBarState; Loading Loading @@ -154,6 +155,7 @@ public class NotificationShelf extends ActivatableNotificationView implements mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold); mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf); mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size); mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding); if (!mShowNotificationShelf) { setVisibility(GONE); Loading Loading @@ -276,6 +278,7 @@ public class NotificationShelf extends ActivatableNotificationView implements int baseZHeight = mAmbientState.getBaseZHeight(); int backgroundTop = 0; float firstElementRoundness = 0.0f; ExpandableNotificationRow previousRow = null; for (int i = 0; i < mHostLayout.getChildCount(); i++) { ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i); Loading Loading @@ -343,8 +346,27 @@ public class NotificationShelf extends ActivatableNotificationView implements + " \n number of notifications: " + mHostLayout.getChildCount() ); } } if (row.isFirstInSection() && previousRow != null && previousRow.isLastInSection()) { // If the top of the shelf is between the view before a gap and the view after a gap // then we need to adjust the shelf's top roundness. float distanceToGapBottom = row.getTranslationY() - getTranslationY(); float distanceToGapTop = getTranslationY() - (previousRow.getTranslationY() + previousRow.getActualHeight()); if (distanceToGapTop > 0) { // We interpolate our top roundness so that it's fully rounded if we're at the // bottom of the gap, and not rounded at all if we're at the top of the gap // (directly up against the bottom of previousRow) // Then we apply the same roundness to the bottom of previousRow so that the // corners join together as the shelf approaches previousRow. firstElementRoundness = (float) Math.min(1.0, distanceToGapTop / mGapHeight); previousRow.setBottomRoundness(firstElementRoundness, false /* don't animate */); backgroundTop = (int) distanceToGapBottom; } } notGoneIndex++; previousColor = ownColorUntinted; previousRow = row; } clipTransientViews(); Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +29 −1 Original line number Diff line number Diff line Loading @@ -40,9 +40,9 @@ import com.android.systemui.classifier.FalsingManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.phone.DoubleTapHelper; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.DoubleTapHelper; /** * Base class for both {@link ExpandableNotificationRow} and {@link NotificationShelf} Loading Loading @@ -134,6 +134,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private float mAppearAnimationFraction = -1.0f; private float mAppearAnimationTranslation; private int mNormalColor; private boolean mLastInSection; private boolean mFirstInSection; private boolean mIsBelowSpeedBump; private FalsingManager mFalsingManager; Loading Loading @@ -533,6 +535,32 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundDimmed.setDistanceToTopRoundness(distanceToTopRoundness); } public boolean isLastInSection() { return mLastInSection; } public boolean isFirstInSection() { return mFirstInSection; } /** Sets whether this view is the last notification in a section. */ public void setLastInSection(boolean lastInSection) { if (lastInSection != mLastInSection) { mLastInSection = lastInSection; mBackgroundNormal.setLastInSection(lastInSection); mBackgroundDimmed.setLastInSection(lastInSection); } } /** Sets whether this view is the first notification in a section. */ public void setFirstInSection(boolean firstInSection) { if (firstInSection != mFirstInSection) { mFirstInSection = firstInSection; mBackgroundNormal.setFirstInSection(firstInSection); mBackgroundDimmed.setFirstInSection(firstInSection); } } /** * Set an override tint color that is used for the background. * Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java +33 −10 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ public class NotificationBackgroundView extends View { private int mTintColor; private float[] mCornerRadii = new float[8]; private boolean mBottomIsRounded; private boolean mLastInSection; private boolean mFirstInSection; private int mBackgroundTop; private boolean mBottomAmountClips = true; private boolean mExpandAnimationRunning; Loading Loading @@ -79,7 +81,10 @@ public class NotificationBackgroundView extends View { if (drawable != null) { int top = mBackgroundTop; int bottom = mActualHeight; if (mBottomIsRounded && mBottomAmountClips && !mExpandAnimationRunning) { if (mBottomIsRounded && mBottomAmountClips && !mExpandAnimationRunning && !mLastInSection) { bottom -= mClipBottomAmount; } int left = 0; Loading @@ -90,8 +95,10 @@ public class NotificationBackgroundView extends View { } if (mTopAmountRounded) { int clipTop = (int) (mClipTopAmount - mDistanceToTopRoundness); if (clipTop >= 0 || !mFirstInSection) { top += clipTop; if (clipTop >= 0) { } if (clipTop >= 0 && !mLastInSection) { bottom += clipTop; } } Loading Loading @@ -216,19 +223,23 @@ public class NotificationBackgroundView extends View { mBackground.setAlpha(drawableAlpha); } public void setRoundness(float topRoundness, float bottomRoundNess) { if (topRoundness == mCornerRadii[0] && bottomRoundNess == mCornerRadii[4]) { /** * Sets the current top and bottom roundness amounts for this background, between 0.0 (not * rounded) and 1.0 (maximally rounded). */ public void setRoundness(float topRoundness, float bottomRoundness) { if (topRoundness == mCornerRadii[0] && bottomRoundness == mCornerRadii[4]) { return; } mBottomIsRounded = bottomRoundNess != 0.0f; mBottomIsRounded = bottomRoundness != 0.0f; mCornerRadii[0] = topRoundness; mCornerRadii[1] = topRoundness; mCornerRadii[2] = topRoundness; mCornerRadii[3] = topRoundness; mCornerRadii[4] = bottomRoundNess; mCornerRadii[5] = bottomRoundNess; mCornerRadii[6] = bottomRoundNess; mCornerRadii[7] = bottomRoundNess; mCornerRadii[4] = bottomRoundness; mCornerRadii[5] = bottomRoundness; mCornerRadii[6] = bottomRoundness; mCornerRadii[7] = bottomRoundness; updateBackgroundRadii(); } Loading @@ -239,6 +250,18 @@ public class NotificationBackgroundView extends View { } } /** Sets whether this background belongs to the last notification in a section. */ public void setLastInSection(boolean lastInSection) { mLastInSection = lastInSection; invalidate(); } /** Sets whether this background belongs to the first notification in a section. */ public void setFirstInSection(boolean firstInSection) { mFirstInSection = firstInSection; invalidate(); } private void updateBackgroundRadii() { if (mDontModifyCorners) { return; Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +31 −4 Original line number Diff line number Diff line Loading @@ -22,27 +22,32 @@ import android.view.View; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.NotificationShelf; import java.util.ArrayList; import java.util.List; /** * A global state to track all input states for the algorithm. */ public class AmbientState { private ArrayList<View> mDraggedViews = new ArrayList<View>(); private static final int NO_SECTION_BOUNDARY = -1; private ArrayList<View> mDraggedViews = new ArrayList<>(); private int mScrollY; private boolean mDimmed; private ActivatableNotificationView mActivatedChild; private float mOverScrollTopAmount; private float mOverScrollBottomAmount; private int mSpeedBumpIndex = -1; private final List<Integer> mSectionBoundaryIndices = new ArrayList<>(); private boolean mDark; private boolean mHideSensitive; private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class); Loading Loading @@ -75,6 +80,7 @@ public class AmbientState { private boolean mAppearing; public AmbientState(Context context) { mSectionBoundaryIndices.add(NO_SECTION_BOUNDARY); reload(context); } Loading Loading @@ -208,6 +214,27 @@ public class AmbientState { mSpeedBumpIndex = shelfIndex; } /** * Returns the index of the boundary between two sections, where the first section is at index * {@code boundaryNum}. */ public int getSectionBoundaryIndex(int boundaryNum) { return mSectionBoundaryIndices.get(boundaryNum); } /** Returns true if the item at {@code index} is directly below a section boundary. */ public boolean beginsNewSection(int index) { return mSectionBoundaryIndices.contains(index); } /** * Sets the index of the boundary between the section at {@code boundaryNum} and the following * section to {@code boundaryIndex}. */ public void setSectionBoundaryIndex(int boundaryNum, int boundaryIndex) { mSectionBoundaryIndices.set(boundaryNum, boundaryIndex); } public float getStackTranslation() { return mStackTranslation; } Loading Loading
packages/SystemUI/res/values/dimens.xml +3 −0 Original line number Diff line number Diff line Loading @@ -478,6 +478,9 @@ <!-- The height of the divider between the individual notifications when the notification wants it to be increased. This is currently the case for notification groups --> <dimen name="notification_divider_height_increased">6dp</dimen> <!-- The height of the gap between adjacent notification sections. --> <dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen> <!-- The minimum amount of top overscroll to go to the quick settings. --> <dimen name="min_top_overscroll_to_qs">36dp</dimen> Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +22 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ public class NotificationShelf extends ActivatableNotificationView implements private float mFirstElementRoundness; private Rect mClipRect = new Rect(); private int mCutoutHeight; private int mGapHeight; private final StateListener mStateListener = this::setStatusBarState; Loading Loading @@ -154,6 +155,7 @@ public class NotificationShelf extends ActivatableNotificationView implements mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold); mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf); mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size); mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding); if (!mShowNotificationShelf) { setVisibility(GONE); Loading Loading @@ -276,6 +278,7 @@ public class NotificationShelf extends ActivatableNotificationView implements int baseZHeight = mAmbientState.getBaseZHeight(); int backgroundTop = 0; float firstElementRoundness = 0.0f; ExpandableNotificationRow previousRow = null; for (int i = 0; i < mHostLayout.getChildCount(); i++) { ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i); Loading Loading @@ -343,8 +346,27 @@ public class NotificationShelf extends ActivatableNotificationView implements + " \n number of notifications: " + mHostLayout.getChildCount() ); } } if (row.isFirstInSection() && previousRow != null && previousRow.isLastInSection()) { // If the top of the shelf is between the view before a gap and the view after a gap // then we need to adjust the shelf's top roundness. float distanceToGapBottom = row.getTranslationY() - getTranslationY(); float distanceToGapTop = getTranslationY() - (previousRow.getTranslationY() + previousRow.getActualHeight()); if (distanceToGapTop > 0) { // We interpolate our top roundness so that it's fully rounded if we're at the // bottom of the gap, and not rounded at all if we're at the top of the gap // (directly up against the bottom of previousRow) // Then we apply the same roundness to the bottom of previousRow so that the // corners join together as the shelf approaches previousRow. firstElementRoundness = (float) Math.min(1.0, distanceToGapTop / mGapHeight); previousRow.setBottomRoundness(firstElementRoundness, false /* don't animate */); backgroundTop = (int) distanceToGapBottom; } } notGoneIndex++; previousColor = ownColorUntinted; previousRow = row; } clipTransientViews(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +29 −1 Original line number Diff line number Diff line Loading @@ -40,9 +40,9 @@ import com.android.systemui.classifier.FalsingManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.phone.DoubleTapHelper; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.DoubleTapHelper; /** * Base class for both {@link ExpandableNotificationRow} and {@link NotificationShelf} Loading Loading @@ -134,6 +134,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private float mAppearAnimationFraction = -1.0f; private float mAppearAnimationTranslation; private int mNormalColor; private boolean mLastInSection; private boolean mFirstInSection; private boolean mIsBelowSpeedBump; private FalsingManager mFalsingManager; Loading Loading @@ -533,6 +535,32 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundDimmed.setDistanceToTopRoundness(distanceToTopRoundness); } public boolean isLastInSection() { return mLastInSection; } public boolean isFirstInSection() { return mFirstInSection; } /** Sets whether this view is the last notification in a section. */ public void setLastInSection(boolean lastInSection) { if (lastInSection != mLastInSection) { mLastInSection = lastInSection; mBackgroundNormal.setLastInSection(lastInSection); mBackgroundDimmed.setLastInSection(lastInSection); } } /** Sets whether this view is the first notification in a section. */ public void setFirstInSection(boolean firstInSection) { if (firstInSection != mFirstInSection) { mFirstInSection = firstInSection; mBackgroundNormal.setFirstInSection(firstInSection); mBackgroundDimmed.setFirstInSection(firstInSection); } } /** * Set an override tint color that is used for the background. * Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java +33 −10 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ public class NotificationBackgroundView extends View { private int mTintColor; private float[] mCornerRadii = new float[8]; private boolean mBottomIsRounded; private boolean mLastInSection; private boolean mFirstInSection; private int mBackgroundTop; private boolean mBottomAmountClips = true; private boolean mExpandAnimationRunning; Loading Loading @@ -79,7 +81,10 @@ public class NotificationBackgroundView extends View { if (drawable != null) { int top = mBackgroundTop; int bottom = mActualHeight; if (mBottomIsRounded && mBottomAmountClips && !mExpandAnimationRunning) { if (mBottomIsRounded && mBottomAmountClips && !mExpandAnimationRunning && !mLastInSection) { bottom -= mClipBottomAmount; } int left = 0; Loading @@ -90,8 +95,10 @@ public class NotificationBackgroundView extends View { } if (mTopAmountRounded) { int clipTop = (int) (mClipTopAmount - mDistanceToTopRoundness); if (clipTop >= 0 || !mFirstInSection) { top += clipTop; if (clipTop >= 0) { } if (clipTop >= 0 && !mLastInSection) { bottom += clipTop; } } Loading Loading @@ -216,19 +223,23 @@ public class NotificationBackgroundView extends View { mBackground.setAlpha(drawableAlpha); } public void setRoundness(float topRoundness, float bottomRoundNess) { if (topRoundness == mCornerRadii[0] && bottomRoundNess == mCornerRadii[4]) { /** * Sets the current top and bottom roundness amounts for this background, between 0.0 (not * rounded) and 1.0 (maximally rounded). */ public void setRoundness(float topRoundness, float bottomRoundness) { if (topRoundness == mCornerRadii[0] && bottomRoundness == mCornerRadii[4]) { return; } mBottomIsRounded = bottomRoundNess != 0.0f; mBottomIsRounded = bottomRoundness != 0.0f; mCornerRadii[0] = topRoundness; mCornerRadii[1] = topRoundness; mCornerRadii[2] = topRoundness; mCornerRadii[3] = topRoundness; mCornerRadii[4] = bottomRoundNess; mCornerRadii[5] = bottomRoundNess; mCornerRadii[6] = bottomRoundNess; mCornerRadii[7] = bottomRoundNess; mCornerRadii[4] = bottomRoundness; mCornerRadii[5] = bottomRoundness; mCornerRadii[6] = bottomRoundness; mCornerRadii[7] = bottomRoundness; updateBackgroundRadii(); } Loading @@ -239,6 +250,18 @@ public class NotificationBackgroundView extends View { } } /** Sets whether this background belongs to the last notification in a section. */ public void setLastInSection(boolean lastInSection) { mLastInSection = lastInSection; invalidate(); } /** Sets whether this background belongs to the first notification in a section. */ public void setFirstInSection(boolean firstInSection) { mFirstInSection = firstInSection; invalidate(); } private void updateBackgroundRadii() { if (mDontModifyCorners) { return; Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +31 −4 Original line number Diff line number Diff line Loading @@ -22,27 +22,32 @@ import android.view.View; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.AmbientPulseManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.NotificationData; import com.android.systemui.statusbar.NotificationShelf; import java.util.ArrayList; import java.util.List; /** * A global state to track all input states for the algorithm. */ public class AmbientState { private ArrayList<View> mDraggedViews = new ArrayList<View>(); private static final int NO_SECTION_BOUNDARY = -1; private ArrayList<View> mDraggedViews = new ArrayList<>(); private int mScrollY; private boolean mDimmed; private ActivatableNotificationView mActivatedChild; private float mOverScrollTopAmount; private float mOverScrollBottomAmount; private int mSpeedBumpIndex = -1; private final List<Integer> mSectionBoundaryIndices = new ArrayList<>(); private boolean mDark; private boolean mHideSensitive; private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class); Loading Loading @@ -75,6 +80,7 @@ public class AmbientState { private boolean mAppearing; public AmbientState(Context context) { mSectionBoundaryIndices.add(NO_SECTION_BOUNDARY); reload(context); } Loading Loading @@ -208,6 +214,27 @@ public class AmbientState { mSpeedBumpIndex = shelfIndex; } /** * Returns the index of the boundary between two sections, where the first section is at index * {@code boundaryNum}. */ public int getSectionBoundaryIndex(int boundaryNum) { return mSectionBoundaryIndices.get(boundaryNum); } /** Returns true if the item at {@code index} is directly below a section boundary. */ public boolean beginsNewSection(int index) { return mSectionBoundaryIndices.contains(index); } /** * Sets the index of the boundary between the section at {@code boundaryNum} and the following * section to {@code boundaryIndex}. */ public void setSectionBoundaryIndex(int boundaryNum, int boundaryIndex) { mSectionBoundaryIndices.set(boundaryNum, boundaryIndex); } public float getStackTranslation() { return mStackTranslation; } Loading