Merge changes I635afaaf,Icdd62155 into sc-dev

* changes:
  DO NOT MERGE Fixed the padding of quick settings
  Fix drag down animation when bypassing
This commit is contained in:
TreeHugger Robot
2021-07-23 22:25:37 +00:00
committed by Android (Google) Code Review
19 changed files with 220 additions and 182 deletions

View File

@@ -52,13 +52,6 @@ public interface QS extends FragmentBase {
void setListening(boolean listening);
boolean isShowingDetail();
void closeDetail();
/**
* Set that we're currently pulse expanding
*
* @param pulseExpanding if we're currently expanding during pulsing
*/
default void setPulseExpanding(boolean pulseExpanding) {}
void animateHeaderSlidingOut();
void setQsExpansion(float qsExpansionFraction, float headerTranslation);
void setHeaderListening(boolean listening);

View File

@@ -55,7 +55,7 @@
android:clipChildren="false"
android:clipToPadding="false"
android:focusable="true"
android:paddingBottom="10dp"
android:paddingBottom="24dp"
android:importantForAccessibility="yes" />
</RelativeLayout>

View File

@@ -1456,7 +1456,7 @@
<dimen name="lockscreen_shade_notification_movement">24dp</dimen>
<!-- Maximum overshoot for the pulse expansion -->
<dimen name="pulse_expansion_max_top_overshoot">16dp</dimen>
<dimen name="pulse_expansion_max_top_overshoot">32dp</dimen>
<dimen name="people_space_widget_radius">28dp</dimen>
<dimen name="people_space_image_radius">20dp</dimen>

View File

@@ -48,6 +48,7 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.util.InjectionInflationController;
@@ -69,6 +70,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private final Rect mQsBounds = new Rect();
private final StatusBarStateController mStatusBarStateController;
private final FalsingManager mFalsingManager;
private final KeyguardBypassController mBypassController;
private boolean mQsExpanded;
private boolean mHeaderAnimating;
private boolean mStackScrollerOverscrolling;
@@ -135,6 +137,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
StatusBarStateController statusBarStateController, CommandQueue commandQueue,
QSDetailDisplayer qsDetailDisplayer, @Named(QS_PANEL) MediaHost qsMediaHost,
@Named(QUICK_QS_PANEL) MediaHost qqsMediaHost,
KeyguardBypassController keyguardBypassController,
QSFragmentComponent.Factory qsComponentFactory, FeatureFlags featureFlags,
FalsingManager falsingManager) {
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
@@ -148,6 +151,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
mHost = qsTileHost;
mFeatureFlags = featureFlags;
mFalsingManager = falsingManager;
mBypassController = keyguardBypassController;
mStatusBarStateController = statusBarStateController;
}
@@ -380,16 +384,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
return mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
}
@Override
public void setPulseExpanding(boolean pulseExpanding) {
if (pulseExpanding != mPulseExpanding) {
mPulseExpanding = pulseExpanding;
updateShowCollapsedOnKeyguard();
}
}
private void updateShowCollapsedOnKeyguard() {
boolean showCollapsed = mPulseExpanding || mTransitioningToFullShade;
boolean showCollapsed = mBypassController.getBypassEnabled() || mTransitioningToFullShade;
if (showCollapsed != mShowCollapsedOnKeyguard) {
mShowCollapsedOnKeyguard = showCollapsed;
updateQsState();
@@ -719,5 +715,6 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
public void onStateChanged(int newState) {
mState = newState;
setKeyguardShowing(newState == StatusBarState.KEYGUARD);
updateShowCollapsedOnKeyguard();
}
}

View File

@@ -56,6 +56,8 @@ public class QSPanel extends LinearLayout implements Tunable {
private static final String TAG = "QSPanel";
protected final Context mContext;
private final int mMediaTopMargin;
private final int mMediaTotalBottomMargin;
/**
* The index where the content starts that needs to be moved between parents
@@ -99,13 +101,14 @@ public class QSPanel extends LinearLayout implements Tunable {
protected LinearLayout mHorizontalContentContainer;
protected QSTileLayout mTileLayout;
private int mMediaTotalBottomMargin;
public QSPanel(Context context, AttributeSet attrs) {
super(context, attrs);
mUsingMediaPlayer = useQsMediaPlayer(context);
mMediaTotalBottomMargin = getResources().getDimensionPixelSize(
R.dimen.quick_settings_bottom_margin_media);
mMediaTopMargin = getResources().getDimensionPixelSize(
R.dimen.qs_tile_margin_vertical);
mContext = context;
setOrientation(VERTICAL);
@@ -328,7 +331,7 @@ public class QSPanel extends LinearLayout implements Tunable {
private void updateHorizontalLinearLayoutMargins() {
if (mHorizontalLinearLayout != null && !displayMediaMarginsOnMedia()) {
LayoutParams lp = (LayoutParams) mHorizontalLinearLayout.getLayoutParams();
lp.bottomMargin = mMediaTotalBottomMargin - getPaddingBottom();
lp.bottomMargin = Math.max(mMediaTotalBottomMargin - getPaddingBottom(), 0);
mHorizontalLinearLayout.setLayoutParams(lp);
}
}
@@ -343,6 +346,13 @@ public class QSPanel extends LinearLayout implements Tunable {
return true;
}
/**
* @return true if the media view needs margin on the top to separate it from the qs tiles
*/
protected boolean mediaNeedsTopMargin() {
return false;
}
private boolean needsDynamicRowsAndColumns() {
return true;
}
@@ -411,7 +421,9 @@ public class QSPanel extends LinearLayout implements Tunable {
// necessary if the view isn't horizontal, since otherwise the padding is
// carried in the parent of this view (to ensure correct vertical alignment)
layoutParams.bottomMargin = !horizontal || displayMediaMarginsOnMedia()
? mMediaTotalBottomMargin - getPaddingBottom() : 0;
? Math.max(mMediaTotalBottomMargin - getPaddingBottom(), 0) : 0;
layoutParams.topMargin = mediaNeedsTopMargin() && !horizontal
? mMediaTopMargin : 0;
}
}
@@ -674,6 +686,7 @@ public class QSPanel extends LinearLayout implements Tunable {
mTileLayout.setMaxColumns(horizontal ? 2 : 4);
}
updateMargins(mediaHostView);
mHorizontalLinearLayout.setVisibility(horizontal ? View.VISIBLE : View.GONE);
}
}

