Merge "[Large screens][Motion] Improve expansion timing on lockscreen" into tm-qpr-dev

This commit is contained in:
Alex Florescu
2022-09-14 12:22:01 +00:00
committed by Android (Google) Code Review
14 changed files with 915 additions and 339 deletions

View File

@@ -16,6 +16,8 @@ package com.android.systemui.plugins.qs;
import android.view.View;
import androidx.annotation.FloatRange;
import com.android.systemui.plugins.FragmentBase;
import com.android.systemui.plugins.annotations.DependsOn;
import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -107,10 +109,24 @@ public interface QS extends FragmentBase {
void setInSplitShade(boolean shouldTranslate);
/**
* Set the amount of pixels we have currently dragged down if we're transitioning to the full
* shade. 0.0f means we're not transitioning yet.
* Sets the progress of the transition to full shade on the lockscreen.
*
* @param isTransitioningToFullShade
* whether the transition to full shade is in progress. This might be {@code true}, even
* though {@code qsTransitionFraction} is still 0.
* The reason for that is that on some device configurations, the QS transition has a
* start delay compared to the overall transition.
*
* @param qsTransitionFraction
* the fraction of the QS transition progress, from 0 to 1.
*
* @param qsSquishinessFraction
* the fraction of the QS "squish" transition progress, from 0 to 1.
*/
default void setTransitionToFullShadeAmount(float pxAmount, float progress) {}
default void setTransitionToFullShadeProgress(
boolean isTransitioningToFullShade,
@FloatRange(from = 0.0, to = 1.0) float qsTransitionFraction,
@FloatRange(from = 0.0, to = 1.0) float qsSquishinessFraction) {}
/**
* A rounded corner clipping that makes QS feel as if it were behind everything.
@@ -139,6 +155,12 @@ public interface QS extends FragmentBase {
*/
default void setOverScrollAmount(int overScrollAmount) {}
/**
* Sets whether the notification panel is using the full width of the screen. Typically true on
* small screens and false on large screens.
*/
void setIsNotificationPanelFullWidth(boolean isFullWidth);
/**
* Callback for when QSPanel container is scrolled
*/

View File

@@ -49,54 +49,29 @@
<dimen name="status_view_margin_horizontal">8dp</dimen>
<!-- Distance that the full shade transition takes in order to complete by tapping on a button
like "expand". -->
<!-- Lockscreen shade transition values -->
<dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
<!-- Distance that the full shade transition takes in order to complete. -->
<dimen name="lockscreen_shade_full_transition_distance">200dp</dimen>
<!-- Distance that the full shade transition takes in order for media to fully transition to
the shade -->
<dimen name="lockscreen_shade_media_transition_distance">200dp</dimen>
<!-- Distance that the full shade transition takes in order for scrim to fully transition to
the shade (in alpha) -->
<!-- Media transition distance = qs delay + qs distance -->
<dimen name="lockscreen_shade_media_transition_distance">129.28dp</dimen>
<dimen name="lockscreen_shade_scrim_transition_distance">80dp</dimen>
<!-- The notifications scrim transition should start when the other scrims' transition is at
95%. -->
<dimen name="lockscreen_shade_notifications_scrim_transition_delay">76dp</dimen>
<!-- The notifications scrim transition duration is 66.6% of the duration of the other scrims'
transition. -->
transition. -->
<dimen name="lockscreen_shade_notifications_scrim_transition_distance">53.28dp</dimen>
<!-- Distance that the full shade transition takes in order for the keyguard content on
NotificationPanelViewController to fully fade (e.g. Clock & Smartspace) -->
<dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">80dp</dimen>
<!-- Distance that the full shade transition takes in order for the notification shell to fully
expand. -->
<dimen name="lockscreen_shade_notif_shelf_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<!-- Distance that the full shade transition takes in order for the Quick Settings to fully
fade and expand. -->
<dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<!-- Distance that the full shade transition takes in order for depth of the wallpaper to fully
change.
On split-shade, there should be no depth effect, so setting the value to 0. -->
<dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_notifications_scrim_transition_distance</dimen>
<dimen name="lockscreen_shade_qs_transition_delay">@dimen/lockscreen_shade_notifications_scrim_transition_delay</dimen>
<dimen name="lockscreen_shade_qs_squish_transition_distance">@dimen/lockscreen_shade_qs_transition_distance</dimen>
<!-- On split-shade, the QS squish transition should start from half height. -->
<item name="lockscreen_shade_qs_squish_start_fraction" type="dimen" format="float" >0.5</item>
<!-- On split-shade, there should be no depth effect, so setting the value to 0. -->
<dimen name="lockscreen_shade_depth_controller_transition_distance">0dp</dimen>
<!-- Distance that the full shade transition takes in order for the UDFPS Keyguard View to fully
fade. -->
<dimen name="lockscreen_shade_udfps_keyguard_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<!-- Used for StatusBar to know that a transition is in progress. At the moment it only checks
whether the progress is > 0, therefore this value is not very important. -->
<dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_keyguard_transition_distance">@dimen/lockscreen_shade_media_transition_distance</dimen>
<!-- Roughly the same distance as media on LS to media on QS. We will translate by this value

View File

@@ -73,4 +73,24 @@
<dimen name="large_dialog_width">472dp</dimen>
<dimen name="large_screen_shade_header_height">42dp</dimen>
<!-- Lockscreen shade transition values -->
<dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
<dimen name="lockscreen_shade_full_transition_distance">80dp</dimen>
<dimen name="lockscreen_shade_media_transition_distance">120dp</dimen>
<dimen name="lockscreen_shade_scrim_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_notifications_scrim_transition_delay">@dimen/lockscreen_shade_scrim_transition_distance</dimen>
<dimen name="lockscreen_shade_notifications_scrim_transition_distance">@dimen/lockscreen_shade_scrim_transition_distance</dimen>
<dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_notif_shelf_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_qs_transition_delay">@dimen/lockscreen_shade_scrim_transition_distance</dimen>
<dimen name="lockscreen_shade_qs_squish_transition_distance">@dimen/lockscreen_shade_qs_transition_distance</dimen>
<!-- On large screen portrait, the QS squish transition should start from half height. -->
<item name="lockscreen_shade_qs_squish_start_fraction" type="dimen" format="float" >0.5</item>
<dimen name="lockscreen_shade_depth_controller_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_udfps_keyguard_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_status_bar_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<dimen name="lockscreen_shade_keyguard_transition_distance">@dimen/lockscreen_shade_media_transition_distance</dimen>
</resources>

View File

@@ -1212,6 +1212,17 @@
fade and expand. -->
<dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
<!-- Distance delay for the QS transition to start during the lockscreen shade expansion. -->
<dimen name="lockscreen_shade_qs_transition_delay">0dp</dimen>
<!-- Distance that it takes to complete the QS "squish" transition during the lockscreen shade
expansion. -->
<dimen name="lockscreen_shade_qs_squish_transition_distance">@dimen/lockscreen_shade_qs_transition_distance</dimen>
<!-- The fraction at which the QS "squish" transition should start during the lockscreen shade
expansion. 0 is fully collapsed, 1 is fully expanded. -->
<item type="dimen" format="float" name="lockscreen_shade_qs_squish_start_fraction">0</item>
<!-- Distance that the full shade transition takes in order for depth of the wallpaper to fully
change. -->
<dimen name="lockscreen_shade_depth_controller_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>

View File

@@ -34,6 +34,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import androidx.annotation.FloatRange;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.Lifecycle;
@@ -166,6 +167,13 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
// visible;
private boolean mQsVisible;
/**
* Whether the notification panel uses the full width of the screen.
*
* Usually {@code true} on small screens, and {@code false} on large screens.
*/
private boolean mIsNotificationPanelFullWidth;
@Inject
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
QSTileHost qsTileHost,
@@ -571,15 +579,17 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
@Override
public void setTransitionToFullShadeAmount(float pxAmount, float progress) {
boolean isTransitioningToFullShade = pxAmount > 0;
public void setTransitionToFullShadeProgress(
boolean isTransitioningToFullShade,
@FloatRange(from = 0.0, to = 1.0) float qsTransitionFraction,
@FloatRange(from = 0.0, to = 1.0) float qsSquishinessFraction) {
if (isTransitioningToFullShade != mTransitioningToFullShade) {
mTransitioningToFullShade = isTransitioningToFullShade;
updateShowCollapsedOnKeyguard();
}
mFullShadeProgress = progress;
mFullShadeProgress = qsTransitionFraction;
setQsExpansion(mLastQSExpansion, mLastPanelFraction, mLastHeaderTranslation,
isTransitioningToFullShade ? progress : mSquishinessFraction);
isTransitioningToFullShade ? qsSquishinessFraction : mSquishinessFraction);
}
@Override
@@ -597,13 +607,17 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
+ mHeader.getPaddingBottom();
}
@Override
public void setIsNotificationPanelFullWidth(boolean isFullWidth) {
mIsNotificationPanelFullWidth = isFullWidth;
}
@Override
public void setQsExpansion(float expansion, float panelExpansionFraction,
float proposedTranslation, float squishinessFraction) {
float headerTranslation = mTransitioningToFullShade ? 0 : proposedTranslation;
float alphaProgress = mTransitioningToFullShade || mState == StatusBarState.KEYGUARD
? mFullShadeProgress : panelExpansionFraction;
setAlphaAnimationProgress(mInSplitShade ? alphaProgress : 1);
float alphaProgress = calculateAlphaProgress(panelExpansionFraction);
setAlphaAnimationProgress(alphaProgress);
mContainer.setExpansion(expansion);
final float translationScaleY = (mInSplitShade
? 1 : QSAnimator.SHORT_PARALLAX_AMOUNT) * (expansion - 1);
@@ -683,10 +697,43 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
} else if (progress > 0 && view.getVisibility() != View.VISIBLE) {
view.setVisibility((View.VISIBLE));
}
float alpha = mQSPanelController.isBouncerInTransit()
? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(progress)
: ShadeInterpolation.getContentAlpha(progress);
view.setAlpha(alpha);
view.setAlpha(interpolateAlphaAnimationProgress(progress));
}
private float calculateAlphaProgress(float panelExpansionFraction) {
if (mIsNotificationPanelFullWidth) {
// Small screens. QS alpha is not animated.
return 1;
}
if (mInSplitShade) {
// Large screens in landscape.
if (mTransitioningToFullShade || isKeyguardState()) {
// Always use "mFullShadeProgress" on keyguard, because
// "panelExpansionFractions" is always 1 on keyguard split shade.
return mFullShadeProgress;
} else {
return panelExpansionFraction;
}
}
// Large screens in portrait.
if (mTransitioningToFullShade) {
// Only use this value during the standard lock screen shade expansion. During the
// "quick" expansion from top, this value is 0.
return mFullShadeProgress;
} else {
return panelExpansionFraction;
}
}
private float interpolateAlphaAnimationProgress(float progress) {
if (mQSPanelController.isBouncerInTransit()) {
return BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(progress);
}
if (isKeyguardState()) {
// Alpha progress should be linear on lockscreen shade expansion.
return progress;
}
return ShadeInterpolation.getContentAlpha(progress);
}
private void updateQsBounds() {

View File

@@ -1326,6 +1326,9 @@ public final class NotificationPanelViewController extends PanelViewController {
mIsFullWidth = isFullWidth;
mScrimController.setClipsQsScrim(isFullWidth);
mNotificationStackScrollLayoutController.setIsFullWidth(isFullWidth);
if (mQs != null) {
mQs.setIsNotificationPanelFullWidth(isFullWidth);
}
}
private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) {
@@ -2434,8 +2437,8 @@ public final class NotificationPanelViewController extends PanelViewController {
final float squishiness;
if ((mQsExpandImmediate || mQsExpanded) && !mSplitShadeEnabled) {
squishiness = 1;
} else if (mLockscreenShadeTransitionController.getQSDragProgress() > 0) {
squishiness = mLockscreenShadeTransitionController.getQSDragProgress();
} else if (mTransitioningToFullShadeProgress > 0.0f) {
squishiness = mLockscreenShadeTransitionController.getQsSquishTransitionFraction();
} else {
squishiness = mNotificationStackScrollLayoutController
.getNotificationSquishinessFraction();
@@ -3763,6 +3766,7 @@ public final class NotificationPanelViewController extends PanelViewController {
mQs.setHeaderClickable(isQsExpansionEnabled());
mQs.setOverscrolling(mStackScrollerOverscrolling);
mQs.setInSplitShade(mSplitShadeEnabled);
mQs.setIsNotificationPanelFullWidth(mIsFullWidth);
// recompute internal state when qspanel height changes
mQs.getView().addOnLayoutChangeListener(

View File

@@ -0,0 +1,159 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar
import android.content.Context
import android.util.IndentingPrintWriter
import android.util.MathUtils
import androidx.annotation.FloatRange
import androidx.annotation.Px
import com.android.systemui.R
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.qs.QS
import com.android.systemui.statusbar.policy.ConfigurationController
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlin.math.max
/** Responsible for the QS components during the lockscreen shade transition. */
class LockscreenShadeQsTransitionController
@AssistedInject
constructor(
context: Context,
configurationController: ConfigurationController,
dumpManager: DumpManager,
@Assisted private val qsProvider: () -> QS,
) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {
private val qs: QS
get() = qsProvider()
/**
* The progress fraction of the QS transition during lockscreen shade expansion.
*
* Note that this value might be 0 for some time when the expansion is already in progress,
* since there is a transition start delay for QS on some device configurations. For this
* reason, don't use this value to check whether the shade expansion is in progress.
*/
@FloatRange(from = 0.0, to = 1.0)
var qsTransitionFraction = 0f
private set
/**
* The fraction of the QS "squish" transition progress during lockscreen shade expansion.
*
* Note that in some device configurations (large screens) this value can start at a value
* greater than 0. For this reason don't use this value to check whether the QS transition has
* started or not.
*/
@FloatRange(from = 0.0, to = 1.0)
var qsSquishTransitionFraction = 0f
private set
/**
* The drag down amount, in pixels __for the QS transition__, also taking into account the
* [qsTransitionStartDelay].
*
* Since it takes into account the start delay, it is __not__ the same as the raw drag down
* amount from the shade expansion.
*/
@Px private var qsDragDownAmount = 0f
/**
* Distance it takes for the QS transition to complete during the lockscreen shade expansion.
*/
@Px private var qsTransitionDistance = 0
/** Distance delay for the QS transition to start during the lockscreen shade expansion. */
@Px private var qsTransitionStartDelay = 0
/**
* Distance that it takes to complete the QS "squish" transition during the lockscreen shade
* expansion.
*/
@Px private var qsSquishTransitionDistance = 0
/**
* Whether the transition to full shade is in progress. Might be `true` even though
* [qsTransitionFraction] is still 0, due to [qsTransitionStartDelay].
*/
private var isTransitioningToFullShade = false
/**
* The fraction at which the QS "squish" transition should start during the lockscreen shade
* expansion.
*
* 0 is fully collapsed, 1 is fully expanded.
*/
@FloatRange(from = 0.0, to = 1.0) private var qsSquishStartFraction = 0f
override fun updateResources() {
qsTransitionDistance =
context.resources.getDimensionPixelSize(R.dimen.lockscreen_shade_qs_transition_distance)
qsTransitionStartDelay =
context.resources.getDimensionPixelSize(R.dimen.lockscreen_shade_qs_transition_delay)
qsSquishTransitionDistance =
context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_qs_squish_transition_distance
)
qsSquishStartFraction =
context.resources.getFloat(R.dimen.lockscreen_shade_qs_squish_start_fraction)
qsSquishTransitionFraction = max(qsSquishTransitionFraction, qsSquishStartFraction)
}
override fun onDragDownAmountChanged(dragDownAmount: Float) {
qsDragDownAmount = dragDownAmount - qsTransitionStartDelay
qsTransitionFraction = MathUtils.saturate(qsDragDownAmount / qsTransitionDistance)
qsSquishTransitionFraction =
MathUtils.lerp(
/* start= */ qsSquishStartFraction,
/* stop= */ 1f,
/* amount= */ MathUtils.saturate(qsDragDownAmount / qsSquishTransitionDistance)
)
isTransitioningToFullShade = dragDownAmount > 0.0f
qs.setTransitionToFullShadeProgress(
isTransitioningToFullShade,
qsTransitionFraction,
qsSquishTransitionFraction
)
}
override fun dump(pw: IndentingPrintWriter) {
pw.println(
"""
Resources:
qsTransitionDistance: $qsTransitionDistance
qsTransitionStartDelay: $qsTransitionStartDelay
qsSquishTransitionDistance: $qsSquishTransitionDistance
qsSquishStartFraction: $qsSquishStartFraction
State:
dragDownAmount: $dragDownAmount
qsDragDownAmount: $qsDragDownAmount
qsDragFraction: $qsTransitionFraction
qsSquishFraction: $qsSquishTransitionFraction
isTransitioningToFullShade: $isTransitioningToFullShade
""".trimIndent()
)
}
@AssistedFactory
fun interface Factory {
fun create(qsProvider: () -> QS): LockscreenShadeQsTransitionController
}
}

View File

@@ -11,6 +11,7 @@ import android.util.MathUtils
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import androidx.annotation.FloatRange
import androidx.annotation.VisibleForTesting
import com.android.systemui.Dumpable
import com.android.systemui.ExpandHelper
@@ -68,7 +69,8 @@ class LockscreenShadeTransitionController @Inject constructor(
wakefulnessLifecycle: WakefulnessLifecycle,
configurationController: ConfigurationController,
falsingManager: FalsingManager,
dumpManager: DumpManager
dumpManager: DumpManager,
qsTransitionControllerFactory: LockscreenShadeQsTransitionController.Factory,
) : Dumpable {
private var pulseHeight: Float = 0f
@get:VisibleForTesting
@@ -119,12 +121,6 @@ class LockscreenShadeTransitionController @Inject constructor(
*/
private var notificationShelfTransitionDistance = 0
/**
* Distance that the full shade transition takes in order for the Quick Settings to fully fade
* and expand.
*/
private var qsTransitionDistance = 0
/**
* Distance that the full shade transition takes in order for depth of the wallpaper to fully
* change.
@@ -188,6 +184,18 @@ class LockscreenShadeTransitionController @Inject constructor(
keyguardTransitionControllerFactory.create(notificationPanelController)
}
private val qsTransitionController = qsTransitionControllerFactory.create { qS }
/** See [LockscreenShadeQsTransitionController.qsTransitionFraction].*/
@get:FloatRange(from = 0.0, to = 1.0)
val qSDragProgress: Float
get() = qsTransitionController.qsTransitionFraction
/** See [LockscreenShadeQsTransitionController.qsSquishTransitionFraction].*/
@get:FloatRange(from = 0.0, to = 1.0)
val qsSquishTransitionFraction: Float
get() = qsTransitionController.qsSquishTransitionFraction
/**
* [LockScreenShadeOverScroller] property that delegates to either
* [SingleShadeLockScreenOverScroller] or [SplitShadeLockScreenOverScroller].
@@ -242,8 +250,6 @@ class LockscreenShadeTransitionController @Inject constructor(
R.dimen.lockscreen_shade_transition_by_tap_distance)
notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_notif_shelf_transition_distance)
qsTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_qs_transition_distance)
depthControllerTransitionDistance = context.resources.getDimensionPixelSize(
R.dimen.lockscreen_shade_depth_controller_transition_distance)
udfpsTransitionDistance = context.resources.getDimensionPixelSize(
@@ -411,8 +417,7 @@ class LockscreenShadeTransitionController @Inject constructor(
MathUtils.saturate(dragDownAmount / notificationShelfTransitionDistance)
nsslController.setTransitionToFullShadeAmount(fractionToShade)
qSDragProgress = MathUtils.saturate(dragDownAmount / qsTransitionDistance)
qS.setTransitionToFullShadeAmount(field, qSDragProgress)
qsTransitionController.dragDownAmount = value
notificationPanelController.setTransitionToFullShadeAmount(field,
false /* animate */, 0 /* delay */)
@@ -426,12 +431,6 @@ class LockscreenShadeTransitionController @Inject constructor(
}
}
/**
* The drag progress of the quick settings drag down amount
*/
var qSDragProgress = 0f
private set
private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
if (depthControllerTransitionDistance == 0) { // split shade
depthController.transitionToFullShadeProgress = 0f
@@ -704,7 +703,6 @@ class LockscreenShadeTransitionController @Inject constructor(
it.println("pulseHeight: $pulseHeight")
it.println("useSplitShade: $useSplitShade")
it.println("dragDownAmount: $dragDownAmount")
it.println("qSDragProgress: $qSDragProgress")
it.println("isDragDownAnywhereEnabled: $isDragDownAnywhereEnabled")
it.println("isFalsingCheckNeeded: $isFalsingCheckNeeded")
it.println("isWakingToShadeLocked: $isWakingToShadeLocked")

View File

@@ -259,11 +259,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private boolean mKeyguardOccluded;
@Inject
public ScrimController(LightBarController lightBarController, DozeParameters dozeParameters,
AlarmManager alarmManager, KeyguardStateController keyguardStateController,
DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
ConfigurationController configurationController, @Main Executor mainExecutor,
public ScrimController(
LightBarController lightBarController,
DozeParameters dozeParameters,
AlarmManager alarmManager,
KeyguardStateController keyguardStateController,
DelayedWakeLock.Builder delayedWakeLockBuilder,
Handler handler,
KeyguardUpdateMonitor keyguardUpdateMonitor,
DockManager dockManager,
ConfigurationController configurationController,
@Main Executor mainExecutor,
ScreenOffAnimationController screenOffAnimationController,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
@@ -826,20 +832,15 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mBehindTint = Color.BLACK;
} else {
mBehindAlpha = behindAlpha;
if (mState == ScrimState.SHADE_LOCKED) {
if (mState == ScrimState.KEYGUARD && mTransitionToFullShadeProgress > 0.0f) {
mNotificationsAlpha = MathUtils
.saturate(mTransitionToLockScreenFullShadeNotificationsProgress);
} else if (mState == ScrimState.SHADE_LOCKED) {
// going from KEYGUARD to SHADE_LOCKED state
mNotificationsAlpha = getInterpolatedFraction();
} else {
mNotificationsAlpha = Math.max(1.0f - getInterpolatedFraction(), mQsExpansion);
}
if (mState == ScrimState.KEYGUARD
&& mTransitionToLockScreenFullShadeNotificationsProgress > 0.0f) {
// Interpolate the notification alpha when transitioning!
mNotificationsAlpha = MathUtils.lerp(
mNotificationsAlpha,
getInterpolatedFraction(),
mTransitionToLockScreenFullShadeNotificationsProgress);
}
mNotificationsTint = mState.getNotifTint();
mBehindTint = behindTint;
}
@@ -1430,6 +1431,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
pw.print(mNotificationsAlpha);
pw.print(" tint=0x");
pw.println(Integer.toHexString(mNotificationsScrim.getTint()));
pw.print(" expansionProgress=");
pw.println(mTransitionToLockScreenFullShadeNotificationsProgress);
pw.print(" mTracking=");
pw.println(mTracking);

View File

@@ -94,6 +94,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
@Mock private QSPanel.QSTileLayout mQQsTileLayout;
@Mock private QSAnimator mQSAnimator;
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private QSSquishinessController mSquishinessController;
private View mQsFragmentView;
public QSFragmentTest() {
@@ -139,13 +140,15 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
}
@Test
public void transitionToFullShade_inSplitShade_setsAlphaBasedOnProgress() {
public void transitionToFullShade_setsAlphaUsingShadeInterpolator() {
QSFragment fragment = resumeAndGetFragment();
enableSplitShade();
int transitionPxAmount = 123;
setStatusBarState(StatusBarState.SHADE);
boolean isTransitioningToFullShade = true;
float transitionProgress = 0.5f;
float squishinessFraction = 0.5f;
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
squishinessFraction);
assertThat(mQsFragmentView.getAlpha())
.isEqualTo(ShadeInterpolation.getContentAlpha(transitionProgress));
@@ -153,31 +156,32 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
@Test
public void
transitionToFullShade_inSplitShade_onKeyguard_bouncerNotActive_usesShadeInterpolator() {
transitionToFullShade_onKeyguard_noBouncer_setsAlphaUsingLinearInterpolator() {
QSFragment fragment = resumeAndGetFragment();
enableSplitShade();
setStatusBarState(StatusBarState.KEYGUARD);
when(mQSPanelController.isBouncerInTransit()).thenReturn(false);
int transitionPxAmount = 123;
boolean isTransitioningToFullShade = true;
float transitionProgress = 0.5f;
float squishinessFraction = 0.5f;
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
squishinessFraction);
assertThat(mQsFragmentView.getAlpha())
.isEqualTo(ShadeInterpolation.getContentAlpha(transitionProgress));
assertThat(mQsFragmentView.getAlpha()).isEqualTo(transitionProgress);
}
@Test
public void
transitionToFullShade_inSplitShade_onKeyguard_bouncerActive_usesBouncerInterpolator() {
transitionToFullShade_onKeyguard_bouncerActive_setsAlphaUsingBouncerInterpolator() {
QSFragment fragment = resumeAndGetFragment();
enableSplitShade();
setStatusBarState(StatusBarState.KEYGUARD);
when(mQSPanelController.isBouncerInTransit()).thenReturn(true);
int transitionPxAmount = 123;
boolean isTransitioningToFullShade = true;
float transitionProgress = 0.5f;
float squishinessFraction = 0.5f;
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
squishinessFraction);
assertThat(mQsFragmentView.getAlpha())
.isEqualTo(
@@ -186,27 +190,43 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
}
@Test
public void transitionToFullShade_notInSplitShade_alwaysSetsAlphaTo1() {
public void transitionToFullShade_inFullWidth_alwaysSetsAlphaTo1() {
QSFragment fragment = resumeAndGetFragment();
disableSplitShade();
fragment.setIsNotificationPanelFullWidth(true);
int transitionPxAmount = 12;
boolean isTransitioningToFullShade = true;
float transitionProgress = 0.1f;
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
float squishinessFraction = 0.5f;
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
squishinessFraction);
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
transitionPxAmount = 123;
transitionProgress = 0.5f;
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
squishinessFraction);
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
transitionPxAmount = 234;
transitionProgress = 0.7f;
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
squishinessFraction);
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
}
@Test
public void transitionToFullShade_setsSquishinessOnController() {
QSFragment fragment = resumeAndGetFragment();
boolean isTransitioningToFullShade = true;
float transitionProgress = 0.123f;
float squishinessFraction = 0.456f;
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
squishinessFraction);
verify(mQsFragmentComponent.getQSSquishinessController())
.setSquishiness(squishinessFraction);
}
@Test
public void setQsExpansion_inSplitShade_setsFooterActionsExpansion_basedOnPanelExpFraction() {
// Random test values without any meaning. They just have to be different from each other.
@@ -453,6 +473,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
when(mQsFragmentComponent.getQSFooterActionController())
.thenReturn(mQSFooterActionController);
when(mQsFragmentComponent.getQSAnimator()).thenReturn(mQSAnimator);
when(mQsFragmentComponent.getQSSquishinessController()).thenReturn(mSquishinessController);
}
private QSFragment getFragment() {

View File

@@ -42,7 +42,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.annotation.IdRes;
import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -57,6 +56,7 @@ import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewPropertyAnimator;
import android.view.ViewStub;
@@ -107,6 +107,7 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
import com.android.systemui.qs.QSFragment;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.shade.transition.ShadeTransitionController;
import com.android.systemui.statusbar.CommandQueue;
@@ -160,8 +161,6 @@ import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.time.SystemClock;
import com.android.systemui.wallet.controller.QuickAccessWalletController;
@@ -186,225 +185,134 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
private static final int SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400;
private static final int NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE = 50;
private static final int PANEL_WIDTH = 500; // Random value just for the test.
@Mock
private CentralSurfaces mCentralSurfaces;
@Mock
private NotificationStackScrollLayout mNotificationStackScrollLayout;
@Mock
private KeyguardBottomAreaView mKeyguardBottomArea;
@Mock
private KeyguardBottomAreaViewController mKeyguardBottomAreaViewController;
@Mock
private KeyguardBottomAreaView mQsFrame;
private KeyguardStatusView mKeyguardStatusView;
@Mock
private NotificationIconAreaController mNotificationAreaController;
@Mock
private HeadsUpManagerPhone mHeadsUpManager;
@Mock
private NotificationShelfController mNotificationShelfController;
@Mock
private KeyguardStatusBarView mKeyguardStatusBar;
@Mock
private KeyguardUserSwitcherView mUserSwitcherView;
@Mock
private ViewStub mUserSwitcherStubView;
@Mock
private HeadsUpTouchHelper.Callback mHeadsUpCallback;
@Mock
private KeyguardUpdateMonitor mUpdateMonitor;
@Mock
private KeyguardBypassController mKeyguardBypassController;
@Mock
private DozeParameters mDozeParameters;
@Mock
private ScreenOffAnimationController mScreenOffAnimationController;
@Mock
private NotificationPanelView mView;
@Mock
private LayoutInflater mLayoutInflater;
@Mock
private FeatureFlags mFeatureFlags;
@Mock
private DynamicPrivacyController mDynamicPrivacyController;
@Mock
private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
private DozeLog mDozeLog;
@Mock
private ShadeLogger mShadeLog;
@Mock
private CommandQueue mCommandQueue;
@Mock
private VibratorHelper mVibratorHelper;
@Mock
private LatencyTracker mLatencyTracker;
@Mock
private PowerManager mPowerManager;
@Mock
private AccessibilityManager mAccessibilityManager;
@Mock
private MetricsLogger mMetricsLogger;
@Mock
private ActivityManager mActivityManager;
@Mock
private Resources mResources;
@Mock
private Configuration mConfiguration;
private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@Mock
private KeyguardClockSwitch mKeyguardClockSwitch;
private NotificationPanelViewController.TouchHandler mTouchHandler;
private ConfigurationController mConfigurationController;
@Mock
private MediaHierarchyManager mMediaHiearchyManager;
@Mock
private ConversationNotificationManager mConversationNotificationManager;
@Mock
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock
private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
@Mock
private KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
@Mock
private KeyguardQsUserSwitchComponent mKeyguardQsUserSwitchComponent;
@Mock
private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
@Mock
private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
@Mock
private KeyguardUserSwitcherComponent mKeyguardUserSwitcherComponent;
@Mock
private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
@Mock
private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
@Mock
private KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
@Mock
private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
@Mock
private KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock
private KeyguardStatusViewController mKeyguardStatusViewController;
@Mock
private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
@Mock
private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
@Mock
private NotificationShadeDepthController mNotificationShadeDepthController;
@Mock
private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Mock
private AuthController mAuthController;
@Mock
private ScrimController mScrimController;
@Mock
private MediaDataManager mMediaDataManager;
@Mock
private AmbientState mAmbientState;
@Mock
private UserManager mUserManager;
@Mock
private UiEventLogger mUiEventLogger;
@Mock
private LockIconViewController mLockIconViewController;
@Mock
private KeyguardMediaController mKeyguardMediaController;
@Mock
private PrivacyDotViewController mPrivacyDotViewController;
@Mock
private NavigationModeController mNavigationModeController;
@Mock
private SecureSettings mSecureSettings;
@Mock
private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController;
@Mock
private ContentResolver mContentResolver;
@Mock
private TapAgainViewController mTapAgainViewController;
@Mock
private KeyguardIndicationController mKeyguardIndicationController;
@Mock
private FragmentService mFragmentService;
@Mock
private FragmentHostManager mFragmentHostManager;
@Mock
private QuickAccessWalletController mQuickAccessWalletController;
@Mock
private QRCodeScannerController mQrCodeScannerController;
@Mock
private NotificationRemoteInputManager mNotificationRemoteInputManager;
@Mock
private RecordingController mRecordingController;
@Mock
private ControlsComponent mControlsComponent;
@Mock
private LockscreenGestureLogger mLockscreenGestureLogger;
@Mock
private DumpManager mDumpManager;
@Mock
private InteractionJankMonitor mInteractionJankMonitor;
@Mock
private NotificationsQSContainerController mNotificationsQSContainerController;
@Mock
private QsFrameTranslateController mQsFrameTranslateController;
@Mock
private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock
private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock
private NotificationShadeWindowController mNotificationShadeWindowController;
@Mock
private SysUiState mSysUiState;
@Mock
private NotificationListContainer mNotificationListContainer;
@Mock
private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
@Mock
private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
@Mock
private ShadeTransitionController mShadeTransitionController;
@Mock
private QS mQs;
@Mock
private View mQsHeader;
@Mock
private ViewParent mViewParent;
@Mock
private ViewTreeObserver mViewTreeObserver;
@Mock private CentralSurfaces mCentralSurfaces;
@Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
@Mock private KeyguardBottomAreaView mKeyguardBottomArea;
@Mock private KeyguardBottomAreaViewController mKeyguardBottomAreaViewController;
@Mock private KeyguardBottomAreaView mQsFrame;
@Mock private NotificationIconAreaController mNotificationAreaController;
@Mock private HeadsUpManagerPhone mHeadsUpManager;
@Mock private NotificationShelfController mNotificationShelfController;
@Mock private KeyguardStatusBarView mKeyguardStatusBar;
@Mock private KeyguardUserSwitcherView mUserSwitcherView;
@Mock private ViewStub mUserSwitcherStubView;
@Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback;
@Mock private KeyguardUpdateMonitor mUpdateMonitor;
@Mock private KeyguardBypassController mKeyguardBypassController;
@Mock private DozeParameters mDozeParameters;
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
@Mock private NotificationPanelView mView;
@Mock private LayoutInflater mLayoutInflater;
@Mock private FeatureFlags mFeatureFlags;
@Mock private DynamicPrivacyController mDynamicPrivacyController;
@Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private DozeLog mDozeLog;
@Mock private ShadeLogger mShadeLog;
@Mock private CommandQueue mCommandQueue;
@Mock private VibratorHelper mVibratorHelper;
@Mock private LatencyTracker mLatencyTracker;
@Mock private PowerManager mPowerManager;
@Mock private AccessibilityManager mAccessibilityManager;
@Mock private MetricsLogger mMetricsLogger;
@Mock private Resources mResources;
@Mock private Configuration mConfiguration;
@Mock private KeyguardClockSwitch mKeyguardClockSwitch;
@Mock private MediaHierarchyManager mMediaHiearchyManager;
@Mock private ConversationNotificationManager mConversationNotificationManager;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
@Mock private KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
@Mock private KeyguardQsUserSwitchComponent mKeyguardQsUserSwitchComponent;
@Mock private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
@Mock private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
@Mock private KeyguardUserSwitcherComponent mKeyguardUserSwitcherComponent;
@Mock private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
@Mock private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
@Mock private KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
@Mock private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
@Mock private KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock private KeyguardStatusViewController mKeyguardStatusViewController;
@Mock private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
@Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
@Mock private NotificationShadeDepthController mNotificationShadeDepthController;
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Mock private AuthController mAuthController;
@Mock private ScrimController mScrimController;
@Mock private MediaDataManager mMediaDataManager;
@Mock private AmbientState mAmbientState;
@Mock private UserManager mUserManager;
@Mock private UiEventLogger mUiEventLogger;
@Mock private LockIconViewController mLockIconViewController;
@Mock private KeyguardMediaController mKeyguardMediaController;
@Mock private PrivacyDotViewController mPrivacyDotViewController;
@Mock private NavigationModeController mNavigationModeController;
@Mock private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController;
@Mock private ContentResolver mContentResolver;
@Mock private TapAgainViewController mTapAgainViewController;
@Mock private KeyguardIndicationController mKeyguardIndicationController;
@Mock private FragmentService mFragmentService;
@Mock private FragmentHostManager mFragmentHostManager;
@Mock private QuickAccessWalletController mQuickAccessWalletController;
@Mock private QRCodeScannerController mQrCodeScannerController;
@Mock private NotificationRemoteInputManager mNotificationRemoteInputManager;
@Mock private RecordingController mRecordingController;
@Mock private ControlsComponent mControlsComponent;
@Mock private LockscreenGestureLogger mLockscreenGestureLogger;
@Mock private DumpManager mDumpManager;
@Mock private InteractionJankMonitor mInteractionJankMonitor;
@Mock private NotificationsQSContainerController mNotificationsQSContainerController;
@Mock private QsFrameTranslateController mQsFrameTranslateController;
@Mock private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock private NotificationShadeWindowController mNotificationShadeWindowController;
@Mock private SysUiState mSysUiState;
@Mock private NotificationListContainer mNotificationListContainer;
@Mock private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
@Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
@Mock private ShadeTransitionController mShadeTransitionController;
@Mock private QS mQs;
@Mock private QSFragment mQSFragment;
@Mock private ViewGroup mQsHeader;
@Mock private ViewParent mViewParent;
@Mock private ViewTreeObserver mViewTreeObserver;
@Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
private NotificationPanelViewController.TouchHandler mTouchHandler;
private ConfigurationController mConfigurationController;
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
private View.AccessibilityDelegate mAccessibiltyDelegate;
private NotificationsQuickSettingsContainer mNotificationContainerParent;
private List<View.OnAttachStateChangeListener> mOnAttachStateChangeListeners;
private FalsingManagerFake mFalsingManager = new FalsingManagerFake();
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private Handler mMainHandler;
private View.OnLayoutChangeListener mLayoutChangeListener;
private final FalsingManagerFake mFalsingManager = new FalsingManagerFake();
private final Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
private final PanelExpansionStateManager mPanelExpansionStateManager =
new PanelExpansionStateManager();
private SystemClock mSystemClock;
private FragmentHostManager.FragmentListener mFragmentListener;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mSystemClock = new FakeSystemClock();
SystemClock systemClock = new FakeSystemClock();
mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
mInteractionJankMonitor);
mKeyguardStatusView = new KeyguardStatusView(mContext);
mKeyguardStatusView.setId(R.id.keyguard_status_view);
KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
keyguardStatusView.setId(R.id.keyguard_status_view);
DejankUtils.setImmediate(true);
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
when(mHeadsUpCallback.getContext()).thenReturn(mContext);
when(mView.getResources()).thenReturn(mResources);
when(mView.getWidth()).thenReturn(PANEL_WIDTH);
when(mResources.getConfiguration()).thenReturn(mConfiguration);
mConfiguration.orientation = ORIENTATION_PORTRAIT;
when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
@@ -434,7 +342,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
when(mView.findViewById(R.id.keyguard_status_view))
.thenReturn(mock(KeyguardStatusView.class));
mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
mNotificationContainerParent.addView(mKeyguardStatusView);
mNotificationContainerParent.addView(keyguardStatusView);
mNotificationContainerParent.onFinishInflate();
when(mView.findViewById(R.id.notification_container_parent))
.thenReturn(mNotificationContainerParent);
@@ -450,7 +358,12 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
when(mKeyguardUserSwitcherComponent.getKeyguardUserSwitcherController())
.thenReturn(mKeyguardUserSwitcherController);
when(mScreenOffAnimationController.shouldAnimateClockChange()).thenReturn(true);
when(mQs.getView()).thenReturn(mView);
when(mQSFragment.getView()).thenReturn(mView);
doAnswer(invocation -> {
mFragmentListener = invocation.getArgument(1);
return null;
}).when(mFragmentHostManager).addTagListener(eq(QS.TAG), any());
doAnswer((Answer<Void>) invocation -> {
mTouchHandler = invocation.getArgument(0);
return null;
@@ -487,7 +400,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
.thenReturn(mKeyguardStatusBarViewController);
when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
.thenReturn(mKeyguardStatusView);
.thenReturn(keyguardStatusView);
when(mLayoutInflater.inflate(eq(R.layout.keyguard_user_switcher), any(), anyBoolean()))
.thenReturn(mUserSwitcherView);
when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean()))
@@ -502,13 +415,18 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
((Runnable) invocation.getArgument(0)).run();
return null;
}).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
doAnswer(invocation -> {
mLayoutChangeListener = invocation.getArgument(0);
return null;
}).when(mView).addOnLayoutChangeListener(any());
when(mView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
when(mView.getParent()).thenReturn(mViewParent);
when(mQs.getHeader()).thenReturn(mQsHeader);
mMainHandler = new Handler(Looper.getMainLooper());
mPanelEventsEmitter = new NotificationPanelViewController.PanelEventsEmitter();
NotificationPanelViewController.PanelEventsEmitter panelEventsEmitter =
new NotificationPanelViewController.PanelEventsEmitter();
mNotificationPanelViewController = new NotificationPanelViewController(
mView,
@@ -563,11 +481,11 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
() -> mKeyguardBottomAreaViewController,
mKeyguardUnlockAnimationController,
mNotificationListContainer,
mPanelEventsEmitter,
panelEventsEmitter,
mNotificationStackSizeCalculator,
mUnlockedScreenOffAnimationController,
mShadeTransitionController,
mSystemClock,
systemClock,
mock(CameraGestureHelper.class),
mKeyguardBottomAreaViewModel,
mKeyguardBottomAreaInteractor);
@@ -1492,6 +1410,96 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
assertThat(maxDistance).isNotEqualTo(SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
}
@Test
public void onLayoutChange_fullWidth_updatesQSWithFullWithTrue() {
mNotificationPanelViewController.mQs = mQs;
setIsFullWidth(true);
verify(mQs).setIsNotificationPanelFullWidth(true);
}
@Test
public void onLayoutChange_notFullWidth_updatesQSWithFullWithFalse() {
mNotificationPanelViewController.mQs = mQs;
setIsFullWidth(false);
verify(mQs).setIsNotificationPanelFullWidth(false);
}
@Test
public void onLayoutChange_qsNotSet_doesNotCrash() {
mNotificationPanelViewController.mQs = null;
triggerLayoutChange();
}
@Test
public void onQsFragmentAttached_fullWidth_setsFullWidthTrueOnQS() {
setIsFullWidth(true);
givenViewAttached();
mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
verify(mQSFragment).setIsNotificationPanelFullWidth(true);
}
@Test
public void onQsFragmentAttached_notFullWidth_setsFullWidthFalseOnQS() {
setIsFullWidth(false);
givenViewAttached();
mFragmentListener.onFragmentViewCreated(QS.TAG, mQSFragment);
verify(mQSFragment).setIsNotificationPanelFullWidth(false);
}
@Test
public void setQsExpansion_lockscreenShadeTransitionInProgress_usesLockscreenSquishiness() {
float squishinessFraction = 0.456f;
mNotificationPanelViewController.mQs = mQs;
when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
.thenReturn(squishinessFraction);
when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
.thenReturn(0.987f);
// Call setTransitionToFullShadeAmount to get into the full shade transition in progress
// state.
mNotificationPanelViewController.setTransitionToFullShadeAmount(
/* pxAmount= */ 234,
/* animate= */ false,
/* delay= */ 0
);
mNotificationPanelViewController.setQsExpansion(/* height= */ 123);
// First for setTransitionToFullShadeAmount and then setQsExpansion
verify(mQs, times(2)).setQsExpansion(
/* expansion= */ anyFloat(),
/* panelExpansionFraction= */ anyFloat(),
/* proposedTranslation= */ anyFloat(),
eq(squishinessFraction)
);
}
@Test
public void setQsExpansion_lockscreenShadeTransitionNotInProgress_usesStandardSquishiness() {
float lsSquishinessFraction = 0.456f;
float nsslSquishinessFraction = 0.987f;
mNotificationPanelViewController.mQs = mQs;
when(mLockscreenShadeTransitionController.getQsSquishTransitionFraction())
.thenReturn(lsSquishinessFraction);
when(mNotificationStackScrollLayoutController.getNotificationSquishinessFraction())
.thenReturn(nsslSquishinessFraction);
mNotificationPanelViewController.setQsExpansion(/* height= */ 123);
verify(mQs).setQsExpansion(
/* expansion= */ anyFloat(),
/* panelExpansionFraction= */ anyFloat(),
/* proposedTranslation= */ anyFloat(),
eq(nsslSquishinessFraction)
);
}
private static MotionEvent createMotionEvent(int x, int y, int action) {
return MotionEvent.obtain(
/* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0);
@@ -1565,4 +1573,24 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
assertThat(getConstraintSetLayout(R.id.keyguard_status_view).endToEnd).isEqualTo(
R.id.qs_edge_guideline);
}
private void setIsFullWidth(boolean fullWidth) {
float nsslWidth = fullWidth ? PANEL_WIDTH : PANEL_WIDTH / 2f;
when(mNotificationStackScrollLayoutController.getWidth()).thenReturn(nsslWidth);
triggerLayoutChange();
}
private void triggerLayoutChange() {
mLayoutChangeListener.onLayoutChange(
mView,
/* left= */ 0,
/* top= */ 0,
/* right= */ 0,
/* bottom= */ 0,
/* oldLeft= */ 0,
/* oldTop= */ 0,
/* oldRight= */ 0,
/* oldBottom= */ 0
);
}
}

View File

@@ -0,0 +1,255 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.qs.QS
import com.android.systemui.statusbar.policy.FakeConfigurationController
import com.google.common.truth.Expect
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
class LockscreenShadeQsTransitionControllerTest : SysuiTestCase() {
private val configurationController = FakeConfigurationController()
@get:Rule val expect: Expect = Expect.create()
@Mock private lateinit var dumpManager: DumpManager
@Mock private lateinit var qS: QS
private lateinit var controller: LockscreenShadeQsTransitionController
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
setTransitionDistance(TRANSITION_DISTANCE)
setTransitionDelay(TRANSITION_DELAY)
setSquishTransitionDistance(SQUISH_TRANSITION_DISTANCE)
setSquishStartFraction(SQUISH_START_FRACTION)
controller =
LockscreenShadeQsTransitionController(
context,
configurationController,
dumpManager,
qsProvider = { qS }
)
}
@Test
fun qsTransitionFraction_byDefault_returns0() {
assertThat(controller.qsTransitionFraction).isZero()
}
@Test
fun qsTransitionFraction_noStartDelay_returnsBasedOnTransitionDistance() {
setTransitionDelay(0)
setTransitionDistance(100)
controller.dragDownAmount = 25f
expect.that(controller.qsTransitionFraction).isEqualTo(0.25f)
controller.dragDownAmount = 50f
expect.that(controller.qsTransitionFraction).isEqualTo(0.5f)
controller.dragDownAmount = 75f
expect.that(controller.qsTransitionFraction).isEqualTo(0.75f)
controller.dragDownAmount = 100f
expect.that(controller.qsTransitionFraction).isEqualTo(1f)
}
@Test
fun qsTransitionFraction_noStartDelay_returnsValuesBetween0and1() {
setTransitionDelay(0)
setTransitionDistance(100)
controller.dragDownAmount = -500f
expect.that(controller.qsTransitionFraction).isEqualTo(0f)
controller.dragDownAmount = 500f
expect.that(controller.qsTransitionFraction).isEqualTo(1f)
}
@Test
fun qsTransitionFraction_withStartDelay_returnsBasedOnTransitionDistanceAndDelay() {
setTransitionDelay(10)
setTransitionDistance(100)
controller.dragDownAmount = 0f
expect.that(controller.qsTransitionFraction).isEqualTo(0f)
controller.dragDownAmount = 10f
expect.that(controller.qsTransitionFraction).isEqualTo(0f)
controller.dragDownAmount = 25f
expect.that(controller.qsTransitionFraction).isEqualTo(0.15f)
controller.dragDownAmount = 100f
expect.that(controller.qsTransitionFraction).isEqualTo(0.9f)
controller.dragDownAmount = 110f
expect.that(controller.qsTransitionFraction).isEqualTo(1f)
}
@Test
fun qsTransitionFraction_withStartDelay_returnsValuesBetween0and1() {
setTransitionDelay(10)
setTransitionDistance(100)
controller.dragDownAmount = -500f
expect.that(controller.qsTransitionFraction).isEqualTo(0f)
controller.dragDownAmount = 500f
expect.that(controller.qsTransitionFraction).isEqualTo(1f)
}
@Test
fun qsSquishTransitionFraction_byDefault_returnsValueSetFromResource() {
assertThat(controller.qsSquishTransitionFraction).isEqualTo(SQUISH_START_FRACTION)
}
@Test
fun qsSquishTransitionFraction_noStartDelay_startFraction0_returnsBasedOnTransitionDistance() {
setTransitionDelay(0)
setSquishStartFraction(0f)
setSquishTransitionDistance(1000)
controller.dragDownAmount = 250f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.25f)
controller.dragDownAmount = 500f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.5f)
controller.dragDownAmount = 750f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.75f)
controller.dragDownAmount = 1000f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(1f)
}
@Test
fun qsSquishTransitionFraction_startDelay_startFraction0_basedOnTransitionDistanceAndDelay() {
setTransitionDelay(100)
setSquishStartFraction(0f)
setSquishTransitionDistance(1000)
controller.dragDownAmount = 250f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.15f)
controller.dragDownAmount = 500f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.4f)
controller.dragDownAmount = 750f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.65f)
controller.dragDownAmount = 1000f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.9f)
controller.dragDownAmount = 1100f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(1f)
}
@Test
fun qsSquishTransitionFraction_noStartDelay_startFractionSet_returnsBasedOnStartAndDistance() {
setTransitionDelay(0)
setSquishStartFraction(0.5f)
setSquishTransitionDistance(1000)
controller.dragDownAmount = 0f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.5f)
controller.dragDownAmount = 500f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.75f)
controller.dragDownAmount = 1000f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(1f)
}
@Test
fun qsSquishTransitionFraction_startDelay_startFractionSet_basedOnStartAndDistanceAndDelay() {
setTransitionDelay(10)
setSquishStartFraction(0.5f)
setSquishTransitionDistance(100)
controller.dragDownAmount = 0f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.5f)
controller.dragDownAmount = 50f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.7f)
controller.dragDownAmount = 100f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.95f)
controller.dragDownAmount = 110f
expect.that(controller.qsSquishTransitionFraction).isEqualTo(1f)
}
@Test
fun onDragDownAmountChanged_setsValuesOnQS() {
val rawDragAmount = 200f
controller.dragDownAmount = rawDragAmount
verify(qS)
.setTransitionToFullShadeProgress(
/* isTransitioningToFullShade= */ true,
/* transitionFraction= */ controller.qsTransitionFraction,
/* squishinessFraction= */ controller.qsSquishTransitionFraction
)
}
private fun setTransitionDistance(value: Int) {
overrideResource(R.dimen.lockscreen_shade_qs_transition_distance, value)
configurationController.notifyConfigurationChanged()
}
private fun setTransitionDelay(value: Int) {
overrideResource(R.dimen.lockscreen_shade_qs_transition_delay, value)
configurationController.notifyConfigurationChanged()
}
private fun setSquishTransitionDistance(value: Int) {
overrideResource(R.dimen.lockscreen_shade_qs_squish_transition_distance, value)
configurationController.notifyConfigurationChanged()
}
private fun setSquishStartFraction(value: Float) {
overrideResource(R.dimen.lockscreen_shade_qs_squish_start_fraction, value)
configurationController.notifyConfigurationChanged()
}
companion object {
private const val TRANSITION_DELAY = 123
private const val TRANSITION_DISTANCE = 321
private const val SQUISH_START_FRACTION = 0.123f
private const val SQUISH_TRANSITION_DISTANCE = 456
}
}

