Merge "[Large screens][Motion] Improve expansion timing on lockscreen" into tm-qpr-dev am: d9ef4d8ed7
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19394627 Change-Id: Ib9e2abb37db7af56e733c6eec9e2296fcfcb08c9 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -16,6 +16,8 @@ package com.android.systemui.plugins.qs;
|
|||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.FloatRange;
|
||||||
|
|
||||||
import com.android.systemui.plugins.FragmentBase;
|
import com.android.systemui.plugins.FragmentBase;
|
||||||
import com.android.systemui.plugins.annotations.DependsOn;
|
import com.android.systemui.plugins.annotations.DependsOn;
|
||||||
import com.android.systemui.plugins.annotations.ProvidesInterface;
|
import com.android.systemui.plugins.annotations.ProvidesInterface;
|
||||||
@@ -107,10 +109,24 @@ public interface QS extends FragmentBase {
|
|||||||
void setInSplitShade(boolean shouldTranslate);
|
void setInSplitShade(boolean shouldTranslate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the amount of pixels we have currently dragged down if we're transitioning to the full
|
* Sets the progress of the transition to full shade on the lockscreen.
|
||||||
* shade. 0.0f means we're not transitioning yet.
|
*
|
||||||
|
* @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.
|
* 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) {}
|
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
|
* Callback for when QSPanel container is scrolled
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -49,54 +49,29 @@
|
|||||||
|
|
||||||
<dimen name="status_view_margin_horizontal">8dp</dimen>
|
<dimen name="status_view_margin_horizontal">8dp</dimen>
|
||||||
|
|
||||||
<!-- Distance that the full shade transition takes in order to complete by tapping on a button
|
<!-- Lockscreen shade transition values -->
|
||||||
like "expand". -->
|
|
||||||
<dimen name="lockscreen_shade_transition_by_tap_distance">200dp</dimen>
|
<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>
|
<dimen name="lockscreen_shade_full_transition_distance">200dp</dimen>
|
||||||
|
<!-- Media transition distance = qs delay + qs distance -->
|
||||||
<!-- Distance that the full shade transition takes in order for media to fully transition to
|
<dimen name="lockscreen_shade_media_transition_distance">129.28dp</dimen>
|
||||||
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) -->
|
|
||||||
<dimen name="lockscreen_shade_scrim_transition_distance">80dp</dimen>
|
<dimen name="lockscreen_shade_scrim_transition_distance">80dp</dimen>
|
||||||
|
|
||||||
<!-- The notifications scrim transition should start when the other scrims' transition is at
|
<!-- The notifications scrim transition should start when the other scrims' transition is at
|
||||||
95%. -->
|
95%. -->
|
||||||
<dimen name="lockscreen_shade_notifications_scrim_transition_delay">76dp</dimen>
|
<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'
|
<!-- 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>
|
<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>
|
<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>
|
<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_notifications_scrim_transition_distance</dimen>
|
||||||
<!-- Distance that the full shade transition takes in order for the Quick Settings to fully
|
<dimen name="lockscreen_shade_qs_transition_delay">@dimen/lockscreen_shade_notifications_scrim_transition_delay</dimen>
|
||||||
fade and expand. -->
|
<dimen name="lockscreen_shade_qs_squish_transition_distance">@dimen/lockscreen_shade_qs_transition_distance</dimen>
|
||||||
<dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_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>
|
||||||
<!-- Distance that the full shade transition takes in order for depth of the wallpaper to fully
|
<!-- On split-shade, there should be no depth effect, so setting the value to 0. -->
|
||||||
change.
|
|
||||||
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>
|
<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>
|
<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_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>
|
<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
|
<!-- 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_dialog_width">472dp</dimen>
|
||||||
|
|
||||||
<dimen name="large_screen_shade_header_height">42dp</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>
|
</resources>
|
||||||
|
|||||||
@@ -1212,6 +1212,17 @@
|
|||||||
fade and expand. -->
|
fade and expand. -->
|
||||||
<dimen name="lockscreen_shade_qs_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
|
<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
|
<!-- Distance that the full shade transition takes in order for depth of the wallpaper to fully
|
||||||
change. -->
|
change. -->
|
||||||
<dimen name="lockscreen_shade_depth_controller_transition_distance">@dimen/lockscreen_shade_full_transition_distance</dimen>
|
<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.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
|
|
||||||
|
import androidx.annotation.FloatRange;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.lifecycle.Lifecycle;
|
import androidx.lifecycle.Lifecycle;
|
||||||
@@ -166,6 +167,13 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
|||||||
// visible;
|
// visible;
|
||||||
private boolean mQsVisible;
|
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
|
@Inject
|
||||||
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
|
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
|
||||||
QSTileHost qsTileHost,
|
QSTileHost qsTileHost,
|
||||||
@@ -571,15 +579,17 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTransitionToFullShadeAmount(float pxAmount, float progress) {
|
public void setTransitionToFullShadeProgress(
|
||||||
boolean isTransitioningToFullShade = pxAmount > 0;
|
boolean isTransitioningToFullShade,
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) float qsTransitionFraction,
|
||||||
|
@FloatRange(from = 0.0, to = 1.0) float qsSquishinessFraction) {
|
||||||
if (isTransitioningToFullShade != mTransitioningToFullShade) {
|
if (isTransitioningToFullShade != mTransitioningToFullShade) {
|
||||||
mTransitioningToFullShade = isTransitioningToFullShade;
|
mTransitioningToFullShade = isTransitioningToFullShade;
|
||||||
updateShowCollapsedOnKeyguard();
|
updateShowCollapsedOnKeyguard();
|
||||||
}
|
}
|
||||||
mFullShadeProgress = progress;
|
mFullShadeProgress = qsTransitionFraction;
|
||||||
setQsExpansion(mLastQSExpansion, mLastPanelFraction, mLastHeaderTranslation,
|
setQsExpansion(mLastQSExpansion, mLastPanelFraction, mLastHeaderTranslation,
|
||||||
isTransitioningToFullShade ? progress : mSquishinessFraction);
|
isTransitioningToFullShade ? qsSquishinessFraction : mSquishinessFraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -597,13 +607,17 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
|||||||
+ mHeader.getPaddingBottom();
|
+ mHeader.getPaddingBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIsNotificationPanelFullWidth(boolean isFullWidth) {
|
||||||
|
mIsNotificationPanelFullWidth = isFullWidth;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setQsExpansion(float expansion, float panelExpansionFraction,
|
public void setQsExpansion(float expansion, float panelExpansionFraction,
|
||||||
float proposedTranslation, float squishinessFraction) {
|
float proposedTranslation, float squishinessFraction) {
|
||||||
float headerTranslation = mTransitioningToFullShade ? 0 : proposedTranslation;
|
float headerTranslation = mTransitioningToFullShade ? 0 : proposedTranslation;
|
||||||
float alphaProgress = mTransitioningToFullShade || mState == StatusBarState.KEYGUARD
|
float alphaProgress = calculateAlphaProgress(panelExpansionFraction);
|
||||||
? mFullShadeProgress : panelExpansionFraction;
|
setAlphaAnimationProgress(alphaProgress);
|
||||||
setAlphaAnimationProgress(mInSplitShade ? alphaProgress : 1);
|
|
||||||
mContainer.setExpansion(expansion);
|
mContainer.setExpansion(expansion);
|
||||||
final float translationScaleY = (mInSplitShade
|
final float translationScaleY = (mInSplitShade
|
||||||
? 1 : QSAnimator.SHORT_PARALLAX_AMOUNT) * (expansion - 1);
|
? 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) {
|
} else if (progress > 0 && view.getVisibility() != View.VISIBLE) {
|
||||||
view.setVisibility((View.VISIBLE));
|
view.setVisibility((View.VISIBLE));
|
||||||
}
|
}
|
||||||
float alpha = mQSPanelController.isBouncerInTransit()
|
view.setAlpha(interpolateAlphaAnimationProgress(progress));
|
||||||
? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(progress)
|
}
|
||||||
: ShadeInterpolation.getContentAlpha(progress);
|
|
||||||
view.setAlpha(alpha);
|
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() {
|
private void updateQsBounds() {
|
||||||
|
|||||||
@@ -1326,6 +1326,9 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
mIsFullWidth = isFullWidth;
|
mIsFullWidth = isFullWidth;
|
||||||
mScrimController.setClipsQsScrim(isFullWidth);
|
mScrimController.setClipsQsScrim(isFullWidth);
|
||||||
mNotificationStackScrollLayoutController.setIsFullWidth(isFullWidth);
|
mNotificationStackScrollLayoutController.setIsFullWidth(isFullWidth);
|
||||||
|
if (mQs != null) {
|
||||||
|
mQs.setIsNotificationPanelFullWidth(isFullWidth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) {
|
private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) {
|
||||||
@@ -2434,8 +2437,8 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
final float squishiness;
|
final float squishiness;
|
||||||
if ((mQsExpandImmediate || mQsExpanded) && !mSplitShadeEnabled) {
|
if ((mQsExpandImmediate || mQsExpanded) && !mSplitShadeEnabled) {
|
||||||
squishiness = 1;
|
squishiness = 1;
|
||||||
} else if (mLockscreenShadeTransitionController.getQSDragProgress() > 0) {
|
} else if (mTransitioningToFullShadeProgress > 0.0f) {
|
||||||
squishiness = mLockscreenShadeTransitionController.getQSDragProgress();
|
squishiness = mLockscreenShadeTransitionController.getQsSquishTransitionFraction();
|
||||||
} else {
|
} else {
|
||||||
squishiness = mNotificationStackScrollLayoutController
|
squishiness = mNotificationStackScrollLayoutController
|
||||||
.getNotificationSquishinessFraction();
|
.getNotificationSquishinessFraction();
|
||||||
@@ -3763,6 +3766,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
mQs.setHeaderClickable(isQsExpansionEnabled());
|
mQs.setHeaderClickable(isQsExpansionEnabled());
|
||||||
mQs.setOverscrolling(mStackScrollerOverscrolling);
|
mQs.setOverscrolling(mStackScrollerOverscrolling);
|
||||||
mQs.setInSplitShade(mSplitShadeEnabled);
|
mQs.setInSplitShade(mSplitShadeEnabled);
|
||||||
|
mQs.setIsNotificationPanelFullWidth(mIsFullWidth);
|
||||||
|
|
||||||
// recompute internal state when qspanel height changes
|
// recompute internal state when qspanel height changes
|
||||||
mQs.getView().addOnLayoutChangeListener(
|
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.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewConfiguration
|
import android.view.ViewConfiguration
|
||||||
|
import androidx.annotation.FloatRange
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import com.android.systemui.Dumpable
|
import com.android.systemui.Dumpable
|
||||||
import com.android.systemui.ExpandHelper
|
import com.android.systemui.ExpandHelper
|
||||||
@@ -68,7 +69,8 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
wakefulnessLifecycle: WakefulnessLifecycle,
|
wakefulnessLifecycle: WakefulnessLifecycle,
|
||||||
configurationController: ConfigurationController,
|
configurationController: ConfigurationController,
|
||||||
falsingManager: FalsingManager,
|
falsingManager: FalsingManager,
|
||||||
dumpManager: DumpManager
|
dumpManager: DumpManager,
|
||||||
|
qsTransitionControllerFactory: LockscreenShadeQsTransitionController.Factory,
|
||||||
) : Dumpable {
|
) : Dumpable {
|
||||||
private var pulseHeight: Float = 0f
|
private var pulseHeight: Float = 0f
|
||||||
@get:VisibleForTesting
|
@get:VisibleForTesting
|
||||||
@@ -119,12 +121,6 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
private var notificationShelfTransitionDistance = 0
|
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
|
* Distance that the full shade transition takes in order for depth of the wallpaper to fully
|
||||||
* change.
|
* change.
|
||||||
@@ -188,6 +184,18 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
keyguardTransitionControllerFactory.create(notificationPanelController)
|
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
|
* [LockScreenShadeOverScroller] property that delegates to either
|
||||||
* [SingleShadeLockScreenOverScroller] or [SplitShadeLockScreenOverScroller].
|
* [SingleShadeLockScreenOverScroller] or [SplitShadeLockScreenOverScroller].
|
||||||
@@ -242,8 +250,6 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
R.dimen.lockscreen_shade_transition_by_tap_distance)
|
R.dimen.lockscreen_shade_transition_by_tap_distance)
|
||||||
notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
|
notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
|
||||||
R.dimen.lockscreen_shade_notif_shelf_transition_distance)
|
R.dimen.lockscreen_shade_notif_shelf_transition_distance)
|
||||||
qsTransitionDistance = context.resources.getDimensionPixelSize(
|
|
||||||
R.dimen.lockscreen_shade_qs_transition_distance)
|
|
||||||
depthControllerTransitionDistance = context.resources.getDimensionPixelSize(
|
depthControllerTransitionDistance = context.resources.getDimensionPixelSize(
|
||||||
R.dimen.lockscreen_shade_depth_controller_transition_distance)
|
R.dimen.lockscreen_shade_depth_controller_transition_distance)
|
||||||
udfpsTransitionDistance = context.resources.getDimensionPixelSize(
|
udfpsTransitionDistance = context.resources.getDimensionPixelSize(
|
||||||
@@ -411,8 +417,7 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
MathUtils.saturate(dragDownAmount / notificationShelfTransitionDistance)
|
MathUtils.saturate(dragDownAmount / notificationShelfTransitionDistance)
|
||||||
nsslController.setTransitionToFullShadeAmount(fractionToShade)
|
nsslController.setTransitionToFullShadeAmount(fractionToShade)
|
||||||
|
|
||||||
qSDragProgress = MathUtils.saturate(dragDownAmount / qsTransitionDistance)
|
qsTransitionController.dragDownAmount = value
|
||||||
qS.setTransitionToFullShadeAmount(field, qSDragProgress)
|
|
||||||
|
|
||||||
notificationPanelController.setTransitionToFullShadeAmount(field,
|
notificationPanelController.setTransitionToFullShadeAmount(field,
|
||||||
false /* animate */, 0 /* delay */)
|
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) {
|
private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
|
||||||
if (depthControllerTransitionDistance == 0) { // split shade
|
if (depthControllerTransitionDistance == 0) { // split shade
|
||||||
depthController.transitionToFullShadeProgress = 0f
|
depthController.transitionToFullShadeProgress = 0f
|
||||||
@@ -704,7 +703,6 @@ class LockscreenShadeTransitionController @Inject constructor(
|
|||||||
it.println("pulseHeight: $pulseHeight")
|
it.println("pulseHeight: $pulseHeight")
|
||||||
it.println("useSplitShade: $useSplitShade")
|
it.println("useSplitShade: $useSplitShade")
|
||||||
it.println("dragDownAmount: $dragDownAmount")
|
it.println("dragDownAmount: $dragDownAmount")
|
||||||
it.println("qSDragProgress: $qSDragProgress")
|
|
||||||
it.println("isDragDownAnywhereEnabled: $isDragDownAnywhereEnabled")
|
it.println("isDragDownAnywhereEnabled: $isDragDownAnywhereEnabled")
|
||||||
it.println("isFalsingCheckNeeded: $isFalsingCheckNeeded")
|
it.println("isFalsingCheckNeeded: $isFalsingCheckNeeded")
|
||||||
it.println("isWakingToShadeLocked: $isWakingToShadeLocked")
|
it.println("isWakingToShadeLocked: $isWakingToShadeLocked")
|
||||||
|
|||||||
@@ -259,11 +259,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
private boolean mKeyguardOccluded;
|
private boolean mKeyguardOccluded;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ScrimController(LightBarController lightBarController, DozeParameters dozeParameters,
|
public ScrimController(
|
||||||
AlarmManager alarmManager, KeyguardStateController keyguardStateController,
|
LightBarController lightBarController,
|
||||||
DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
|
DozeParameters dozeParameters,
|
||||||
KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
|
AlarmManager alarmManager,
|
||||||
ConfigurationController configurationController, @Main Executor mainExecutor,
|
KeyguardStateController keyguardStateController,
|
||||||
|
DelayedWakeLock.Builder delayedWakeLockBuilder,
|
||||||
|
Handler handler,
|
||||||
|
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||||
|
DockManager dockManager,
|
||||||
|
ConfigurationController configurationController,
|
||||||
|
@Main Executor mainExecutor,
|
||||||
ScreenOffAnimationController screenOffAnimationController,
|
ScreenOffAnimationController screenOffAnimationController,
|
||||||
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
|
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
|
||||||
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
|
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
|
||||||
@@ -826,20 +832,15 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
mBehindTint = Color.BLACK;
|
mBehindTint = Color.BLACK;
|
||||||
} else {
|
} else {
|
||||||
mBehindAlpha = behindAlpha;
|
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
|
// going from KEYGUARD to SHADE_LOCKED state
|
||||||
mNotificationsAlpha = getInterpolatedFraction();
|
mNotificationsAlpha = getInterpolatedFraction();
|
||||||
} else {
|
} else {
|
||||||
mNotificationsAlpha = Math.max(1.0f - getInterpolatedFraction(), mQsExpansion);
|
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();
|
mNotificationsTint = mState.getNotifTint();
|
||||||
mBehindTint = behindTint;
|
mBehindTint = behindTint;
|
||||||
}
|
}
|
||||||
@@ -1430,6 +1431,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
pw.print(mNotificationsAlpha);
|
pw.print(mNotificationsAlpha);
|
||||||
pw.print(" tint=0x");
|
pw.print(" tint=0x");
|
||||||
pw.println(Integer.toHexString(mNotificationsScrim.getTint()));
|
pw.println(Integer.toHexString(mNotificationsScrim.getTint()));
|
||||||
|
pw.print(" expansionProgress=");
|
||||||
|
pw.println(mTransitionToLockScreenFullShadeNotificationsProgress);
|
||||||
|
|
||||||
pw.print(" mTracking=");
|
pw.print(" mTracking=");
|
||||||
pw.println(mTracking);
|
pw.println(mTracking);
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
@Mock private QSPanel.QSTileLayout mQQsTileLayout;
|
@Mock private QSPanel.QSTileLayout mQQsTileLayout;
|
||||||
@Mock private QSAnimator mQSAnimator;
|
@Mock private QSAnimator mQSAnimator;
|
||||||
@Mock private StatusBarStateController mStatusBarStateController;
|
@Mock private StatusBarStateController mStatusBarStateController;
|
||||||
|
@Mock private QSSquishinessController mSquishinessController;
|
||||||
private View mQsFragmentView;
|
private View mQsFragmentView;
|
||||||
|
|
||||||
public QSFragmentTest() {
|
public QSFragmentTest() {
|
||||||
@@ -139,13 +140,15 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transitionToFullShade_inSplitShade_setsAlphaBasedOnProgress() {
|
public void transitionToFullShade_setsAlphaUsingShadeInterpolator() {
|
||||||
QSFragment fragment = resumeAndGetFragment();
|
QSFragment fragment = resumeAndGetFragment();
|
||||||
enableSplitShade();
|
setStatusBarState(StatusBarState.SHADE);
|
||||||
int transitionPxAmount = 123;
|
boolean isTransitioningToFullShade = true;
|
||||||
float transitionProgress = 0.5f;
|
float transitionProgress = 0.5f;
|
||||||
|
float squishinessFraction = 0.5f;
|
||||||
|
|
||||||
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
|
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
|
||||||
|
squishinessFraction);
|
||||||
|
|
||||||
assertThat(mQsFragmentView.getAlpha())
|
assertThat(mQsFragmentView.getAlpha())
|
||||||
.isEqualTo(ShadeInterpolation.getContentAlpha(transitionProgress));
|
.isEqualTo(ShadeInterpolation.getContentAlpha(transitionProgress));
|
||||||
@@ -153,31 +156,32 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
transitionToFullShade_inSplitShade_onKeyguard_bouncerNotActive_usesShadeInterpolator() {
|
transitionToFullShade_onKeyguard_noBouncer_setsAlphaUsingLinearInterpolator() {
|
||||||
QSFragment fragment = resumeAndGetFragment();
|
QSFragment fragment = resumeAndGetFragment();
|
||||||
enableSplitShade();
|
|
||||||
setStatusBarState(StatusBarState.KEYGUARD);
|
setStatusBarState(StatusBarState.KEYGUARD);
|
||||||
when(mQSPanelController.isBouncerInTransit()).thenReturn(false);
|
when(mQSPanelController.isBouncerInTransit()).thenReturn(false);
|
||||||
int transitionPxAmount = 123;
|
boolean isTransitioningToFullShade = true;
|
||||||
float transitionProgress = 0.5f;
|
float transitionProgress = 0.5f;
|
||||||
|
float squishinessFraction = 0.5f;
|
||||||
|
|
||||||
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
|
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
|
||||||
|
squishinessFraction);
|
||||||
|
|
||||||
assertThat(mQsFragmentView.getAlpha())
|
assertThat(mQsFragmentView.getAlpha()).isEqualTo(transitionProgress);
|
||||||
.isEqualTo(ShadeInterpolation.getContentAlpha(transitionProgress));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
transitionToFullShade_inSplitShade_onKeyguard_bouncerActive_usesBouncerInterpolator() {
|
transitionToFullShade_onKeyguard_bouncerActive_setsAlphaUsingBouncerInterpolator() {
|
||||||
QSFragment fragment = resumeAndGetFragment();
|
QSFragment fragment = resumeAndGetFragment();
|
||||||
enableSplitShade();
|
|
||||||
setStatusBarState(StatusBarState.KEYGUARD);
|
setStatusBarState(StatusBarState.KEYGUARD);
|
||||||
when(mQSPanelController.isBouncerInTransit()).thenReturn(true);
|
when(mQSPanelController.isBouncerInTransit()).thenReturn(true);
|
||||||
int transitionPxAmount = 123;
|
boolean isTransitioningToFullShade = true;
|
||||||
float transitionProgress = 0.5f;
|
float transitionProgress = 0.5f;
|
||||||
|
float squishinessFraction = 0.5f;
|
||||||
|
|
||||||
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
|
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
|
||||||
|
squishinessFraction);
|
||||||
|
|
||||||
assertThat(mQsFragmentView.getAlpha())
|
assertThat(mQsFragmentView.getAlpha())
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
@@ -186,27 +190,43 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transitionToFullShade_notInSplitShade_alwaysSetsAlphaTo1() {
|
public void transitionToFullShade_inFullWidth_alwaysSetsAlphaTo1() {
|
||||||
QSFragment fragment = resumeAndGetFragment();
|
QSFragment fragment = resumeAndGetFragment();
|
||||||
disableSplitShade();
|
fragment.setIsNotificationPanelFullWidth(true);
|
||||||
|
|
||||||
int transitionPxAmount = 12;
|
boolean isTransitioningToFullShade = true;
|
||||||
float transitionProgress = 0.1f;
|
float transitionProgress = 0.1f;
|
||||||
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
|
float squishinessFraction = 0.5f;
|
||||||
|
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
|
||||||
|
squishinessFraction);
|
||||||
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
||||||
|
|
||||||
transitionPxAmount = 123;
|
|
||||||
transitionProgress = 0.5f;
|
transitionProgress = 0.5f;
|
||||||
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
|
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
|
||||||
|
squishinessFraction);
|
||||||
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
||||||
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
||||||
|
|
||||||
transitionPxAmount = 234;
|
|
||||||
transitionProgress = 0.7f;
|
transitionProgress = 0.7f;
|
||||||
fragment.setTransitionToFullShadeAmount(transitionPxAmount, transitionProgress);
|
fragment.setTransitionToFullShadeProgress(isTransitioningToFullShade, transitionProgress,
|
||||||
|
squishinessFraction);
|
||||||
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
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
|
@Test
|
||||||
public void setQsExpansion_inSplitShade_setsFooterActionsExpansion_basedOnPanelExpFraction() {
|
public void setQsExpansion_inSplitShade_setsFooterActionsExpansion_basedOnPanelExpFraction() {
|
||||||
// Random test values without any meaning. They just have to be different from each other.
|
// 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())
|
when(mQsFragmentComponent.getQSFooterActionController())
|
||||||
.thenReturn(mQSFooterActionController);
|
.thenReturn(mQSFooterActionController);
|
||||||
when(mQsFragmentComponent.getQSAnimator()).thenReturn(mQSAnimator);
|
when(mQsFragmentComponent.getQSAnimator()).thenReturn(mQSAnimator);
|
||||||
|
when(mQsFragmentComponent.getQSSquishinessController()).thenReturn(mSquishinessController);
|
||||||
}
|
}
|
||||||
|
|
||||||
private QSFragment getFragment() {
|
private QSFragment getFragment() {
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.annotation.IdRes;
|
import android.annotation.IdRes;
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
@@ -57,6 +56,7 @@ import android.util.DisplayMetrics;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewParent;
|
import android.view.ViewParent;
|
||||||
import android.view.ViewPropertyAnimator;
|
import android.view.ViewPropertyAnimator;
|
||||||
import android.view.ViewStub;
|
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.FalsingManager;
|
||||||
import com.android.systemui.plugins.qs.QS;
|
import com.android.systemui.plugins.qs.QS;
|
||||||
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
|
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController;
|
||||||
|
import com.android.systemui.qs.QSFragment;
|
||||||
import com.android.systemui.screenrecord.RecordingController;
|
import com.android.systemui.screenrecord.RecordingController;
|
||||||
import com.android.systemui.shade.transition.ShadeTransitionController;
|
import com.android.systemui.shade.transition.ShadeTransitionController;
|
||||||
import com.android.systemui.statusbar.CommandQueue;
|
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.policy.KeyguardUserSwitcherView;
|
||||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||||
import com.android.systemui.unfold.SysUIUnfoldComponent;
|
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.FakeSystemClock;
|
||||||
import com.android.systemui.util.time.SystemClock;
|
import com.android.systemui.util.time.SystemClock;
|
||||||
import com.android.systemui.wallet.controller.QuickAccessWalletController;
|
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 SPLIT_SHADE_FULL_TRANSITION_DISTANCE = 400;
|
||||||
private static final int NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE = 50;
|
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
|
@Mock private CentralSurfaces mCentralSurfaces;
|
||||||
private CentralSurfaces mCentralSurfaces;
|
@Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
|
||||||
@Mock
|
@Mock private KeyguardBottomAreaView mKeyguardBottomArea;
|
||||||
private NotificationStackScrollLayout mNotificationStackScrollLayout;
|
@Mock private KeyguardBottomAreaViewController mKeyguardBottomAreaViewController;
|
||||||
@Mock
|
@Mock private KeyguardBottomAreaView mQsFrame;
|
||||||
private KeyguardBottomAreaView mKeyguardBottomArea;
|
@Mock private NotificationIconAreaController mNotificationAreaController;
|
||||||
@Mock
|
@Mock private HeadsUpManagerPhone mHeadsUpManager;
|
||||||
private KeyguardBottomAreaViewController mKeyguardBottomAreaViewController;
|
@Mock private NotificationShelfController mNotificationShelfController;
|
||||||
@Mock
|
@Mock private KeyguardStatusBarView mKeyguardStatusBar;
|
||||||
private KeyguardBottomAreaView mQsFrame;
|
@Mock private KeyguardUserSwitcherView mUserSwitcherView;
|
||||||
private KeyguardStatusView mKeyguardStatusView;
|
@Mock private ViewStub mUserSwitcherStubView;
|
||||||
@Mock
|
@Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback;
|
||||||
private NotificationIconAreaController mNotificationAreaController;
|
@Mock private KeyguardUpdateMonitor mUpdateMonitor;
|
||||||
@Mock
|
@Mock private KeyguardBypassController mKeyguardBypassController;
|
||||||
private HeadsUpManagerPhone mHeadsUpManager;
|
@Mock private DozeParameters mDozeParameters;
|
||||||
@Mock
|
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
|
||||||
private NotificationShelfController mNotificationShelfController;
|
@Mock private NotificationPanelView mView;
|
||||||
@Mock
|
@Mock private LayoutInflater mLayoutInflater;
|
||||||
private KeyguardStatusBarView mKeyguardStatusBar;
|
@Mock private FeatureFlags mFeatureFlags;
|
||||||
@Mock
|
@Mock private DynamicPrivacyController mDynamicPrivacyController;
|
||||||
private KeyguardUserSwitcherView mUserSwitcherView;
|
@Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
|
||||||
@Mock
|
@Mock private KeyguardStateController mKeyguardStateController;
|
||||||
private ViewStub mUserSwitcherStubView;
|
@Mock private DozeLog mDozeLog;
|
||||||
@Mock
|
@Mock private ShadeLogger mShadeLog;
|
||||||
private HeadsUpTouchHelper.Callback mHeadsUpCallback;
|
@Mock private CommandQueue mCommandQueue;
|
||||||
@Mock
|
@Mock private VibratorHelper mVibratorHelper;
|
||||||
private KeyguardUpdateMonitor mUpdateMonitor;
|
@Mock private LatencyTracker mLatencyTracker;
|
||||||
@Mock
|
@Mock private PowerManager mPowerManager;
|
||||||
private KeyguardBypassController mKeyguardBypassController;
|
@Mock private AccessibilityManager mAccessibilityManager;
|
||||||
@Mock
|
@Mock private MetricsLogger mMetricsLogger;
|
||||||
private DozeParameters mDozeParameters;
|
@Mock private Resources mResources;
|
||||||
@Mock
|
@Mock private Configuration mConfiguration;
|
||||||
private ScreenOffAnimationController mScreenOffAnimationController;
|
@Mock private KeyguardClockSwitch mKeyguardClockSwitch;
|
||||||
@Mock
|
@Mock private MediaHierarchyManager mMediaHiearchyManager;
|
||||||
private NotificationPanelView mView;
|
@Mock private ConversationNotificationManager mConversationNotificationManager;
|
||||||
@Mock
|
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||||
private LayoutInflater mLayoutInflater;
|
@Mock private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
|
||||||
@Mock
|
@Mock private KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
|
||||||
private FeatureFlags mFeatureFlags;
|
@Mock private KeyguardQsUserSwitchComponent mKeyguardQsUserSwitchComponent;
|
||||||
@Mock
|
@Mock private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
|
||||||
private DynamicPrivacyController mDynamicPrivacyController;
|
@Mock private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
|
||||||
@Mock
|
@Mock private KeyguardUserSwitcherComponent mKeyguardUserSwitcherComponent;
|
||||||
private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
|
@Mock private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
|
||||||
@Mock
|
@Mock private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
|
||||||
private KeyguardStateController mKeyguardStateController;
|
@Mock private KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
|
||||||
@Mock
|
@Mock private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
|
||||||
private DozeLog mDozeLog;
|
@Mock private KeyguardClockSwitchController mKeyguardClockSwitchController;
|
||||||
@Mock
|
@Mock private KeyguardStatusViewController mKeyguardStatusViewController;
|
||||||
private ShadeLogger mShadeLog;
|
@Mock private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
|
||||||
@Mock
|
@Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
|
||||||
private CommandQueue mCommandQueue;
|
@Mock private NotificationShadeDepthController mNotificationShadeDepthController;
|
||||||
@Mock
|
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
||||||
private VibratorHelper mVibratorHelper;
|
@Mock private AuthController mAuthController;
|
||||||
@Mock
|
@Mock private ScrimController mScrimController;
|
||||||
private LatencyTracker mLatencyTracker;
|
@Mock private MediaDataManager mMediaDataManager;
|
||||||
@Mock
|
@Mock private AmbientState mAmbientState;
|
||||||
private PowerManager mPowerManager;
|
@Mock private UserManager mUserManager;
|
||||||
@Mock
|
@Mock private UiEventLogger mUiEventLogger;
|
||||||
private AccessibilityManager mAccessibilityManager;
|
@Mock private LockIconViewController mLockIconViewController;
|
||||||
@Mock
|
@Mock private KeyguardMediaController mKeyguardMediaController;
|
||||||
private MetricsLogger mMetricsLogger;
|
@Mock private PrivacyDotViewController mPrivacyDotViewController;
|
||||||
@Mock
|
@Mock private NavigationModeController mNavigationModeController;
|
||||||
private ActivityManager mActivityManager;
|
@Mock private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController;
|
||||||
@Mock
|
@Mock private ContentResolver mContentResolver;
|
||||||
private Resources mResources;
|
@Mock private TapAgainViewController mTapAgainViewController;
|
||||||
@Mock
|
@Mock private KeyguardIndicationController mKeyguardIndicationController;
|
||||||
private Configuration mConfiguration;
|
@Mock private FragmentService mFragmentService;
|
||||||
private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
|
@Mock private FragmentHostManager mFragmentHostManager;
|
||||||
@Mock
|
@Mock private QuickAccessWalletController mQuickAccessWalletController;
|
||||||
private KeyguardClockSwitch mKeyguardClockSwitch;
|
@Mock private QRCodeScannerController mQrCodeScannerController;
|
||||||
private NotificationPanelViewController.TouchHandler mTouchHandler;
|
@Mock private NotificationRemoteInputManager mNotificationRemoteInputManager;
|
||||||
private ConfigurationController mConfigurationController;
|
@Mock private RecordingController mRecordingController;
|
||||||
@Mock
|
@Mock private ControlsComponent mControlsComponent;
|
||||||
private MediaHierarchyManager mMediaHiearchyManager;
|
@Mock private LockscreenGestureLogger mLockscreenGestureLogger;
|
||||||
@Mock
|
@Mock private DumpManager mDumpManager;
|
||||||
private ConversationNotificationManager mConversationNotificationManager;
|
@Mock private InteractionJankMonitor mInteractionJankMonitor;
|
||||||
@Mock
|
@Mock private NotificationsQSContainerController mNotificationsQSContainerController;
|
||||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
@Mock private QsFrameTranslateController mQsFrameTranslateController;
|
||||||
@Mock
|
@Mock private StatusBarWindowStateController mStatusBarWindowStateController;
|
||||||
private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
|
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||||
@Mock
|
@Mock private NotificationShadeWindowController mNotificationShadeWindowController;
|
||||||
private KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
|
@Mock private SysUiState mSysUiState;
|
||||||
@Mock
|
@Mock private NotificationListContainer mNotificationListContainer;
|
||||||
private KeyguardQsUserSwitchComponent mKeyguardQsUserSwitchComponent;
|
@Mock private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
|
||||||
@Mock
|
@Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
|
||||||
private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
|
@Mock private ShadeTransitionController mShadeTransitionController;
|
||||||
@Mock
|
@Mock private QS mQs;
|
||||||
private KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
|
@Mock private QSFragment mQSFragment;
|
||||||
@Mock
|
@Mock private ViewGroup mQsHeader;
|
||||||
private KeyguardUserSwitcherComponent mKeyguardUserSwitcherComponent;
|
@Mock private ViewParent mViewParent;
|
||||||
@Mock
|
@Mock private ViewTreeObserver mViewTreeObserver;
|
||||||
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 KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
|
@Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
|
||||||
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
|
@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 SysuiStatusBarStateController mStatusBarStateController;
|
||||||
private NotificationPanelViewController mNotificationPanelViewController;
|
private NotificationPanelViewController mNotificationPanelViewController;
|
||||||
private View.AccessibilityDelegate mAccessibiltyDelegate;
|
private View.AccessibilityDelegate mAccessibiltyDelegate;
|
||||||
private NotificationsQuickSettingsContainer mNotificationContainerParent;
|
private NotificationsQuickSettingsContainer mNotificationContainerParent;
|
||||||
private List<View.OnAttachStateChangeListener> mOnAttachStateChangeListeners;
|
private List<View.OnAttachStateChangeListener> mOnAttachStateChangeListeners;
|
||||||
private FalsingManagerFake mFalsingManager = new FalsingManagerFake();
|
|
||||||
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
|
||||||
private Handler mMainHandler;
|
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 =
|
private final PanelExpansionStateManager mPanelExpansionStateManager =
|
||||||
new PanelExpansionStateManager();
|
new PanelExpansionStateManager();
|
||||||
private SystemClock mSystemClock;
|
private FragmentHostManager.FragmentListener mFragmentListener;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mSystemClock = new FakeSystemClock();
|
SystemClock systemClock = new FakeSystemClock();
|
||||||
mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
|
mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
|
||||||
mInteractionJankMonitor);
|
mInteractionJankMonitor);
|
||||||
|
|
||||||
mKeyguardStatusView = new KeyguardStatusView(mContext);
|
KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
|
||||||
mKeyguardStatusView.setId(R.id.keyguard_status_view);
|
keyguardStatusView.setId(R.id.keyguard_status_view);
|
||||||
DejankUtils.setImmediate(true);
|
DejankUtils.setImmediate(true);
|
||||||
|
|
||||||
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
|
when(mAuthController.isUdfpsEnrolled(anyInt())).thenReturn(false);
|
||||||
when(mHeadsUpCallback.getContext()).thenReturn(mContext);
|
when(mHeadsUpCallback.getContext()).thenReturn(mContext);
|
||||||
when(mView.getResources()).thenReturn(mResources);
|
when(mView.getResources()).thenReturn(mResources);
|
||||||
|
when(mView.getWidth()).thenReturn(PANEL_WIDTH);
|
||||||
when(mResources.getConfiguration()).thenReturn(mConfiguration);
|
when(mResources.getConfiguration()).thenReturn(mConfiguration);
|
||||||
mConfiguration.orientation = ORIENTATION_PORTRAIT;
|
mConfiguration.orientation = ORIENTATION_PORTRAIT;
|
||||||
when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
|
when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics);
|
||||||
@@ -434,7 +342,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
when(mView.findViewById(R.id.keyguard_status_view))
|
when(mView.findViewById(R.id.keyguard_status_view))
|
||||||
.thenReturn(mock(KeyguardStatusView.class));
|
.thenReturn(mock(KeyguardStatusView.class));
|
||||||
mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
|
mNotificationContainerParent = new NotificationsQuickSettingsContainer(getContext(), null);
|
||||||
mNotificationContainerParent.addView(mKeyguardStatusView);
|
mNotificationContainerParent.addView(keyguardStatusView);
|
||||||
mNotificationContainerParent.onFinishInflate();
|
mNotificationContainerParent.onFinishInflate();
|
||||||
when(mView.findViewById(R.id.notification_container_parent))
|
when(mView.findViewById(R.id.notification_container_parent))
|
||||||
.thenReturn(mNotificationContainerParent);
|
.thenReturn(mNotificationContainerParent);
|
||||||
@@ -450,7 +358,12 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
when(mKeyguardUserSwitcherComponent.getKeyguardUserSwitcherController())
|
when(mKeyguardUserSwitcherComponent.getKeyguardUserSwitcherController())
|
||||||
.thenReturn(mKeyguardUserSwitcherController);
|
.thenReturn(mKeyguardUserSwitcherController);
|
||||||
when(mScreenOffAnimationController.shouldAnimateClockChange()).thenReturn(true);
|
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 -> {
|
doAnswer((Answer<Void>) invocation -> {
|
||||||
mTouchHandler = invocation.getArgument(0);
|
mTouchHandler = invocation.getArgument(0);
|
||||||
return null;
|
return null;
|
||||||
@@ -487,7 +400,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
|
when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
|
||||||
.thenReturn(mKeyguardStatusBarViewController);
|
.thenReturn(mKeyguardStatusBarViewController);
|
||||||
when(mLayoutInflater.inflate(eq(R.layout.keyguard_status_view), any(), anyBoolean()))
|
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()))
|
when(mLayoutInflater.inflate(eq(R.layout.keyguard_user_switcher), any(), anyBoolean()))
|
||||||
.thenReturn(mUserSwitcherView);
|
.thenReturn(mUserSwitcherView);
|
||||||
when(mLayoutInflater.inflate(eq(R.layout.keyguard_bottom_area), any(), anyBoolean()))
|
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();
|
((Runnable) invocation.getArgument(0)).run();
|
||||||
return null;
|
return null;
|
||||||
}).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
|
}).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
|
||||||
|
doAnswer(invocation -> {
|
||||||
|
mLayoutChangeListener = invocation.getArgument(0);
|
||||||
|
return null;
|
||||||
|
}).when(mView).addOnLayoutChangeListener(any());
|
||||||
|
|
||||||
when(mView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
|
when(mView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
|
||||||
when(mView.getParent()).thenReturn(mViewParent);
|
when(mView.getParent()).thenReturn(mViewParent);
|
||||||
when(mQs.getHeader()).thenReturn(mQsHeader);
|
when(mQs.getHeader()).thenReturn(mQsHeader);
|
||||||
|
|
||||||
mMainHandler = new Handler(Looper.getMainLooper());
|
mMainHandler = new Handler(Looper.getMainLooper());
|
||||||
mPanelEventsEmitter = new NotificationPanelViewController.PanelEventsEmitter();
|
NotificationPanelViewController.PanelEventsEmitter panelEventsEmitter =
|
||||||
|
new NotificationPanelViewController.PanelEventsEmitter();
|
||||||
|
|
||||||
mNotificationPanelViewController = new NotificationPanelViewController(
|
mNotificationPanelViewController = new NotificationPanelViewController(
|
||||||
mView,
|
mView,
|
||||||
@@ -563,11 +481,11 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
() -> mKeyguardBottomAreaViewController,
|
() -> mKeyguardBottomAreaViewController,
|
||||||
mKeyguardUnlockAnimationController,
|
mKeyguardUnlockAnimationController,
|
||||||
mNotificationListContainer,
|
mNotificationListContainer,
|
||||||
mPanelEventsEmitter,
|
panelEventsEmitter,
|
||||||
mNotificationStackSizeCalculator,
|
mNotificationStackSizeCalculator,
|
||||||
mUnlockedScreenOffAnimationController,
|
mUnlockedScreenOffAnimationController,
|
||||||
mShadeTransitionController,
|
mShadeTransitionController,
|
||||||
mSystemClock,
|
systemClock,
|
||||||
mock(CameraGestureHelper.class),
|
mock(CameraGestureHelper.class),
|
||||||
mKeyguardBottomAreaViewModel,
|
mKeyguardBottomAreaViewModel,
|
||||||
mKeyguardBottomAreaInteractor);
|
mKeyguardBottomAreaInteractor);
|
||||||
@@ -1492,6 +1410,96 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
assertThat(maxDistance).isNotEqualTo(SPLIT_SHADE_FULL_TRANSITION_DISTANCE);
|
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) {
|
private static MotionEvent createMotionEvent(int x, int y, int action) {
|
||||||
return MotionEvent.obtain(
|
return MotionEvent.obtain(
|
||||||
/* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0);
|
/* 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(
|
assertThat(getConstraintSetLayout(R.id.keyguard_status_view).endToEnd).isEqualTo(
|
||||||
R.id.qs_edge_guideline);
|
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
|
package com.android.systemui.statusbar
|
||||||
|
|
||||||
import android.test.suitebuilder.annotation.SmallTest
|
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
import android.testing.TestableLooper.RunWithLooper
|
import android.testing.TestableLooper.RunWithLooper
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.ExpandHelper
|
import com.android.systemui.ExpandHelper
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
@@ -78,6 +78,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
|
|||||||
@Mock lateinit var qS: QS
|
@Mock lateinit var qS: QS
|
||||||
@Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller
|
@Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller
|
||||||
@Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller
|
@Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller
|
||||||
|
@Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController
|
||||||
@JvmField @Rule val mockito = MockitoJUnit.rule()
|
@JvmField @Rule val mockito = MockitoJUnit.rule()
|
||||||
|
|
||||||
private val configurationController = FakeConfigurationController()
|
private val configurationController = FakeConfigurationController()
|
||||||
@@ -120,7 +121,9 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
|
|||||||
context,
|
context,
|
||||||
configurationController,
|
configurationController,
|
||||||
dumpManager)
|
dumpManager)
|
||||||
})
|
},
|
||||||
|
qsTransitionControllerFactory = { qsTransitionController },
|
||||||
|
)
|
||||||
whenever(nsslController.view).thenReturn(stackscroller)
|
whenever(nsslController.view).thenReturn(stackscroller)
|
||||||
whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
|
whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
|
||||||
transitionController.notificationPanelController = notificationPanelController
|
transitionController.notificationPanelController = notificationPanelController
|
||||||
@@ -249,7 +252,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
|
|||||||
verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
|
verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
|
||||||
verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(),
|
verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(),
|
||||||
anyBoolean(), anyLong())
|
anyBoolean(), anyLong())
|
||||||
verify(qS, never()).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
|
verify(qsTransitionController, never()).dragDownAmount = anyFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -260,7 +263,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
|
|||||||
verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
|
verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
|
||||||
verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(),
|
verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(),
|
||||||
anyBoolean(), anyLong())
|
anyBoolean(), anyLong())
|
||||||
verify(qS).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
|
verify(qsTransitionController).dragDownAmount = 10f
|
||||||
verify(depthController).transitionToFullShadeProgress = anyFloat()
|
verify(depthController).transitionToFullShadeProgress = anyFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,16 +59,19 @@ import com.android.systemui.animation.ShadeInterpolation;
|
|||||||
import com.android.systemui.dock.DockManager;
|
import com.android.systemui.dock.DockManager;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
import com.android.systemui.scrim.ScrimView;
|
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.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||||
import com.android.systemui.util.time.FakeSystemClock;
|
import com.android.systemui.util.time.FakeSystemClock;
|
||||||
import com.android.systemui.util.wakelock.DelayedWakeLock;
|
import com.android.systemui.util.wakelock.DelayedWakeLock;
|
||||||
import com.android.systemui.utils.os.FakeHandler;
|
import com.android.systemui.utils.os.FakeHandler;
|
||||||
|
|
||||||
|
import com.google.common.truth.Expect;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
@@ -86,6 +89,11 @@ import java.util.Map;
|
|||||||
@SmallTest
|
@SmallTest
|
||||||
public class ScrimControllerTest extends SysuiTestCase {
|
public class ScrimControllerTest extends SysuiTestCase {
|
||||||
|
|
||||||
|
@Rule public Expect mExpect = Expect.create();
|
||||||
|
|
||||||
|
private final FakeConfigurationController mConfigurationController =
|
||||||
|
new FakeConfigurationController();
|
||||||
|
|
||||||
private ScrimController mScrimController;
|
private ScrimController mScrimController;
|
||||||
private ScrimView mScrimBehind;
|
private ScrimView mScrimBehind;
|
||||||
private ScrimView mNotificationsScrim;
|
private ScrimView mNotificationsScrim;
|
||||||
@@ -96,32 +104,19 @@ public class ScrimControllerTest extends SysuiTestCase {
|
|||||||
private int mScrimVisibility;
|
private int mScrimVisibility;
|
||||||
private boolean mAlwaysOnEnabled;
|
private boolean mAlwaysOnEnabled;
|
||||||
private TestableLooper mLooper;
|
private TestableLooper mLooper;
|
||||||
@Mock
|
@Mock private AlarmManager mAlarmManager;
|
||||||
private AlarmManager mAlarmManager;
|
@Mock private DozeParameters mDozeParameters;
|
||||||
@Mock
|
@Mock private LightBarController mLightBarController;
|
||||||
private DozeParameters mDozeParameters;
|
@Mock private DelayedWakeLock.Builder mDelayedWakeLockBuilder;
|
||||||
@Mock
|
@Mock private DelayedWakeLock mWakeLock;
|
||||||
LightBarController mLightBarController;
|
@Mock private KeyguardStateController mKeyguardStateController;
|
||||||
@Mock
|
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||||
DelayedWakeLock.Builder mDelayedWakeLockBuilder;
|
@Mock private DockManager mDockManager;
|
||||||
@Mock
|
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
|
||||||
private DelayedWakeLock mWakeLock;
|
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||||
@Mock
|
|
||||||
KeyguardStateController mKeyguardStateController;
|
|
||||||
@Mock
|
|
||||||
KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
|
||||||
@Mock
|
|
||||||
private DockManager mDockManager;
|
|
||||||
@Mock
|
|
||||||
private ConfigurationController mConfigurationController;
|
|
||||||
@Mock
|
|
||||||
private ScreenOffAnimationController mScreenOffAnimationController;
|
|
||||||
@Mock
|
|
||||||
private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
|
||||||
// TODO(b/204991468): Use a real PanelExpansionStateManager object once this bug is fixed. (The
|
// 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.)
|
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
|
||||||
@Mock
|
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
|
||||||
|
|
||||||
private static class AnimatorListener implements Animator.AnimatorListener {
|
private static class AnimatorListener implements Animator.AnimatorListener {
|
||||||
private int mNumStarts;
|
private int mNumStarts;
|
||||||
@@ -1449,6 +1444,41 @@ public class ScrimControllerTest extends SysuiTestCase {
|
|||||||
assertThat(mNotificationsScrim.getViewAlpha()).isEqualTo(notifProgress);
|
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
|
@Test
|
||||||
public void setNotificationsOverScrollAmount_setsTranslationYOnNotificationsScrim() {
|
public void setNotificationsOverScrollAmount_setsTranslationYOnNotificationsScrim() {
|
||||||
int overScrollAmount = 10;
|
int overScrollAmount = 10;
|
||||||
|
|||||||
Reference in New Issue
Block a user