View File

@@ -72,6 +72,11 @@ public class QuickQSPanel extends QSPanel {
return false;
}
@Override
protected boolean mediaNeedsTopMargin() {
return true;
}
@Override
protected void updatePadding() {
// QS Panel is setting a top padding by default, which we don't need.
@@ -180,7 +185,6 @@ public class QuickQSPanel extends QSPanel {
LayoutParams.WRAP_CONTENT);
setLayoutParams(lp);
setMaxColumns(4);
mLastRowPadding = true;
}
@Override

View File

@@ -31,7 +31,6 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
protected int mCellMarginVertical;
protected int mSidePadding;
protected int mRows = 1;
protected boolean mLastRowPadding = false;
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
protected boolean mListening;
@@ -168,9 +167,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
}
int height = (mCellHeight + mCellMarginVertical) * mRows;
if (!mLastRowPadding) {
height -= mCellMarginVertical;
}
height -= mCellMarginVertical;
if (height < 0) height = 0;

View File

@@ -65,6 +65,7 @@ class LockscreenShadeTransitionController @Inject constructor(
configurationController: ConfigurationController,
falsingManager: FalsingManager
) {
private var pulseHeight: Float = 0f
private var useSplitShade: Boolean = false
private lateinit var nsslController: NotificationStackScrollLayoutController
lateinit var notificationPanelController: NotificationPanelViewController
@@ -87,6 +88,12 @@ class LockscreenShadeTransitionController @Inject constructor(
@VisibleForTesting
internal var dragDownAnimator: ValueAnimator? = null
/**
* The current pulse height animator if any
*/
@VisibleForTesting
internal var pulseHeightAnimator: ValueAnimator? = null
/**
* Distance that the full shade transition takes in order for scrim to fully transition to
* the shade (in alpha)
@@ -109,6 +116,12 @@ class LockscreenShadeTransitionController @Inject constructor(
*/
private var nextHideKeyguardNeedsNoAnimation = false
/**
* The distance until we're showing the notifications when pulsing
*/
val distanceUntilShowingPulsingNotifications
get() = scrimTransitionDistance
/**
* The udfpsKeyguardViewController if it exists.
*/
@@ -286,22 +299,26 @@ class LockscreenShadeTransitionController @Inject constructor(
nsslController.setTransitionToFullShadeAmount(field)
notificationPanelController.setTransitionToFullShadeAmount(field,
false /* animate */, 0 /* delay */)
val scrimProgress = MathUtils.saturate(field / scrimTransitionDistance)
scrimController.setTransitionToFullShadeProgress(scrimProgress)
// TODO: appear qs also in split shade
val qsAmount = if (useSplitShade) 0f else field
qS.setTransitionToFullShadeAmount(qsAmount, false /* animate */)
// TODO: appear media also in split shade
val mediaAmount = if (useSplitShade) 0f else field
mediaHierarchyManager.setTransitionToFullShadeAmount(mediaAmount)
// Fade out all content only visible on the lockscreen
notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress)
depthController.transitionToFullShadeProgress = scrimProgress
udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress)
transitionToShadeAmountCommon(field)
}
}
}
private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
scrimController.setTransitionToFullShadeProgress(scrimProgress)
// Fade out all content only visible on the lockscreen
notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress)
depthController.transitionToFullShadeProgress = scrimProgress
udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress)
}
private fun setDragDownAmountAnimated(
target: Float,
delay: Long = 0,
@@ -453,15 +470,19 @@ class LockscreenShadeTransitionController @Inject constructor(
/**
* Notify this handler that the keyguard was just dismissed and that a animation to
* the full shade should happen.
*
* @param delay the delay to do the animation with
* @param previousState which state were we in when we hid the keyguard?
*/
fun onHideKeyguard(delay: Long) {
fun onHideKeyguard(delay: Long, previousState: Int) {
if (animationHandlerOnKeyguardDismiss != null) {
animationHandlerOnKeyguardDismiss!!.invoke(delay)
animationHandlerOnKeyguardDismiss = null
} else {
if (nextHideKeyguardNeedsNoAnimation) {
nextHideKeyguardNeedsNoAnimation = false
} else {
} else if (previousState != StatusBarState.SHADE_LOCKED) {
// No animation necessary if we already were in the shade locked!
performDefaultGoToFullShadeAnimation(delay)
}
}
@@ -479,6 +500,53 @@ class LockscreenShadeTransitionController @Inject constructor(
notificationPanelController.animateToFullShade(delay)
animateAppear(delay)
}
//
// PULSE EXPANSION
//
/**
* Set the height how tall notifications are pulsing. This is only set whenever we are expanding
* from a pulse and determines how much the notifications are expanded.
*/
fun setPulseHeight(height: Float, animate: Boolean = false) {
if (animate) {
val pulseHeightAnimator = ValueAnimator.ofFloat(pulseHeight, height)
pulseHeightAnimator.interpolator = Interpolators.FAST_OUT_SLOW_IN
pulseHeightAnimator.duration = SPRING_BACK_ANIMATION_LENGTH_MS
pulseHeightAnimator.addUpdateListener { animation: ValueAnimator ->
setPulseHeight(animation.animatedValue as Float)
}
pulseHeightAnimator.start()
this.pulseHeightAnimator = pulseHeightAnimator
} else {
pulseHeight = height
val overflow = nsslController.setPulseHeight(height)
notificationPanelController.setOverStrechAmount(overflow)
val transitionHeight = if (keyguardBypassController.bypassEnabled) height else 0.0f
transitionToShadeAmountCommon(transitionHeight)
}
}
/**
* Finish the pulse animation when the touch interaction finishes
* @param cancelled was the interaction cancelled and this is a reset?
*/
fun finishPulseAnimation(cancelled: Boolean) {
if (cancelled) {
setPulseHeight(0f, animate = true)
} else {
notificationPanelController.onPulseExpansionFinished()
setPulseHeight(0f, animate = false)
}
}
/**
* Notify this class that a pulse expansion is starting
*/
fun onPulseExpansionStarted() {
pulseHeightAnimator?.cancel()
}
}
/**

View File

@@ -19,8 +19,8 @@ package com.android.systemui.statusbar
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.Configuration
import android.os.PowerManager
import android.os.PowerManager.WAKE_REASON_GESTURE
import android.os.SystemClock
@@ -42,6 +42,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationRoundnessMa
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import javax.inject.Inject
import kotlin.math.max
@@ -56,18 +57,17 @@ constructor(
private val bypassController: KeyguardBypassController,
private val headsUpManager: HeadsUpManagerPhone,
private val roundnessManager: NotificationRoundnessManager,
private val configurationController: ConfigurationController,
private val statusBarStateController: StatusBarStateController,
private val falsingManager: FalsingManager,
private val lockscreenShadeTransitionController: LockscreenShadeTransitionController,
private val falsingCollector: FalsingCollector
) : Gefingerpoken {
companion object {
private val RUBBERBAND_FACTOR_STATIC = 0.25f
private val SPRING_BACK_ANIMATION_LENGTH_MS = 375
}
private val mPowerManager: PowerManager?
private val mMinDragDistance: Int
private var mInitialTouchX: Float = 0.0f
private var mInitialTouchY: Float = 0.0f
var isExpanding: Boolean = false
@@ -81,6 +81,7 @@ constructor(
topEntry?.let {
roundnessManager.setTrackingHeadsUp(it.row)
}
lockscreenShadeTransitionController.onPulseExpansionStarted()
} else {
roundnessManager.setTrackingHeadsUp(null)
if (!leavingLockscreen) {
@@ -93,8 +94,8 @@ constructor(
}
var leavingLockscreen: Boolean = false
private set
private val mTouchSlop: Float
private lateinit var overStretchHandler: OverStretchHandler
private var touchSlop = 0f
private var minDragDistance = 0
private lateinit var stackScrollerController: NotificationStackScrollLayoutController
private val mTemp2 = IntArray(2)
private var mDraggedFarEnough: Boolean = false
@@ -102,9 +103,7 @@ constructor(
private var mPulsing: Boolean = false
var isWakingToShadeLocked: Boolean = false
private set
private var overStretchAmount: Float = 0.0f
private var mWakeUpHeight: Float = 0.0f
private var mReachedWakeUpHeight: Boolean = false
private var velocityTracker: VelocityTracker? = null
private val isFalseTouch: Boolean
@@ -114,12 +113,21 @@ constructor(
var bouncerShowing: Boolean = false
init {
mMinDragDistance = context.resources.getDimensionPixelSize(
R.dimen.keyguard_drag_down_min_distance)
mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
initResources(context)
configurationController.addCallback(object : ConfigurationController.ConfigurationListener {
override fun onConfigChanged(newConfig: Configuration?) {
initResources(context)
}
})
mPowerManager = context.getSystemService(PowerManager::class.java)
}
private fun initResources(context: Context) {
minDragDistance = context.resources.getDimensionPixelSize(
R.dimen.keyguard_drag_down_min_distance)
touchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
}
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
return canHandleMotionEvent() && startExpansion(event)
}
@@ -148,14 +156,12 @@ constructor(
MotionEvent.ACTION_MOVE -> {
val h = y - mInitialTouchY
if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) {
if (h > touchSlop && h > Math.abs(x - mInitialTouchX)) {
falsingCollector.onStartExpandingFromPulse()
isExpanding = true
captureStartingChild(mInitialTouchX, mInitialTouchY)
mInitialTouchY = y
mInitialTouchX = x
mWakeUpHeight = wakeUpCoordinator.getWakeUpHeight()
mReachedWakeUpHeight = false
return true
}
}
@@ -216,7 +222,6 @@ constructor(
}
private fun finishExpansion() {
resetClock()
val startingChild = mStartingChild
if (mStartingChild != null) {
setUserLocked(mStartingChild!!, false)
@@ -230,6 +235,7 @@ constructor(
}
lockscreenShadeTransitionController.goToLockedShade(startingChild,
needsQSAnimation = false)
lockscreenShadeTransitionController.finishPulseAnimation(cancelled = false)
leavingLockscreen = true
isExpanding = false
if (mStartingChild is ExpandableNotificationRow) {
@@ -240,24 +246,19 @@ constructor(
private fun updateExpansionHeight(height: Float) {
var expansionHeight = max(height, 0.0f)
if (!mReachedWakeUpHeight && height > mWakeUpHeight) {
mReachedWakeUpHeight = true
}
if (mStartingChild != null) {
val child = mStartingChild!!
val newHeight = Math.min((child.collapsedHeight + expansionHeight).toInt(),
child.maxContentHeight)
child.actualHeight = newHeight
expansionHeight = max(newHeight.toFloat(), expansionHeight)
} else {
val target = if (mReachedWakeUpHeight) mWakeUpHeight else 0.0f
wakeUpCoordinator.setNotificationsVisibleForExpansion(height > target,
true /* animate */,
true /* increaseSpeed */)
expansionHeight = max(mWakeUpHeight, expansionHeight)
wakeUpCoordinator.setNotificationsVisibleForExpansion(
height
> lockscreenShadeTransitionController.distanceUntilShowingPulsingNotifications,
true /* animate */,
true /* increaseSpeed */)
}
val dragDownAmount = wakeUpCoordinator.setPulseHeight(expansionHeight)
setOverStretchAmount(dragDownAmount)
lockscreenShadeTransitionController.setPulseHeight(expansionHeight, animate = false)
}
private fun captureStartingChild(x: Float, y: Float) {
@@ -269,11 +270,6 @@ constructor(
}
}
private fun setOverStretchAmount(amount: Float) {
overStretchAmount = amount
overStretchHandler.setOverStretchAmount(amount)
}
private fun reset(child: ExpandableView) {
if (child.actualHeight == child.collapsedHeight) {
setUserLocked(child, false)
@@ -297,25 +293,14 @@ constructor(
}
}
private fun resetClock() {
val anim = ValueAnimator.ofFloat(overStretchAmount, 0f)
anim.interpolator = Interpolators.FAST_OUT_SLOW_IN
anim.duration = SPRING_BACK_ANIMATION_LENGTH_MS.toLong()
anim.addUpdateListener {
animation -> setOverStretchAmount(animation.animatedValue as Float)
}
anim.start()
}
private fun cancelExpansion() {
isExpanding = false
falsingCollector.onExpansionFromPulseStopped()
if (mStartingChild != null) {
reset(mStartingChild!!)
mStartingChild = null
} else {
resetClock()
}
lockscreenShadeTransitionController.finishPulseAnimation(cancelled = true)
wakeUpCoordinator.setNotificationsVisibleForExpansion(false /* visible */,
true /* animate */,
false /* increaseSpeed */)
@@ -333,11 +318,7 @@ constructor(
} else null
}
fun setUp(
stackScrollerController: NotificationStackScrollLayoutController,
overStrechHandler: OverStretchHandler
) {
this.overStretchHandler = overStrechHandler
fun setUp(stackScrollerController: NotificationStackScrollLayoutController) {
this.stackScrollerController = stackScrollerController
}
@@ -348,12 +329,4 @@ constructor(
fun onStartedWakingUp() {
isWakingToShadeLocked = false
}
interface OverStretchHandler {
/**
* Set the overstretch amount in pixels This will be rubberbanded later
*/
fun setOverStretchAmount(amount: Float)
}
}

View File

@@ -374,10 +374,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
fun getWakeUpHeight(): Float {
return mStackScrollerController.wakeUpHeight
}
private fun updateHideAmount() {
val linearAmount = min(1.0f - mLinearVisibilityAmount, mLinearDozeAmount)
val amount = min(1.0f - mVisibilityAmount, mDozeAmount)
@@ -395,16 +391,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
/**
* Set the height how tall notifications are pulsing. This is only set whenever we are expanding
* from a pulse and determines how much the notifications are expanded.
*/
fun setPulseHeight(height: Float): Float {
val overflow = mStackScrollerController.setPulseHeight(height)
// no overflow for the bypass experience
return if (bypassController.bypassEnabled) 0.0f else overflow
}
override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
var animate = shouldAnimateVisibility()
if (!isHeadsUp) {

View File

@@ -5138,12 +5138,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
* @return the overflow how much the height is further than he lowest notification
*/
public float setPulseHeight(float height) {
float overflow;
mAmbientState.setPulseHeight(height);
if (mKeyguardBypassEnabledProvider.getBypassEnabled()) {
notifyAppearChangedListeners();
overflow = Math.max(0, height - getIntrinsicPadding());
} else {
overflow = Math.max(0, height
- mAmbientState.getInnerHeight(true /* ignorePulseHeight */));
}
requestChildrenUpdate();
return Math.max(0, height - mAmbientState.getInnerHeight(true /* ignorePulseHeight */));
return overflow;
}
public float getPulseHeight() {
@@ -5203,12 +5208,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
public float calculateAppearFractionBypass() {
float pulseHeight = getPulseHeight();
float wakeUpHeight = getWakeUpHeight();
float dragDownAmount = pulseHeight - wakeUpHeight;
// The total distance required to fully reveal the header
float totalDistance = getIntrinsicPadding();
return MathUtils.smoothStep(0, totalDistance, dragDownAmount);
return MathUtils.smoothStep(0, totalDistance, pulseHeight);
}
public void setController(

View File

@@ -885,10 +885,6 @@ public class NotificationStackScrollLayoutController {
mView.setDozeAmount(amount);
}
public float getWakeUpHeight() {
return mView.getWakeUpHeight();
}
public int getSpeedBumpIndex() {
return mView.getSpeedBumpIndex();
}

View File

@@ -274,7 +274,9 @@ public class StackScrollAlgorithm {
// expanded. Consider updating these states in updateContentView instead so that we don't
// have to recalculate in every frame.
float currentY = -ambientState.getScrollY();
if (!ambientState.isOnKeyguard()) {
if (!ambientState.isOnKeyguard()
|| (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
// add top padding at the start as long as we're not on the lock screen
currentY += mNotificationScrimPadding;
}
state.firstViewInShelf = null;
@@ -324,7 +326,8 @@ public class StackScrollAlgorithm {
*/
private void updatePositionsForState(StackScrollAlgorithmState algorithmState,
AmbientState ambientState) {
if (!ambientState.isOnKeyguard()) {
if (!ambientState.isOnKeyguard()
|| (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
algorithmState.mCurrentYPosition += mNotificationScrimPadding;
algorithmState.mCurrentExpandedYPosition += mNotificationScrimPadding;
}
@@ -355,7 +358,9 @@ public class StackScrollAlgorithm {
&& algorithmState.firstViewInShelf != null;
final float shelfHeight = showingShelf ? ambientState.getShelf().getIntrinsicHeight() : 0f;
final float scrimPadding = ambientState.isOnKeyguard() ? 0 : mNotificationScrimPadding;
final float scrimPadding = ambientState.isOnKeyguard()
&& (!ambientState.isBypassEnabled() || !ambientState.isPulseExpanding())
? 0 : mNotificationScrimPadding;
final float stackHeight = ambientState.getStackHeight() - shelfHeight - scrimPadding;
final float stackEndHeight = ambientState.getStackEndHeight() - shelfHeight - scrimPadding;

View File

@@ -211,7 +211,7 @@ public class KeyguardClockPositionAlgorithm {
private int getStackScrollerPadding(int clockYPosition) {
if (mBypassEnabled) {
return mUnlockedStackScrollerPadding;
return (int) (mUnlockedStackScrollerPadding + mOverStretchAmount);
} else if (mIsSplitShade) {
return clockYPosition;
} else {

View File

@@ -165,14 +165,14 @@ public class NotificationIconAreaController implements
* Called by the Keyguard*ViewController whose view contains the aod icons.
*/
public void setupAodIcons(@NonNull NotificationIconContainer aodIcons) {
boolean changed = mAodIcons != null;
boolean changed = mAodIcons != null && aodIcons != mAodIcons;
if (changed) {
mAodIcons.setAnimationsEnabled(false);
mAodIcons.removeAllViews();
}
mAodIcons = aodIcons;
mAodIcons.setOnLockScreen(true);
updateAodIconsVisibility(false /* animate */);
updateAodIconsVisibility(false /* animate */, changed);
updateAnimations();
if (changed) {
updateAodNotificationIcons();
@@ -587,7 +587,7 @@ public class NotificationIconAreaController implements
@Override
public void onStateChanged(int newState) {
updateAodIconsVisibility(false /* animate */);
updateAodIconsVisibility(false /* animate */, false /* force */);
updateAnimations();
}
@@ -663,18 +663,18 @@ public class NotificationIconAreaController implements
// since otherwise the unhide animation overlaps
animate &= fullyHidden;
}
updateAodIconsVisibility(animate);
updateAodIconsVisibility(animate, false /* force */);
updateAodNotificationIcons();
}
@Override
public void onPulseExpansionChanged(boolean expandingChanged) {
if (expandingChanged) {
updateAodIconsVisibility(true /* animate */);
updateAodIconsVisibility(true /* animate */, false /* force */);
}
}
private void updateAodIconsVisibility(boolean animate) {
private void updateAodIconsVisibility(boolean animate, boolean forceUpdate) {
if (mAodIcons == null) {
return;
}
@@ -688,10 +688,11 @@ public class NotificationIconAreaController implements
&& !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) {
visible = false;
}
if (visible && mWakeUpCoordinator.isPulseExpanding()) {
if (visible && mWakeUpCoordinator.isPulseExpanding()
&& !mBypassController.getBypassEnabled()) {
visible = false;
}
if (mAodIconsVisible != visible) {
if (mAodIconsVisible != visible || forceUpdate) {
mAodIconsVisible = visible;
mAodIcons.animate().cancel();
if (animate) {

View File

@@ -608,6 +608,11 @@ public class NotificationPanelViewController extends PanelViewController {
* Is the current animator resetting the qs translation.
*/
private boolean mIsQsTranslationResetAnimator;
/**
* Is the current animator resetting the pulse expansion after a drag down
*/
private boolean mIsPulseExpansionResetAnimator;
private final Rect mKeyguardStatusAreaClipBounds = new Rect();
private final Region mQsInterceptRegion = new Region();
@@ -884,14 +889,7 @@ public class NotificationPanelViewController extends PanelViewController {
mWakeUpCoordinator.setStackScroller(mNotificationStackScrollLayoutController);
mQsFrame = mView.findViewById(R.id.qs_frame);
mPulseExpansionHandler.setUp(mNotificationStackScrollLayoutController,
amount -> {
float progress = amount / mView.getHeight();
float overstretch = Interpolators.getOvershootInterpolation(progress,
(float) mMaxOverscrollAmountForPulse / mView.getHeight(),
0.2f);
setOverStrechAmount(overstretch);
});
mPulseExpansionHandler.setUp(mNotificationStackScrollLayoutController);
mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
@Override
public void onFullyHiddenChanged(boolean isFullyHidden) {
@@ -903,7 +901,6 @@ public class NotificationPanelViewController extends PanelViewController {
if (mKeyguardBypassController.getBypassEnabled()) {
// Position the notifications while dragging down while pulsing
requestScrollerTopPaddingUpdate(false /* animate */);
updateQSPulseExpansion();
}
}
});
@@ -941,8 +938,6 @@ public class NotificationPanelViewController extends PanelViewController {
R.dimen.notification_panel_min_side_margin);
mIndicationBottomPadding = mResources.getDimensionPixelSize(
R.dimen.keyguard_indication_bottom_padding);
mQsNotificationTopPadding = mResources.getDimensionPixelSize(
R.dimen.qs_notification_padding);
mShelfHeight = mResources.getDimensionPixelSize(R.dimen.notification_shelf_height);
mDarkIconSize = mResources.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size_dark);
int statusbarHeight = mResources.getDimensionPixelSize(
@@ -1341,8 +1336,7 @@ public class NotificationPanelViewController extends PanelViewController {
* @return the padding of the stackscroller when unlocked
*/
private int getUnlockedStackScrollerPadding() {
return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight
+ mQsNotificationTopPadding;
return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight;
}
/**
@@ -2239,7 +2233,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
protected void updateQsExpansion() {
private void updateQsExpansion() {
if (mQs == null) return;
float qsExpansionFraction = computeQsExpansionFraction();
mQs.setQsExpansion(qsExpansionFraction, getHeaderTranslation());
@@ -2298,9 +2292,20 @@ public class NotificationPanelViewController extends PanelViewController {
top = mTransitionToFullShadeQSPosition;
} else {
final float notificationTop = getQSEdgePosition();
top = (int) (isOnKeyguard() ? Math.min(qsPanelBottomY, notificationTop)
: notificationTop);
if (isOnKeyguard()) {
if (mKeyguardBypassController.getBypassEnabled()) {
// When bypassing on the keyguard, let's use the panel bottom.
// this should go away once we unify the stackY position and don't have
// to do this min anymore below.
top = qsPanelBottomY;
} else {
top = (int) Math.min(qsPanelBottomY, notificationTop);
}
} else {
top = (int) notificationTop;
}
}
top += mOverStretchAmount;
bottom = getView().getBottom();
// notification bounds should take full screen width regardless of insets
left = 0;
@@ -2353,6 +2358,7 @@ public class NotificationPanelViewController extends PanelViewController {
public void onAnimationEnd(Animator animation) {
mQsClippingAnimation = null;
mIsQsTranslationResetAnimator = false;
mIsPulseExpansionResetAnimator = false;
}
});
mQsClippingAnimation.start();
@@ -2378,9 +2384,17 @@ public class NotificationPanelViewController extends PanelViewController {
}
if (mQs != null) {
float qsTranslation = 0;
if (mTransitioningToFullShadeProgress > 0.0f || (mQsClippingAnimation != null
&& mIsQsTranslationResetAnimator)) {
qsTranslation = (top - mQs.getHeader().getHeight()) * QS_PARALLAX_AMOUNT;
boolean pulseExpanding = mPulseExpansionHandler.isExpanding();
if (mTransitioningToFullShadeProgress > 0.0f || pulseExpanding
|| (mQsClippingAnimation != null
&& (mIsQsTranslationResetAnimator || mIsPulseExpansionResetAnimator))) {
if (pulseExpanding || mIsPulseExpansionResetAnimator) {
// qsTranslation should only be positive during pulse expansion because it's
// already translating in from the top
qsTranslation = Math.max(0, (top - mQs.getHeader().getHeight()) / 2.0f);
} else {
qsTranslation = (top - mQs.getHeader().getHeight()) * QS_PARALLAX_AMOUNT;
}
}
mQsTranslationForFullShadeTransition = qsTranslation;
updateQsFrameTranslation();
@@ -2447,7 +2461,7 @@ public class NotificationPanelViewController extends PanelViewController {
private float calculateNotificationsTopPadding() {
if (mShouldUseSplitNotificationShade && !mKeyguardShowing) {
return mSplitShadeNotificationsTopPadding + mQsNotificationTopPadding;
return mSplitShadeNotificationsTopPadding;
}
if (mKeyguardShowing && (mQsExpandImmediate
|| mIsExpanding && mQsExpandedWhenExpandingStarted)) {
@@ -2458,7 +2472,7 @@ public class NotificationPanelViewController extends PanelViewController {
// panel. We need to take the maximum and linearly interpolate with the panel expansion
// for a nice motion.
int maxNotificationPadding = getKeyguardNotificationStaticPadding();
int maxQsPadding = mQsMaxExpansionHeight + mQsNotificationTopPadding;
int maxQsPadding = mQsMaxExpansionHeight;
int max = mBarState == KEYGUARD ? Math.max(
maxNotificationPadding, maxQsPadding) : maxQsPadding;
return (int) MathUtils.lerp((float) mQsMinExpansionHeight, (float) max,
@@ -2471,10 +2485,10 @@ public class NotificationPanelViewController extends PanelViewController {
// We can only do the smoother transition on Keyguard when we also are not collapsing
// from a scrolled quick settings.
return MathUtils.lerp((float) getKeyguardNotificationStaticPadding(),
(float) (mQsMaxExpansionHeight + mQsNotificationTopPadding),
(float) (mQsMaxExpansionHeight),
computeQsExpansionFraction());
} else {
return mQsExpansionHeight + mQsNotificationTopPadding;
return mQsExpansionHeight;
}
}
@@ -2509,14 +2523,6 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
private void updateQSPulseExpansion() {
if (mQs != null) {
mQs.setPulseExpanding(
mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()
&& mNotificationStackScrollLayoutController.isPulseExpanding());
}
}
/**
* Set the amount of pixels we have currently dragged down if we're transitioning to the full
* shade. 0.0f means we're not transitioning yet.
@@ -2567,6 +2573,15 @@ public class NotificationPanelViewController extends PanelViewController {
updateQsExpansion();
}
/**
* Notify the panel that the pulse expansion has finished and that we're going to the full
* shade
*/
public void onPulseExpansionFinished() {
animateNextNotificationBounds(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE, 0);
mIsPulseExpansionResetAnimator = true;
}
/**
* Set the alpha of the keyguard elements which only show on the lockscreen, but not in
* shade locked / shade. This is used when dragging down to the full shade.
@@ -2860,10 +2875,6 @@ public class NotificationPanelViewController extends PanelViewController {
}
int maxQsHeight = mQsMaxExpansionHeight;
if (mKeyguardShowing) {
maxQsHeight += mQsNotificationTopPadding;
}
// If an animation is changing the size of the QS panel, take the animated value.
if (mQsSizeChangeAnimator != null) {
maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue();
@@ -2928,19 +2939,7 @@ public class NotificationPanelViewController extends PanelViewController {
startHeight = -mQsExpansionHeight * QS_PARALLAX_AMOUNT;
}
if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()) {
if (mNotificationStackScrollLayoutController.isPulseExpanding()) {
if (!mPulseExpansionHandler.isExpanding()
&& !mPulseExpansionHandler.getLeavingLockscreen()) {
// If we aborted the expansion we need to make sure the header doesn't reappear
// again after the header has animated away
appearAmount = 0;
} else {
appearAmount = mNotificationStackScrollLayoutController
.calculateAppearFractionBypass();
}
} else {
appearAmount = 0.0f;
}
appearAmount = mNotificationStackScrollLayoutController.calculateAppearFractionBypass();
startHeight = -mQs.getQsMinExpansionHeight();
}
float translation = MathUtils.lerp(startHeight, 0, Math.min(1.0f, appearAmount));
@@ -3543,7 +3542,6 @@ public class NotificationPanelViewController extends PanelViewController {
mQs.setPanelView(mHeightListener);
mQs.setExpandClickListener(mOnClickListener);
mQs.setHeaderClickable(isQsExpansionEnabled());
updateQSPulseExpansion();
mQs.setOverscrolling(mStackScrollerOverscrolling);
mQs.setTranslateWhileExpanding(mShouldUseSplitNotificationShade);
@@ -4304,8 +4302,7 @@ public class NotificationPanelViewController extends PanelViewController {
if (mAccessibilityManager.isEnabled()) {
mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
}
mNotificationStackScrollLayoutController.setMaxTopPadding(
mQsMaxExpansionHeight + mQsNotificationTopPadding);
mNotificationStackScrollLayoutController.setMaxTopPadding(mQsMaxExpansionHeight);
}
}
@@ -4423,7 +4420,6 @@ public class NotificationPanelViewController extends PanelViewController {
updateMaxDisplayedNotifications(false);
// The update needs to happen after the headerSlide in above, otherwise the translation
// would reset
updateQSPulseExpansion();
maybeAnimateBottomAreaAlpha();
resetHorizontalPanelPosition();
updateQsState();
@@ -4458,7 +4454,9 @@ public class NotificationPanelViewController extends PanelViewController {
* Sets the overstretch amount in raw pixels when dragging down.
*/
public void setOverStrechAmount(float amount) {
mOverStretchAmount = amount;
float progress = amount / mView.getHeight();
float overstretch = Interpolators.getOvershootInterpolation(progress);
mOverStretchAmount = overstretch * mMaxOverscrollAmountForPulse;
positionClockAndNotifications(true /* forceUpdate */);
}
@@ -4512,8 +4510,7 @@ public class NotificationPanelViewController extends PanelViewController {
if (mQs != null) {
updateQSMinHeight();
mQsMaxExpansionHeight = mQs.getDesiredHeight();
mNotificationStackScrollLayoutController.setMaxTopPadding(
mQsMaxExpansionHeight + mQsNotificationTopPadding);
mNotificationStackScrollLayoutController.setMaxTopPadding(mQsMaxExpansionHeight);
}
positionClockAndNotifications();
if (mQsExpanded && mQsFullyExpanded) {

View File

@@ -3616,6 +3616,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mIsKeyguard = false;
Trace.beginSection("StatusBar#hideKeyguard");
boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
int previousState = mStatusBarStateController.getState();
if (!(mStatusBarStateController.setState(StatusBarState.SHADE, force))) {
//TODO: StatusBarStateController should probably know about hiding the keyguard and
// notify listeners.
@@ -3628,7 +3629,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
}
long delay = mKeyguardStateController.calculateGoingToFullShadeDelay();
mLockscreenShadeTransitionController.onHideKeyguard(delay);
mLockscreenShadeTransitionController.onHideKeyguard(delay, previousState);
// Disable layout transitions in navbar for this transition because the load is just
// too heavy for the CPU and GPU on any device.

View File

@@ -55,6 +55,7 @@ import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.phone.AutoTileManager;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.Clock;
@@ -92,6 +93,8 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
@Mock
private MediaHost mQQSMediaHost;
@Mock
private KeyguardBypassController mBypassController;
@Mock
private FeatureFlags mFeatureFlags;
@Mock
private FalsingManager mFalsingManager;
@@ -184,6 +187,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
new QSDetailDisplayer(),
mQSMediaHost,
mQQSMediaHost,
mBypassController,
mQsComponentFactory,
mFeatureFlags,
mFalsingManager);

View File

@@ -372,16 +372,17 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mKeyguardBypassController,
mDozeParameters,
mUnlockedScreenOffAnimationController);
mConfigurationController = new ConfigurationControllerImpl(mContext);
PulseExpansionHandler expansionHandler = new PulseExpansionHandler(
mContext,
coordinator,
mKeyguardBypassController, mHeadsUpManager,
mock(NotificationRoundnessManager.class),
mConfigurationController,
mStatusBarStateController,
mFalsingManager,
mLockscreenShadeTransitionController,
new FalsingCollectorFake());
mConfigurationController = new ConfigurationControllerImpl(mContext);
when(mKeyguardStatusViewComponentFactory.build(any()))
.thenReturn(mKeyguardStatusViewComponent);
when(mKeyguardStatusViewComponent.getKeyguardClockSwitchController())