View File

@@ -1,9 +1,9 @@
package com.android.systemui.statusbar
import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.ExpandHelper
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -78,6 +78,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
@Mock lateinit var qS: QS
@Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller
@Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller
@Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController
@JvmField @Rule val mockito = MockitoJUnit.rule()
private val configurationController = FakeConfigurationController()
@@ -120,7 +121,9 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
context,
configurationController,
dumpManager)
})
},
qsTransitionControllerFactory = { qsTransitionController },
)
whenever(nsslController.view).thenReturn(stackscroller)
whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
transitionController.notificationPanelController = notificationPanelController
@@ -249,7 +252,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(),
anyBoolean(), anyLong())
verify(qS, never()).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
verify(qsTransitionController, never()).dragDownAmount = anyFloat()
}
@Test
@@ -260,7 +263,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(),
anyBoolean(), anyLong())
verify(qS).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
verify(qsTransitionController).dragDownAmount = 10f
verify(depthController).transitionToFullShadeProgress = anyFloat()
}

View File

@@ -59,16 +59,19 @@ import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.FakeConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.wakelock.DelayedWakeLock;
import com.android.systemui.utils.os.FakeHandler;
import com.google.common.truth.Expect;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -86,6 +89,11 @@ import java.util.Map;
@SmallTest
public class ScrimControllerTest extends SysuiTestCase {
@Rule public Expect mExpect = Expect.create();
private final FakeConfigurationController mConfigurationController =
new FakeConfigurationController();
private ScrimController mScrimController;
private ScrimView mScrimBehind;
private ScrimView mNotificationsScrim;
@@ -96,32 +104,19 @@ public class ScrimControllerTest extends SysuiTestCase {
private int mScrimVisibility;
private boolean mAlwaysOnEnabled;
private TestableLooper mLooper;
@Mock
private AlarmManager mAlarmManager;
@Mock
private DozeParameters mDozeParameters;
@Mock
LightBarController mLightBarController;
@Mock
DelayedWakeLock.Builder mDelayedWakeLockBuilder;
@Mock
private DelayedWakeLock mWakeLock;
@Mock
KeyguardStateController mKeyguardStateController;
@Mock
KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
private DockManager mDockManager;
@Mock
private ConfigurationController mConfigurationController;
@Mock
private ScreenOffAnimationController mScreenOffAnimationController;
@Mock
private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock private AlarmManager mAlarmManager;
@Mock private DozeParameters mDozeParameters;
@Mock private LightBarController mLightBarController;
@Mock private DelayedWakeLock.Builder mDelayedWakeLockBuilder;
@Mock private DelayedWakeLock mWakeLock;
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private DockManager mDockManager;
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
// TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@Mock
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private static class AnimatorListener implements Animator.AnimatorListener {
private int mNumStarts;
@@ -1449,6 +1444,41 @@ public class ScrimControllerTest extends SysuiTestCase {
assertThat(mNotificationsScrim.getViewAlpha()).isEqualTo(notifProgress);
}
@Test
public void notificationAlpha_qsNotClipped_alphaMatchesNotificationExpansionProgress() {
mScrimController.setClipsQsScrim(false);
mScrimController.transitionTo(ScrimState.KEYGUARD);
// RawPanelExpansion and QsExpansion are usually used for the notification alpha
// calculation.
// Here we set them to non-zero values explicitly to make sure that in not clipped mode,
// they are not being used even when set.
mScrimController.setRawPanelExpansionFraction(0.5f);
mScrimController.setQsPosition(/* expansionFraction= */ 0.5f, /* qsPanelBottomY= */ 500);
finishAnimationsImmediately();
float progress = 0.5f;
float notificationExpansionProgress = 0f;
mScrimController.setTransitionToFullShadeProgress(progress, notificationExpansionProgress);
mExpect.that(mNotificationsScrim.getViewAlpha()).isEqualTo(notificationExpansionProgress);
notificationExpansionProgress = 0.25f;
mScrimController.setTransitionToFullShadeProgress(progress, notificationExpansionProgress);
mExpect.that(mNotificationsScrim.getViewAlpha()).isEqualTo(notificationExpansionProgress);
notificationExpansionProgress = 0.5f;
mScrimController.setTransitionToFullShadeProgress(progress, notificationExpansionProgress);
mExpect.that(mNotificationsScrim.getViewAlpha()).isEqualTo(notificationExpansionProgress);
notificationExpansionProgress = 0.75f;
mScrimController.setTransitionToFullShadeProgress(progress, notificationExpansionProgress);
mExpect.that(mNotificationsScrim.getViewAlpha()).isEqualTo(notificationExpansionProgress);
notificationExpansionProgress = 1f;
mScrimController.setTransitionToFullShadeProgress(progress, notificationExpansionProgress);
mExpect.that(mNotificationsScrim.getViewAlpha()).isEqualTo(notificationExpansionProgress);
}
@Test
public void setNotificationsOverScrollAmount_setsTranslationYOnNotificationsScrim() {
int overScrollAmount = 10;