Merge "Fix "No Notification" text not gradually showing on LockScreen" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0162aec6c8
@@ -24,6 +24,8 @@ import android.util.AttributeSet;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
|
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
|
||||||
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
|
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
|
||||||
@@ -73,6 +75,7 @@ public class EmptyShadeView extends StackScrollerDecorView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NonNull
|
||||||
public ExpandableViewState createExpandableViewState() {
|
public ExpandableViewState createExpandableViewState() {
|
||||||
return new EmptyShadeViewState();
|
return new EmptyShadeViewState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
|||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
import android.view.animation.PathInterpolator;
|
import android.view.animation.PathInterpolator;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.policy.SystemBarUtils;
|
import com.android.internal.policy.SystemBarUtils;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
@@ -153,6 +155,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NonNull
|
||||||
public ExpandableViewState createExpandableViewState() {
|
public ExpandableViewState createExpandableViewState() {
|
||||||
return new ShelfState();
|
return new ShelfState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ import android.animation.Animator;
|
|||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.app.INotificationManager;
|
import android.app.INotificationManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
@@ -68,6 +66,9 @@ import android.widget.Chronometer;
|
|||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
@@ -3247,6 +3248,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NonNull
|
||||||
public ExpandableViewState createExpandableViewState() {
|
public ExpandableViewState createExpandableViewState() {
|
||||||
return new NotificationViewState();
|
return new NotificationViewState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.view.ViewGroup;
|
|||||||
import android.view.ViewParent;
|
import android.view.ViewParent;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.systemui.Dumpable;
|
import com.android.systemui.Dumpable;
|
||||||
@@ -66,7 +67,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
|
|||||||
protected float mContentTransformationAmount;
|
protected float mContentTransformationAmount;
|
||||||
protected boolean mIsLastChild;
|
protected boolean mIsLastChild;
|
||||||
protected int mContentShift;
|
protected int mContentShift;
|
||||||
private final ExpandableViewState mViewState;
|
@NonNull private final ExpandableViewState mViewState;
|
||||||
private float mContentTranslation;
|
private float mContentTranslation;
|
||||||
protected boolean mLastInSection;
|
protected boolean mLastInSection;
|
||||||
protected boolean mFirstInSection;
|
protected boolean mFirstInSection;
|
||||||
@@ -610,6 +611,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
|
|||||||
|
|
||||||
public void setActualHeightAnimating(boolean animating) {}
|
public void setActualHeightAnimating(boolean animating) {}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
protected ExpandableViewState createExpandableViewState() {
|
protected ExpandableViewState createExpandableViewState() {
|
||||||
return new ExpandableViewState();
|
return new ExpandableViewState();
|
||||||
}
|
}
|
||||||
@@ -642,7 +644,12 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
|
|||||||
return mViewState;
|
return mViewState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable public ExpandableViewState getViewState() {
|
/**
|
||||||
|
* Get the {@link ExpandableViewState} associated with the view.
|
||||||
|
*
|
||||||
|
* @return the ExpandableView's view state.
|
||||||
|
*/
|
||||||
|
@NonNull public ExpandableViewState getViewState() {
|
||||||
return mViewState;
|
return mViewState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import android.util.AttributeSet;
|
|||||||
import android.util.IndentingPrintWriter;
|
import android.util.IndentingPrintWriter;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
|
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
|
||||||
import com.android.systemui.statusbar.notification.stack.ViewState;
|
import com.android.systemui.statusbar.notification.stack.ViewState;
|
||||||
@@ -142,6 +144,7 @@ public class FooterView extends StackScrollerDecorView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NonNull
|
||||||
public ExpandableViewState createExpandableViewState() {
|
public ExpandableViewState createExpandableViewState() {
|
||||||
return new FooterViewState();
|
return new FooterViewState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4460,8 +4460,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateVisibility() {
|
private void updateVisibility() {
|
||||||
boolean shouldShow = !mAmbientState.isFullyHidden() || !onKeyguard();
|
mController.updateVisibility(!mAmbientState.isFullyHidden() || !onKeyguard());
|
||||||
setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||||
@@ -4526,17 +4525,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
void updateEmptyShadeView(boolean visible, boolean notifVisibleInShade) {
|
void updateEmptyShadeView(boolean visible, boolean areNotificationsHiddenInShade) {
|
||||||
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
|
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
|
||||||
|
|
||||||
int oldTextRes = mEmptyShadeView.getTextResource();
|
int oldTextRes = mEmptyShadeView.getTextResource();
|
||||||
int newTextRes = notifVisibleInShade
|
int newTextRes = areNotificationsHiddenInShade
|
||||||
? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
|
? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
|
||||||
if (oldTextRes != newTextRes) {
|
if (oldTextRes != newTextRes) {
|
||||||
mEmptyShadeView.setText(newTextRes);
|
mEmptyShadeView.setText(newTextRes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEmptyShadeViewVisible() {
|
||||||
|
return mEmptyShadeView.isVisible();
|
||||||
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
public void updateFooterView(boolean visible, boolean showDismissView, boolean showHistory) {
|
public void updateFooterView(boolean visible, boolean showDismissView, boolean showHistory) {
|
||||||
if (mFooterView == null) {
|
if (mFooterView == null) {
|
||||||
|
|||||||
@@ -177,7 +177,6 @@ public class NotificationStackScrollLayoutController {
|
|||||||
private NotificationStackScrollLayout mView;
|
private NotificationStackScrollLayout mView;
|
||||||
private boolean mFadeNotificationsOnDismiss;
|
private boolean mFadeNotificationsOnDismiss;
|
||||||
private NotificationSwipeHelper mSwipeHelper;
|
private NotificationSwipeHelper mSwipeHelper;
|
||||||
private boolean mShowEmptyShadeView;
|
|
||||||
@Nullable private Boolean mHistoryEnabled;
|
@Nullable private Boolean mHistoryEnabled;
|
||||||
private int mBarState;
|
private int mBarState;
|
||||||
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
||||||
@@ -1173,8 +1172,21 @@ public class NotificationStackScrollLayoutController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update whether we should show the empty shade view (no notifications in the shade).
|
* Set the visibility of the view, and propagate it to specific children.
|
||||||
* If so, send the update to our view.
|
*
|
||||||
|
* @param visible either the view is visible or not.
|
||||||
|
*/
|
||||||
|
public void updateVisibility(boolean visible) {
|
||||||
|
mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
|
||||||
|
if (mView.getVisibility() == View.VISIBLE) {
|
||||||
|
// Synchronize EmptyShadeView visibility with the parent container.
|
||||||
|
updateShowEmptyShadeView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update whether we should show the empty shade view ("no notifications" in the shade).
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@@ -1182,18 +1194,31 @@ public class NotificationStackScrollLayoutController {
|
|||||||
*/
|
*/
|
||||||
public void updateShowEmptyShadeView() {
|
public void updateShowEmptyShadeView() {
|
||||||
Trace.beginSection("NSSLC.updateShowEmptyShadeView");
|
Trace.beginSection("NSSLC.updateShowEmptyShadeView");
|
||||||
mShowEmptyShadeView = mStatusBarStateController.getCurrentOrUpcomingState() != KEYGUARD
|
|
||||||
&& !mView.isQsFullScreen()
|
|
||||||
&& getVisibleNotificationCount() == 0;
|
|
||||||
|
|
||||||
mView.updateEmptyShadeView(
|
final boolean shouldShow = getVisibleNotificationCount() == 0
|
||||||
mShowEmptyShadeView,
|
&& !mView.isQsFullScreen()
|
||||||
mZenModeController.areNotificationsHiddenInShade());
|
// Hide empty shade view when in transition to Keyguard.
|
||||||
|
// That avoids "No Notifications" to blink when transitioning to AOD.
|
||||||
|
// For more details, see: b/228790482
|
||||||
|
&& !isInTransitionToKeyguard();
|
||||||
|
|
||||||
|
mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade());
|
||||||
|
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if {@link StatusBarStateController} is in transition to the KEYGUARD
|
||||||
|
* and false otherwise.
|
||||||
|
*/
|
||||||
|
private boolean isInTransitionToKeyguard() {
|
||||||
|
final int currentState = mStatusBarStateController.getState();
|
||||||
|
final int upcomingState = mStatusBarStateController.getCurrentOrUpcomingState();
|
||||||
|
return (currentState != upcomingState && upcomingState == KEYGUARD);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isShowingEmptyShadeView() {
|
public boolean isShowingEmptyShadeView() {
|
||||||
return mShowEmptyShadeView;
|
return mView.isEmptyShadeViewVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
|
public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
|
||||||
|
|||||||
@@ -120,11 +120,64 @@ public class StackScrollAlgorithm {
|
|||||||
updateClipping(algorithmState, ambientState);
|
updateClipping(algorithmState, ambientState);
|
||||||
updateSpeedBumpState(algorithmState, speedBumpIndex);
|
updateSpeedBumpState(algorithmState, speedBumpIndex);
|
||||||
updateShelfState(algorithmState, ambientState);
|
updateShelfState(algorithmState, ambientState);
|
||||||
|
updateAlphaState(algorithmState, ambientState);
|
||||||
getNotificationChildrenStates(algorithmState, ambientState);
|
getNotificationChildrenStates(algorithmState, ambientState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateAlphaState(StackScrollAlgorithmState algorithmState,
|
||||||
|
AmbientState ambientState) {
|
||||||
|
for (ExpandableView view : algorithmState.visibleChildren) {
|
||||||
|
final ViewState viewState = view.getViewState();
|
||||||
|
|
||||||
|
final boolean isHunGoingToShade = ambientState.isShadeExpanded()
|
||||||
|
&& view == ambientState.getTrackedHeadsUpRow();
|
||||||
|
|
||||||
|
if (isHunGoingToShade) {
|
||||||
|
// Keep 100% opacity for heads up notification going to shade.
|
||||||
|
viewState.alpha = 1f;
|
||||||
|
} else if (ambientState.isOnKeyguard()) {
|
||||||
|
// Adjust alpha for wakeup to lockscreen.
|
||||||
|
viewState.alpha = 1f - ambientState.getHideAmount();
|
||||||
|
} else if (ambientState.isExpansionChanging()) {
|
||||||
|
// Adjust alpha for shade open & close.
|
||||||
|
float expansion = ambientState.getExpansionFraction();
|
||||||
|
viewState.alpha = ambientState.isBouncerInTransit()
|
||||||
|
? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion)
|
||||||
|
: ShadeInterpolation.getContentAlpha(expansion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For EmptyShadeView if on keyguard, we need to control the alpha to create
|
||||||
|
// a nice transition when the user is dragging down the notification panel.
|
||||||
|
if (view instanceof EmptyShadeView && ambientState.isOnKeyguard()) {
|
||||||
|
final float fractionToShade = ambientState.getFractionToShade();
|
||||||
|
viewState.alpha = ShadeInterpolation.getContentAlpha(fractionToShade);
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationShelf shelf = ambientState.getShelf();
|
||||||
|
if (shelf != null) {
|
||||||
|
final ViewState shelfState = shelf.getViewState();
|
||||||
|
|
||||||
|
// After the shelf has updated its yTranslation, explicitly set alpha=0 for view
|
||||||
|
// below shelf to skip rendering them in the hardware layer. We do not set them
|
||||||
|
// invisible because that runs invalidate & onDraw when these views return onscreen,
|
||||||
|
// which is more expensive.
|
||||||
|
if (shelfState.hidden) {
|
||||||
|
// When the shelf is hidden, it won't clip views, so we don't hide rows
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final float shelfTop = shelfState.yTranslation;
|
||||||
|
final float viewTop = viewState.yTranslation;
|
||||||
|
if (viewTop >= shelfTop) {
|
||||||
|
viewState.alpha = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How expanded or collapsed notifications are when pulling down the shade.
|
* How expanded or collapsed notifications are when pulling down the shade.
|
||||||
|
*
|
||||||
* @param ambientState Current ambient state.
|
* @param ambientState Current ambient state.
|
||||||
* @return 0 when fully collapsed, 1 when expanded.
|
* @return 0 when fully collapsed, 1 when expanded.
|
||||||
*/
|
*/
|
||||||
@@ -208,22 +261,6 @@ public class StackScrollAlgorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shelf.updateState(algorithmState, ambientState);
|
shelf.updateState(algorithmState, ambientState);
|
||||||
|
|
||||||
// After the shelf has updated its yTranslation, explicitly set alpha=0 for view below shelf
|
|
||||||
// to skip rendering them in the hardware layer. We do not set them invisible because that
|
|
||||||
// runs invalidate & onDraw when these views return onscreen, which is more expensive.
|
|
||||||
if (shelf.getViewState().hidden) {
|
|
||||||
// When the shelf is hidden, it won't clip views, so we don't hide rows
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final float shelfTop = shelf.getViewState().yTranslation;
|
|
||||||
|
|
||||||
for (ExpandableView view : algorithmState.visibleChildren) {
|
|
||||||
final float viewTop = view.getViewState().yTranslation;
|
|
||||||
if (viewTop >= shelfTop) {
|
|
||||||
view.getViewState().alpha = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateClipping(StackScrollAlgorithmState algorithmState,
|
private void updateClipping(StackScrollAlgorithmState algorithmState,
|
||||||
@@ -473,21 +510,6 @@ public class StackScrollAlgorithm {
|
|||||||
ExpandableViewState viewState = view.getViewState();
|
ExpandableViewState viewState = view.getViewState();
|
||||||
viewState.location = ExpandableViewState.LOCATION_UNKNOWN;
|
viewState.location = ExpandableViewState.LOCATION_UNKNOWN;
|
||||||
|
|
||||||
final boolean isHunGoingToShade = ambientState.isShadeExpanded()
|
|
||||||
&& view == ambientState.getTrackedHeadsUpRow();
|
|
||||||
if (isHunGoingToShade) {
|
|
||||||
// Keep 100% opacity for heads up notification going to shade.
|
|
||||||
} else if (ambientState.isOnKeyguard()) {
|
|
||||||
// Adjust alpha for wakeup to lockscreen.
|
|
||||||
viewState.alpha = 1f - ambientState.getHideAmount();
|
|
||||||
} else if (ambientState.isExpansionChanging()) {
|
|
||||||
// Adjust alpha for shade open & close.
|
|
||||||
float expansion = ambientState.getExpansionFraction();
|
|
||||||
viewState.alpha = ambientState.isBouncerInTransit()
|
|
||||||
? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion)
|
|
||||||
: ShadeInterpolation.getContentAlpha(expansion);
|
|
||||||
}
|
|
||||||
|
|
||||||
final float expansionFraction = getExpansionFractionWithoutShelf(
|
final float expansionFraction = getExpansionFractionWithoutShelf(
|
||||||
algorithmState, ambientState);
|
algorithmState, ambientState);
|
||||||
|
|
||||||
|
|||||||
@@ -3,19 +3,21 @@ package com.android.systemui.statusbar.notification.stack
|
|||||||
import android.annotation.DimenRes
|
import android.annotation.DimenRes
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.animation.ShadeInterpolation.getContentAlpha
|
||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
import com.android.systemui.statusbar.EmptyShadeView
|
import com.android.systemui.statusbar.EmptyShadeView
|
||||||
|
import com.android.systemui.statusbar.NotificationShelf
|
||||||
|
import com.android.systemui.statusbar.StatusBarState
|
||||||
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.stack.StackScrollAlgorithm.BypassController
|
|
||||||
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
|
|
||||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
|
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import junit.framework.Assert.assertEquals
|
||||||
import junit.framework.Assert.assertFalse
|
import junit.framework.Assert.assertFalse
|
||||||
import junit.framework.Assert.assertTrue
|
import junit.framework.Assert.assertTrue
|
||||||
import junit.framework.Assert.assertEquals
|
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mockito.mock
|
import org.mockito.Mockito.mock
|
||||||
@@ -26,17 +28,20 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
|
|||||||
|
|
||||||
private val hostView = FrameLayout(context)
|
private val hostView = FrameLayout(context)
|
||||||
private val stackScrollAlgorithm = StackScrollAlgorithm(context, hostView)
|
private val stackScrollAlgorithm = StackScrollAlgorithm(context, hostView)
|
||||||
private val expandableViewState = ExpandableViewState()
|
|
||||||
private val notificationRow = mock(ExpandableNotificationRow::class.java)
|
private val notificationRow = mock(ExpandableNotificationRow::class.java)
|
||||||
private val dumpManager = mock(DumpManager::class.java)
|
private val dumpManager = mock(DumpManager::class.java)
|
||||||
private val mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager::class.java)
|
private val mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager::class.java)
|
||||||
|
private val notificationShelf = mock(NotificationShelf::class.java)
|
||||||
|
private val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply {
|
||||||
|
layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
|
||||||
|
}
|
||||||
|
|
||||||
private val ambientState = AmbientState(
|
private val ambientState = AmbientState(
|
||||||
context,
|
context,
|
||||||
dumpManager,
|
dumpManager,
|
||||||
SectionProvider { _, _ -> false },
|
/* sectionProvider */ { _, _ -> false },
|
||||||
BypassController { false },
|
/* bypassController */ { false },
|
||||||
mStatusBarKeyguardViewManager
|
mStatusBarKeyguardViewManager
|
||||||
)
|
)
|
||||||
|
|
||||||
private val testableResources = mContext.orCreateTestableResources
|
private val testableResources = mContext.orCreateTestableResources
|
||||||
@@ -49,7 +54,9 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
whenever(notificationRow.viewState).thenReturn(expandableViewState)
|
whenever(notificationShelf.viewState).thenReturn(ExpandableViewState())
|
||||||
|
whenever(notificationRow.viewState).thenReturn(ExpandableViewState())
|
||||||
|
|
||||||
hostView.addView(notificationRow)
|
hostView.addView(notificationRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +67,8 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
|
|||||||
|
|
||||||
stackScrollAlgorithm.resetViewStates(ambientState, 0)
|
stackScrollAlgorithm.resetViewStates(ambientState, 0)
|
||||||
|
|
||||||
assertThat(expandableViewState.yTranslation).isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
|
assertThat(notificationRow.viewState.yTranslation)
|
||||||
|
.isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -75,15 +83,12 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
|
|||||||
stackScrollAlgorithm.resetViewStates(ambientState, 0)
|
stackScrollAlgorithm.resetViewStates(ambientState, 0)
|
||||||
|
|
||||||
// top margin presence should decrease heads up translation up to minHeadsUpTranslation
|
// top margin presence should decrease heads up translation up to minHeadsUpTranslation
|
||||||
assertThat(expandableViewState.yTranslation).isEqualTo(minHeadsUpTranslation)
|
assertThat(notificationRow.viewState.yTranslation).isEqualTo(minHeadsUpTranslation)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun resetViewStates_emptyShadeView_isCenteredVertically() {
|
fun resetViewStates_emptyShadeView_isCenteredVertically() {
|
||||||
stackScrollAlgorithm.initView(context)
|
stackScrollAlgorithm.initView(context)
|
||||||
val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply {
|
|
||||||
layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
|
|
||||||
}
|
|
||||||
hostView.removeAllViews()
|
hostView.removeAllViews()
|
||||||
hostView.addView(emptyShadeView)
|
hostView.addView(emptyShadeView)
|
||||||
ambientState.layoutMaxHeight = 1280
|
ambientState.layoutMaxHeight = 1280
|
||||||
@@ -97,6 +102,121 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
|
|||||||
assertThat(emptyShadeView.viewState?.yTranslation).isEqualTo(centeredY)
|
assertThat(emptyShadeView.viewState?.yTranslation).isEqualTo(centeredY)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_hunGoingToShade_viewBecomesOpaque() {
|
||||||
|
whenever(notificationRow.isAboveShelf).thenReturn(true)
|
||||||
|
ambientState.isShadeExpanded = true
|
||||||
|
ambientState.trackedHeadsUpRow = notificationRow
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
assertThat(notificationRow.viewState.alpha).isEqualTo(1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_isExpansionChanging_viewBecomesTransparent() {
|
||||||
|
whenever(mStatusBarKeyguardViewManager.isBouncerInTransit).thenReturn(false)
|
||||||
|
ambientState.isExpansionChanging = true
|
||||||
|
ambientState.expansionFraction = 0.25f
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
val expected = getContentAlpha(0.25f)
|
||||||
|
assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_isExpansionChangingWhileBouncerInTransit_viewBecomesTransparent() {
|
||||||
|
whenever(mStatusBarKeyguardViewManager.isBouncerInTransit).thenReturn(true)
|
||||||
|
ambientState.isExpansionChanging = true
|
||||||
|
ambientState.expansionFraction = 0.25f
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
val expected = aboutToShowBouncerProgress(0.25f)
|
||||||
|
assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_isOnKeyguard_viewBecomesTransparent() {
|
||||||
|
ambientState.setStatusBarState(StatusBarState.KEYGUARD)
|
||||||
|
ambientState.hideAmount = 0.25f
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
assertThat(notificationRow.viewState.alpha).isEqualTo(1f - ambientState.hideAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_isOnKeyguard_emptyShadeViewBecomesTransparent() {
|
||||||
|
ambientState.setStatusBarState(StatusBarState.KEYGUARD)
|
||||||
|
ambientState.fractionToShade = 0.25f
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
hostView.removeAllViews()
|
||||||
|
hostView.addView(emptyShadeView)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
val expected = getContentAlpha(ambientState.fractionToShade)
|
||||||
|
assertThat(emptyShadeView.viewState.alpha).isEqualTo(expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_isOnKeyguard_emptyShadeViewBecomesOpaque() {
|
||||||
|
ambientState.setStatusBarState(StatusBarState.SHADE)
|
||||||
|
ambientState.fractionToShade = 0.25f
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
hostView.removeAllViews()
|
||||||
|
hostView.addView(emptyShadeView)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
assertThat(emptyShadeView.viewState.alpha).isEqualTo(1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_hiddenShelf_viewAlphaDoesNotChange() {
|
||||||
|
val expected = notificationShelf.viewState.alpha
|
||||||
|
notificationShelf.viewState.hidden = true
|
||||||
|
ambientState.shelf = notificationShelf
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
assertThat(notificationShelf.viewState.alpha).isEqualTo(expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_shelfTopLessThanViewTop_hidesView() {
|
||||||
|
notificationRow.viewState.yTranslation = 10f
|
||||||
|
notificationShelf.viewState.yTranslation = 0.9f
|
||||||
|
notificationShelf.viewState.hidden = false
|
||||||
|
ambientState.shelf = notificationShelf
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
assertThat(notificationRow.viewState.alpha).isEqualTo(0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun resetViewStates_shelfTopGreaterOrEqualThanViewTop_viewAlphaDoesNotChange() {
|
||||||
|
val expected = notificationRow.viewState.alpha
|
||||||
|
notificationRow.viewState.yTranslation = 10f
|
||||||
|
notificationShelf.viewState.yTranslation = 10f
|
||||||
|
notificationShelf.viewState.hidden = false
|
||||||
|
ambientState.shelf = notificationShelf
|
||||||
|
stackScrollAlgorithm.initView(context)
|
||||||
|
|
||||||
|
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
|
||||||
|
|
||||||
|
assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getGapForLocation_onLockscreen_returnsSmallGap() {
|
fun getGapForLocation_onLockscreen_returnsSmallGap() {
|
||||||
val gap = stackScrollAlgorithm.getGapForLocation(
|
val gap = stackScrollAlgorithm.getGapForLocation(
|
||||||
@@ -267,7 +387,6 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
|
|||||||
assertEquals(10f, expandableViewState.yTranslation)
|
assertEquals(10f, expandableViewState.yTranslation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun clampHunToTop_viewYFarAboveVisibleStack_heightCollapsed() {
|
fun clampHunToTop_viewYFarAboveVisibleStack_heightCollapsed() {
|
||||||
val expandableViewState = ExpandableViewState()
|
val expandableViewState = ExpandableViewState()
|
||||||
|
|||||||
Reference in New Issue
Block a user