Merge "[Large screens][Motion] Improve expansion timing on lockscreen" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d9ef4d8ed7
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user