Merge "Define clear ownership for roundness SourceType" into tm-qpr-dev am: 446cb95aa1
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20494945 Change-Id: I71376cbc2b732ba8fcbe817171984793cd72b3ce Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -83,8 +83,7 @@ object Flags {
|
|||||||
val SEMI_STABLE_SORT = unreleasedFlag(115, "semi_stable_sort", teamfood = true)
|
val SEMI_STABLE_SORT = unreleasedFlag(115, "semi_stable_sort", teamfood = true)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val NOTIFICATION_GROUP_CORNER =
|
val USE_ROUNDNESS_SOURCETYPES = unreleasedFlag(116, "use_roundness_sourcetype", teamfood = true)
|
||||||
unreleasedFlag(116, "notification_group_corner", teamfood = true)
|
|
||||||
|
|
||||||
// TODO(b/259217907)
|
// TODO(b/259217907)
|
||||||
@JvmField
|
@JvmField
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import com.android.systemui.R;
|
|||||||
import com.android.systemui.animation.Interpolators;
|
import com.android.systemui.animation.Interpolators;
|
||||||
import com.android.systemui.animation.ShadeInterpolation;
|
import com.android.systemui.animation.ShadeInterpolation;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
|
||||||
|
import com.android.systemui.statusbar.notification.LegacySourceType;
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||||
import com.android.systemui.statusbar.notification.SourceType;
|
import com.android.systemui.statusbar.notification.SourceType;
|
||||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||||
@@ -66,6 +67,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
// the next icon has translated out of the way, to avoid overlapping.
|
// the next icon has translated out of the way, to avoid overlapping.
|
||||||
private static final Interpolator ICON_ALPHA_INTERPOLATOR =
|
private static final Interpolator ICON_ALPHA_INTERPOLATOR =
|
||||||
new PathInterpolator(0.6f, 0f, 0.6f, 0f);
|
new PathInterpolator(0.6f, 0f, 0.6f, 0f);
|
||||||
|
private static final SourceType BASE_VALUE = SourceType.from("BaseValue");
|
||||||
|
private static final SourceType SHELF_SCROLL = SourceType.from("ShelfScroll");
|
||||||
|
|
||||||
private NotificationIconContainer mShelfIcons;
|
private NotificationIconContainer mShelfIcons;
|
||||||
private int[] mTmp = new int[2];
|
private int[] mTmp = new int[2];
|
||||||
@@ -112,19 +115,24 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
setClipChildren(false);
|
setClipChildren(false);
|
||||||
setClipToPadding(false);
|
setClipToPadding(false);
|
||||||
mShelfIcons.setIsStaticLayout(false);
|
mShelfIcons.setIsStaticLayout(false);
|
||||||
requestBottomRoundness(1.0f, /* animate = */ false, SourceType.DefaultValue);
|
requestRoundness(/* top = */ 1f, /* bottom = */ 1f, BASE_VALUE, /* animate = */ false);
|
||||||
requestTopRoundness(1f, false, SourceType.DefaultValue);
|
|
||||||
|
|
||||||
// Setting this to first in section to get the clipping to the top roundness correct. This
|
if (!mUseRoundnessSourceTypes) {
|
||||||
// value determines the way we are clipping to the top roundness of the overall shade
|
// Setting this to first in section to get the clipping to the top roundness correct.
|
||||||
setFirstInSection(true);
|
// This value determines the way we are clipping to the top roundness of the overall
|
||||||
|
// shade
|
||||||
|
setFirstInSection(true);
|
||||||
|
}
|
||||||
updateResources();
|
updateResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(AmbientState ambientState,
|
public void bind(AmbientState ambientState,
|
||||||
NotificationStackScrollLayoutController hostLayoutController) {
|
NotificationStackScrollLayoutController hostLayoutController) {
|
||||||
mAmbientState = ambientState;
|
mAmbientState = ambientState;
|
||||||
mHostLayoutController = hostLayoutController;
|
mHostLayoutController = hostLayoutController;
|
||||||
|
hostLayoutController.setOnNotificationRemovedListener((child, isTransferInProgress) -> {
|
||||||
|
child.requestRoundnessReset(SHELF_SCROLL);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateResources() {
|
private void updateResources() {
|
||||||
@@ -185,9 +193,11 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
+ " indexOfFirstViewInShelf=" + mIndexOfFirstViewInShelf + ')';
|
+ " indexOfFirstViewInShelf=" + mIndexOfFirstViewInShelf + ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update the state of the shelf. */
|
/**
|
||||||
|
* Update the state of the shelf.
|
||||||
|
*/
|
||||||
public void updateState(StackScrollAlgorithm.StackScrollAlgorithmState algorithmState,
|
public void updateState(StackScrollAlgorithm.StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState) {
|
AmbientState ambientState) {
|
||||||
ExpandableView lastView = ambientState.getLastVisibleBackgroundChild();
|
ExpandableView lastView = ambientState.getLastVisibleBackgroundChild();
|
||||||
ShelfState viewState = (ShelfState) getViewState();
|
ShelfState viewState = (ShelfState) getViewState();
|
||||||
if (mShowNotificationShelf && lastView != null) {
|
if (mShowNotificationShelf && lastView != null) {
|
||||||
@@ -246,7 +256,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param fractionToShade Fraction of lockscreen to shade transition
|
* @param fractionToShade Fraction of lockscreen to shade transition
|
||||||
* @param shortestWidth Shortest width to use for lockscreen shelf
|
* @param shortestWidth Shortest width to use for lockscreen shelf
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public void updateActualWidth(float fractionToShade, float shortestWidth) {
|
public void updateActualWidth(float fractionToShade, float shortestWidth) {
|
||||||
@@ -281,9 +291,9 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param localX Click x from left of screen
|
* @param localX Click x from left of screen
|
||||||
* @param slop Margin of error within which we count x for valid click
|
* @param slop Margin of error within which we count x for valid click
|
||||||
* @param left Left of shelf, from left of screen
|
* @param left Left of shelf, from left of screen
|
||||||
* @param right Right of shelf, from left of screen
|
* @param right Right of shelf, from left of screen
|
||||||
* @return Whether click x was in view
|
* @return Whether click x was in view
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -293,8 +303,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param localY Click y from top of shelf
|
* @param localY Click y from top of shelf
|
||||||
* @param slop Margin of error within which we count y for valid click
|
* @param slop Margin of error within which we count y for valid click
|
||||||
* @param top Top of shelf
|
* @param top Top of shelf
|
||||||
* @param bottom Height of shelf
|
* @param bottom Height of shelf
|
||||||
* @return Whether click y was in view
|
* @return Whether click y was in view
|
||||||
*/
|
*/
|
||||||
@@ -306,7 +316,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
/**
|
/**
|
||||||
* @param localX Click x
|
* @param localX Click x
|
||||||
* @param localY Click y
|
* @param localY Click y
|
||||||
* @param slop Margin of error for valid click
|
* @param slop Margin of error for valid click
|
||||||
* @return Whether this click was on the visible (non-clipped) part of the shelf
|
* @return Whether this click was on the visible (non-clipped) part of the shelf
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -478,13 +488,15 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCornerRoundnessOnScroll(ActivatableNotificationView anv, float viewStart,
|
private void updateCornerRoundnessOnScroll(
|
||||||
|
ActivatableNotificationView anv,
|
||||||
|
float viewStart,
|
||||||
float shelfStart) {
|
float shelfStart) {
|
||||||
|
|
||||||
final boolean isUnlockedHeadsUp = !mAmbientState.isOnKeyguard()
|
final boolean isUnlockedHeadsUp = !mAmbientState.isOnKeyguard()
|
||||||
&& !mAmbientState.isShadeExpanded()
|
&& !mAmbientState.isShadeExpanded()
|
||||||
&& anv instanceof ExpandableNotificationRow
|
&& anv instanceof ExpandableNotificationRow
|
||||||
&& ((ExpandableNotificationRow) anv).isHeadsUp();
|
&& anv.isHeadsUp();
|
||||||
|
|
||||||
final boolean isHunGoingToShade = mAmbientState.isShadeExpanded()
|
final boolean isHunGoingToShade = mAmbientState.isShadeExpanded()
|
||||||
&& anv == mAmbientState.getTrackedHeadsUpRow();
|
&& anv == mAmbientState.getTrackedHeadsUpRow();
|
||||||
@@ -506,41 +518,40 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
* mAmbientState.getExpansionFraction();
|
* mAmbientState.getExpansionFraction();
|
||||||
final float cornerAnimationTop = shelfStart - cornerAnimationDistance;
|
final float cornerAnimationTop = shelfStart - cornerAnimationDistance;
|
||||||
|
|
||||||
if (viewEnd >= cornerAnimationTop) {
|
final SourceType sourceType;
|
||||||
// Round bottom corners within animation bounds
|
if (mUseRoundnessSourceTypes) {
|
||||||
final float changeFraction = MathUtils.saturate(
|
sourceType = SHELF_SCROLL;
|
||||||
(viewEnd - cornerAnimationTop) / cornerAnimationDistance);
|
} else {
|
||||||
anv.requestBottomRoundness(
|
sourceType = LegacySourceType.OnScroll;
|
||||||
/* value = */ anv.isLastInSection() ? 1f : changeFraction,
|
|
||||||
/* animate = */ false,
|
|
||||||
SourceType.OnScroll);
|
|
||||||
|
|
||||||
} else if (viewEnd < cornerAnimationTop) {
|
|
||||||
// Fast scroll skips frames and leaves corners with unfinished rounding.
|
|
||||||
// Reset top and bottom corners outside of animation bounds.
|
|
||||||
anv.requestBottomRoundness(
|
|
||||||
/* value = */ anv.isLastInSection() ? 1f : 0f,
|
|
||||||
/* animate = */ false,
|
|
||||||
SourceType.OnScroll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewStart >= cornerAnimationTop) {
|
final float topValue;
|
||||||
|
if (!mUseRoundnessSourceTypes && anv.isFirstInSection()) {
|
||||||
|
topValue = 1f;
|
||||||
|
} else if (viewStart >= cornerAnimationTop) {
|
||||||
// Round top corners within animation bounds
|
// Round top corners within animation bounds
|
||||||
final float changeFraction = MathUtils.saturate(
|
topValue = MathUtils.saturate(
|
||||||
(viewStart - cornerAnimationTop) / cornerAnimationDistance);
|
(viewStart - cornerAnimationTop) / cornerAnimationDistance);
|
||||||
anv.requestTopRoundness(
|
} else {
|
||||||
/* value = */ anv.isFirstInSection() ? 1f : changeFraction,
|
|
||||||
/* animate = */ false,
|
|
||||||
SourceType.OnScroll);
|
|
||||||
|
|
||||||
} else if (viewStart < cornerAnimationTop) {
|
|
||||||
// Fast scroll skips frames and leaves corners with unfinished rounding.
|
// Fast scroll skips frames and leaves corners with unfinished rounding.
|
||||||
// Reset top and bottom corners outside of animation bounds.
|
// Reset top and bottom corners outside of animation bounds.
|
||||||
anv.requestTopRoundness(
|
topValue = 0f;
|
||||||
/* value = */ anv.isFirstInSection() ? 1f : 0f,
|
|
||||||
/* animate = */ false,
|
|
||||||
SourceType.OnScroll);
|
|
||||||
}
|
}
|
||||||
|
anv.requestTopRoundness(topValue, sourceType, /* animate = */ false);
|
||||||
|
|
||||||
|
final float bottomValue;
|
||||||
|
if (!mUseRoundnessSourceTypes && anv.isLastInSection()) {
|
||||||
|
bottomValue = 1f;
|
||||||
|
} else if (viewEnd >= cornerAnimationTop) {
|
||||||
|
// Round bottom corners within animation bounds
|
||||||
|
bottomValue = MathUtils.saturate(
|
||||||
|
(viewEnd - cornerAnimationTop) / cornerAnimationDistance);
|
||||||
|
} else {
|
||||||
|
// Fast scroll skips frames and leaves corners with unfinished rounding.
|
||||||
|
// Reset top and bottom corners outside of animation bounds.
|
||||||
|
bottomValue = 0f;
|
||||||
|
}
|
||||||
|
anv.requestBottomRoundness(bottomValue, sourceType, /* animate = */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -626,10 +637,11 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the clipping of this view.
|
* Update the clipping of this view.
|
||||||
|
*
|
||||||
* @return the amount that our own top should be clipped
|
* @return the amount that our own top should be clipped
|
||||||
*/
|
*/
|
||||||
private int updateNotificationClipHeight(ExpandableView view,
|
private int updateNotificationClipHeight(ExpandableView view,
|
||||||
float notificationClipEnd, int childIndex) {
|
float notificationClipEnd, int childIndex) {
|
||||||
float viewEnd = view.getTranslationY() + view.getActualHeight();
|
float viewEnd = view.getTranslationY() + view.getActualHeight();
|
||||||
boolean isPinned = (view.isPinned() || view.isHeadsUpAnimatingAway())
|
boolean isPinned = (view.isPinned() || view.isHeadsUpAnimatingAway())
|
||||||
&& !mAmbientState.isDozingAndNotPulsing(view);
|
&& !mAmbientState.isDozingAndNotPulsing(view);
|
||||||
@@ -657,7 +669,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd,
|
public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd,
|
||||||
int outlineTranslation) {
|
int outlineTranslation) {
|
||||||
if (!mHasItemsInStableShelf) {
|
if (!mHasItemsInStableShelf) {
|
||||||
shadowIntensity = 0.0f;
|
shadowIntensity = 0.0f;
|
||||||
}
|
}
|
||||||
@@ -665,18 +677,24 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param i Index of the view in the host layout.
|
* @param i Index of the view in the host layout.
|
||||||
* @param view The current ExpandableView.
|
* @param view The current ExpandableView.
|
||||||
* @param scrollingFast Whether we are scrolling fast.
|
* @param scrollingFast Whether we are scrolling fast.
|
||||||
* @param expandingAnimated Whether we are expanding a notification.
|
* @param expandingAnimated Whether we are expanding a notification.
|
||||||
* @param isLastChild Whether this is the last view.
|
* @param isLastChild Whether this is the last view.
|
||||||
* @param shelfClipStart The point at which notifications start getting clipped by the shelf.
|
* @param shelfClipStart The point at which notifications start getting clipped by the shelf.
|
||||||
* @return The amount how much this notification is in the shelf.
|
* @return The amount how much this notification is in the shelf.
|
||||||
* 0f is not in shelf. 1f is completely in shelf.
|
* 0f is not in shelf. 1f is completely in shelf.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public float getAmountInShelf(int i, ExpandableView view, boolean scrollingFast,
|
public float getAmountInShelf(
|
||||||
boolean expandingAnimated, boolean isLastChild, float shelfClipStart) {
|
int i,
|
||||||
|
ExpandableView view,
|
||||||
|
boolean scrollingFast,
|
||||||
|
boolean expandingAnimated,
|
||||||
|
boolean isLastChild,
|
||||||
|
float shelfClipStart
|
||||||
|
) {
|
||||||
|
|
||||||
// Let's calculate how much the view is in the shelf
|
// Let's calculate how much the view is in the shelf
|
||||||
float viewStart = view.getTranslationY();
|
float viewStart = view.getTranslationY();
|
||||||
@@ -755,8 +773,13 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateIconPositioning(ExpandableView view, float iconTransitionAmount,
|
private void updateIconPositioning(
|
||||||
boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) {
|
ExpandableView view,
|
||||||
|
float iconTransitionAmount,
|
||||||
|
boolean scrollingFast,
|
||||||
|
boolean expandingAnimated,
|
||||||
|
boolean isLastChild
|
||||||
|
) {
|
||||||
StatusBarIconView icon = view.getShelfIcon();
|
StatusBarIconView icon = view.getShelfIcon();
|
||||||
NotificationIconContainer.IconState iconState = getIconState(icon);
|
NotificationIconContainer.IconState iconState = getIconState(icon);
|
||||||
if (iconState == null) {
|
if (iconState == null) {
|
||||||
@@ -817,7 +840,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|| row.showingPulsing()
|
|| row.showingPulsing()
|
||||||
|| row.getTranslationZ() > mAmbientState.getBaseZHeight();
|
|| row.getTranslationZ() > mAmbientState.getBaseZHeight();
|
||||||
|
|
||||||
iconState.iconAppearAmount = iconState.hidden? 0f : transitionAmount;
|
iconState.iconAppearAmount = iconState.hidden ? 0f : transitionAmount;
|
||||||
|
|
||||||
// Fade in icons at shelf start
|
// Fade in icons at shelf start
|
||||||
// This is important for conversation icons, which are badged and need x reset
|
// This is important for conversation icons, which are badged and need x reset
|
||||||
@@ -847,7 +870,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private float getFullyClosedTranslation() {
|
private float getFullyClosedTranslation() {
|
||||||
return - (getIntrinsicHeight() - mStatusBarHeight) / 2;
|
return -(getIntrinsicHeight() - mStatusBarHeight) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -904,7 +927,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return whether the shelf has any icons in it when a potential animation has finished, i.e
|
* @return whether the shelf has any icons in it when a potential animation has finished, i.e
|
||||||
* if the current state would be applied right now
|
* if the current state would be applied right now
|
||||||
*/
|
*/
|
||||||
public boolean hasItemsInStableShelf() {
|
public boolean hasItemsInStableShelf() {
|
||||||
return mHasItemsInStableShelf;
|
return mHasItemsInStableShelf;
|
||||||
@@ -962,7 +985,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
|
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
|
||||||
int oldTop, int oldRight, int oldBottom) {
|
int oldTop, int oldRight, int oldBottom) {
|
||||||
updateRelativeOffset();
|
updateRelativeOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,12 +1004,11 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method resets the OnScroll roundness of a view to 0f
|
* This method resets the OnScroll roundness of a view to 0f
|
||||||
*
|
* <p>
|
||||||
* Note: This should be the only class that handles roundness {@code SourceType.OnScroll}
|
* Note: This should be the only class that handles roundness {@code SourceType.OnScroll}
|
||||||
*/
|
*/
|
||||||
public static void resetOnScrollRoundness(ExpandableView expandableView) {
|
public static void resetLegacyOnScrollRoundness(ExpandableView expandableView) {
|
||||||
expandableView.requestTopRoundness(0f, false, SourceType.OnScroll);
|
expandableView.requestRoundnessReset(LegacySourceType.OnScroll);
|
||||||
expandableView.requestBottomRoundness(0f, false, SourceType.OnScroll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ShelfState extends ExpandableViewState {
|
public class ShelfState extends ExpandableViewState {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.android.systemui.statusbar;
|
|||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
|
import com.android.systemui.flags.Flags;
|
||||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
|
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
|
||||||
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
|
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
|
||||||
@@ -42,14 +44,17 @@ public class NotificationShelfController {
|
|||||||
private AmbientState mAmbientState;
|
private AmbientState mAmbientState;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public NotificationShelfController(NotificationShelf notificationShelf,
|
public NotificationShelfController(
|
||||||
|
NotificationShelf notificationShelf,
|
||||||
ActivatableNotificationViewController activatableNotificationViewController,
|
ActivatableNotificationViewController activatableNotificationViewController,
|
||||||
KeyguardBypassController keyguardBypassController,
|
KeyguardBypassController keyguardBypassController,
|
||||||
SysuiStatusBarStateController statusBarStateController) {
|
SysuiStatusBarStateController statusBarStateController,
|
||||||
|
FeatureFlags featureFlags) {
|
||||||
mView = notificationShelf;
|
mView = notificationShelf;
|
||||||
mActivatableNotificationViewController = activatableNotificationViewController;
|
mActivatableNotificationViewController = activatableNotificationViewController;
|
||||||
mKeyguardBypassController = keyguardBypassController;
|
mKeyguardBypassController = keyguardBypassController;
|
||||||
mStatusBarStateController = statusBarStateController;
|
mStatusBarStateController = statusBarStateController;
|
||||||
|
mView.useRoundnessSourceTypes(featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES));
|
||||||
mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() {
|
mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onViewAttachedToWindow(View v) {
|
public void onViewAttachedToWindow(View v) {
|
||||||
@@ -88,7 +93,7 @@ public class NotificationShelfController {
|
|||||||
|
|
||||||
public @View.Visibility int getVisibility() {
|
public @View.Visibility int getVisibility() {
|
||||||
return mView.getVisibility();
|
return mView.getVisibility();
|
||||||
};
|
}
|
||||||
|
|
||||||
public void setCollapsedIcons(NotificationIconContainer notificationIcons) {
|
public void setCollapsedIcons(NotificationIconContainer notificationIcons) {
|
||||||
mView.setCollapsedIcons(notificationIcons);
|
mView.setCollapsedIcons(notificationIcons);
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ interface Roundable {
|
|||||||
@JvmDefault
|
@JvmDefault
|
||||||
fun requestTopRoundness(
|
fun requestTopRoundness(
|
||||||
@FloatRange(from = 0.0, to = 1.0) value: Float,
|
@FloatRange(from = 0.0, to = 1.0) value: Float,
|
||||||
animate: Boolean,
|
|
||||||
sourceType: SourceType,
|
sourceType: SourceType,
|
||||||
|
animate: Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val roundnessMap = roundableState.topRoundnessMap
|
val roundnessMap = roundableState.topRoundnessMap
|
||||||
val lastValue = roundnessMap.values.maxOrNull() ?: 0f
|
val lastValue = roundnessMap.values.maxOrNull() ?: 0f
|
||||||
@@ -104,6 +104,30 @@ interface Roundable {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the top roundness [value] for a specific [sourceType]. Animate the roundness if the
|
||||||
|
* view is shown.
|
||||||
|
*
|
||||||
|
* The top roundness of a [Roundable] can be defined by different [sourceType]. In case more
|
||||||
|
* origins require different roundness, for the same property, the maximum value will always be
|
||||||
|
* chosen.
|
||||||
|
*
|
||||||
|
* @param value a value between 0f and 1f.
|
||||||
|
* @param sourceType the source from which the request for roundness comes.
|
||||||
|
* @return Whether the roundness was changed.
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun requestTopRoundness(
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) value: Float,
|
||||||
|
sourceType: SourceType,
|
||||||
|
): Boolean {
|
||||||
|
return requestTopRoundness(
|
||||||
|
value = value,
|
||||||
|
sourceType = sourceType,
|
||||||
|
animate = roundableState.targetView.isShown
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request the bottom roundness [value] for a specific [sourceType].
|
* Request the bottom roundness [value] for a specific [sourceType].
|
||||||
*
|
*
|
||||||
@@ -119,8 +143,8 @@ interface Roundable {
|
|||||||
@JvmDefault
|
@JvmDefault
|
||||||
fun requestBottomRoundness(
|
fun requestBottomRoundness(
|
||||||
@FloatRange(from = 0.0, to = 1.0) value: Float,
|
@FloatRange(from = 0.0, to = 1.0) value: Float,
|
||||||
animate: Boolean,
|
|
||||||
sourceType: SourceType,
|
sourceType: SourceType,
|
||||||
|
animate: Boolean,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val roundnessMap = roundableState.bottomRoundnessMap
|
val roundnessMap = roundableState.bottomRoundnessMap
|
||||||
val lastValue = roundnessMap.values.maxOrNull() ?: 0f
|
val lastValue = roundnessMap.values.maxOrNull() ?: 0f
|
||||||
@@ -149,9 +173,101 @@ interface Roundable {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the bottom roundness [value] for a specific [sourceType]. Animate the roundness if
|
||||||
|
* the view is shown.
|
||||||
|
*
|
||||||
|
* The bottom roundness of a [Roundable] can be defined by different [sourceType]. In case more
|
||||||
|
* origins require different roundness, for the same property, the maximum value will always be
|
||||||
|
* chosen.
|
||||||
|
*
|
||||||
|
* @param value value between 0f and 1f.
|
||||||
|
* @param sourceType the source from which the request for roundness comes.
|
||||||
|
* @return Whether the roundness was changed.
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun requestBottomRoundness(
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) value: Float,
|
||||||
|
sourceType: SourceType,
|
||||||
|
): Boolean {
|
||||||
|
return requestBottomRoundness(
|
||||||
|
value = value,
|
||||||
|
sourceType = sourceType,
|
||||||
|
animate = roundableState.targetView.isShown
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the roundness [value] for a specific [sourceType].
|
||||||
|
*
|
||||||
|
* The top/bottom roundness of a [Roundable] can be defined by different [sourceType]. In case
|
||||||
|
* more origins require different roundness, for the same property, the maximum value will
|
||||||
|
* always be chosen.
|
||||||
|
*
|
||||||
|
* @param top top value between 0f and 1f.
|
||||||
|
* @param bottom bottom value between 0f and 1f.
|
||||||
|
* @param sourceType the source from which the request for roundness comes.
|
||||||
|
* @param animate true if it should animate to that value.
|
||||||
|
* @return Whether the roundness was changed.
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun requestRoundness(
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) top: Float,
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) bottom: Float,
|
||||||
|
sourceType: SourceType,
|
||||||
|
animate: Boolean,
|
||||||
|
): Boolean {
|
||||||
|
val hasTopChanged =
|
||||||
|
requestTopRoundness(value = top, sourceType = sourceType, animate = animate)
|
||||||
|
val hasBottomChanged =
|
||||||
|
requestBottomRoundness(value = bottom, sourceType = sourceType, animate = animate)
|
||||||
|
return hasTopChanged || hasBottomChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the roundness [value] for a specific [sourceType]. Animate the roundness if the view
|
||||||
|
* is shown.
|
||||||
|
*
|
||||||
|
* The top/bottom roundness of a [Roundable] can be defined by different [sourceType]. In case
|
||||||
|
* more origins require different roundness, for the same property, the maximum value will
|
||||||
|
* always be chosen.
|
||||||
|
*
|
||||||
|
* @param top top value between 0f and 1f.
|
||||||
|
* @param bottom bottom value between 0f and 1f.
|
||||||
|
* @param sourceType the source from which the request for roundness comes.
|
||||||
|
* @return Whether the roundness was changed.
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun requestRoundness(
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) top: Float,
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) bottom: Float,
|
||||||
|
sourceType: SourceType,
|
||||||
|
): Boolean {
|
||||||
|
return requestRoundness(
|
||||||
|
top = top,
|
||||||
|
bottom = bottom,
|
||||||
|
sourceType = sourceType,
|
||||||
|
animate = roundableState.targetView.isShown,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the roundness 0f for a [SourceType]. Animate the roundness if the view is shown.
|
||||||
|
*
|
||||||
|
* The top/bottom roundness of a [Roundable] can be defined by different [sourceType]. In case
|
||||||
|
* more origins require different roundness, for the same property, the maximum value will
|
||||||
|
* always be chosen.
|
||||||
|
*
|
||||||
|
* @param sourceType the source from which the request for roundness comes.
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun requestRoundnessReset(sourceType: SourceType) {
|
||||||
|
requestRoundness(top = 0f, bottom = 0f, sourceType = sourceType)
|
||||||
|
}
|
||||||
|
|
||||||
/** Apply the roundness changes, usually means invalidate the [RoundableState.targetView]. */
|
/** Apply the roundness changes, usually means invalidate the [RoundableState.targetView]. */
|
||||||
@JvmDefault
|
@JvmDefault
|
||||||
fun applyRoundness() {
|
fun applyRoundnessAndInvalidate() {
|
||||||
roundableState.targetView.invalidate()
|
roundableState.targetView.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +343,7 @@ class RoundableState(
|
|||||||
/** Set the current top roundness */
|
/** Set the current top roundness */
|
||||||
internal fun setTopRoundness(
|
internal fun setTopRoundness(
|
||||||
value: Float,
|
value: Float,
|
||||||
animated: Boolean = targetView.isShown,
|
animated: Boolean,
|
||||||
) {
|
) {
|
||||||
PropertyAnimator.setProperty(targetView, topAnimatable, value, DURATION, animated)
|
PropertyAnimator.setProperty(targetView, topAnimatable, value, DURATION, animated)
|
||||||
}
|
}
|
||||||
@@ -235,11 +351,19 @@ class RoundableState(
|
|||||||
/** Set the current bottom roundness */
|
/** Set the current bottom roundness */
|
||||||
internal fun setBottomRoundness(
|
internal fun setBottomRoundness(
|
||||||
value: Float,
|
value: Float,
|
||||||
animated: Boolean = targetView.isShown,
|
animated: Boolean,
|
||||||
) {
|
) {
|
||||||
PropertyAnimator.setProperty(targetView, bottomAnimatable, value, DURATION, animated)
|
PropertyAnimator.setProperty(targetView, bottomAnimatable, value, DURATION, animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun debugString() = buildString {
|
||||||
|
append("TargetView: ${targetView.hashCode()} ")
|
||||||
|
append("Top: $topRoundness ")
|
||||||
|
append(topRoundnessMap.map { "${it.key} ${it.value}" })
|
||||||
|
append(" Bottom: $bottomRoundness ")
|
||||||
|
append(bottomRoundnessMap.map { "${it.key} ${it.value}" })
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val DURATION: AnimationProperties =
|
private val DURATION: AnimationProperties =
|
||||||
AnimationProperties()
|
AnimationProperties()
|
||||||
@@ -252,7 +376,7 @@ class RoundableState(
|
|||||||
|
|
||||||
override fun setValue(view: View, value: Float) {
|
override fun setValue(view: View, value: Float) {
|
||||||
roundable.roundableState.topRoundness = value
|
roundable.roundableState.topRoundness = value
|
||||||
roundable.applyRoundness()
|
roundable.applyRoundnessAndInvalidate()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
R.id.top_roundess_animator_tag,
|
R.id.top_roundess_animator_tag,
|
||||||
@@ -267,7 +391,7 @@ class RoundableState(
|
|||||||
|
|
||||||
override fun setValue(view: View, value: Float) {
|
override fun setValue(view: View, value: Float) {
|
||||||
roundable.roundableState.bottomRoundness = value
|
roundable.roundableState.bottomRoundness = value
|
||||||
roundable.applyRoundness()
|
roundable.applyRoundnessAndInvalidate()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
R.id.bottom_roundess_animator_tag,
|
R.id.bottom_roundess_animator_tag,
|
||||||
@@ -277,7 +401,31 @@ class RoundableState(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class SourceType {
|
/**
|
||||||
|
* Interface used to define the owner of a roundness. Usually the [SourceType] is defined as a
|
||||||
|
* private property of a class.
|
||||||
|
*/
|
||||||
|
interface SourceType {
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* This is the most convenient way to define a new [SourceType].
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
*
|
||||||
|
* ```kotlin
|
||||||
|
* private val SECTION = SourceType.from("Section")
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun from(name: String) =
|
||||||
|
object : SourceType {
|
||||||
|
override fun toString() = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Use SourceType.from() instead", ReplaceWith("SourceType.from()"))
|
||||||
|
enum class LegacySourceType : SourceType {
|
||||||
DefaultValue,
|
DefaultValue,
|
||||||
OnDismissAnimation,
|
OnDismissAnimation,
|
||||||
OnScroll,
|
OnScroll,
|
||||||
|
|||||||
@@ -39,9 +39,13 @@ import com.android.systemui.animation.Interpolators;
|
|||||||
import com.android.systemui.statusbar.NotificationShelf;
|
import com.android.systemui.statusbar.NotificationShelf;
|
||||||
import com.android.systemui.statusbar.notification.FakeShadowView;
|
import com.android.systemui.statusbar.notification.FakeShadowView;
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||||
|
import com.android.systemui.statusbar.notification.SourceType;
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||||
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
|
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for both {@link ExpandableNotificationRow} and {@link NotificationShelf}
|
* Base class for both {@link ExpandableNotificationRow} and {@link NotificationShelf}
|
||||||
* to implement dimming/activating on Keyguard for the double-tap gesture
|
* to implement dimming/activating on Keyguard for the double-tap gesture
|
||||||
@@ -91,6 +95,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
= new PathInterpolator(0.6f, 0, 0.5f, 1);
|
= new PathInterpolator(0.6f, 0, 0.5f, 1);
|
||||||
private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
|
private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
|
||||||
= new PathInterpolator(0, 0, 0.5f, 1);
|
= new PathInterpolator(0, 0, 0.5f, 1);
|
||||||
|
private final Set<SourceType> mOnDetachResetRoundness = new HashSet<>();
|
||||||
private int mTintedRippleColor;
|
private int mTintedRippleColor;
|
||||||
private int mNormalRippleColor;
|
private int mNormalRippleColor;
|
||||||
private Gefingerpoken mTouchHandler;
|
private Gefingerpoken mTouchHandler;
|
||||||
@@ -134,6 +139,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
private boolean mDismissed;
|
private boolean mDismissed;
|
||||||
private boolean mRefocusOnDismiss;
|
private boolean mRefocusOnDismiss;
|
||||||
private AccessibilityManager mAccessibilityManager;
|
private AccessibilityManager mAccessibilityManager;
|
||||||
|
protected boolean mUseRoundnessSourceTypes;
|
||||||
|
|
||||||
public ActivatableNotificationView(Context context, AttributeSet attrs) {
|
public ActivatableNotificationView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
@@ -613,9 +619,9 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
protected void resetAllContentAlphas() {}
|
protected void resetAllContentAlphas() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyRoundness() {
|
public void applyRoundnessAndInvalidate() {
|
||||||
super.applyRoundness();
|
|
||||||
applyBackgroundRoundness(getTopCornerRadius(), getBottomCornerRadius());
|
applyBackgroundRoundness(getTopCornerRadius(), getBottomCornerRadius());
|
||||||
|
super.applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -775,6 +781,33 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
mAccessibilityManager = accessibilityManager;
|
mAccessibilityManager = accessibilityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the support for rounded corner based on the SourceType
|
||||||
|
* @param enabled true if is supported
|
||||||
|
*/
|
||||||
|
public void useRoundnessSourceTypes(boolean enabled) {
|
||||||
|
mUseRoundnessSourceTypes = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
if (mUseRoundnessSourceTypes && !mOnDetachResetRoundness.isEmpty()) {
|
||||||
|
for (SourceType sourceType : mOnDetachResetRoundness) {
|
||||||
|
requestRoundnessReset(sourceType);
|
||||||
|
}
|
||||||
|
mOnDetachResetRoundness.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SourceType which should be reset when this View is detached
|
||||||
|
* @param sourceType will be reset on View detached
|
||||||
|
*/
|
||||||
|
public void addOnDetachResetRoundness(SourceType sourceType) {
|
||||||
|
mOnDetachResetRoundness.add(sourceType);
|
||||||
|
}
|
||||||
|
|
||||||
public interface OnActivatedListener {
|
public interface OnActivatedListener {
|
||||||
void onActivated(ActivatableNotificationView view);
|
void onActivated(ActivatableNotificationView view);
|
||||||
void onActivationReset(ActivatableNotificationView view);
|
void onActivationReset(ActivatableNotificationView view);
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ import com.android.systemui.statusbar.StatusBarIconView;
|
|||||||
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
|
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
|
||||||
import com.android.systemui.statusbar.notification.FeedbackIcon;
|
import com.android.systemui.statusbar.notification.FeedbackIcon;
|
||||||
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
|
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
|
||||||
|
import com.android.systemui.statusbar.notification.LegacySourceType;
|
||||||
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
|
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||||
@@ -143,6 +144,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
private static final int MENU_VIEW_INDEX = 0;
|
private static final int MENU_VIEW_INDEX = 0;
|
||||||
public static final float DEFAULT_HEADER_VISIBLE_AMOUNT = 1.0f;
|
public static final float DEFAULT_HEADER_VISIBLE_AMOUNT = 1.0f;
|
||||||
private static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
|
private static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
|
||||||
|
private static final SourceType BASE_VALUE = SourceType.from("BaseValue");
|
||||||
|
private static final SourceType FROM_PARENT = SourceType.from("FromParent(ENR)");
|
||||||
|
private static final SourceType PINNED = SourceType.from("Pinned");
|
||||||
|
|
||||||
// We don't correctly track dark mode until the content views are inflated, so always update
|
// We don't correctly track dark mode until the content views are inflated, so always update
|
||||||
// the background on first content update just in case it happens to be during a theme change.
|
// the background on first content update just in case it happens to be during a theme change.
|
||||||
@@ -150,6 +154,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
private boolean mNotificationTranslationFinished = false;
|
private boolean mNotificationTranslationFinished = false;
|
||||||
private boolean mIsSnoozed;
|
private boolean mIsSnoozed;
|
||||||
private boolean mIsFaded;
|
private boolean mIsFaded;
|
||||||
|
private boolean mAnimatePinnedRoundness = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener for when {@link ExpandableNotificationRow} is laid out.
|
* Listener for when {@link ExpandableNotificationRow} is laid out.
|
||||||
@@ -376,7 +381,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
|
|
||||||
private float mTopRoundnessDuringLaunchAnimation;
|
private float mTopRoundnessDuringLaunchAnimation;
|
||||||
private float mBottomRoundnessDuringLaunchAnimation;
|
private float mBottomRoundnessDuringLaunchAnimation;
|
||||||
private boolean mIsNotificationGroupCornerEnabled;
|
private float mSmallRoundness;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the given {@code statusBarNotification} is a system notification.
|
* Returns whether the given {@code statusBarNotification} is a system notification.
|
||||||
@@ -844,7 +849,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
}
|
}
|
||||||
onAttachedChildrenCountChanged();
|
onAttachedChildrenCountChanged();
|
||||||
row.setIsChildInGroup(false, null);
|
row.setIsChildInGroup(false, null);
|
||||||
row.requestBottomRoundness(0.0f, /* animate = */ false, SourceType.DefaultValue);
|
if (!mUseRoundnessSourceTypes) {
|
||||||
|
row.requestBottomRoundness(0.0f, LegacySourceType.DefaultValue, /* animate = */ false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -860,7 +867,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
if (child.keepInParentForDismissAnimation()) {
|
if (child.keepInParentForDismissAnimation()) {
|
||||||
mChildrenContainer.removeNotification(child);
|
mChildrenContainer.removeNotification(child);
|
||||||
child.setIsChildInGroup(false, null);
|
child.setIsChildInGroup(false, null);
|
||||||
child.requestBottomRoundness(0.0f, /* animate = */ false, SourceType.DefaultValue);
|
if (!mUseRoundnessSourceTypes) {
|
||||||
|
LegacySourceType sourceType = LegacySourceType.DefaultValue;
|
||||||
|
child.requestBottomRoundness(0f, sourceType, /* animate = */ false);
|
||||||
|
}
|
||||||
child.setKeepInParentForDismissAnimation(false);
|
child.setKeepInParentForDismissAnimation(false);
|
||||||
logKeepInParentChildDetached(child);
|
logKeepInParentChildDetached(child);
|
||||||
childCountChanged = true;
|
childCountChanged = true;
|
||||||
@@ -915,6 +925,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
mNotificationParent.updateBackgroundForGroupState();
|
mNotificationParent.updateBackgroundForGroupState();
|
||||||
}
|
}
|
||||||
updateBackgroundClipping();
|
updateBackgroundClipping();
|
||||||
|
if (mUseRoundnessSourceTypes) {
|
||||||
|
updateBaseRoundness();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1033,6 +1046,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
if (isAboveShelf() != wasAboveShelf) {
|
if (isAboveShelf() != wasAboveShelf) {
|
||||||
mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
|
mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
|
||||||
}
|
}
|
||||||
|
if (mUseRoundnessSourceTypes) {
|
||||||
|
if (pinned) {
|
||||||
|
// Should be animated if someone explicitly set it to 0 and the row is shown.
|
||||||
|
boolean animated = mAnimatePinnedRoundness && isShown();
|
||||||
|
requestRoundness(/* top = */ 1f, /* bottom = */ 1f, PINNED, animated);
|
||||||
|
} else {
|
||||||
|
requestRoundnessReset(PINNED);
|
||||||
|
mAnimatePinnedRoundness = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1607,6 +1630,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
mImageResolver = new NotificationInlineImageResolver(context,
|
mImageResolver = new NotificationInlineImageResolver(context,
|
||||||
new NotificationInlineImageCache());
|
new NotificationInlineImageCache());
|
||||||
|
float radius = getResources().getDimension(R.dimen.notification_corner_radius_small);
|
||||||
|
mSmallRoundness = radius / getMaxRadius();
|
||||||
initDimens();
|
initDimens();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1839,7 +1864,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
mChildrenContainer.setIsLowPriority(mIsLowPriority);
|
mChildrenContainer.setIsLowPriority(mIsLowPriority);
|
||||||
mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
|
mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
|
||||||
mChildrenContainer.onNotificationUpdated();
|
mChildrenContainer.onNotificationUpdated();
|
||||||
mChildrenContainer.enableNotificationGroupCorner(mIsNotificationGroupCornerEnabled);
|
mChildrenContainer.useRoundnessSourceTypes(mUseRoundnessSourceTypes);
|
||||||
|
|
||||||
mTranslateableViews.add(mChildrenContainer);
|
mTranslateableViews.add(mChildrenContainer);
|
||||||
});
|
});
|
||||||
@@ -2271,7 +2296,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getTopRoundness() {
|
public float getTopRoundness() {
|
||||||
if (mExpandAnimationRunning) {
|
if (!mUseRoundnessSourceTypes && mExpandAnimationRunning) {
|
||||||
return mTopRoundnessDuringLaunchAnimation;
|
return mTopRoundnessDuringLaunchAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2280,7 +2305,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getBottomRoundness() {
|
public float getBottomRoundness() {
|
||||||
if (mExpandAnimationRunning) {
|
if (!mUseRoundnessSourceTypes && mExpandAnimationRunning) {
|
||||||
return mBottomRoundnessDuringLaunchAnimation;
|
return mBottomRoundnessDuringLaunchAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3436,17 +3461,24 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyRoundness() {
|
public void applyRoundnessAndInvalidate() {
|
||||||
super.applyRoundness();
|
|
||||||
applyChildrenRoundness();
|
applyChildrenRoundness();
|
||||||
|
super.applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyChildrenRoundness() {
|
private void applyChildrenRoundness() {
|
||||||
if (mIsSummaryWithChildren) {
|
if (mIsSummaryWithChildren) {
|
||||||
mChildrenContainer.requestBottomRoundness(
|
if (mUseRoundnessSourceTypes) {
|
||||||
getBottomRoundness(),
|
mChildrenContainer.requestRoundness(
|
||||||
/* animate = */ false,
|
/* top = */ getTopRoundness(),
|
||||||
SourceType.DefaultValue);
|
/* bottom = */ getBottomRoundness(),
|
||||||
|
FROM_PARENT);
|
||||||
|
} else {
|
||||||
|
mChildrenContainer.requestBottomRoundness(
|
||||||
|
getBottomRoundness(),
|
||||||
|
LegacySourceType.DefaultValue,
|
||||||
|
/* animate = */ false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3605,6 +3637,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
} else {
|
} else {
|
||||||
pw.println("no viewState!!!");
|
pw.println("no viewState!!!");
|
||||||
}
|
}
|
||||||
|
pw.println("Roundness: " + getRoundableState().debugString());
|
||||||
|
|
||||||
if (mIsSummaryWithChildren) {
|
if (mIsSummaryWithChildren) {
|
||||||
pw.println();
|
pw.println();
|
||||||
@@ -3649,14 +3682,38 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
return mTargetPoint;
|
return mTargetPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Update the minimum roundness based on current state */
|
||||||
|
private void updateBaseRoundness() {
|
||||||
|
if (isChildInGroup()) {
|
||||||
|
requestRoundnessReset(BASE_VALUE);
|
||||||
|
} else {
|
||||||
|
requestRoundness(mSmallRoundness, mSmallRoundness, BASE_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable the support for rounded corner in notification group
|
* Enable the support for rounded corner based on the SourceType
|
||||||
* @param enabled true if is supported
|
* @param enabled true if is supported
|
||||||
*/
|
*/
|
||||||
public void enableNotificationGroupCorner(boolean enabled) {
|
@Override
|
||||||
mIsNotificationGroupCornerEnabled = enabled;
|
public void useRoundnessSourceTypes(boolean enabled) {
|
||||||
|
super.useRoundnessSourceTypes(enabled);
|
||||||
if (mChildrenContainer != null) {
|
if (mChildrenContainer != null) {
|
||||||
mChildrenContainer.enableNotificationGroupCorner(mIsNotificationGroupCornerEnabled);
|
mChildrenContainer.useRoundnessSourceTypes(mUseRoundnessSourceTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String roundableStateDebug = "RoundableState = " + getRoundableState().debugString();
|
||||||
|
return "ExpandableNotificationRow:" + hashCode() + " { " + roundableStateDebug + " }";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
if (mUseRoundnessSourceTypes) {
|
||||||
|
updateBaseRoundness();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,8 +255,8 @@ public class ExpandableNotificationRowController implements NotifViewController
|
|||||||
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
mStatusBarStateController.removeCallback(mStatusBarStateListener);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mView.enableNotificationGroupCorner(
|
mView.useRoundnessSourceTypes(
|
||||||
mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_CORNER));
|
mFeatureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final StatusBarStateController.StateListener mStatusBarStateListener =
|
private final StatusBarStateController.StateListener mStatusBarStateListener =
|
||||||
|
|||||||
@@ -219,9 +219,9 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyRoundness() {
|
public void applyRoundnessAndInvalidate() {
|
||||||
invalidateOutline();
|
invalidateOutline();
|
||||||
super.applyRoundness();
|
super.applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setBackgroundTop(int backgroundTop) {
|
protected void setBackgroundTop(int backgroundTop) {
|
||||||
@@ -233,7 +233,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
|
|
||||||
public void onDensityOrFontScaleChanged() {
|
public void onDensityOrFontScaleChanged() {
|
||||||
initDimens();
|
initDimens();
|
||||||
applyRoundness();
|
applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -241,7 +241,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
int previousHeight = getActualHeight();
|
int previousHeight = getActualHeight();
|
||||||
super.setActualHeight(actualHeight, notifyListeners);
|
super.setActualHeight(actualHeight, notifyListeners);
|
||||||
if (previousHeight != actualHeight) {
|
if (previousHeight != actualHeight) {
|
||||||
applyRoundness();
|
applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
int previousAmount = getClipTopAmount();
|
int previousAmount = getClipTopAmount();
|
||||||
super.setClipTopAmount(clipTopAmount);
|
super.setClipTopAmount(clipTopAmount);
|
||||||
if (previousAmount != clipTopAmount) {
|
if (previousAmount != clipTopAmount) {
|
||||||
applyRoundness();
|
applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,14 +259,14 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
int previousAmount = getClipBottomAmount();
|
int previousAmount = getClipBottomAmount();
|
||||||
super.setClipBottomAmount(clipBottomAmount);
|
super.setClipBottomAmount(clipBottomAmount);
|
||||||
if (previousAmount != clipBottomAmount) {
|
if (previousAmount != clipBottomAmount) {
|
||||||
applyRoundness();
|
applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setOutlineAlpha(float alpha) {
|
protected void setOutlineAlpha(float alpha) {
|
||||||
if (alpha != mOutlineAlpha) {
|
if (alpha != mOutlineAlpha) {
|
||||||
mOutlineAlpha = alpha;
|
mOutlineAlpha = alpha;
|
||||||
applyRoundness();
|
applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +280,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
setOutlineRect(rect.left, rect.top, rect.right, rect.bottom);
|
setOutlineRect(rect.left, rect.top, rect.right, rect.bottom);
|
||||||
} else {
|
} else {
|
||||||
mCustomOutline = false;
|
mCustomOutline = false;
|
||||||
applyRoundness();
|
applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +340,7 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
// Outlines need to be at least 1 dp
|
// Outlines need to be at least 1 dp
|
||||||
mOutlineRect.bottom = (int) Math.max(top, mOutlineRect.bottom);
|
mOutlineRect.bottom = (int) Math.max(top, mOutlineRect.bottom);
|
||||||
mOutlineRect.right = (int) Math.max(left, mOutlineRect.right);
|
mOutlineRect.right = (int) Math.max(left, mOutlineRect.right);
|
||||||
applyRoundness();
|
applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path getCustomClipPath(View child) {
|
public Path getCustomClipPath(View child) {
|
||||||
|
|||||||
@@ -343,4 +343,14 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface that handle the Roundness changes
|
||||||
|
*/
|
||||||
|
public interface RoundnessChangedListener {
|
||||||
|
/**
|
||||||
|
* This method will be called when this class call applyRoundnessAndInvalidate()
|
||||||
|
*/
|
||||||
|
void applyRoundnessAndInvalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import com.android.systemui.statusbar.CrossFadeHelper;
|
|||||||
import com.android.systemui.statusbar.NotificationGroupingUtil;
|
import com.android.systemui.statusbar.NotificationGroupingUtil;
|
||||||
import com.android.systemui.statusbar.NotificationShelf;
|
import com.android.systemui.statusbar.NotificationShelf;
|
||||||
import com.android.systemui.statusbar.notification.FeedbackIcon;
|
import com.android.systemui.statusbar.notification.FeedbackIcon;
|
||||||
|
import com.android.systemui.statusbar.notification.LegacySourceType;
|
||||||
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||||
import com.android.systemui.statusbar.notification.Roundable;
|
import com.android.systemui.statusbar.notification.Roundable;
|
||||||
@@ -83,6 +84,7 @@ public class NotificationChildrenContainer extends ViewGroup
|
|||||||
return mAnimationFilter;
|
return mAnimationFilter;
|
||||||
}
|
}
|
||||||
}.setDuration(200);
|
}.setDuration(200);
|
||||||
|
private static final SourceType FROM_PARENT = SourceType.from("FromParent(NCC)");
|
||||||
|
|
||||||
private final List<View> mDividers = new ArrayList<>();
|
private final List<View> mDividers = new ArrayList<>();
|
||||||
private final List<ExpandableNotificationRow> mAttachedChildren = new ArrayList<>();
|
private final List<ExpandableNotificationRow> mAttachedChildren = new ArrayList<>();
|
||||||
@@ -131,7 +133,7 @@ public class NotificationChildrenContainer extends ViewGroup
|
|||||||
private int mUntruncatedChildCount;
|
private int mUntruncatedChildCount;
|
||||||
private boolean mContainingNotificationIsFaded = false;
|
private boolean mContainingNotificationIsFaded = false;
|
||||||
private RoundableState mRoundableState;
|
private RoundableState mRoundableState;
|
||||||
private boolean mIsNotificationGroupCornerEnabled;
|
private boolean mUseRoundnessSourceTypes;
|
||||||
|
|
||||||
public NotificationChildrenContainer(Context context) {
|
public NotificationChildrenContainer(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -313,9 +315,12 @@ public class NotificationChildrenContainer extends ViewGroup
|
|||||||
row.setContentTransformationAmount(0, false /* isLastChild */);
|
row.setContentTransformationAmount(0, false /* isLastChild */);
|
||||||
row.setNotificationFaded(mContainingNotificationIsFaded);
|
row.setNotificationFaded(mContainingNotificationIsFaded);
|
||||||
|
|
||||||
// This is a workaround, the NotificationShelf should be the owner of `OnScroll` roundness.
|
if (!mUseRoundnessSourceTypes) {
|
||||||
// Here we should reset the `OnScroll` roundness only on top-level rows.
|
// This is a workaround, the NotificationShelf should be the owner of `OnScroll`
|
||||||
NotificationShelf.resetOnScrollRoundness(row);
|
// roundness.
|
||||||
|
// Here we should reset the `OnScroll` roundness only on top-level rows.
|
||||||
|
NotificationShelf.resetLegacyOnScrollRoundness(row);
|
||||||
|
}
|
||||||
|
|
||||||
// It doesn't make sense to keep old animations around, lets cancel them!
|
// It doesn't make sense to keep old animations around, lets cancel them!
|
||||||
ExpandableViewState viewState = row.getViewState();
|
ExpandableViewState viewState = row.getViewState();
|
||||||
@@ -323,6 +328,10 @@ public class NotificationChildrenContainer extends ViewGroup
|
|||||||
viewState.cancelAnimations(row);
|
viewState.cancelAnimations(row);
|
||||||
row.cancelAppearDrawing();
|
row.cancelAppearDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mUseRoundnessSourceTypes) {
|
||||||
|
applyRoundnessAndInvalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureRemovedFromTransientContainer(View v) {
|
private void ensureRemovedFromTransientContainer(View v) {
|
||||||
@@ -356,6 +365,11 @@ public class NotificationChildrenContainer extends ViewGroup
|
|||||||
if (!row.isRemoved()) {
|
if (!row.isRemoved()) {
|
||||||
mGroupingUtil.restoreChildNotification(row);
|
mGroupingUtil.restoreChildNotification(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mUseRoundnessSourceTypes) {
|
||||||
|
row.requestRoundnessReset(FROM_PARENT);
|
||||||
|
applyRoundnessAndInvalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -841,7 +855,7 @@ public class NotificationChildrenContainer extends ViewGroup
|
|||||||
|
|
||||||
isCanvasChanged = true;
|
isCanvasChanged = true;
|
||||||
canvas.save();
|
canvas.save();
|
||||||
if (mIsNotificationGroupCornerEnabled && translation != 0f) {
|
if (mUseRoundnessSourceTypes && translation != 0f) {
|
||||||
clipPath.offset(translation, 0f);
|
clipPath.offset(translation, 0f);
|
||||||
canvas.clipPath(clipPath);
|
canvas.clipPath(clipPath);
|
||||||
clipPath.offset(-translation, 0f);
|
clipPath.offset(-translation, 0f);
|
||||||
@@ -1392,24 +1406,28 @@ public class NotificationChildrenContainer extends ViewGroup
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyRoundness() {
|
public void applyRoundnessAndInvalidate() {
|
||||||
Roundable.super.applyRoundness();
|
|
||||||
boolean last = true;
|
boolean last = true;
|
||||||
for (int i = mAttachedChildren.size() - 1; i >= 0; i--) {
|
for (int i = mAttachedChildren.size() - 1; i >= 0; i--) {
|
||||||
ExpandableNotificationRow child = mAttachedChildren.get(i);
|
ExpandableNotificationRow child = mAttachedChildren.get(i);
|
||||||
if (child.getVisibility() == View.GONE) {
|
if (child.getVisibility() == View.GONE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
child.requestTopRoundness(
|
if (mUseRoundnessSourceTypes) {
|
||||||
/* value = */ 0f,
|
child.requestRoundness(
|
||||||
/* animate = */ isShown(),
|
/* top = */ 0f,
|
||||||
SourceType.DefaultValue);
|
/* bottom = */ last ? getBottomRoundness() : 0f,
|
||||||
child.requestBottomRoundness(
|
FROM_PARENT);
|
||||||
/* value = */ last ? getBottomRoundness() : 0f,
|
} else {
|
||||||
/* animate = */ isShown(),
|
child.requestRoundness(
|
||||||
SourceType.DefaultValue);
|
/* top = */ 0f,
|
||||||
|
/* bottom = */ last ? getBottomRoundness() : 0f,
|
||||||
|
LegacySourceType.DefaultValue,
|
||||||
|
/* animate = */ isShown());
|
||||||
|
}
|
||||||
last = false;
|
last = false;
|
||||||
}
|
}
|
||||||
|
Roundable.super.applyRoundnessAndInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeaderVisibleAmount(float headerVisibleAmount) {
|
public void setHeaderVisibleAmount(float headerVisibleAmount) {
|
||||||
@@ -1467,10 +1485,17 @@ public class NotificationChildrenContainer extends ViewGroup
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable the support for rounded corner in notification group
|
* Enable the support for rounded corner based on the SourceType
|
||||||
|
*
|
||||||
* @param enabled true if is supported
|
* @param enabled true if is supported
|
||||||
*/
|
*/
|
||||||
public void enableNotificationGroupCorner(boolean enabled) {
|
public void useRoundnessSourceTypes(boolean enabled) {
|
||||||
mIsNotificationGroupCornerEnabled = enabled;
|
mUseRoundnessSourceTypes = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String roundableStateDebug = "RoundableState = " + getRoundableState().debugString();
|
||||||
|
return "NotificationChildrenContainer:" + hashCode() + " { " + roundableStateDebug + " }";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ import com.android.systemui.Dumpable;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
|
import com.android.systemui.flags.Flags;
|
||||||
|
import com.android.systemui.statusbar.notification.LegacySourceType;
|
||||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
|
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
|
||||||
import com.android.systemui.statusbar.notification.Roundable;
|
import com.android.systemui.statusbar.notification.Roundable;
|
||||||
import com.android.systemui.statusbar.notification.SourceType;
|
import com.android.systemui.statusbar.notification.SourceType;
|
||||||
@@ -45,6 +48,7 @@ import javax.inject.Inject;
|
|||||||
public class NotificationRoundnessManager implements Dumpable {
|
public class NotificationRoundnessManager implements Dumpable {
|
||||||
|
|
||||||
private static final String TAG = "NotificationRoundnessManager";
|
private static final String TAG = "NotificationRoundnessManager";
|
||||||
|
private static final SourceType DISMISS_ANIMATION = SourceType.from("DismissAnimation");
|
||||||
|
|
||||||
private final ExpandableView[] mFirstInSectionViews;
|
private final ExpandableView[] mFirstInSectionViews;
|
||||||
private final ExpandableView[] mLastInSectionViews;
|
private final ExpandableView[] mLastInSectionViews;
|
||||||
@@ -63,12 +67,14 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
private ExpandableView mSwipedView = null;
|
private ExpandableView mSwipedView = null;
|
||||||
private Roundable mViewBeforeSwipedView = null;
|
private Roundable mViewBeforeSwipedView = null;
|
||||||
private Roundable mViewAfterSwipedView = null;
|
private Roundable mViewAfterSwipedView = null;
|
||||||
|
private boolean mUseRoundnessSourceTypes;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
NotificationRoundnessManager(
|
NotificationRoundnessManager(
|
||||||
NotificationSectionsFeatureManager sectionsFeatureManager,
|
NotificationSectionsFeatureManager sectionsFeatureManager,
|
||||||
NotificationRoundnessLogger notifLogger,
|
NotificationRoundnessLogger notifLogger,
|
||||||
DumpManager dumpManager) {
|
DumpManager dumpManager,
|
||||||
|
FeatureFlags featureFlags) {
|
||||||
int numberOfSections = sectionsFeatureManager.getNumberOfBuckets();
|
int numberOfSections = sectionsFeatureManager.getNumberOfBuckets();
|
||||||
mFirstInSectionViews = new ExpandableView[numberOfSections];
|
mFirstInSectionViews = new ExpandableView[numberOfSections];
|
||||||
mLastInSectionViews = new ExpandableView[numberOfSections];
|
mLastInSectionViews = new ExpandableView[numberOfSections];
|
||||||
@@ -76,6 +82,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
mTmpLastInSectionViews = new ExpandableView[numberOfSections];
|
mTmpLastInSectionViews = new ExpandableView[numberOfSections];
|
||||||
mNotifLogger = notifLogger;
|
mNotifLogger = notifLogger;
|
||||||
mDumpManager = dumpManager;
|
mDumpManager = dumpManager;
|
||||||
|
mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
|
||||||
|
|
||||||
mDumpManager.registerDumpable(TAG, this);
|
mDumpManager.registerDumpable(TAG, this);
|
||||||
}
|
}
|
||||||
@@ -94,6 +101,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateView(ExpandableView view, boolean animate) {
|
public void updateView(ExpandableView view, boolean animate) {
|
||||||
|
if (mUseRoundnessSourceTypes) return;
|
||||||
boolean changed = updateViewWithoutCallback(view, animate);
|
boolean changed = updateViewWithoutCallback(view, animate);
|
||||||
if (changed) {
|
if (changed) {
|
||||||
mRoundingChangedCallback.run();
|
mRoundingChangedCallback.run();
|
||||||
@@ -110,6 +118,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
boolean updateViewWithoutCallback(
|
boolean updateViewWithoutCallback(
|
||||||
ExpandableView view,
|
ExpandableView view,
|
||||||
boolean animate) {
|
boolean animate) {
|
||||||
|
if (mUseRoundnessSourceTypes) return false;
|
||||||
if (view == null
|
if (view == null
|
||||||
|| view == mViewBeforeSwipedView
|
|| view == mViewBeforeSwipedView
|
||||||
|| view == mViewAfterSwipedView) {
|
|| view == mViewAfterSwipedView) {
|
||||||
@@ -118,13 +127,13 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
|
|
||||||
final boolean isTopChanged = view.requestTopRoundness(
|
final boolean isTopChanged = view.requestTopRoundness(
|
||||||
getRoundnessDefaultValue(view, true /* top */),
|
getRoundnessDefaultValue(view, true /* top */),
|
||||||
animate,
|
LegacySourceType.DefaultValue,
|
||||||
SourceType.DefaultValue);
|
animate);
|
||||||
|
|
||||||
final boolean isBottomChanged = view.requestBottomRoundness(
|
final boolean isBottomChanged = view.requestBottomRoundness(
|
||||||
getRoundnessDefaultValue(view, /* top = */ false),
|
getRoundnessDefaultValue(view, /* top = */ false),
|
||||||
animate,
|
LegacySourceType.DefaultValue,
|
||||||
SourceType.DefaultValue);
|
animate);
|
||||||
|
|
||||||
final boolean isFirstInSection = isFirstInSection(view);
|
final boolean isFirstInSection = isFirstInSection(view);
|
||||||
final boolean isLastInSection = isLastInSection(view);
|
final boolean isLastInSection = isLastInSection(view);
|
||||||
@@ -139,6 +148,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFirstInSection(ExpandableView view) {
|
private boolean isFirstInSection(ExpandableView view) {
|
||||||
|
if (mUseRoundnessSourceTypes) return false;
|
||||||
for (int i = 0; i < mFirstInSectionViews.length; i++) {
|
for (int i = 0; i < mFirstInSectionViews.length; i++) {
|
||||||
if (view == mFirstInSectionViews[i]) {
|
if (view == mFirstInSectionViews[i]) {
|
||||||
return true;
|
return true;
|
||||||
@@ -148,6 +158,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isLastInSection(ExpandableView view) {
|
private boolean isLastInSection(ExpandableView view) {
|
||||||
|
if (mUseRoundnessSourceTypes) return false;
|
||||||
for (int i = mLastInSectionViews.length - 1; i >= 0; i--) {
|
for (int i = mLastInSectionViews.length - 1; i >= 0; i--) {
|
||||||
if (view == mLastInSectionViews[i]) {
|
if (view == mLastInSectionViews[i]) {
|
||||||
return true;
|
return true;
|
||||||
@@ -160,9 +171,6 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
Roundable viewBefore,
|
Roundable viewBefore,
|
||||||
ExpandableView viewSwiped,
|
ExpandableView viewSwiped,
|
||||||
Roundable viewAfter) {
|
Roundable viewAfter) {
|
||||||
final boolean animate = true;
|
|
||||||
final SourceType source = SourceType.OnDismissAnimation;
|
|
||||||
|
|
||||||
// This method requires you to change the roundness of the current View targets and reset
|
// This method requires you to change the roundness of the current View targets and reset
|
||||||
// the roundness of the old View targets (if any) to 0f.
|
// the roundness of the old View targets (if any) to 0f.
|
||||||
// To avoid conflicts, it generates a set of old Views and removes the current Views
|
// To avoid conflicts, it generates a set of old Views and removes the current Views
|
||||||
@@ -172,31 +180,34 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
if (mSwipedView != null) oldViews.add(mSwipedView);
|
if (mSwipedView != null) oldViews.add(mSwipedView);
|
||||||
if (mViewAfterSwipedView != null) oldViews.add(mViewAfterSwipedView);
|
if (mViewAfterSwipedView != null) oldViews.add(mViewAfterSwipedView);
|
||||||
|
|
||||||
|
final SourceType source;
|
||||||
|
if (mUseRoundnessSourceTypes) {
|
||||||
|
source = DISMISS_ANIMATION;
|
||||||
|
} else {
|
||||||
|
source = LegacySourceType.OnDismissAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
mViewBeforeSwipedView = viewBefore;
|
mViewBeforeSwipedView = viewBefore;
|
||||||
if (viewBefore != null) {
|
if (viewBefore != null) {
|
||||||
oldViews.remove(viewBefore);
|
oldViews.remove(viewBefore);
|
||||||
viewBefore.requestTopRoundness(0f, animate, source);
|
viewBefore.requestRoundness(/* top = */ 0f, /* bottom = */ 1f, source);
|
||||||
viewBefore.requestBottomRoundness(1f, animate, source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mSwipedView = viewSwiped;
|
mSwipedView = viewSwiped;
|
||||||
if (viewSwiped != null) {
|
if (viewSwiped != null) {
|
||||||
oldViews.remove(viewSwiped);
|
oldViews.remove(viewSwiped);
|
||||||
viewSwiped.requestTopRoundness(1f, animate, source);
|
viewSwiped.requestRoundness(/* top = */ 1f, /* bottom = */ 1f, source);
|
||||||
viewSwiped.requestBottomRoundness(1f, animate, source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mViewAfterSwipedView = viewAfter;
|
mViewAfterSwipedView = viewAfter;
|
||||||
if (viewAfter != null) {
|
if (viewAfter != null) {
|
||||||
oldViews.remove(viewAfter);
|
oldViews.remove(viewAfter);
|
||||||
viewAfter.requestTopRoundness(1f, animate, source);
|
viewAfter.requestRoundness(/* top = */ 1f, /* bottom = */ 0f, source);
|
||||||
viewAfter.requestBottomRoundness(0f, animate, source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// After setting the current Views, reset the views that are still present in the set.
|
// After setting the current Views, reset the views that are still present in the set.
|
||||||
for (Roundable oldView : oldViews) {
|
for (Roundable oldView : oldViews) {
|
||||||
oldView.requestTopRoundness(0f, animate, source);
|
oldView.requestRoundnessReset(source);
|
||||||
oldView.requestBottomRoundness(0f, animate, source);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +215,23 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
mIsClearAllInProgress = isClearingAll;
|
mIsClearAllInProgress = isClearingAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if "Clear all" notifications is in progress.
|
||||||
|
*/
|
||||||
|
public boolean isClearAllInProgress() {
|
||||||
|
return mIsClearAllInProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we can request the `Pulsing` roundness for notification.
|
||||||
|
*/
|
||||||
|
public boolean shouldRoundNotificationPulsing() {
|
||||||
|
return mRoundForPulsingViews;
|
||||||
|
}
|
||||||
|
|
||||||
private float getRoundnessDefaultValue(Roundable view, boolean top) {
|
private float getRoundnessDefaultValue(Roundable view, boolean top) {
|
||||||
|
if (mUseRoundnessSourceTypes) return 0f;
|
||||||
|
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
return 0f;
|
return 0f;
|
||||||
}
|
}
|
||||||
@@ -250,6 +277,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setExpanded(float expandedHeight, float appearFraction) {
|
public void setExpanded(float expandedHeight, float appearFraction) {
|
||||||
|
if (mUseRoundnessSourceTypes) return;
|
||||||
mExpanded = expandedHeight != 0.0f;
|
mExpanded = expandedHeight != 0.0f;
|
||||||
mAppearFraction = appearFraction;
|
mAppearFraction = appearFraction;
|
||||||
if (mTrackedHeadsUp != null) {
|
if (mTrackedHeadsUp != null) {
|
||||||
@@ -258,6 +286,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateRoundedChildren(NotificationSection[] sections) {
|
public void updateRoundedChildren(NotificationSection[] sections) {
|
||||||
|
if (mUseRoundnessSourceTypes) return;
|
||||||
boolean anyChanged = false;
|
boolean anyChanged = false;
|
||||||
for (int i = 0; i < sections.length; i++) {
|
for (int i = 0; i < sections.length; i++) {
|
||||||
mTmpFirstInSectionViews[i] = mFirstInSectionViews[i];
|
mTmpFirstInSectionViews[i] = mFirstInSectionViews[i];
|
||||||
@@ -280,6 +309,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
NotificationSection[] sections,
|
NotificationSection[] sections,
|
||||||
ExpandableView[] oldViews,
|
ExpandableView[] oldViews,
|
||||||
boolean first) {
|
boolean first) {
|
||||||
|
if (mUseRoundnessSourceTypes) return false;
|
||||||
boolean anyChanged = false;
|
boolean anyChanged = false;
|
||||||
for (ExpandableView oldView : oldViews) {
|
for (ExpandableView oldView : oldViews) {
|
||||||
if (oldView != null) {
|
if (oldView != null) {
|
||||||
@@ -313,6 +343,7 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
NotificationSection[] sections,
|
NotificationSection[] sections,
|
||||||
ExpandableView[] oldViews,
|
ExpandableView[] oldViews,
|
||||||
boolean first) {
|
boolean first) {
|
||||||
|
if (mUseRoundnessSourceTypes) return false;
|
||||||
boolean anyChanged = false;
|
boolean anyChanged = false;
|
||||||
for (NotificationSection section : sections) {
|
for (NotificationSection section : sections) {
|
||||||
ExpandableView newView =
|
ExpandableView newView =
|
||||||
@@ -339,6 +370,15 @@ public class NotificationRoundnessManager implements Dumpable {
|
|||||||
mAnimatedChildren = animatedChildren;
|
mAnimatedChildren = animatedChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the view should be animated
|
||||||
|
* @param view target view
|
||||||
|
* @return true, if is in the AnimatedChildren set
|
||||||
|
*/
|
||||||
|
public boolean isAnimatedChild(ExpandableView view) {
|
||||||
|
return mAnimatedChildren.contains(view);
|
||||||
|
}
|
||||||
|
|
||||||
public void setOnRoundingChangedCallback(Runnable roundingChangedCallback) {
|
public void setOnRoundingChangedCallback(Runnable roundingChangedCallback) {
|
||||||
mRoundingChangedCallback = roundingChangedCallback;
|
mRoundingChangedCallback = roundingChangedCallback;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,11 @@ import android.annotation.ColorInt
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.android.internal.annotations.VisibleForTesting
|
import com.android.internal.annotations.VisibleForTesting
|
||||||
|
import com.android.systemui.flags.FeatureFlags
|
||||||
|
import com.android.systemui.flags.Flags
|
||||||
import com.android.systemui.media.controls.ui.KeyguardMediaController
|
import com.android.systemui.media.controls.ui.KeyguardMediaController
|
||||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
|
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
|
||||||
|
import com.android.systemui.statusbar.notification.SourceType
|
||||||
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController
|
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController
|
||||||
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
|
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
|
||||||
import com.android.systemui.statusbar.notification.dagger.AlertingHeader
|
import com.android.systemui.statusbar.notification.dagger.AlertingHeader
|
||||||
@@ -44,12 +47,16 @@ class NotificationSectionsManager @Inject internal constructor(
|
|||||||
private val keyguardMediaController: KeyguardMediaController,
|
private val keyguardMediaController: KeyguardMediaController,
|
||||||
private val sectionsFeatureManager: NotificationSectionsFeatureManager,
|
private val sectionsFeatureManager: NotificationSectionsFeatureManager,
|
||||||
private val mediaContainerController: MediaContainerController,
|
private val mediaContainerController: MediaContainerController,
|
||||||
|
private val notificationRoundnessManager: NotificationRoundnessManager,
|
||||||
@IncomingHeader private val incomingHeaderController: SectionHeaderController,
|
@IncomingHeader private val incomingHeaderController: SectionHeaderController,
|
||||||
@PeopleHeader private val peopleHeaderController: SectionHeaderController,
|
@PeopleHeader private val peopleHeaderController: SectionHeaderController,
|
||||||
@AlertingHeader private val alertingHeaderController: SectionHeaderController,
|
@AlertingHeader private val alertingHeaderController: SectionHeaderController,
|
||||||
@SilentHeader private val silentHeaderController: SectionHeaderController
|
@SilentHeader private val silentHeaderController: SectionHeaderController,
|
||||||
|
featureFlags: FeatureFlags
|
||||||
) : SectionProvider {
|
) : SectionProvider {
|
||||||
|
|
||||||
|
private val useRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES)
|
||||||
|
|
||||||
private val configurationListener = object : ConfigurationController.ConfigurationListener {
|
private val configurationListener = object : ConfigurationController.ConfigurationListener {
|
||||||
override fun onLocaleListChanged() {
|
override fun onLocaleListChanged() {
|
||||||
reinflateViews()
|
reinflateViews()
|
||||||
@@ -177,11 +184,49 @@ class NotificationSectionsManager @Inject internal constructor(
|
|||||||
size = sections.size,
|
size = sections.size,
|
||||||
operation = SectionBounds::addNotif
|
operation = SectionBounds::addNotif
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Build a set of the old first/last Views of the sections
|
||||||
|
val oldFirstChildren = sections.mapNotNull { it.firstVisibleChild }.toSet().toMutableSet()
|
||||||
|
val oldLastChildren = sections.mapNotNull { it.lastVisibleChild }.toSet().toMutableSet()
|
||||||
|
|
||||||
// Update each section with the associated boundary, tracking if there was a change
|
// Update each section with the associated boundary, tracking if there was a change
|
||||||
val changed = sections.fold(false) { changed, section ->
|
val changed = sections.fold(false) { changed, section ->
|
||||||
val bounds = sectionBounds[section.bucket] ?: SectionBounds.None
|
val bounds = sectionBounds[section.bucket] ?: SectionBounds.None
|
||||||
bounds.updateSection(section) || changed
|
val isSectionChanged = bounds.updateSection(section)
|
||||||
|
isSectionChanged || changed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useRoundnessSourceTypes) {
|
||||||
|
val newFirstChildren = sections.mapNotNull { it.firstVisibleChild }
|
||||||
|
val newLastChildren = sections.mapNotNull { it.lastVisibleChild }
|
||||||
|
|
||||||
|
// Update the roundness of Views that weren't already in the first/last position
|
||||||
|
newFirstChildren.forEach { firstChild ->
|
||||||
|
val wasFirstChild = oldFirstChildren.remove(firstChild)
|
||||||
|
if (!wasFirstChild) {
|
||||||
|
val notAnimatedChild = !notificationRoundnessManager.isAnimatedChild(firstChild)
|
||||||
|
val animated = firstChild.isShown && notAnimatedChild
|
||||||
|
firstChild.requestTopRoundness(1f, SECTION, animated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newLastChildren.forEach { lastChild ->
|
||||||
|
val wasLastChild = oldLastChildren.remove(lastChild)
|
||||||
|
if (!wasLastChild) {
|
||||||
|
val notAnimatedChild = !notificationRoundnessManager.isAnimatedChild(lastChild)
|
||||||
|
val animated = lastChild.isShown && notAnimatedChild
|
||||||
|
lastChild.requestBottomRoundness(1f, SECTION, animated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Views left in the set are no longer in the first/last position
|
||||||
|
oldFirstChildren.forEach { noMoreFirstChild ->
|
||||||
|
noMoreFirstChild.requestTopRoundness(0f, SECTION)
|
||||||
|
}
|
||||||
|
oldLastChildren.forEach { noMoreLastChild ->
|
||||||
|
noMoreLastChild.requestBottomRoundness(0f, SECTION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
logSections(sections)
|
logSections(sections)
|
||||||
}
|
}
|
||||||
@@ -215,5 +260,6 @@ class NotificationSectionsManager @Inject internal constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "NotifSectionsManager"
|
private const val TAG = "NotifSectionsManager"
|
||||||
private const val DEBUG = false
|
private const val DEBUG = false
|
||||||
|
private val SECTION = SourceType.from("Section")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,10 +191,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
|
|
||||||
private final boolean mDebugLines;
|
private final boolean mDebugLines;
|
||||||
private Paint mDebugPaint;
|
private Paint mDebugPaint;
|
||||||
/** Used to track the Y positions that were already used to draw debug text labels. */
|
/**
|
||||||
|
* Used to track the Y positions that were already used to draw debug text labels.
|
||||||
|
*/
|
||||||
private Set<Integer> mDebugTextUsedYPositions;
|
private Set<Integer> mDebugTextUsedYPositions;
|
||||||
private final boolean mDebugRemoveAnimation;
|
private final boolean mDebugRemoveAnimation;
|
||||||
private final boolean mSimplifiedAppearFraction;
|
private final boolean mSimplifiedAppearFraction;
|
||||||
|
private final boolean mUseRoundnessSourceTypes;
|
||||||
|
|
||||||
private int mContentHeight;
|
private int mContentHeight;
|
||||||
private float mIntrinsicContentHeight;
|
private float mIntrinsicContentHeight;
|
||||||
@@ -355,15 +358,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
private final Rect mQsHeaderBound = new Rect();
|
private final Rect mQsHeaderBound = new Rect();
|
||||||
private boolean mContinuousShadowUpdate;
|
private boolean mContinuousShadowUpdate;
|
||||||
private boolean mContinuousBackgroundUpdate;
|
private boolean mContinuousBackgroundUpdate;
|
||||||
private final ViewTreeObserver.OnPreDrawListener mShadowUpdater
|
private final ViewTreeObserver.OnPreDrawListener mShadowUpdater = () -> {
|
||||||
= () -> {
|
updateViewShadows();
|
||||||
updateViewShadows();
|
return true;
|
||||||
return true;
|
};
|
||||||
};
|
|
||||||
private final ViewTreeObserver.OnPreDrawListener mBackgroundUpdater = () -> {
|
private final ViewTreeObserver.OnPreDrawListener mBackgroundUpdater = () -> {
|
||||||
updateBackground();
|
updateBackground();
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
private final Comparator<ExpandableView> mViewPositionComparator = (view, otherView) -> {
|
private final Comparator<ExpandableView> mViewPositionComparator = (view, otherView) -> {
|
||||||
float endY = view.getTranslationY() + view.getActualHeight();
|
float endY = view.getTranslationY() + view.getActualHeight();
|
||||||
float otherEndY = otherView.getTranslationY() + otherView.getActualHeight();
|
float otherEndY = otherView.getTranslationY() + otherView.getActualHeight();
|
||||||
@@ -419,7 +421,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
*/
|
*/
|
||||||
private int mMaxDisplayedNotifications = -1;
|
private int mMaxDisplayedNotifications = -1;
|
||||||
private float mKeyguardBottomPadding = -1;
|
private float mKeyguardBottomPadding = -1;
|
||||||
@VisibleForTesting int mStatusBarHeight;
|
@VisibleForTesting
|
||||||
|
int mStatusBarHeight;
|
||||||
private int mMinInteractionHeight;
|
private int mMinInteractionHeight;
|
||||||
private final Rect mClipRect = new Rect();
|
private final Rect mClipRect = new Rect();
|
||||||
private boolean mIsClipped;
|
private boolean mIsClipped;
|
||||||
@@ -568,6 +571,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private OnClickListener mManageButtonClickListener;
|
private OnClickListener mManageButtonClickListener;
|
||||||
|
@Nullable
|
||||||
|
private OnNotificationRemovedListener mOnNotificationRemovedListener;
|
||||||
|
|
||||||
public NotificationStackScrollLayout(Context context, AttributeSet attrs) {
|
public NotificationStackScrollLayout(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs, 0, 0);
|
super(context, attrs, 0, 0);
|
||||||
@@ -576,6 +581,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mDebugLines = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES);
|
mDebugLines = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES);
|
||||||
mDebugRemoveAnimation = featureFlags.isEnabled(Flags.NSSL_DEBUG_REMOVE_ANIMATION);
|
mDebugRemoveAnimation = featureFlags.isEnabled(Flags.NSSL_DEBUG_REMOVE_ANIMATION);
|
||||||
mSimplifiedAppearFraction = featureFlags.isEnabled(Flags.SIMPLIFIED_APPEAR_FRACTION);
|
mSimplifiedAppearFraction = featureFlags.isEnabled(Flags.SIMPLIFIED_APPEAR_FRACTION);
|
||||||
|
mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
|
||||||
mSectionsManager = Dependency.get(NotificationSectionsManager.class);
|
mSectionsManager = Dependency.get(NotificationSectionsManager.class);
|
||||||
mScreenOffAnimationController =
|
mScreenOffAnimationController =
|
||||||
Dependency.get(ScreenOffAnimationController.class);
|
Dependency.get(ScreenOffAnimationController.class);
|
||||||
@@ -741,7 +747,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void logHunSkippedForUnexpectedState(ExpandableNotificationRow enr,
|
private void logHunSkippedForUnexpectedState(ExpandableNotificationRow enr,
|
||||||
boolean expected, boolean actual) {
|
boolean expected, boolean actual) {
|
||||||
if (mLogger == null) return;
|
if (mLogger == null) return;
|
||||||
mLogger.hunSkippedForUnexpectedState(enr.getEntry(), expected, actual);
|
mLogger.hunSkippedForUnexpectedState(enr.getEntry(), expected, actual);
|
||||||
}
|
}
|
||||||
@@ -868,13 +874,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws round rects for each background section.
|
* Draws round rects for each background section.
|
||||||
*
|
* <p>
|
||||||
* We want to draw a round rect for each background section as defined by {@link #mSections}.
|
* We want to draw a round rect for each background section as defined by {@link #mSections}.
|
||||||
* However, if two sections are directly adjacent with no gap between them (e.g. on the
|
* However, if two sections are directly adjacent with no gap between them (e.g. on the
|
||||||
* lockscreen where the shelf can appear directly below the high priority section, or while
|
* lockscreen where the shelf can appear directly below the high priority section, or while
|
||||||
* scrolling the shade so that the top of the shelf is right at the bottom of the high priority
|
* scrolling the shade so that the top of the shelf is right at the bottom of the high priority
|
||||||
* section), we don't want to round the adjacent corners.
|
* section), we don't want to round the adjacent corners.
|
||||||
*
|
* <p>
|
||||||
* Since {@link Canvas} doesn't provide a way to draw a half-rounded rect, this means that we
|
* Since {@link Canvas} doesn't provide a way to draw a half-rounded rect, this means that we
|
||||||
* need to coalesce the backgrounds for adjacent sections and draw them as a single round rect.
|
* need to coalesce the backgrounds for adjacent sections and draw them as a single round rect.
|
||||||
* This method tracks the top of each rect we need to draw, then iterates through the visible
|
* This method tracks the top of each rect we need to draw, then iterates through the visible
|
||||||
@@ -883,7 +889,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
* the current section. When we're done iterating we will always have one rect left to draw.
|
* the current section. When we're done iterating we will always have one rect left to draw.
|
||||||
*/
|
*/
|
||||||
private void drawBackgroundRects(Canvas canvas, int left, int right, int top,
|
private void drawBackgroundRects(Canvas canvas, int left, int right, int top,
|
||||||
int animationYOffset) {
|
int animationYOffset) {
|
||||||
int backgroundRectTop = top;
|
int backgroundRectTop = top;
|
||||||
int lastSectionBottom =
|
int lastSectionBottom =
|
||||||
mSections[0].getCurrentBounds().bottom + animationYOffset;
|
mSections[0].getCurrentBounds().bottom + animationYOffset;
|
||||||
@@ -974,7 +980,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
void initView(Context context, NotificationSwipeHelper swipeHelper,
|
void initView(Context context, NotificationSwipeHelper swipeHelper,
|
||||||
NotificationStackSizeCalculator notificationStackSizeCalculator) {
|
NotificationStackSizeCalculator notificationStackSizeCalculator) {
|
||||||
mScroller = new OverScroller(getContext());
|
mScroller = new OverScroller(getContext());
|
||||||
mSwipeHelper = swipeHelper;
|
mSwipeHelper = swipeHelper;
|
||||||
mNotificationStackSizeCalculator = notificationStackSizeCalculator;
|
mNotificationStackSizeCalculator = notificationStackSizeCalculator;
|
||||||
@@ -1304,18 +1310,19 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
/**
|
/**
|
||||||
* @return Whether we should skip stack height updates.
|
* @return Whether we should skip stack height updates.
|
||||||
* True when
|
* True when
|
||||||
* 1) Unlock hint is running
|
* 1) Unlock hint is running
|
||||||
* 2) Swiping up on lockscreen or flinging down after swipe up
|
* 2) Swiping up on lockscreen or flinging down after swipe up
|
||||||
*/
|
*/
|
||||||
private boolean shouldSkipHeightUpdate() {
|
private boolean shouldSkipHeightUpdate() {
|
||||||
return mAmbientState.isOnKeyguard()
|
return mAmbientState.isOnKeyguard()
|
||||||
&& (mAmbientState.isUnlockHintRunning()
|
&& (mAmbientState.isUnlockHintRunning()
|
||||||
|| mAmbientState.isSwipingUp()
|
|| mAmbientState.isSwipingUp()
|
||||||
|| mAmbientState.isFlingingAfterSwipeUpOnLockscreen());
|
|| mAmbientState.isFlingingAfterSwipeUpOnLockscreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply expansion fraction to the y position and height of the notifications panel.
|
* Apply expansion fraction to the y position and height of the notifications panel.
|
||||||
|
*
|
||||||
* @param listenerNeedsAnimation does the listener need to animate?
|
* @param listenerNeedsAnimation does the listener need to animate?
|
||||||
*/
|
*/
|
||||||
private void updateStackPosition(boolean listenerNeedsAnimation) {
|
private void updateStackPosition(boolean listenerNeedsAnimation) {
|
||||||
@@ -1708,7 +1715,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
*/
|
*/
|
||||||
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
||||||
ExpandableView getChildAtPosition(float touchX, float touchY,
|
ExpandableView getChildAtPosition(float touchX, float touchY,
|
||||||
boolean requireMinHeight, boolean ignoreDecors) {
|
boolean requireMinHeight, boolean ignoreDecors) {
|
||||||
// find the view under the pointer, accounting for GONE views
|
// find the view under the pointer, accounting for GONE views
|
||||||
final int count = getChildCount();
|
final int count = getChildCount();
|
||||||
for (int childIdx = 0; childIdx < count; childIdx++) {
|
for (int childIdx = 0; childIdx < count; childIdx++) {
|
||||||
@@ -1868,9 +1875,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
public void dismissViewAnimated(
|
public void dismissViewAnimated(
|
||||||
View child, Consumer<Boolean> endRunnable, int delay, long duration) {
|
View child, Consumer<Boolean> endRunnable, int delay, long duration) {
|
||||||
if (child instanceof SectionHeaderView) {
|
if (child instanceof SectionHeaderView) {
|
||||||
((StackScrollerDecorView) child).setContentVisible(
|
((StackScrollerDecorView) child).setContentVisible(
|
||||||
false /* visible */, true /* animate */, endRunnable);
|
false /* visible */, true /* animate */, endRunnable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mSwipeHelper.dismissChild(
|
mSwipeHelper.dismissChild(
|
||||||
child,
|
child,
|
||||||
@@ -2032,10 +2039,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
/**
|
/**
|
||||||
* Scrolls by the given delta, overscrolling if needed. If called during a fling and the delta
|
* Scrolls by the given delta, overscrolling if needed. If called during a fling and the delta
|
||||||
* would cause us to exceed the provided maximum overscroll, springs back instead.
|
* would cause us to exceed the provided maximum overscroll, springs back instead.
|
||||||
*
|
* <p>
|
||||||
* This method performs the determination of whether we're exceeding the overscroll and clamps
|
* This method performs the determination of whether we're exceeding the overscroll and clamps
|
||||||
* the scroll amount if so. The actual scrolling/overscrolling happens in
|
* the scroll amount if so. The actual scrolling/overscrolling happens in
|
||||||
* {@link #onCustomOverScrolled(int, boolean)}
|
* {@link #onCustomOverScrolled(int, boolean)}
|
||||||
|
*
|
||||||
* @param deltaY The (signed) number of pixels to scroll.
|
* @param deltaY The (signed) number of pixels to scroll.
|
||||||
* @param scrollY The current scroll position (absolute scrolling only).
|
* @param scrollY The current scroll position (absolute scrolling only).
|
||||||
* @param scrollRangeY The maximum allowable scroll position (absolute scrolling only).
|
* @param scrollRangeY The maximum allowable scroll position (absolute scrolling only).
|
||||||
@@ -2098,7 +2106,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
*/
|
*/
|
||||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||||
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
|
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
|
||||||
boolean cancelAnimators) {
|
boolean cancelAnimators) {
|
||||||
setOverScrollAmount(amount, onTop, animate, cancelAnimators, isRubberbanded(onTop));
|
setOverScrollAmount(amount, onTop, animate, cancelAnimators, isRubberbanded(onTop));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2114,7 +2122,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
*/
|
*/
|
||||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||||
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
|
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
|
||||||
boolean cancelAnimators, boolean isRubberbanded) {
|
boolean cancelAnimators, boolean isRubberbanded) {
|
||||||
if (cancelAnimators) {
|
if (cancelAnimators) {
|
||||||
mStateAnimator.cancelOverScrollAnimators(onTop);
|
mStateAnimator.cancelOverScrollAnimators(onTop);
|
||||||
}
|
}
|
||||||
@@ -2123,7 +2131,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||||
private void setOverScrollAmountInternal(float amount, boolean onTop, boolean animate,
|
private void setOverScrollAmountInternal(float amount, boolean onTop, boolean animate,
|
||||||
boolean isRubberbanded) {
|
boolean isRubberbanded) {
|
||||||
amount = Math.max(0, amount);
|
amount = Math.max(0, amount);
|
||||||
if (animate) {
|
if (animate) {
|
||||||
mStateAnimator.animateOverScrollToAmount(amount, onTop, isRubberbanded);
|
mStateAnimator.animateOverScrollToAmount(amount, onTop, isRubberbanded);
|
||||||
@@ -2179,7 +2187,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
* Scrolls to the given position, overscrolling if needed. If called during a fling and the
|
* Scrolls to the given position, overscrolling if needed. If called during a fling and the
|
||||||
* position exceeds the provided maximum overscroll, springs back instead.
|
* position exceeds the provided maximum overscroll, springs back instead.
|
||||||
*
|
*
|
||||||
* @param scrollY The target scroll position.
|
* @param scrollY The target scroll position.
|
||||||
* @param clampedY Whether this value was clamped by the calling method, meaning we've reached
|
* @param clampedY Whether this value was clamped by the calling method, meaning we've reached
|
||||||
* the overscroll limit.
|
* the overscroll limit.
|
||||||
*/
|
*/
|
||||||
@@ -2288,8 +2296,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
|
if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
|
||||||
List<ExpandableNotificationRow> notificationChildren =
|
List<ExpandableNotificationRow> notificationChildren =
|
||||||
row.getAttachedChildren();
|
row.getAttachedChildren();
|
||||||
for (int childIndex = 0; childIndex < notificationChildren.size();
|
int childrenSize = notificationChildren.size();
|
||||||
childIndex++) {
|
for (int childIndex = 0; childIndex < childrenSize; childIndex++) {
|
||||||
ExpandableNotificationRow rowChild = notificationChildren.get(childIndex);
|
ExpandableNotificationRow rowChild = notificationChildren.get(childIndex);
|
||||||
if (rowChild.getTranslationY() + rowTranslation >= translationY) {
|
if (rowChild.getTranslationY() + rowTranslation >= translationY) {
|
||||||
return rowChild;
|
return rowChild;
|
||||||
@@ -2365,10 +2373,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
/**
|
/**
|
||||||
* Calculate the gap height between two different views
|
* Calculate the gap height between two different views
|
||||||
*
|
*
|
||||||
* @param previous the previousView
|
* @param previous the previousView
|
||||||
* @param current the currentView
|
* @param current the currentView
|
||||||
* @param visibleIndex the visible index in the list
|
* @param visibleIndex the visible index in the list
|
||||||
*
|
|
||||||
* @return the gap height needed before the current view
|
* @return the gap height needed before the current view
|
||||||
*/
|
*/
|
||||||
public float calculateGapHeight(
|
public float calculateGapHeight(
|
||||||
@@ -2376,7 +2383,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
ExpandableView current,
|
ExpandableView current,
|
||||||
int visibleIndex
|
int visibleIndex
|
||||||
) {
|
) {
|
||||||
return mStackScrollAlgorithm.getGapHeightForChild(mSectionsManager, visibleIndex, current,
|
return mStackScrollAlgorithm.getGapHeightForChild(mSectionsManager, visibleIndex, current,
|
||||||
previous, mAmbientState.getFractionToShade(), mAmbientState.isOnKeyguard());
|
previous, mAmbientState.getFractionToShade(), mAmbientState.isOnKeyguard());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2642,15 +2649,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
return mScrolledToTopOnFirstDown
|
return mScrolledToTopOnFirstDown
|
||||||
&& !mExpandedInThisMotion
|
&& !mExpandedInThisMotion
|
||||||
&& (initialVelocity > mMinimumVelocity
|
&& (initialVelocity > mMinimumVelocity
|
||||||
|| (topOverScroll > mMinTopOverScrollToEscape && initialVelocity > 0));
|
|| (topOverScroll > mMinTopOverScrollToEscape && initialVelocity > 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the top padding of the notifications, taking {@link #getIntrinsicPadding()} into
|
* Updates the top padding of the notifications, taking {@link #getIntrinsicPadding()} into
|
||||||
* account.
|
* account.
|
||||||
*
|
*
|
||||||
* @param qsHeight the top padding imposed by the quick settings panel
|
* @param qsHeight the top padding imposed by the quick settings panel
|
||||||
* @param animate whether to animate the change
|
* @param animate whether to animate the change
|
||||||
*/
|
*/
|
||||||
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
||||||
public void updateTopPadding(float qsHeight, boolean animate) {
|
public void updateTopPadding(float qsHeight, boolean animate) {
|
||||||
@@ -2724,21 +2731,34 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
public void setChildTransferInProgress(boolean childTransferInProgress) {
|
public void setChildTransferInProgress(boolean childTransferInProgress) {
|
||||||
Assert.isMainThread();
|
Assert.isMainThread();
|
||||||
mChildTransferInProgress = childTransferInProgress;
|
mChildTransferInProgress = childTransferInProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the remove notification listener
|
||||||
|
* @param listener callback for notification removed
|
||||||
|
*/
|
||||||
|
public void setOnNotificationRemovedListener(OnNotificationRemovedListener listener) {
|
||||||
|
mOnNotificationRemovedListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
@Override
|
@Override
|
||||||
public void onViewRemoved(View child) {
|
public void onViewRemoved(View child) {
|
||||||
super.onViewRemoved(child);
|
super.onViewRemoved(child);
|
||||||
// we only call our internal methods if this is actually a removal and not just a
|
// we only call our internal methods if this is actually a removal and not just a
|
||||||
// notification which becomes a child notification
|
// notification which becomes a child notification
|
||||||
|
ExpandableView expandableView = (ExpandableView) child;
|
||||||
if (!mChildTransferInProgress) {
|
if (!mChildTransferInProgress) {
|
||||||
onViewRemovedInternal((ExpandableView) child, this);
|
onViewRemovedInternal(expandableView, this);
|
||||||
|
}
|
||||||
|
if (mOnNotificationRemovedListener != null) {
|
||||||
|
mOnNotificationRemovedListener.onNotificationRemoved(
|
||||||
|
expandableView,
|
||||||
|
mChildTransferInProgress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2998,8 +3018,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mAnimateNextSectionBoundsChange = false;
|
mAnimateNextSectionBoundsChange = false;
|
||||||
}
|
}
|
||||||
mAmbientState.setLastVisibleBackgroundChild(lastChild);
|
mAmbientState.setLastVisibleBackgroundChild(lastChild);
|
||||||
// TODO: Refactor SectionManager and put the RoundnessManager there.
|
if (!mUseRoundnessSourceTypes) {
|
||||||
mController.getNotificationRoundnessManager().updateRoundedChildren(mSections);
|
// TODO: Refactor SectionManager and put the RoundnessManager there.
|
||||||
|
mController.getNotificationRoundnessManager().updateRoundedChildren(mSections);
|
||||||
|
}
|
||||||
mAnimateBottomOnLayout = false;
|
mAnimateBottomOnLayout = false;
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
@@ -3206,7 +3228,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
// Only animate if we still have pinned heads up, otherwise we just have the
|
// Only animate if we still have pinned heads up, otherwise we just have the
|
||||||
// regular collapse animation of the lock screen
|
// regular collapse animation of the lock screen
|
||||||
|| (mKeyguardBypassEnabled && onKeyguard()
|
|| (mKeyguardBypassEnabled && onKeyguard()
|
||||||
&& mInHeadsUpPinnedMode);
|
&& mInHeadsUpPinnedMode);
|
||||||
if (performDisappearAnimation && !isHeadsUp) {
|
if (performDisappearAnimation && !isHeadsUp) {
|
||||||
type = row.wasJustClicked()
|
type = row.wasJustClicked()
|
||||||
? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
|
? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
|
||||||
@@ -3351,7 +3373,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
AnimationEvent animEvent = duration == null
|
AnimationEvent animEvent = duration == null
|
||||||
? new AnimationEvent(child, AnimationEvent.ANIMATION_TYPE_CHANGE_POSITION)
|
? new AnimationEvent(child, AnimationEvent.ANIMATION_TYPE_CHANGE_POSITION)
|
||||||
: new AnimationEvent(
|
: new AnimationEvent(
|
||||||
child, AnimationEvent.ANIMATION_TYPE_CHANGE_POSITION, duration);
|
child, AnimationEvent.ANIMATION_TYPE_CHANGE_POSITION, duration);
|
||||||
mAnimationEvents.add(animEvent);
|
mAnimationEvents.add(animEvent);
|
||||||
}
|
}
|
||||||
mChildrenChangingPositions.clear();
|
mChildrenChangingPositions.clear();
|
||||||
@@ -3442,7 +3464,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
|
@ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
|
||||||
protected StackScrollAlgorithm createStackScrollAlgorithm(Context context) {
|
protected StackScrollAlgorithm createStackScrollAlgorithm(Context context) {
|
||||||
return new StackScrollAlgorithm(context, this);
|
StackScrollAlgorithm stackScrollAlgorithm = new StackScrollAlgorithm(context, this);
|
||||||
|
stackScrollAlgorithm.useRoundnessSourceTypes(mUseRoundnessSourceTypes);
|
||||||
|
return stackScrollAlgorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3772,7 +3796,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void logEmptySpaceClick(MotionEvent ev, boolean isTouchBelowLastNotification,
|
private void logEmptySpaceClick(MotionEvent ev, boolean isTouchBelowLastNotification,
|
||||||
int statusBarState, boolean touchIsClick) {
|
int statusBarState, boolean touchIsClick) {
|
||||||
if (mLogger == null) {
|
if (mLogger == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3957,7 +3981,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mOnEmptySpaceClickListener = listener;
|
mOnEmptySpaceClickListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ShadeViewRefactor(RefactorComponent.INPUT)
|
@ShadeViewRefactor(RefactorComponent.INPUT)
|
||||||
public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
|
public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
|
||||||
@@ -4728,7 +4754,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
return touchY > mTopPadding + mStackTranslation;
|
return touchY > mTopPadding + mStackTranslation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
|
public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
|
||||||
@@ -5353,7 +5381,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
return canChildBeCleared(row) && matchesSelection(row, selection);
|
return canChildBeCleared(row) && matchesSelection(row, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Register a {@link View.OnClickListener} to be invoked when the Manage button is clicked. */
|
/**
|
||||||
|
* Register a {@link View.OnClickListener} to be invoked when the Manage button is clicked.
|
||||||
|
*/
|
||||||
public void setManageButtonClickListener(@Nullable OnClickListener listener) {
|
public void setManageButtonClickListener(@Nullable OnClickListener listener) {
|
||||||
mManageButtonClickListener = listener;
|
mManageButtonClickListener = listener;
|
||||||
if (mFooterView != null) {
|
if (mFooterView != null) {
|
||||||
@@ -5418,6 +5448,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
/**
|
/**
|
||||||
* Set how far the wake up is when waking up from pulsing. This is a height and will adjust the
|
* Set how far the wake up is when waking up from pulsing. This is a height and will adjust the
|
||||||
* notification positions accordingly.
|
* notification positions accordingly.
|
||||||
|
*
|
||||||
* @param height the new wake up height
|
* @param height the new wake up height
|
||||||
* @return the overflow how much the height is further than he lowest notification
|
* @return the overflow how much the height is further than he lowest notification
|
||||||
*/
|
*/
|
||||||
@@ -5649,7 +5680,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
* Set rounded rect clipping bounds on this view.
|
* Set rounded rect clipping bounds on this view.
|
||||||
*/
|
*/
|
||||||
public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
|
public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
|
||||||
int bottomRadius) {
|
int bottomRadius) {
|
||||||
if (mRoundedRectClippingLeft == left && mRoundedRectClippingRight == right
|
if (mRoundedRectClippingLeft == left && mRoundedRectClippingRight == right
|
||||||
&& mRoundedRectClippingBottom == bottom && mRoundedRectClippingTop == top
|
&& mRoundedRectClippingBottom == bottom && mRoundedRectClippingTop == top
|
||||||
&& mBgCornerRadii[0] == topRadius && mBgCornerRadii[5] == bottomRadius) {
|
&& mBgCornerRadii[0] == topRadius && mBgCornerRadii[5] == bottomRadius) {
|
||||||
@@ -5710,7 +5741,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mLaunchingNotification = launching;
|
mLaunchingNotification = launching;
|
||||||
mLaunchingNotificationNeedsToBeClipped = mLaunchAnimationParams != null
|
mLaunchingNotificationNeedsToBeClipped = mLaunchAnimationParams != null
|
||||||
&& (mLaunchAnimationParams.getStartRoundedTopClipping() > 0
|
&& (mLaunchAnimationParams.getStartRoundedTopClipping() > 0
|
||||||
|| mLaunchAnimationParams.getParentStartRoundedTopClipping() > 0);
|
|| mLaunchAnimationParams.getParentStartRoundedTopClipping() > 0);
|
||||||
if (!mLaunchingNotificationNeedsToBeClipped || !mLaunchingNotification) {
|
if (!mLaunchingNotificationNeedsToBeClipped || !mLaunchingNotification) {
|
||||||
mLaunchedNotificationClipPath.reset();
|
mLaunchedNotificationClipPath.reset();
|
||||||
}
|
}
|
||||||
@@ -5748,7 +5779,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mLaunchAnimationParams.getProgress(0,
|
mLaunchAnimationParams.getProgress(0,
|
||||||
NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING));
|
NotificationLaunchAnimatorController.ANIMATION_DURATION_TOP_ROUNDING));
|
||||||
int top = (int) Math.min(MathUtils.lerp(mRoundedRectClippingTop,
|
int top = (int) Math.min(MathUtils.lerp(mRoundedRectClippingTop,
|
||||||
mLaunchAnimationParams.getTop(), expandProgress),
|
mLaunchAnimationParams.getTop(), expandProgress),
|
||||||
mRoundedRectClippingTop);
|
mRoundedRectClippingTop);
|
||||||
float topRadius = mLaunchAnimationParams.getTopCornerRadius();
|
float topRadius = mLaunchAnimationParams.getTopCornerRadius();
|
||||||
float bottomRadius = mLaunchAnimationParams.getBottomCornerRadius();
|
float bottomRadius = mLaunchAnimationParams.getBottomCornerRadius();
|
||||||
@@ -5872,25 +5903,25 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
public interface OnOverscrollTopChangedListener {
|
public interface OnOverscrollTopChangedListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies a listener that the overscroll has changed.
|
* Notifies a listener that the overscroll has changed.
|
||||||
*
|
*
|
||||||
* @param amount the amount of overscroll, in pixels
|
* @param amount the amount of overscroll, in pixels
|
||||||
* @param isRubberbanded if true, this is a rubberbanded overscroll; if false, this is an
|
* @param isRubberbanded if true, this is a rubberbanded overscroll; if false, this is an
|
||||||
* unrubberbanded motion to directly expand overscroll view (e.g
|
* unrubberbanded motion to directly expand overscroll view (e.g
|
||||||
* expand
|
* expand
|
||||||
* QS)
|
* QS)
|
||||||
*/
|
*/
|
||||||
void onOverscrollTopChanged(float amount, boolean isRubberbanded);
|
void onOverscrollTopChanged(float amount, boolean isRubberbanded);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify a listener that the scroller wants to escape from the scrolling motion and
|
* Notify a listener that the scroller wants to escape from the scrolling motion and
|
||||||
* start a fling animation to the expanded or collapsed overscroll view (e.g expand the QS)
|
* start a fling animation to the expanded or collapsed overscroll view (e.g expand the QS)
|
||||||
*
|
*
|
||||||
* @param velocity The velocity that the Scroller had when over flinging
|
* @param velocity The velocity that the Scroller had when over flinging
|
||||||
* @param open Should the fling open or close the overscroll view.
|
* @param open Should the fling open or close the overscroll view.
|
||||||
*/
|
*/
|
||||||
void flingTopOverscroll(float velocity, boolean open);
|
void flingTopOverscroll(float velocity, boolean open);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
@@ -6252,7 +6283,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public HeadsUpTouchHelper.Callback getHeadsUpCallback() { return mHeadsUpCallback; }
|
public HeadsUpTouchHelper.Callback getHeadsUpCallback() {
|
||||||
|
return mHeadsUpCallback;
|
||||||
|
}
|
||||||
|
|
||||||
void onGroupExpandChanged(ExpandableNotificationRow changedRow, boolean expanded) {
|
void onGroupExpandChanged(ExpandableNotificationRow changedRow, boolean expanded) {
|
||||||
boolean animated = mAnimationsEnabled && (mIsExpanded || changedRow.isPinned());
|
boolean animated = mAnimationsEnabled && (mIsExpanded || changedRow.isPinned());
|
||||||
@@ -6357,15 +6390,25 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
return mLastSentExpandedHeight;
|
return mLastSentExpandedHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Enum for selecting some or all notification rows (does not included non-notif views). */
|
/**
|
||||||
|
* Enum for selecting some or all notification rows (does not included non-notif views).
|
||||||
|
*/
|
||||||
@Retention(SOURCE)
|
@Retention(SOURCE)
|
||||||
@IntDef({ROWS_ALL, ROWS_HIGH_PRIORITY, ROWS_GENTLE})
|
@IntDef({ROWS_ALL, ROWS_HIGH_PRIORITY, ROWS_GENTLE})
|
||||||
@interface SelectedRows {}
|
@interface SelectedRows {
|
||||||
/** All rows representing notifs. */
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All rows representing notifs.
|
||||||
|
*/
|
||||||
public static final int ROWS_ALL = 0;
|
public static final int ROWS_ALL = 0;
|
||||||
/** Only rows where entry.isHighPriority() is true. */
|
/**
|
||||||
|
* Only rows where entry.isHighPriority() is true.
|
||||||
|
*/
|
||||||
public static final int ROWS_HIGH_PRIORITY = 1;
|
public static final int ROWS_HIGH_PRIORITY = 1;
|
||||||
/** Only rows where entry.isHighPriority() is false. */
|
/**
|
||||||
|
* Only rows where entry.isHighPriority() is false.
|
||||||
|
*/
|
||||||
public static final int ROWS_GENTLE = 2;
|
public static final int ROWS_GENTLE = 2;
|
||||||
|
|
||||||
interface ClearAllListener {
|
interface ClearAllListener {
|
||||||
@@ -6380,4 +6423,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
void onAnimationEnd(
|
void onAnimationEnd(
|
||||||
List<ExpandableNotificationRow> viewsToRemove, @SelectedRows int selectedRows);
|
List<ExpandableNotificationRow> viewsToRemove, @SelectedRows int selectedRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface OnNotificationRemovedListener {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param child
|
||||||
|
* @param isTransferInProgress
|
||||||
|
*/
|
||||||
|
void onNotificationRemoved(ExpandableView child, boolean isTransferInProgress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,10 +182,12 @@ public class NotificationStackScrollLayoutController {
|
|||||||
private NotificationStackScrollLayout mView;
|
private NotificationStackScrollLayout mView;
|
||||||
private boolean mFadeNotificationsOnDismiss;
|
private boolean mFadeNotificationsOnDismiss;
|
||||||
private NotificationSwipeHelper mSwipeHelper;
|
private NotificationSwipeHelper mSwipeHelper;
|
||||||
@Nullable private Boolean mHistoryEnabled;
|
@Nullable
|
||||||
|
private Boolean mHistoryEnabled;
|
||||||
private int mBarState;
|
private int mBarState;
|
||||||
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
||||||
private final FeatureFlags mFeatureFlags;
|
private final FeatureFlags mFeatureFlags;
|
||||||
|
private final boolean mUseRoundnessSourceTypes;
|
||||||
private final NotificationTargetsHelper mNotificationTargetsHelper;
|
private final NotificationTargetsHelper mNotificationTargetsHelper;
|
||||||
|
|
||||||
private View mLongPressedView;
|
private View mLongPressedView;
|
||||||
@@ -391,7 +393,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
if (item != null) {
|
if (item != null) {
|
||||||
Point origin = provider.getRevealAnimationOrigin();
|
Point origin = provider.getRevealAnimationOrigin();
|
||||||
mNotificationGutsManager.openGuts(row, origin.x, origin.y, item);
|
mNotificationGutsManager.openGuts(row, origin.x, origin.y, item);
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Provider has shouldShowGutsOnSnapOpen, but provided no "
|
Log.e(TAG, "Provider has shouldShowGutsOnSnapOpen, but provided no "
|
||||||
+ "menu item in menuItemtoExposeOnSnap. Skipping.");
|
+ "menu item in menuItemtoExposeOnSnap. Skipping.");
|
||||||
}
|
}
|
||||||
@@ -420,7 +422,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSnooze(StatusBarNotification sbn,
|
public void onSnooze(StatusBarNotification sbn,
|
||||||
NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
|
NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
|
||||||
mCentralSurfaces.setNotificationSnoozed(sbn, snoozeOption);
|
mCentralSurfaces.setNotificationSnoozed(sbn, snoozeOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,7 +546,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean updateSwipeProgress(View animView, boolean dismissable,
|
public boolean updateSwipeProgress(View animView, boolean dismissable,
|
||||||
float swipeProgress) {
|
float swipeProgress) {
|
||||||
// Returning true prevents alpha fading.
|
// Returning true prevents alpha fading.
|
||||||
return !mFadeNotificationsOnDismiss;
|
return !mFadeNotificationsOnDismiss;
|
||||||
}
|
}
|
||||||
@@ -584,16 +586,22 @@ public class NotificationStackScrollLayoutController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHeadsUpPinned(NotificationEntry entry) {
|
public void onHeadsUpPinned(NotificationEntry entry) {
|
||||||
mNotificationRoundnessManager.updateView(entry.getRow(), false /* animate */);
|
if (!mUseRoundnessSourceTypes) {
|
||||||
|
mNotificationRoundnessManager.updateView(
|
||||||
|
entry.getRow(),
|
||||||
|
/* animate = */ false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onHeadsUpUnPinned(NotificationEntry entry) {
|
public void onHeadsUpUnPinned(NotificationEntry entry) {
|
||||||
ExpandableNotificationRow row = entry.getRow();
|
if (!mUseRoundnessSourceTypes) {
|
||||||
// update the roundedness posted, because we might be animating away the
|
ExpandableNotificationRow row = entry.getRow();
|
||||||
// headsup soon, so no need to set the roundedness to 0 and then back to 1.
|
// update the roundedness posted, because we might be animating away the
|
||||||
row.post(() -> mNotificationRoundnessManager.updateView(row,
|
// headsup soon, so no need to set the roundedness to 0 and then back to 1.
|
||||||
true /* animate */));
|
row.post(() -> mNotificationRoundnessManager.updateView(row,
|
||||||
|
true /* animate */));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -603,8 +611,10 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mView.setNumHeadsUp(numEntries);
|
mView.setNumHeadsUp(numEntries);
|
||||||
mView.setTopHeadsUpEntry(topEntry);
|
mView.setTopHeadsUpEntry(topEntry);
|
||||||
generateHeadsUpAnimation(entry, isHeadsUp);
|
generateHeadsUpAnimation(entry, isHeadsUp);
|
||||||
ExpandableNotificationRow row = entry.getRow();
|
if (!mUseRoundnessSourceTypes) {
|
||||||
mNotificationRoundnessManager.updateView(row, true /* animate */);
|
ExpandableNotificationRow row = entry.getRow();
|
||||||
|
mNotificationRoundnessManager.updateView(row, true /* animate */);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -697,6 +707,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mSeenNotificationsProvider = seenNotificationsProvider;
|
mSeenNotificationsProvider = seenNotificationsProvider;
|
||||||
mShadeController = shadeController;
|
mShadeController = shadeController;
|
||||||
mFeatureFlags = featureFlags;
|
mFeatureFlags = featureFlags;
|
||||||
|
mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
|
||||||
mNotificationTargetsHelper = notificationTargetsHelper;
|
mNotificationTargetsHelper = notificationTargetsHelper;
|
||||||
updateResources();
|
updateResources();
|
||||||
}
|
}
|
||||||
@@ -763,8 +774,10 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener);
|
mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener);
|
||||||
|
|
||||||
mFadeNotificationsOnDismiss = mFeatureFlags.isEnabled(Flags.NOTIFICATION_DISMISSAL_FADE);
|
mFadeNotificationsOnDismiss = mFeatureFlags.isEnabled(Flags.NOTIFICATION_DISMISSAL_FADE);
|
||||||
mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate);
|
if (!mUseRoundnessSourceTypes) {
|
||||||
mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded);
|
mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate);
|
||||||
|
mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded);
|
||||||
|
}
|
||||||
|
|
||||||
mVisibilityLocationProviderDelegator.setDelegate(this::isInVisibleLocation);
|
mVisibilityLocationProviderDelegator.setDelegate(this::isInVisibleLocation);
|
||||||
|
|
||||||
@@ -997,9 +1010,11 @@ public class NotificationStackScrollLayoutController {
|
|||||||
Log.wtf(TAG, "isHistoryEnabled failed to initialize its value");
|
Log.wtf(TAG, "isHistoryEnabled failed to initialize its value");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mHistoryEnabled = historyEnabled =
|
mHistoryEnabled = historyEnabled = Settings.Secure.getIntForUser(
|
||||||
Settings.Secure.getIntForUser(mView.getContext().getContentResolver(),
|
mView.getContext().getContentResolver(),
|
||||||
Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
|
Settings.Secure.NOTIFICATION_HISTORY_ENABLED,
|
||||||
|
0,
|
||||||
|
UserHandle.USER_CURRENT) == 1;
|
||||||
}
|
}
|
||||||
return historyEnabled;
|
return historyEnabled;
|
||||||
}
|
}
|
||||||
@@ -1029,7 +1044,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
|
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
|
||||||
boolean cancelAnimators) {
|
boolean cancelAnimators) {
|
||||||
mView.setOverScrollAmount(amount, onTop, animate, cancelAnimators);
|
mView.setOverScrollAmount(amount, onTop, animate, cancelAnimators);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1207,7 +1222,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update whether we should show the empty shade view ("no notifications" in the shade).
|
* Update whether we should show the empty shade view ("no notifications" in the shade).
|
||||||
*
|
* <p>
|
||||||
* When in split mode, notifications are always visible regardless of the state of the
|
* When in split mode, notifications are always visible regardless of the state of the
|
||||||
* QuickSettings panel. That being the case, empty view is always shown if the other conditions
|
* QuickSettings panel. That being the case, empty view is always shown if the other conditions
|
||||||
* are true.
|
* are true.
|
||||||
@@ -1233,7 +1248,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if {@link StatusBarStateController} is in transition to the KEYGUARD
|
* @return true if {@link StatusBarStateController} is in transition to the KEYGUARD
|
||||||
* and false otherwise.
|
* and false otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean isInTransitionToKeyguard() {
|
private boolean isInTransitionToKeyguard() {
|
||||||
final int currentState = mStatusBarStateController.getState();
|
final int currentState = mStatusBarStateController.getState();
|
||||||
@@ -1265,7 +1280,9 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mView.setExpandedHeight(expandedHeight);
|
mView.setExpandedHeight(expandedHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the QS header. Used to check if a touch is within its bounds. */
|
/**
|
||||||
|
* Sets the QS header. Used to check if a touch is within its bounds.
|
||||||
|
*/
|
||||||
public void setQsHeader(ViewGroup view) {
|
public void setQsHeader(ViewGroup view) {
|
||||||
mView.setQsHeader(view);
|
mView.setQsHeader(view);
|
||||||
}
|
}
|
||||||
@@ -1328,7 +1345,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
public RemoteInputController.Delegate createDelegate() {
|
public RemoteInputController.Delegate createDelegate() {
|
||||||
return new RemoteInputController.Delegate() {
|
return new RemoteInputController.Delegate() {
|
||||||
public void setRemoteInputActive(NotificationEntry entry,
|
public void setRemoteInputActive(NotificationEntry entry,
|
||||||
boolean remoteInputActive) {
|
boolean remoteInputActive) {
|
||||||
mHeadsUpManager.setRemoteInputActive(entry, remoteInputActive);
|
mHeadsUpManager.setRemoteInputActive(entry, remoteInputActive);
|
||||||
entry.notifyHeightChanged(true /* needsAnimation */);
|
entry.notifyHeightChanged(true /* needsAnimation */);
|
||||||
updateFooter();
|
updateFooter();
|
||||||
@@ -1459,7 +1476,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onAnimationEnd(List<ExpandableNotificationRow> viewsToRemove,
|
private void onAnimationEnd(List<ExpandableNotificationRow> viewsToRemove,
|
||||||
@SelectedRows int selectedRows) {
|
@SelectedRows int selectedRows) {
|
||||||
if (selectedRows == ROWS_ALL) {
|
if (selectedRows == ROWS_ALL) {
|
||||||
mNotifCollection.dismissAllNotifications(
|
mNotifCollection.dismissAllNotifications(
|
||||||
mLockscreenUserManager.getCurrentUserId());
|
mLockscreenUserManager.getCurrentUserId());
|
||||||
@@ -1502,8 +1519,8 @@ public class NotificationStackScrollLayoutController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the inset during the full shade transition, that needs to be added to the position
|
* @return the inset during the full shade transition, that needs to be added to the position
|
||||||
* of the quick settings edge. This is relevant for media, that is transitioning
|
* of the quick settings edge. This is relevant for media, that is transitioning
|
||||||
* from the keyguard host to the quick settings one.
|
* from the keyguard host to the quick settings one.
|
||||||
*/
|
*/
|
||||||
public int getFullShadeTransitionInset() {
|
public int getFullShadeTransitionInset() {
|
||||||
MediaContainerView view = mKeyguardMediaController.getSinglePaneContainer();
|
MediaContainerView view = mKeyguardMediaController.getSinglePaneContainer();
|
||||||
@@ -1517,10 +1534,10 @@ public class NotificationStackScrollLayoutController {
|
|||||||
/**
|
/**
|
||||||
* @param fraction The fraction of lockscreen to shade transition.
|
* @param fraction The fraction of lockscreen to shade transition.
|
||||||
* 0f for all other states.
|
* 0f for all other states.
|
||||||
*
|
* <p>
|
||||||
* Once the lockscreen to shade transition completes and the shade is 100% open,
|
* Once the lockscreen to shade transition completes and the shade is 100% open,
|
||||||
* LockscreenShadeTransitionController resets amount and fraction to 0, where they remain
|
* LockscreenShadeTransitionController resets amount and fraction to 0, where
|
||||||
* until the next lockscreen-to-shade transition.
|
* they remain until the next lockscreen-to-shade transition.
|
||||||
*/
|
*/
|
||||||
public void setTransitionToFullShadeAmount(float fraction) {
|
public void setTransitionToFullShadeAmount(float fraction) {
|
||||||
mView.setFractionToShade(fraction);
|
mView.setFractionToShade(fraction);
|
||||||
@@ -1533,7 +1550,9 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mView.setExtraTopInsetForFullShadeTransition(overScrollAmount);
|
mView.setExtraTopInsetForFullShadeTransition(overScrollAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** */
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
public void setWillExpand(boolean willExpand) {
|
public void setWillExpand(boolean willExpand) {
|
||||||
mView.setWillExpand(willExpand);
|
mView.setWillExpand(willExpand);
|
||||||
}
|
}
|
||||||
@@ -1549,7 +1568,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
* Set rounded rect clipping bounds on this view.
|
* Set rounded rect clipping bounds on this view.
|
||||||
*/
|
*/
|
||||||
public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
|
public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
|
||||||
int bottomRadius) {
|
int bottomRadius) {
|
||||||
mView.setRoundedClippingBounds(left, top, right, bottom, topRadius, bottomRadius);
|
mView.setRoundedClippingBounds(left, top, right, bottom, topRadius, bottomRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1568,6 +1587,15 @@ public class NotificationStackScrollLayoutController {
|
|||||||
return mNotificationTargetsHelper;
|
return mNotificationTargetsHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the remove notification listener
|
||||||
|
* @param listener callback for notification removed
|
||||||
|
*/
|
||||||
|
public void setOnNotificationRemovedListener(
|
||||||
|
NotificationStackScrollLayout.OnNotificationRemovedListener listener) {
|
||||||
|
mView.setOnNotificationRemovedListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum for UiEvent logged from this class
|
* Enum for UiEvent logged from this class
|
||||||
*/
|
*/
|
||||||
@@ -1578,10 +1606,13 @@ public class NotificationStackScrollLayoutController {
|
|||||||
@UiEvent(doc = "User dismissed all silent notifications from notification panel.")
|
@UiEvent(doc = "User dismissed all silent notifications from notification panel.")
|
||||||
DISMISS_SILENT_NOTIFICATIONS_PANEL(314);
|
DISMISS_SILENT_NOTIFICATIONS_PANEL(314);
|
||||||
private final int mId;
|
private final int mId;
|
||||||
|
|
||||||
NotificationPanelEvent(int id) {
|
NotificationPanelEvent(int id) {
|
||||||
mId = id;
|
mId = id;
|
||||||
}
|
}
|
||||||
@Override public int getId() {
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
return mId;
|
return mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1722,8 +1753,12 @@ public class NotificationStackScrollLayoutController {
|
|||||||
@Override
|
@Override
|
||||||
public void bindRow(ExpandableNotificationRow row) {
|
public void bindRow(ExpandableNotificationRow row) {
|
||||||
row.setHeadsUpAnimatingAwayListener(animatingAway -> {
|
row.setHeadsUpAnimatingAwayListener(animatingAway -> {
|
||||||
mNotificationRoundnessManager.updateView(row, false);
|
if (!mUseRoundnessSourceTypes) {
|
||||||
mHeadsUpAppearanceController.updateHeader(row.getEntry());
|
mNotificationRoundnessManager.updateView(row, false);
|
||||||
|
}
|
||||||
|
NotificationEntry entry = row.getEntry();
|
||||||
|
mHeadsUpAppearanceController.updateHeader(entry);
|
||||||
|
mHeadsUpAppearanceController.updateHeadsUpAndPulsingRoundness(entry);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ package com.android.systemui.statusbar.notification.stack;
|
|||||||
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_ROW_SWIPE;
|
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_ROW_SWIPE;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -34,9 +35,11 @@ import com.android.internal.jank.InteractionJankMonitor;
|
|||||||
import com.android.systemui.SwipeHelper;
|
import com.android.systemui.SwipeHelper;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
|
import com.android.systemui.flags.Flags;
|
||||||
import com.android.systemui.plugins.FalsingManager;
|
import com.android.systemui.plugins.FalsingManager;
|
||||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
|
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
|
||||||
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
|
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
|
||||||
|
import com.android.systemui.statusbar.notification.SourceType;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
||||||
|
|
||||||
@@ -49,6 +52,7 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected static final long COVER_MENU_DELAY = 4000;
|
protected static final long COVER_MENU_DELAY = 4000;
|
||||||
private static final String TAG = "NotificationSwipeHelper";
|
private static final String TAG = "NotificationSwipeHelper";
|
||||||
|
private static final SourceType SWIPE_DISMISS = SourceType.from("SwipeDismiss");
|
||||||
private final Runnable mFalsingCheck;
|
private final Runnable mFalsingCheck;
|
||||||
private View mTranslatingParentView;
|
private View mTranslatingParentView;
|
||||||
private View mMenuExposedView;
|
private View mMenuExposedView;
|
||||||
@@ -64,13 +68,21 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
|||||||
private WeakReference<NotificationMenuRowPlugin> mCurrMenuRowRef;
|
private WeakReference<NotificationMenuRowPlugin> mCurrMenuRowRef;
|
||||||
private boolean mIsExpanded;
|
private boolean mIsExpanded;
|
||||||
private boolean mPulsing;
|
private boolean mPulsing;
|
||||||
|
private final NotificationRoundnessManager mNotificationRoundnessManager;
|
||||||
|
private final boolean mUseRoundnessSourceTypes;
|
||||||
|
|
||||||
NotificationSwipeHelper(
|
NotificationSwipeHelper(
|
||||||
Resources resources, ViewConfiguration viewConfiguration,
|
Resources resources,
|
||||||
FalsingManager falsingManager, FeatureFlags featureFlags,
|
ViewConfiguration viewConfiguration,
|
||||||
int swipeDirection, NotificationCallback callback,
|
FalsingManager falsingManager,
|
||||||
NotificationMenuRowPlugin.OnMenuEventListener menuListener) {
|
FeatureFlags featureFlags,
|
||||||
|
int swipeDirection,
|
||||||
|
NotificationCallback callback,
|
||||||
|
NotificationMenuRowPlugin.OnMenuEventListener menuListener,
|
||||||
|
NotificationRoundnessManager notificationRoundnessManager) {
|
||||||
super(swipeDirection, callback, resources, viewConfiguration, falsingManager, featureFlags);
|
super(swipeDirection, callback, resources, viewConfiguration, falsingManager, featureFlags);
|
||||||
|
mNotificationRoundnessManager = notificationRoundnessManager;
|
||||||
|
mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
|
||||||
mMenuListener = menuListener;
|
mMenuListener = menuListener;
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
mFalsingCheck = () -> resetExposedMenuView(true /* animate */, true /* force */);
|
mFalsingCheck = () -> resetExposedMenuView(true /* animate */, true /* force */);
|
||||||
@@ -304,6 +316,33 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
|||||||
handleMenuCoveredOrDismissed();
|
handleMenuCoveredOrDismissed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void prepareDismissAnimation(View view, Animator anim) {
|
||||||
|
super.prepareDismissAnimation(view, anim);
|
||||||
|
|
||||||
|
if (mUseRoundnessSourceTypes
|
||||||
|
&& view instanceof ExpandableNotificationRow
|
||||||
|
&& mNotificationRoundnessManager.isClearAllInProgress()) {
|
||||||
|
ExpandableNotificationRow row = (ExpandableNotificationRow) view;
|
||||||
|
anim.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
row.requestRoundness(/* top = */ 1f, /* bottom = */ 1f, SWIPE_DISMISS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
row.requestRoundnessReset(SWIPE_DISMISS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
row.requestRoundnessReset(SWIPE_DISMISS);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected void superDismissChild(final View view, float velocity, boolean useAccelerateInterpolator) {
|
protected void superDismissChild(final View view, float velocity, boolean useAccelerateInterpolator) {
|
||||||
super.dismissChild(view, velocity, useAccelerateInterpolator);
|
super.dismissChild(view, velocity, useAccelerateInterpolator);
|
||||||
@@ -521,14 +560,17 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
|||||||
private int mSwipeDirection;
|
private int mSwipeDirection;
|
||||||
private NotificationCallback mNotificationCallback;
|
private NotificationCallback mNotificationCallback;
|
||||||
private NotificationMenuRowPlugin.OnMenuEventListener mOnMenuEventListener;
|
private NotificationMenuRowPlugin.OnMenuEventListener mOnMenuEventListener;
|
||||||
|
private NotificationRoundnessManager mNotificationRoundnessManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Builder(@Main Resources resources, ViewConfiguration viewConfiguration,
|
Builder(@Main Resources resources, ViewConfiguration viewConfiguration,
|
||||||
FalsingManager falsingManager, FeatureFlags featureFlags) {
|
FalsingManager falsingManager, FeatureFlags featureFlags,
|
||||||
|
NotificationRoundnessManager notificationRoundnessManager) {
|
||||||
mResources = resources;
|
mResources = resources;
|
||||||
mViewConfiguration = viewConfiguration;
|
mViewConfiguration = viewConfiguration;
|
||||||
mFalsingManager = falsingManager;
|
mFalsingManager = falsingManager;
|
||||||
mFeatureFlags = featureFlags;
|
mFeatureFlags = featureFlags;
|
||||||
|
mNotificationRoundnessManager = notificationRoundnessManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder setSwipeDirection(int swipeDirection) {
|
Builder setSwipeDirection(int swipeDirection) {
|
||||||
@@ -549,7 +591,8 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
|||||||
|
|
||||||
NotificationSwipeHelper build() {
|
NotificationSwipeHelper build() {
|
||||||
return new NotificationSwipeHelper(mResources, mViewConfiguration, mFalsingManager,
|
return new NotificationSwipeHelper(mResources, mViewConfiguration, mFalsingManager,
|
||||||
mFeatureFlags, mSwipeDirection, mNotificationCallback, mOnMenuEventListener);
|
mFeatureFlags, mSwipeDirection, mNotificationCallback, mOnMenuEventListener,
|
||||||
|
mNotificationRoundnessManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ class NotificationTargetsHelper
|
|||||||
constructor(
|
constructor(
|
||||||
featureFlags: FeatureFlags,
|
featureFlags: FeatureFlags,
|
||||||
) {
|
) {
|
||||||
private val isNotificationGroupCornerEnabled =
|
private val useRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES)
|
||||||
featureFlags.isEnabled(Flags.NOTIFICATION_GROUP_CORNER)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method looks for views that can be rounded (and implement [Roundable]) during a
|
* This method looks for views that can be rounded (and implement [Roundable]) during a
|
||||||
@@ -48,7 +47,7 @@ constructor(
|
|||||||
if (notificationParent != null && childrenContainer != null) {
|
if (notificationParent != null && childrenContainer != null) {
|
||||||
// We are inside a notification group
|
// We are inside a notification group
|
||||||
|
|
||||||
if (!isNotificationGroupCornerEnabled) {
|
if (!useRoundnessSourceTypes) {
|
||||||
return RoundableTargets(null, null, null)
|
return RoundableTargets(null, null, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.android.systemui.R;
|
|||||||
import com.android.systemui.animation.ShadeInterpolation;
|
import com.android.systemui.animation.ShadeInterpolation;
|
||||||
import com.android.systemui.statusbar.EmptyShadeView;
|
import com.android.systemui.statusbar.EmptyShadeView;
|
||||||
import com.android.systemui.statusbar.NotificationShelf;
|
import com.android.systemui.statusbar.NotificationShelf;
|
||||||
|
import com.android.systemui.statusbar.notification.LegacySourceType;
|
||||||
import com.android.systemui.statusbar.notification.SourceType;
|
import com.android.systemui.statusbar.notification.SourceType;
|
||||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
@@ -51,6 +52,7 @@ public class StackScrollAlgorithm {
|
|||||||
|
|
||||||
private static final String TAG = "StackScrollAlgorithm";
|
private static final String TAG = "StackScrollAlgorithm";
|
||||||
private static final Boolean DEBUG = false;
|
private static final Boolean DEBUG = false;
|
||||||
|
private static final SourceType STACK_SCROLL_ALGO = SourceType.from("StackScrollAlgorithm");
|
||||||
|
|
||||||
private final ViewGroup mHostView;
|
private final ViewGroup mHostView;
|
||||||
private float mPaddingBetweenElements;
|
private float mPaddingBetweenElements;
|
||||||
@@ -70,6 +72,7 @@ public class StackScrollAlgorithm {
|
|||||||
private float mQuickQsOffsetHeight;
|
private float mQuickQsOffsetHeight;
|
||||||
private float mSmallCornerRadius;
|
private float mSmallCornerRadius;
|
||||||
private float mLargeCornerRadius;
|
private float mLargeCornerRadius;
|
||||||
|
private boolean mUseRoundnessSourceTypes;
|
||||||
|
|
||||||
public StackScrollAlgorithm(
|
public StackScrollAlgorithm(
|
||||||
Context context,
|
Context context,
|
||||||
@@ -129,7 +132,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateAlphaState(StackScrollAlgorithmState algorithmState,
|
private void updateAlphaState(StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState) {
|
AmbientState ambientState) {
|
||||||
for (ExpandableView view : algorithmState.visibleChildren) {
|
for (ExpandableView view : algorithmState.visibleChildren) {
|
||||||
final ViewState viewState = view.getViewState();
|
final ViewState viewState = view.getViewState();
|
||||||
|
|
||||||
@@ -229,7 +232,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void getNotificationChildrenStates(StackScrollAlgorithmState algorithmState,
|
private void getNotificationChildrenStates(StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState) {
|
AmbientState ambientState) {
|
||||||
int childCount = algorithmState.visibleChildren.size();
|
int childCount = algorithmState.visibleChildren.size();
|
||||||
for (int i = 0; i < childCount; i++) {
|
for (int i = 0; i < childCount; i++) {
|
||||||
ExpandableView v = algorithmState.visibleChildren.get(i);
|
ExpandableView v = algorithmState.visibleChildren.get(i);
|
||||||
@@ -241,7 +244,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateSpeedBumpState(StackScrollAlgorithmState algorithmState,
|
private void updateSpeedBumpState(StackScrollAlgorithmState algorithmState,
|
||||||
int speedBumpIndex) {
|
int speedBumpIndex) {
|
||||||
int childCount = algorithmState.visibleChildren.size();
|
int childCount = algorithmState.visibleChildren.size();
|
||||||
int belowSpeedBump = speedBumpIndex;
|
int belowSpeedBump = speedBumpIndex;
|
||||||
for (int i = 0; i < childCount; i++) {
|
for (int i = 0; i < childCount; i++) {
|
||||||
@@ -268,7 +271,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateClipping(StackScrollAlgorithmState algorithmState,
|
private void updateClipping(StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState) {
|
AmbientState ambientState) {
|
||||||
float drawStart = ambientState.isOnKeyguard() ? 0
|
float drawStart = ambientState.isOnKeyguard() ? 0
|
||||||
: ambientState.getStackY() - ambientState.getScrollY();
|
: ambientState.getStackY() - ambientState.getScrollY();
|
||||||
float clipStart = 0;
|
float clipStart = 0;
|
||||||
@@ -314,7 +317,7 @@ public class StackScrollAlgorithm {
|
|||||||
* Updates the dimmed, activated and hiding sensitive states of the children.
|
* Updates the dimmed, activated and hiding sensitive states of the children.
|
||||||
*/
|
*/
|
||||||
private void updateDimmedActivatedHideSensitive(AmbientState ambientState,
|
private void updateDimmedActivatedHideSensitive(AmbientState ambientState,
|
||||||
StackScrollAlgorithmState algorithmState) {
|
StackScrollAlgorithmState algorithmState) {
|
||||||
boolean dimmed = ambientState.isDimmed();
|
boolean dimmed = ambientState.isDimmed();
|
||||||
boolean hideSensitive = ambientState.isHideSensitive();
|
boolean hideSensitive = ambientState.isHideSensitive();
|
||||||
View activatedChild = ambientState.getActivatedChild();
|
View activatedChild = ambientState.getActivatedChild();
|
||||||
@@ -408,7 +411,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int updateNotGoneIndex(StackScrollAlgorithmState state, int notGoneIndex,
|
private int updateNotGoneIndex(StackScrollAlgorithmState state, int notGoneIndex,
|
||||||
ExpandableView v) {
|
ExpandableView v) {
|
||||||
ExpandableViewState viewState = v.getViewState();
|
ExpandableViewState viewState = v.getViewState();
|
||||||
viewState.notGoneIndex = notGoneIndex;
|
viewState.notGoneIndex = notGoneIndex;
|
||||||
state.visibleChildren.add(v);
|
state.visibleChildren.add(v);
|
||||||
@@ -434,7 +437,7 @@ public class StackScrollAlgorithm {
|
|||||||
* @param ambientState The current ambient state
|
* @param ambientState The current ambient state
|
||||||
*/
|
*/
|
||||||
protected void updatePositionsForState(StackScrollAlgorithmState algorithmState,
|
protected void updatePositionsForState(StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState) {
|
AmbientState ambientState) {
|
||||||
if (!ambientState.isOnKeyguard()
|
if (!ambientState.isOnKeyguard()
|
||||||
|| (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
|
|| (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
|
||||||
algorithmState.mCurrentYPosition += mNotificationScrimPadding;
|
algorithmState.mCurrentYPosition += mNotificationScrimPadding;
|
||||||
@@ -448,7 +451,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setLocation(ExpandableViewState expandableViewState, float currentYPosition,
|
private void setLocation(ExpandableViewState expandableViewState, float currentYPosition,
|
||||||
int i) {
|
int i) {
|
||||||
expandableViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
|
expandableViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
|
||||||
if (currentYPosition <= 0) {
|
if (currentYPosition <= 0) {
|
||||||
expandableViewState.location = ExpandableViewState.LOCATION_HIDDEN_TOP;
|
expandableViewState.location = ExpandableViewState.LOCATION_HIDDEN_TOP;
|
||||||
@@ -496,9 +499,13 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void maybeUpdateHeadsUpIsVisible(ExpandableViewState viewState, boolean isShadeExpanded,
|
void maybeUpdateHeadsUpIsVisible(
|
||||||
boolean mustStayOnScreen, boolean topVisible, float viewEnd, float hunMax) {
|
ExpandableViewState viewState,
|
||||||
|
boolean isShadeExpanded,
|
||||||
|
boolean mustStayOnScreen,
|
||||||
|
boolean topVisible,
|
||||||
|
float viewEnd,
|
||||||
|
float hunMax) {
|
||||||
if (isShadeExpanded && mustStayOnScreen && topVisible) {
|
if (isShadeExpanded && mustStayOnScreen && topVisible) {
|
||||||
viewState.headsUpIsVisible = viewEnd < hunMax;
|
viewState.headsUpIsVisible = viewEnd < hunMax;
|
||||||
}
|
}
|
||||||
@@ -676,7 +683,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updatePulsingStates(StackScrollAlgorithmState algorithmState,
|
private void updatePulsingStates(StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState) {
|
AmbientState ambientState) {
|
||||||
int childCount = algorithmState.visibleChildren.size();
|
int childCount = algorithmState.visibleChildren.size();
|
||||||
for (int i = 0; i < childCount; i++) {
|
for (int i = 0; i < childCount; i++) {
|
||||||
View child = algorithmState.visibleChildren.get(i);
|
View child = algorithmState.visibleChildren.get(i);
|
||||||
@@ -693,7 +700,7 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateHeadsUpStates(StackScrollAlgorithmState algorithmState,
|
private void updateHeadsUpStates(StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState) {
|
AmbientState ambientState) {
|
||||||
int childCount = algorithmState.visibleChildren.size();
|
int childCount = algorithmState.visibleChildren.size();
|
||||||
|
|
||||||
// Move the tracked heads up into position during the appear animation, by interpolating
|
// Move the tracked heads up into position during the appear animation, by interpolating
|
||||||
@@ -777,7 +784,7 @@ public class StackScrollAlgorithm {
|
|||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void clampHunToTop(float quickQsOffsetHeight, float stackTranslation, float collapsedHeight,
|
void clampHunToTop(float quickQsOffsetHeight, float stackTranslation, float collapsedHeight,
|
||||||
ExpandableViewState viewState) {
|
ExpandableViewState viewState) {
|
||||||
|
|
||||||
final float newTranslation = Math.max(quickQsOffsetHeight + stackTranslation,
|
final float newTranslation = Math.max(quickQsOffsetHeight + stackTranslation,
|
||||||
viewState.getYTranslation());
|
viewState.getYTranslation());
|
||||||
@@ -792,7 +799,7 @@ public class StackScrollAlgorithm {
|
|||||||
// Pin HUN to bottom of expanded QS
|
// Pin HUN to bottom of expanded QS
|
||||||
// while the rest of notifications are scrolled offscreen.
|
// while the rest of notifications are scrolled offscreen.
|
||||||
private void clampHunToMaxTranslation(AmbientState ambientState, ExpandableNotificationRow row,
|
private void clampHunToMaxTranslation(AmbientState ambientState, ExpandableNotificationRow row,
|
||||||
ExpandableViewState childState) {
|
ExpandableViewState childState) {
|
||||||
float maxHeadsUpTranslation = ambientState.getMaxHeadsUpTranslation();
|
float maxHeadsUpTranslation = ambientState.getMaxHeadsUpTranslation();
|
||||||
final float maxShelfPosition = ambientState.getInnerHeight() + ambientState.getTopPadding()
|
final float maxShelfPosition = ambientState.getInnerHeight() + ambientState.getTopPadding()
|
||||||
+ ambientState.getStackTranslation();
|
+ ambientState.getStackTranslation();
|
||||||
@@ -807,14 +814,19 @@ public class StackScrollAlgorithm {
|
|||||||
// Animate pinned HUN bottom corners to and from original roundness.
|
// Animate pinned HUN bottom corners to and from original roundness.
|
||||||
final float originalCornerRadius =
|
final float originalCornerRadius =
|
||||||
row.isLastInSection() ? 1f : (mSmallCornerRadius / mLargeCornerRadius);
|
row.isLastInSection() ? 1f : (mSmallCornerRadius / mLargeCornerRadius);
|
||||||
final float roundness = computeCornerRoundnessForPinnedHun(mHostView.getHeight(),
|
final float bottomValue = computeCornerRoundnessForPinnedHun(mHostView.getHeight(),
|
||||||
ambientState.getStackY(), getMaxAllowedChildHeight(row), originalCornerRadius);
|
ambientState.getStackY(), getMaxAllowedChildHeight(row), originalCornerRadius);
|
||||||
row.requestBottomRoundness(roundness, /* animate = */ false, SourceType.OnScroll);
|
if (mUseRoundnessSourceTypes) {
|
||||||
|
row.requestBottomRoundness(bottomValue, STACK_SCROLL_ALGO);
|
||||||
|
row.addOnDetachResetRoundness(STACK_SCROLL_ALGO);
|
||||||
|
} else {
|
||||||
|
row.requestBottomRoundness(bottomValue, LegacySourceType.OnScroll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
float computeCornerRoundnessForPinnedHun(float hostViewHeight, float stackY,
|
float computeCornerRoundnessForPinnedHun(float hostViewHeight, float stackY,
|
||||||
float viewMaxHeight, float originalCornerRadius) {
|
float viewMaxHeight, float originalCornerRadius) {
|
||||||
|
|
||||||
// Compute y where corner roundness should be in its original unpinned state.
|
// Compute y where corner roundness should be in its original unpinned state.
|
||||||
// We use view max height because the pinned collapsed HUN expands to max height
|
// We use view max height because the pinned collapsed HUN expands to max height
|
||||||
@@ -844,7 +856,7 @@ public class StackScrollAlgorithm {
|
|||||||
* @param ambientState The ambient state of the algorithm
|
* @param ambientState The ambient state of the algorithm
|
||||||
*/
|
*/
|
||||||
private void updateZValuesForState(StackScrollAlgorithmState algorithmState,
|
private void updateZValuesForState(StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState) {
|
AmbientState ambientState) {
|
||||||
int childCount = algorithmState.visibleChildren.size();
|
int childCount = algorithmState.visibleChildren.size();
|
||||||
float childrenOnTop = 0.0f;
|
float childrenOnTop = 0.0f;
|
||||||
|
|
||||||
@@ -876,9 +888,9 @@ public class StackScrollAlgorithm {
|
|||||||
* previous HUNs whose Z positions are greater than 0.
|
* previous HUNs whose Z positions are greater than 0.
|
||||||
*/
|
*/
|
||||||
protected float updateChildZValue(int i, float childrenOnTop,
|
protected float updateChildZValue(int i, float childrenOnTop,
|
||||||
StackScrollAlgorithmState algorithmState,
|
StackScrollAlgorithmState algorithmState,
|
||||||
AmbientState ambientState,
|
AmbientState ambientState,
|
||||||
boolean isTopHun) {
|
boolean isTopHun) {
|
||||||
ExpandableView child = algorithmState.visibleChildren.get(i);
|
ExpandableView child = algorithmState.visibleChildren.get(i);
|
||||||
ExpandableViewState childViewState = child.getViewState();
|
ExpandableViewState childViewState = child.getViewState();
|
||||||
float baseZ = ambientState.getBaseZHeight();
|
float baseZ = ambientState.getBaseZHeight();
|
||||||
@@ -950,6 +962,14 @@ public class StackScrollAlgorithm {
|
|||||||
this.mIsExpanded = isExpanded;
|
this.mIsExpanded = isExpanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the support for rounded corner based on the SourceType
|
||||||
|
* @param enabled true if is supported
|
||||||
|
*/
|
||||||
|
public void useRoundnessSourceTypes(boolean enabled) {
|
||||||
|
mUseRoundnessSourceTypes = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
public static class StackScrollAlgorithmState {
|
public static class StackScrollAlgorithmState {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,11 +19,14 @@ package com.android.systemui.statusbar.phone;
|
|||||||
import static com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.OPERATOR_NAME_FRAME_VIEW;
|
import static com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.OPERATOR_NAME_FRAME_VIEW;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.util.MathUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.widget.ViewClippingUtil;
|
import com.android.internal.widget.ViewClippingUtil;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
|
import com.android.systemui.flags.Flags;
|
||||||
import com.android.systemui.plugins.DarkIconDispatcher;
|
import com.android.systemui.plugins.DarkIconDispatcher;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.shade.NotificationPanelViewController;
|
import com.android.systemui.shade.NotificationPanelViewController;
|
||||||
@@ -32,8 +35,10 @@ import com.android.systemui.statusbar.CrossFadeHelper;
|
|||||||
import com.android.systemui.statusbar.HeadsUpStatusBarView;
|
import com.android.systemui.statusbar.HeadsUpStatusBarView;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||||
|
import com.android.systemui.statusbar.notification.SourceType;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
|
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
||||||
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentScope;
|
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentScope;
|
||||||
import com.android.systemui.statusbar.policy.Clock;
|
import com.android.systemui.statusbar.policy.Clock;
|
||||||
@@ -51,6 +56,7 @@ import javax.inject.Named;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the appearance of heads up notifications in the icon area and the header itself.
|
* Controls the appearance of heads up notifications in the icon area and the header itself.
|
||||||
|
* It also controls the roundness of the heads up notifications and the pulsing notifications.
|
||||||
*/
|
*/
|
||||||
@StatusBarFragmentScope
|
@StatusBarFragmentScope
|
||||||
public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBarView>
|
public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBarView>
|
||||||
@@ -59,12 +65,17 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
NotificationWakeUpCoordinator.WakeUpListener {
|
NotificationWakeUpCoordinator.WakeUpListener {
|
||||||
public static final int CONTENT_FADE_DURATION = 110;
|
public static final int CONTENT_FADE_DURATION = 110;
|
||||||
public static final int CONTENT_FADE_DELAY = 100;
|
public static final int CONTENT_FADE_DELAY = 100;
|
||||||
|
|
||||||
|
private static final SourceType HEADS_UP = SourceType.from("HeadsUp");
|
||||||
|
private static final SourceType PULSING = SourceType.from("Pulsing");
|
||||||
private final NotificationIconAreaController mNotificationIconAreaController;
|
private final NotificationIconAreaController mNotificationIconAreaController;
|
||||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||||
private final NotificationStackScrollLayoutController mStackScrollerController;
|
private final NotificationStackScrollLayoutController mStackScrollerController;
|
||||||
|
|
||||||
private final DarkIconDispatcher mDarkIconDispatcher;
|
private final DarkIconDispatcher mDarkIconDispatcher;
|
||||||
private final NotificationPanelViewController mNotificationPanelViewController;
|
private final NotificationPanelViewController mNotificationPanelViewController;
|
||||||
|
private final NotificationRoundnessManager mNotificationRoundnessManager;
|
||||||
|
private final boolean mUseRoundnessSourceTypes;
|
||||||
private final Consumer<ExpandableNotificationRow>
|
private final Consumer<ExpandableNotificationRow>
|
||||||
mSetTrackingHeadsUp = this::setTrackingHeadsUp;
|
mSetTrackingHeadsUp = this::setTrackingHeadsUp;
|
||||||
private final BiConsumer<Float, Float> mSetExpandedHeight = this::setAppearFraction;
|
private final BiConsumer<Float, Float> mSetExpandedHeight = this::setAppearFraction;
|
||||||
@@ -105,11 +116,15 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
CommandQueue commandQueue,
|
CommandQueue commandQueue,
|
||||||
NotificationStackScrollLayoutController stackScrollerController,
|
NotificationStackScrollLayoutController stackScrollerController,
|
||||||
NotificationPanelViewController notificationPanelViewController,
|
NotificationPanelViewController notificationPanelViewController,
|
||||||
|
NotificationRoundnessManager notificationRoundnessManager,
|
||||||
|
FeatureFlags featureFlags,
|
||||||
HeadsUpStatusBarView headsUpStatusBarView,
|
HeadsUpStatusBarView headsUpStatusBarView,
|
||||||
Clock clockView,
|
Clock clockView,
|
||||||
@Named(OPERATOR_NAME_FRAME_VIEW) Optional<View> operatorNameViewOptional) {
|
@Named(OPERATOR_NAME_FRAME_VIEW) Optional<View> operatorNameViewOptional) {
|
||||||
super(headsUpStatusBarView);
|
super(headsUpStatusBarView);
|
||||||
mNotificationIconAreaController = notificationIconAreaController;
|
mNotificationIconAreaController = notificationIconAreaController;
|
||||||
|
mNotificationRoundnessManager = notificationRoundnessManager;
|
||||||
|
mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
|
||||||
mHeadsUpManager = headsUpManager;
|
mHeadsUpManager = headsUpManager;
|
||||||
|
|
||||||
// We may be mid-HUN-expansion when this controller is re-created (for example, if the user
|
// We may be mid-HUN-expansion when this controller is re-created (for example, if the user
|
||||||
@@ -179,6 +194,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
public void onHeadsUpPinned(NotificationEntry entry) {
|
public void onHeadsUpPinned(NotificationEntry entry) {
|
||||||
updateTopEntry();
|
updateTopEntry();
|
||||||
updateHeader(entry);
|
updateHeader(entry);
|
||||||
|
updateHeadsUpAndPulsingRoundness(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTopEntry() {
|
private void updateTopEntry() {
|
||||||
@@ -316,6 +332,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
public void onHeadsUpUnPinned(NotificationEntry entry) {
|
public void onHeadsUpUnPinned(NotificationEntry entry) {
|
||||||
updateTopEntry();
|
updateTopEntry();
|
||||||
updateHeader(entry);
|
updateHeader(entry);
|
||||||
|
updateHeadsUpAndPulsingRoundness(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAppearFraction(float expandedHeight, float appearFraction) {
|
public void setAppearFraction(float expandedHeight, float appearFraction) {
|
||||||
@@ -346,7 +363,9 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
ExpandableNotificationRow previousTracked = mTrackedChild;
|
ExpandableNotificationRow previousTracked = mTrackedChild;
|
||||||
mTrackedChild = trackedChild;
|
mTrackedChild = trackedChild;
|
||||||
if (previousTracked != null) {
|
if (previousTracked != null) {
|
||||||
updateHeader(previousTracked.getEntry());
|
NotificationEntry entry = previousTracked.getEntry();
|
||||||
|
updateHeader(entry);
|
||||||
|
updateHeadsUpAndPulsingRoundness(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,6 +376,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
private void updateHeadsUpHeaders() {
|
private void updateHeadsUpHeaders() {
|
||||||
mHeadsUpManager.getAllEntries().forEach(entry -> {
|
mHeadsUpManager.getAllEntries().forEach(entry -> {
|
||||||
updateHeader(entry);
|
updateHeader(entry);
|
||||||
|
updateHeadsUpAndPulsingRoundness(entry);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,6 +390,31 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
|
|||||||
row.setHeaderVisibleAmount(headerVisibleAmount);
|
row.setHeaderVisibleAmount(headerVisibleAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the HeadsUp and the Pulsing roundness based on current state
|
||||||
|
* @param entry target notification
|
||||||
|
*/
|
||||||
|
public void updateHeadsUpAndPulsingRoundness(NotificationEntry entry) {
|
||||||
|
if (mUseRoundnessSourceTypes) {
|
||||||
|
ExpandableNotificationRow row = entry.getRow();
|
||||||
|
boolean isTrackedChild = row == mTrackedChild;
|
||||||
|
if (row.isPinned() || row.isHeadsUpAnimatingAway() || isTrackedChild) {
|
||||||
|
float roundness = MathUtils.saturate(1f - mAppearFraction);
|
||||||
|
row.requestRoundness(roundness, roundness, HEADS_UP);
|
||||||
|
} else {
|
||||||
|
row.requestRoundnessReset(HEADS_UP);
|
||||||
|
}
|
||||||
|
if (mNotificationRoundnessManager.shouldRoundNotificationPulsing()) {
|
||||||
|
if (row.showingPulsing()) {
|
||||||
|
row.requestRoundness(/* top = */ 1f, /* bottom = */ 1f, PULSING);
|
||||||
|
} else {
|
||||||
|
row.requestRoundnessReset(PULSING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDarkChanged(ArrayList<Rect> areas, float darkIntensity, int tint) {
|
public void onDarkChanged(ArrayList<Rect> areas, float darkIntensity, int tint) {
|
||||||
mView.onDarkChanged(areas, darkIntensity, tint);
|
mView.onDarkChanged(areas, darkIntensity, tint);
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
package com.android.systemui.statusbar.notification
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.util.mockito.mock
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import org.junit.runners.JUnit4
|
||||||
|
import org.mockito.Mockito.atLeastOnce
|
||||||
|
import org.mockito.Mockito.times
|
||||||
|
import org.mockito.Mockito.verify
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(JUnit4::class)
|
||||||
|
class RoundableTest : SysuiTestCase() {
|
||||||
|
val targetView: View = mock()
|
||||||
|
val roundable = FakeRoundable(targetView)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun defaultConfig_shouldNotHaveRoundedCorner() {
|
||||||
|
// the expected default value for the roundness is top = 0f, bottom = 0f
|
||||||
|
assertEquals(0f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0f, roundable.roundableState.bottomRoundness)
|
||||||
|
assertEquals(false, roundable.hasRoundedCorner())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun applyRoundnessAndInvalidate_should_invalidate_targetView() {
|
||||||
|
roundable.applyRoundnessAndInvalidate()
|
||||||
|
|
||||||
|
verify(targetView, times(1)).invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun requestTopRoundness_update_and_invalidate_targetView() {
|
||||||
|
roundable.requestTopRoundness(value = 1f, sourceType = SOURCE1)
|
||||||
|
|
||||||
|
assertEquals(1f, roundable.roundableState.topRoundness)
|
||||||
|
verify(targetView, times(1)).invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun requestBottomRoundness_update_and_invalidate_targetView() {
|
||||||
|
roundable.requestBottomRoundness(value = 1f, sourceType = SOURCE1)
|
||||||
|
|
||||||
|
assertEquals(1f, roundable.roundableState.bottomRoundness)
|
||||||
|
verify(targetView, times(1)).invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun requestRoundness_update_and_invalidate_targetView() {
|
||||||
|
roundable.requestRoundness(top = 1f, bottom = 1f, sourceType = SOURCE1)
|
||||||
|
|
||||||
|
assertEquals(1f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(1f, roundable.roundableState.bottomRoundness)
|
||||||
|
verify(targetView, atLeastOnce()).invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun requestRoundnessReset_update_and_invalidate_targetView() {
|
||||||
|
roundable.requestRoundness(1f, 1f, SOURCE1)
|
||||||
|
assertEquals(1f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(1f, roundable.roundableState.bottomRoundness)
|
||||||
|
|
||||||
|
roundable.requestRoundnessReset(sourceType = SOURCE1)
|
||||||
|
|
||||||
|
assertEquals(0f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0f, roundable.roundableState.bottomRoundness)
|
||||||
|
verify(targetView, atLeastOnce()).invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun hasRoundedCorner_return_true_ifRoundnessIsGreaterThenZero() {
|
||||||
|
roundable.requestRoundness(top = 1f, bottom = 1f, sourceType = SOURCE1)
|
||||||
|
assertEquals(true, roundable.hasRoundedCorner())
|
||||||
|
|
||||||
|
roundable.requestRoundness(top = 1f, bottom = 0f, sourceType = SOURCE1)
|
||||||
|
assertEquals(true, roundable.hasRoundedCorner())
|
||||||
|
|
||||||
|
roundable.requestRoundness(top = 0f, bottom = 1f, sourceType = SOURCE1)
|
||||||
|
assertEquals(true, roundable.hasRoundedCorner())
|
||||||
|
|
||||||
|
roundable.requestRoundness(top = 0f, bottom = 0f, sourceType = SOURCE1)
|
||||||
|
assertEquals(false, roundable.hasRoundedCorner())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun roundness_take_maxValue_onMultipleSources_first_lower() {
|
||||||
|
roundable.requestRoundness(0.1f, 0.1f, SOURCE1)
|
||||||
|
assertEquals(0.1f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.1f, roundable.roundableState.bottomRoundness)
|
||||||
|
|
||||||
|
roundable.requestRoundness(0.2f, 0.2f, SOURCE2)
|
||||||
|
// SOURCE1 has 0.1f - SOURCE2 has 0.2f
|
||||||
|
assertEquals(0.2f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.2f, roundable.roundableState.bottomRoundness)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun roundness_take_maxValue_onMultipleSources_first_higher() {
|
||||||
|
roundable.requestRoundness(0.5f, 0.5f, SOURCE1)
|
||||||
|
assertEquals(0.5f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.5f, roundable.roundableState.bottomRoundness)
|
||||||
|
|
||||||
|
roundable.requestRoundness(0.1f, 0.1f, SOURCE2)
|
||||||
|
// SOURCE1 has 0.5f - SOURCE2 has 0.1f
|
||||||
|
assertEquals(0.5f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.5f, roundable.roundableState.bottomRoundness)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun roundness_take_maxValue_onMultipleSources_first_higher_second_step() {
|
||||||
|
roundable.requestRoundness(0.1f, 0.1f, SOURCE1)
|
||||||
|
assertEquals(0.1f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.1f, roundable.roundableState.bottomRoundness)
|
||||||
|
|
||||||
|
roundable.requestRoundness(0.2f, 0.2f, SOURCE2)
|
||||||
|
// SOURCE1 has 0.1f - SOURCE2 has 0.2f
|
||||||
|
assertEquals(0.2f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.2f, roundable.roundableState.bottomRoundness)
|
||||||
|
|
||||||
|
roundable.requestRoundness(0.3f, 0.3f, SOURCE1)
|
||||||
|
// SOURCE1 has 0.3f - SOURCE2 has 0.2f
|
||||||
|
assertEquals(0.3f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.3f, roundable.roundableState.bottomRoundness)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun roundness_take_maxValue_onMultipleSources_first_lower_second_step() {
|
||||||
|
roundable.requestRoundness(0.5f, 0.5f, SOURCE1)
|
||||||
|
assertEquals(0.5f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.5f, roundable.roundableState.bottomRoundness)
|
||||||
|
|
||||||
|
roundable.requestRoundness(0.2f, 0.2f, SOURCE2)
|
||||||
|
// SOURCE1 has 0.5f - SOURCE2 has 0.2f
|
||||||
|
assertEquals(0.5f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.5f, roundable.roundableState.bottomRoundness)
|
||||||
|
|
||||||
|
roundable.requestRoundness(0.1f, 0.1f, SOURCE1)
|
||||||
|
// SOURCE1 has 0.1f - SOURCE2 has 0.2f
|
||||||
|
assertEquals(0.2f, roundable.roundableState.topRoundness)
|
||||||
|
assertEquals(0.2f, roundable.roundableState.bottomRoundness)
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeRoundable(
|
||||||
|
targetView: View,
|
||||||
|
radius: Float = MAX_RADIUS,
|
||||||
|
) : Roundable {
|
||||||
|
override val roundableState =
|
||||||
|
RoundableState(
|
||||||
|
targetView = targetView,
|
||||||
|
roundable = this,
|
||||||
|
maxRadius = radius,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val MAX_RADIUS = 10f
|
||||||
|
private val SOURCE1 = SourceType.from("Source1")
|
||||||
|
private val SOURCE2 = SourceType.from("Source2")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -215,8 +215,7 @@ public class NotificationTestHelper {
|
|||||||
SourceType sourceType
|
SourceType sourceType
|
||||||
) throws Exception {
|
) throws Exception {
|
||||||
ExpandableNotificationRow row = createRow();
|
ExpandableNotificationRow row = createRow();
|
||||||
row.requestTopRoundness(topRoundness, false, sourceType);
|
row.requestRoundness(topRoundness, bottomRoundness, sourceType, /*animate = */ false);
|
||||||
row.requestBottomRoundness(bottomRoundness, /*animate = */ false, sourceType);
|
|
||||||
assertEquals(topRoundness, row.getTopRoundness(), /* delta = */ 0f);
|
assertEquals(topRoundness, row.getTopRoundness(), /* delta = */ 0f);
|
||||||
assertEquals(bottomRoundness, row.getBottomRoundness(), /* delta = */ 0f);
|
assertEquals(bottomRoundness, row.getBottomRoundness(), /* delta = */ 0f);
|
||||||
return row;
|
return row;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import android.view.View;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.statusbar.notification.SourceType;
|
import com.android.systemui.statusbar.notification.LegacySourceType;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ public class NotificationChildrenContainerTest extends SysuiTestCase {
|
|||||||
ExpandableNotificationRow row = mNotificationTestHelper.createRowWithRoundness(
|
ExpandableNotificationRow row = mNotificationTestHelper.createRowWithRoundness(
|
||||||
/* topRoundness = */ 1f,
|
/* topRoundness = */ 1f,
|
||||||
/* bottomRoundness = */ 1f,
|
/* bottomRoundness = */ 1f,
|
||||||
/* sourceType = */ SourceType.OnScroll);
|
/* sourceType = */ LegacySourceType.OnScroll);
|
||||||
|
|
||||||
mChildrenContainer.addNotification(row, 0);
|
mChildrenContainer.addNotification(row, 0);
|
||||||
|
|
||||||
@@ -171,11 +171,11 @@ public class NotificationChildrenContainerTest extends SysuiTestCase {
|
|||||||
ExpandableNotificationRow row1 = mNotificationTestHelper.createRowWithRoundness(
|
ExpandableNotificationRow row1 = mNotificationTestHelper.createRowWithRoundness(
|
||||||
/* topRoundness = */ 1f,
|
/* topRoundness = */ 1f,
|
||||||
/* bottomRoundness = */ 1f,
|
/* bottomRoundness = */ 1f,
|
||||||
/* sourceType = */ SourceType.DefaultValue);
|
/* sourceType = */ LegacySourceType.DefaultValue);
|
||||||
ExpandableNotificationRow row2 = mNotificationTestHelper.createRowWithRoundness(
|
ExpandableNotificationRow row2 = mNotificationTestHelper.createRowWithRoundness(
|
||||||
/* topRoundness = */ 1f,
|
/* topRoundness = */ 1f,
|
||||||
/* bottomRoundness = */ 1f,
|
/* bottomRoundness = */ 1f,
|
||||||
/* sourceType = */ SourceType.OnDismissAnimation);
|
/* sourceType = */ LegacySourceType.OnDismissAnimation);
|
||||||
|
|
||||||
mChildrenContainer.addNotification(row1, 0);
|
mChildrenContainer.addNotification(row1, 0);
|
||||||
mChildrenContainer.addNotification(row2, 0);
|
mChildrenContainer.addNotification(row2, 0);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import androidx.test.filters.SmallTest;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.dump.DumpManager;
|
import com.android.systemui.dump.DumpManager;
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
|
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.notification.logging.NotificationRoundnessLogger;
|
import com.android.systemui.statusbar.notification.logging.NotificationRoundnessLogger;
|
||||||
@@ -73,7 +74,8 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
|
|||||||
mRoundnessManager = new NotificationRoundnessManager(
|
mRoundnessManager = new NotificationRoundnessManager(
|
||||||
new NotificationSectionsFeatureManager(new DeviceConfigProxy(), mContext),
|
new NotificationSectionsFeatureManager(new DeviceConfigProxy(), mContext),
|
||||||
mLogger,
|
mLogger,
|
||||||
mock(DumpManager.class));
|
mock(DumpManager.class),
|
||||||
|
mock(FeatureFlags.class));
|
||||||
allowTestableLooperAsMainThread();
|
allowTestableLooperAsMainThread();
|
||||||
NotificationTestHelper testHelper = new NotificationTestHelper(
|
NotificationTestHelper testHelper = new NotificationTestHelper(
|
||||||
mContext,
|
mContext,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import android.view.ViewGroup;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.media.controls.ui.KeyguardMediaController;
|
import com.android.systemui.media.controls.ui.KeyguardMediaController;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
@@ -59,10 +60,12 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
|
|||||||
@Mock private KeyguardMediaController mKeyguardMediaController;
|
@Mock private KeyguardMediaController mKeyguardMediaController;
|
||||||
@Mock private NotificationSectionsFeatureManager mSectionsFeatureManager;
|
@Mock private NotificationSectionsFeatureManager mSectionsFeatureManager;
|
||||||
@Mock private MediaContainerController mMediaContainerController;
|
@Mock private MediaContainerController mMediaContainerController;
|
||||||
|
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
|
||||||
@Mock private SectionHeaderController mIncomingHeaderController;
|
@Mock private SectionHeaderController mIncomingHeaderController;
|
||||||
@Mock private SectionHeaderController mPeopleHeaderController;
|
@Mock private SectionHeaderController mPeopleHeaderController;
|
||||||
@Mock private SectionHeaderController mAlertingHeaderController;
|
@Mock private SectionHeaderController mAlertingHeaderController;
|
||||||
@Mock private SectionHeaderController mSilentHeaderController;
|
@Mock private SectionHeaderController mSilentHeaderController;
|
||||||
|
@Mock private FeatureFlags mFeatureFlag;
|
||||||
|
|
||||||
private NotificationSectionsManager mSectionsManager;
|
private NotificationSectionsManager mSectionsManager;
|
||||||
|
|
||||||
@@ -89,10 +92,12 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
|
|||||||
mKeyguardMediaController,
|
mKeyguardMediaController,
|
||||||
mSectionsFeatureManager,
|
mSectionsFeatureManager,
|
||||||
mMediaContainerController,
|
mMediaContainerController,
|
||||||
|
mNotificationRoundnessManager,
|
||||||
mIncomingHeaderController,
|
mIncomingHeaderController,
|
||||||
mPeopleHeaderController,
|
mPeopleHeaderController,
|
||||||
mAlertingHeaderController,
|
mAlertingHeaderController,
|
||||||
mSilentHeaderController
|
mSilentHeaderController,
|
||||||
|
mFeatureFlag
|
||||||
);
|
);
|
||||||
// Required in order for the header inflation to work properly
|
// Required in order for the header inflation to work properly
|
||||||
when(mNssl.generateLayoutParams(any(AttributeSet.class)))
|
when(mNssl.generateLayoutParams(any(AttributeSet.class)))
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import com.android.systemui.SysuiTestCase
|
|||||||
import com.android.systemui.animation.ShadeInterpolation
|
import com.android.systemui.animation.ShadeInterpolation
|
||||||
import com.android.systemui.statusbar.NotificationShelf
|
import com.android.systemui.statusbar.NotificationShelf
|
||||||
import com.android.systemui.statusbar.StatusBarIconView
|
import com.android.systemui.statusbar.StatusBarIconView
|
||||||
import com.android.systemui.statusbar.notification.SourceType
|
import com.android.systemui.statusbar.notification.LegacySourceType
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableView
|
import com.android.systemui.statusbar.notification.row.ExpandableView
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationTestHelper
|
import com.android.systemui.statusbar.notification.row.NotificationTestHelper
|
||||||
@@ -314,9 +314,9 @@ class NotificationShelfTest : SysuiTestCase() {
|
|||||||
val row: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
|
val row: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
|
||||||
/* topRoundness = */ 1f,
|
/* topRoundness = */ 1f,
|
||||||
/* bottomRoundness = */ 1f,
|
/* bottomRoundness = */ 1f,
|
||||||
/* sourceType = */ SourceType.OnScroll)
|
/* sourceType = */ LegacySourceType.OnScroll)
|
||||||
|
|
||||||
NotificationShelf.resetOnScrollRoundness(row)
|
NotificationShelf.resetLegacyOnScrollRoundness(row)
|
||||||
|
|
||||||
assertEquals(0f, row.topRoundness)
|
assertEquals(0f, row.topRoundness)
|
||||||
assertEquals(0f, row.bottomRoundness)
|
assertEquals(0f, row.bottomRoundness)
|
||||||
@@ -327,14 +327,14 @@ class NotificationShelfTest : SysuiTestCase() {
|
|||||||
val row1: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
|
val row1: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
|
||||||
/* topRoundness = */ 1f,
|
/* topRoundness = */ 1f,
|
||||||
/* bottomRoundness = */ 1f,
|
/* bottomRoundness = */ 1f,
|
||||||
/* sourceType = */ SourceType.DefaultValue)
|
/* sourceType = */ LegacySourceType.DefaultValue)
|
||||||
val row2: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
|
val row2: ExpandableNotificationRow = notificationTestHelper.createRowWithRoundness(
|
||||||
/* topRoundness = */ 1f,
|
/* topRoundness = */ 1f,
|
||||||
/* bottomRoundness = */ 1f,
|
/* bottomRoundness = */ 1f,
|
||||||
/* sourceType = */ SourceType.OnDismissAnimation)
|
/* sourceType = */ LegacySourceType.OnDismissAnimation)
|
||||||
|
|
||||||
NotificationShelf.resetOnScrollRoundness(row1)
|
NotificationShelf.resetLegacyOnScrollRoundness(row1)
|
||||||
NotificationShelf.resetOnScrollRoundness(row2)
|
NotificationShelf.resetLegacyOnScrollRoundness(row2)
|
||||||
|
|
||||||
assertEquals(1f, row1.topRoundness)
|
assertEquals(1f, row1.topRoundness)
|
||||||
assertEquals(1f, row1.bottomRoundness)
|
assertEquals(1f, row1.bottomRoundness)
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
|
|||||||
private NotificationSwipeHelper mSwipeHelper;
|
private NotificationSwipeHelper mSwipeHelper;
|
||||||
private NotificationSwipeHelper.NotificationCallback mCallback;
|
private NotificationSwipeHelper.NotificationCallback mCallback;
|
||||||
private NotificationMenuRowPlugin.OnMenuEventListener mListener;
|
private NotificationMenuRowPlugin.OnMenuEventListener mListener;
|
||||||
|
private NotificationRoundnessManager mNotificationRoundnessManager;
|
||||||
private View mView;
|
private View mView;
|
||||||
private MotionEvent mEvent;
|
private MotionEvent mEvent;
|
||||||
private NotificationMenuRowPlugin mMenuRow;
|
private NotificationMenuRowPlugin mMenuRow;
|
||||||
@@ -92,10 +93,17 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mCallback = mock(NotificationSwipeHelper.NotificationCallback.class);
|
mCallback = mock(NotificationSwipeHelper.NotificationCallback.class);
|
||||||
mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class);
|
mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class);
|
||||||
|
mNotificationRoundnessManager = mock(NotificationRoundnessManager.class);
|
||||||
mFeatureFlags = mock(FeatureFlags.class);
|
mFeatureFlags = mock(FeatureFlags.class);
|
||||||
mSwipeHelper = spy(new NotificationSwipeHelper(
|
mSwipeHelper = spy(new NotificationSwipeHelper(
|
||||||
mContext.getResources(), ViewConfiguration.get(mContext),
|
mContext.getResources(),
|
||||||
new FalsingManagerFake(), mFeatureFlags, SwipeHelper.X, mCallback, mListener));
|
ViewConfiguration.get(mContext),
|
||||||
|
new FalsingManagerFake(),
|
||||||
|
mFeatureFlags,
|
||||||
|
SwipeHelper.X,
|
||||||
|
mCallback,
|
||||||
|
mListener,
|
||||||
|
mNotificationRoundnessManager));
|
||||||
mView = mock(View.class);
|
mView = mock(View.class);
|
||||||
mEvent = mock(MotionEvent.class);
|
mEvent = mock(MotionEvent.class);
|
||||||
mMenuRow = mock(NotificationMenuRowPlugin.class);
|
mMenuRow = mock(NotificationMenuRowPlugin.class);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class NotificationTargetsHelperTest : SysuiTestCase() {
|
|||||||
) =
|
) =
|
||||||
NotificationTargetsHelper(
|
NotificationTargetsHelper(
|
||||||
FakeFeatureFlags().apply {
|
FakeFeatureFlags().apply {
|
||||||
set(Flags.NOTIFICATION_GROUP_CORNER, notificationGroupCorner)
|
set(Flags.USE_ROUNDNESS_SOURCETYPES, notificationGroupCorner)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.widget.TextView;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
import com.android.systemui.plugins.DarkIconDispatcher;
|
import com.android.systemui.plugins.DarkIconDispatcher;
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||||
import com.android.systemui.shade.NotificationPanelViewController;
|
import com.android.systemui.shade.NotificationPanelViewController;
|
||||||
@@ -40,6 +41,7 @@ import com.android.systemui.statusbar.HeadsUpStatusBarView;
|
|||||||
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
|
||||||
|
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
||||||
import com.android.systemui.statusbar.policy.Clock;
|
import com.android.systemui.statusbar.policy.Clock;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
@@ -71,6 +73,8 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
|
|||||||
private NotificationWakeUpCoordinator mWakeUpCoordinator;
|
private NotificationWakeUpCoordinator mWakeUpCoordinator;
|
||||||
private KeyguardStateController mKeyguardStateController;
|
private KeyguardStateController mKeyguardStateController;
|
||||||
private CommandQueue mCommandQueue;
|
private CommandQueue mCommandQueue;
|
||||||
|
private NotificationRoundnessManager mNotificationRoundnessManager;
|
||||||
|
private FeatureFlags mFeatureFlag;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@@ -89,6 +93,8 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
|
|||||||
mWakeUpCoordinator = mock(NotificationWakeUpCoordinator.class);
|
mWakeUpCoordinator = mock(NotificationWakeUpCoordinator.class);
|
||||||
mKeyguardStateController = mock(KeyguardStateController.class);
|
mKeyguardStateController = mock(KeyguardStateController.class);
|
||||||
mCommandQueue = mock(CommandQueue.class);
|
mCommandQueue = mock(CommandQueue.class);
|
||||||
|
mNotificationRoundnessManager = mock(NotificationRoundnessManager.class);
|
||||||
|
mFeatureFlag = mock(FeatureFlags.class);
|
||||||
mHeadsUpAppearanceController = new HeadsUpAppearanceController(
|
mHeadsUpAppearanceController = new HeadsUpAppearanceController(
|
||||||
mock(NotificationIconAreaController.class),
|
mock(NotificationIconAreaController.class),
|
||||||
mHeadsUpManager,
|
mHeadsUpManager,
|
||||||
@@ -100,6 +106,8 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
|
|||||||
mCommandQueue,
|
mCommandQueue,
|
||||||
mStackScrollerController,
|
mStackScrollerController,
|
||||||
mPanelView,
|
mPanelView,
|
||||||
|
mNotificationRoundnessManager,
|
||||||
|
mFeatureFlag,
|
||||||
mHeadsUpStatusBarView,
|
mHeadsUpStatusBarView,
|
||||||
new Clock(mContext, null),
|
new Clock(mContext, null),
|
||||||
Optional.of(mOperatorNameView));
|
Optional.of(mOperatorNameView));
|
||||||
@@ -182,6 +190,8 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
|
|||||||
mCommandQueue,
|
mCommandQueue,
|
||||||
mStackScrollerController,
|
mStackScrollerController,
|
||||||
mPanelView,
|
mPanelView,
|
||||||
|
mNotificationRoundnessManager,
|
||||||
|
mFeatureFlag,
|
||||||
mHeadsUpStatusBarView,
|
mHeadsUpStatusBarView,
|
||||||
new Clock(mContext, null),
|
new Clock(mContext, null),
|
||||||
Optional.empty());
|
Optional.empty());
|
||||||
|
|||||||
Reference in New Issue
Block a user