Bouncer animation
More obvious animation where bouncer position is influenced
by touches.
Test: Pull up bouncer, press back button
Test: Pull up bouncer, unlock with fp
Test: Unlock with fp with bouncer hidden
Test: Unlock with SmartLock
Test: Ask for auth on top of FLAG_SHOW_WHEN_LOCKED activity, press back
Test: packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
Fixes: 3699775
Change-Id: I016dfa17f17571261691669c82385d2d844c5917
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
index 474fc90..62b5004 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
@@ -149,7 +149,6 @@
mSecurityContainer.setLockPatternUtils(mLockPatternUtils);
mSecurityContainer.setSecurityCallback(this);
mSecurityContainer.showPrimarySecurityScreen(false);
- // mSecurityContainer.updateSecurityViews(false /* not bouncing */);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java
index 526e5fa..e18ac74 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java
@@ -79,8 +79,8 @@
@Override
public float getFalseTouchEvaluation(int type, Stroke stroke) {
Data data = mStrokeMap.get(stroke);
- return AnglesVarianceEvaluator.evaluate(data.getAnglesVariance())
- + AnglesPercentageEvaluator.evaluate(data.getAnglesPercentage());
+ return AnglesVarianceEvaluator.evaluate(data.getAnglesVariance(), type)
+ + AnglesPercentageEvaluator.evaluate(data.getAnglesPercentage(), type);
}
private static class Data {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesPercentageEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesPercentageEvaluator.java
index e6c42da..e6e42f2 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesPercentageEvaluator.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/AnglesPercentageEvaluator.java
@@ -17,10 +17,11 @@
package com.android.systemui.classifier;
public class AnglesPercentageEvaluator {
- public static float evaluate(float value) {
+ public static float evaluate(float value, int type) {
+ final boolean secureUnlock = type == Classifier.BOUNCER_UNLOCK;
float evaluation = 0.0f;
- if (value < 1.00) evaluation++;
- if (value < 0.90) evaluation++;
+ if (value < 1.00 && !secureUnlock) evaluation++;
+ if (value < 0.90 && !secureUnlock) evaluation++;
if (value < 0.70) evaluation++;
return evaluation;
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java
index 99cc1a6..6883dd0 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java
@@ -17,14 +17,15 @@
package com.android.systemui.classifier;
public class AnglesVarianceEvaluator {
- public static float evaluate(float value) {
+ public static float evaluate(float value, int type) {
+ final boolean secureUnlock = type == Classifier.BOUNCER_UNLOCK;
float evaluation = 0.0f;
if (value > 0.05) evaluation++;
if (value > 0.10) evaluation++;
if (value > 0.20) evaluation++;
- if (value > 0.40) evaluation++;
- if (value > 0.80) evaluation++;
- if (value > 1.50) evaluation++;
+ if (value > 0.40 && !secureUnlock) evaluation++;
+ if (value > 0.80 && !secureUnlock) evaluation++;
+ if (value > 1.50 && !secureUnlock) evaluation++;
return evaluation;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
index cb761a9..909896e 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
@@ -31,6 +31,7 @@
public static final int LEFT_AFFORDANCE = 5;
public static final int RIGHT_AFFORDANCE = 6;
public static final int GENERIC = 7;
+ public static final int BOUNCER_UNLOCK = 8;
/**
* Contains all the information about touch events from which the classifier can query
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DirectionEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/DirectionEvaluator.java
index e20b1ca6..5f04222 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/DirectionEvaluator.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/DirectionEvaluator.java
@@ -33,6 +33,7 @@
}
break;
case Classifier.UNLOCK:
+ case Classifier.BOUNCER_UNLOCK:
if (!vertical || yDiff >= 0.0) {
return falsingEvaluation;
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index ed659e2..913e781 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -356,11 +356,12 @@
mDataCollector.setQsExpanded(expanded);
}
- public void onTrackingStarted() {
+ public void onTrackingStarted(boolean secure) {
if (FalsingLog.ENABLED) {
FalsingLog.i("onTrackingStarted", "");
}
- mHumanInteractionClassifier.setType(Classifier.UNLOCK);
+ mHumanInteractionClassifier.setType(secure ?
+ Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK);
mDataCollector.onTrackingStarted();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6940264..a1b17e4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -83,6 +83,7 @@
import com.android.systemui.UiOffloadThread;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.statusbar.phone.FingerprintUnlockController;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -2011,8 +2012,9 @@
}
public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar,
- ViewGroup container, FingerprintUnlockController fingerprintUnlockController) {
- mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container,
+ ViewGroup container, NotificationPanelView panelView,
+ FingerprintUnlockController fingerprintUnlockController) {
+ mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView,
fingerprintUnlockController, mDismissCallbackRegistry);
return mStatusBarKeyguardViewManager;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index edfbd3f..1109955 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -20,6 +20,7 @@
import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.MathUtils;
import android.util.Slog;
import android.util.StatsLog;
import android.view.KeyEvent;
@@ -49,7 +50,8 @@
*/
public class KeyguardBouncer {
- final static private String TAG = "KeyguardBouncer";
+ private static final String TAG = "KeyguardBouncer";
+ static final float ALPHA_EXPANSION_THRESHOLD = 0.95f;
protected final Context mContext;
protected final ViewMediatorCallback mCallback;
@@ -86,13 +88,25 @@
}
public void show(boolean resetSecuritySelection) {
+ show(resetSecuritySelection, true /* notifyFalsing */);
+ }
+
+ public void show(boolean resetSecuritySelection, boolean notifyFalsing) {
final int keyguardUserId = KeyguardUpdateMonitor.getCurrentUser();
if (keyguardUserId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser()) {
// In split system user mode, we never unlock system user.
return;
}
- mFalsingManager.onBouncerShown();
ensureView();
+
+ // On the keyguard, we want to show the bouncer when the user drags up, but it's
+ // not correct to end the falsing session. We still need to verify if those touches
+ // are valid.
+ // Later, at the end of the animation, when the bouncer is at the top of the screen,
+ // onFullyShown() will be called and FalsingManager will stop recording touches.
+ if (notifyFalsing) {
+ mFalsingManager.onBouncerShown();
+ }
if (resetSecuritySelection) {
// showPrimarySecurityScreen() updates the current security method. This is needed in
// case we are already showing and the current security method changed.
@@ -126,6 +140,28 @@
mCallback.onBouncerVisiblityChanged(true /* shown */);
}
+ /**
+ * This method must be called at the end of the bouncer animation when
+ * the translation is performed manually by the user, otherwise FalsingManager
+ * will never be notified and its internal state will be out of sync.
+ */
+ public void onFullyShown() {
+ mFalsingManager.onBouncerShown();
+ }
+
+ /**
+ * This method must be called at the end of the bouncer animation when
+ * the translation is performed manually by the user, otherwise FalsingManager
+ * will never be notified and its internal state will be out of sync.
+ */
+ public void onFullyHidden() {
+ if (!mShowingSoon) {
+ cancelShowRunnable();
+ inflateView();
+ mFalsingManager.onBouncerHidden();
+ }
+ }
+
private final Runnable mShowRunnable = new Runnable() {
@Override
public void run() {
@@ -247,6 +283,18 @@
mBouncerPromptReason = mCallback.getBouncerPromptReason();
}
+ /**
+ * Current notification panel expansion
+ * @param fraction 0 when notification panel is collapsed and 1 when expanded.
+ * @see StatusBarKeyguardViewManager#onPanelExpansionChanged
+ */
+ public void setExpansion(float fraction) {
+ if (mKeyguardView != null) {
+ mKeyguardView.setAlpha(MathUtils.map(ALPHA_EXPANSION_THRESHOLD, 1, 1, 0, fraction));
+ mKeyguardView.setTranslationY(fraction * mKeyguardView.getHeight());
+ }
+ }
+
protected void ensureView() {
// Removal of the view might be deferred to reduce unlock latency,
// in this case we need to force the removal, otherwise we'll
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 0cf26df..1bd5e33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -79,14 +79,9 @@
private int mMaxShadeBottom;
/**
- * Margin that we should respect within the available space.
+ * Minimum distance from the status bar.
*/
- private int mContainerPadding;
-
- /**
- * Position where clock should be when the panel is collapsed.
- */
- private int mClockYTarget;
+ private int mContainerTopPadding;
/**
* @see NotificationPanelView#getMaxPanelHeight()
@@ -109,12 +104,22 @@
private float mDarkAmount;
/**
+ * If keyguard will require a password or just fade away.
+ */
+ private boolean mCurrentlySecure;
+
+ /**
+ * If notification panel view currently has a touch.
+ */
+ private boolean mTracking;
+
+ /**
* Refreshes the dimension values.
*/
public void loadDimens(Resources res) {
mClockNotificationsMargin = res.getDimensionPixelSize(
R.dimen.keyguard_clock_notifications_margin);
- mContainerPadding = res.getDimensionPixelSize(
+ mContainerTopPadding = res.getDimensionPixelSize(
R.dimen.keyguard_clock_top_margin);
mBurnInPreventionOffsetX = res.getDimensionPixelSize(
R.dimen.burn_in_prevention_offset_x);
@@ -124,8 +129,8 @@
public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
float expandedHeight, float maxPanelHeight, int parentHeight, int keyguardStatusHeight,
- float dark) {
- mMinTopMargin = minTopMargin;
+ float dark, boolean secure, boolean tracking) {
+ mMinTopMargin = minTopMargin + mContainerTopPadding;
mMaxShadeBottom = maxShadeBottom;
mNotificationStackHeight = notificationStackHeight;
mExpandedHeight = expandedHeight;
@@ -133,13 +138,8 @@
mHeight = parentHeight;
mKeyguardStatusHeight = keyguardStatusHeight;
mDarkAmount = dark;
-
- // Where the clock should stop when swiping up.
- // This should be outside of the display when unlocked or
- // under then status bar when the bouncer will be shown
- mClockYTarget = -mKeyguardStatusHeight;
- // TODO: on bouncer animation follow-up CL
- // mClockYTarget = mMinTopMargin + mContainerPadding;
+ mCurrentlySecure = secure;
+ mTracking = tracking;
}
public void run(Result result) {
@@ -173,8 +173,8 @@
float y = containerCenter - mKeyguardStatusHeight * CLOCK_HEIGHT_WEIGHT
- mClockNotificationsMargin - mNotificationStackHeight / 2;
- if (y < mMinTopMargin + mContainerPadding) {
- y = mMinTopMargin + mContainerPadding;
+ if (y < mMinTopMargin) {
+ y = mMinTopMargin;
}
// Don't allow the clock base to be under half of the screen
@@ -190,18 +190,32 @@
// Dark: Align the bottom edge of the clock at about half of the screen:
final float clockYDark = getMaxClockY() + burnInPreventionOffsetY();
float clockYRegular = getExpandedClockPosition();
+ float clockYTarget = mCurrentlySecure ? mMinTopMargin : -mKeyguardStatusHeight;
// Move clock up while collapsing the shade
final float shadeExpansion = mExpandedHeight / mMaxPanelHeight;
- final float clockY = MathUtils.lerp(mClockYTarget, clockYRegular, shadeExpansion);
+ final float clockY = MathUtils.lerp(clockYTarget, clockYRegular, shadeExpansion);
return (int) MathUtils.lerp(clockY, clockYDark, mDarkAmount);
}
+ /**
+ * We might want to fade out the clock when the user is swiping up.
+ * One exception is when the bouncer will become visible, in this cause the clock
+ * should always persist.
+ *
+ * @param y Current clock Y.
+ * @return Alpha from 0 to 1.
+ */
private float getClockAlpha(int y) {
- float alphaKeyguard = Math.max(0, Math.min(1, (y - mMinTopMargin)
- / Math.max(1f, getExpandedClockPosition() - mMinTopMargin)));
- alphaKeyguard = Interpolators.ACCELERATE.getInterpolation(alphaKeyguard);
+ float alphaKeyguard;
+ if (mCurrentlySecure) {
+ alphaKeyguard = 1;
+ } else {
+ alphaKeyguard = Math.max(0, Math.min(1, (y - mMinTopMargin)
+ / Math.max(1f, getExpandedClockPosition() - mMinTopMargin)));
+ alphaKeyguard = Interpolators.ACCELERATE.getInterpolation(alphaKeyguard);
+ }
return MathUtils.lerp(alphaKeyguard, 1f, mDarkAmount);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 9d2480b..2711d7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -238,7 +238,6 @@
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private boolean mNoVisibleNotifications = true;
private ValueAnimator mDarkAnimator;
- private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private boolean mUserSetupComplete;
private int mQsNotificationTopPadding;
private float mExpandOffset;
@@ -265,10 +264,8 @@
mKeyguardStatusBar = findViewById(R.id.keyguard_header);
mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
- mNotificationContainerParent = (NotificationsQuickSettingsContainer)
- findViewById(R.id.notification_container_parent);
- mNotificationStackScroller = (NotificationStackScrollLayout)
- findViewById(R.id.notification_stack_scroller);
+ mNotificationContainerParent = findViewById(R.id.notification_container_parent);
+ mNotificationStackScroller = findViewById(R.id.notification_stack_scroller);
mNotificationStackScroller.setOnHeightChangedListener(this);
mNotificationStackScroller.setOverscrollTopChangedListener(this);
mNotificationStackScroller.setOnEmptySpaceClickListener(this);
@@ -470,7 +467,9 @@
getMaxPanelHeight(),
totalHeight,
mKeyguardStatusView.getHeight(),
- mDarkAmount);
+ mDarkAmount,
+ mStatusBar.isKeyguardCurrentlySecure(),
+ mTracking);
mClockPositionAlgorithm.run(mClockPositionResult);
if (animate || mClockAnimator != null) {
startClockAnimation(mClockPositionResult.clockX, mClockPositionResult.clockY);
@@ -1710,7 +1709,16 @@
}
private void updateKeyguardBottomAreaAlpha() {
- float alpha = Math.min(getKeyguardContentsAlpha(), 1 - getQsExpansionFraction());
+ // There are two possible panel expansion behaviors:
+ // • User dragging up to unlock: we want to fade out as quick as possible
+ // (ALPHA_EXPANSION_THRESHOLD) to avoid seeing the bouncer over the bottom area.
+ // • User tapping on lock screen: bouncer won't be visible but panel expansion will
+ // change due to "unlock hint animation." In this case, fading out the bottom area
+ // would also hide the message that says "swipe to unlock," we don't want to do that.
+ float expansionAlpha = MathUtils.map(isUnlockHintRunning()
+ ? 0 : KeyguardBouncer.ALPHA_EXPANSION_THRESHOLD, 1f,
+ 0f, 1f, getExpandedFraction());
+ float alpha = Math.min(expansionAlpha, 1 - getQsExpansionFraction());
mKeyguardBottomArea.setAlpha(alpha);
mKeyguardBottomArea.setImportantForAccessibility(alpha == 0f
? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
@@ -1809,7 +1817,7 @@
@Override
protected void onTrackingStarted() {
- mFalsingManager.onTrackingStarted();
+ mFalsingManager.onTrackingStarted(mStatusBar.isKeyguardCurrentlySecure());
super.onTrackingStarted();
if (mQsFullyExpanded) {
mQsExpandImmediate = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index cefe972..b448967 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -27,6 +27,7 @@
public static final boolean DEBUG = false;
public static final String TAG = PanelBar.class.getSimpleName();
private static final boolean SPEW = false;
+ private boolean mBouncerShowing;
public static final void LOG(String fmt, Object... args) {
if (!DEBUG) return;
@@ -65,6 +66,7 @@
}
public void setBouncerShowing(boolean showing) {
+ mBouncerShowing = showing;
int important = showing ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
: IMPORTANT_FOR_ACCESSIBILITY_AUTO;
@@ -122,7 +124,7 @@
boolean fullyOpened = false;
if (SPEW) LOG("panelExpansionChanged: start state=%d", mState);
PanelView pv = mPanel;
- pv.setVisibility(expanded ? VISIBLE : INVISIBLE);
+ pv.setVisibility(expanded || mBouncerShowing ? VISIBLE : INVISIBLE);
// adjust any other panels that may be partially visible
if (expanded) {
if (mState == STATE_CLOSED) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 7c91a40..3de0a41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -23,14 +23,8 @@
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.os.AsyncTask;
-import android.os.Handler;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.os.VibrationEffect;
-import android.os.Vibrator;
-import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.InputDevice;
@@ -51,10 +45,10 @@
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.function.BiConsumer;
public abstract class PanelView extends FrameLayout {
public static final boolean DEBUG = PanelBar.DEBUG;
@@ -69,6 +63,7 @@
private boolean mVibrateOnOpening;
protected boolean mLaunchingNotification;
private int mFixedDuration = NO_FIXED_DURATION;
+ private BiConsumer<Float, Boolean> mExpansionListener;
private final void logf(String fmt, Object... args) {
Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -326,7 +321,8 @@
cancelPeek();
onTrackingStarted();
}
- if (isFullyCollapsed() && !mHeadsUpManager.hasPinnedHeadsUp()) {
+ if (isFullyCollapsed() && !mHeadsUpManager.hasPinnedHeadsUp()
+ && !mStatusBar.isBouncerShowing()) {
startOpening(event);
}
break;
@@ -490,7 +486,8 @@
if (mUpdateFlingOnLayout) {
mUpdateFlingVelocity = vel;
}
- } else if (mPanelClosedOnDown && !mHeadsUpManager.hasPinnedHeadsUp() && !mTracking) {
+ } else if (mPanelClosedOnDown && !mHeadsUpManager.hasPinnedHeadsUp() && !mTracking
+ && !mStatusBar.isBouncerShowing()) {
long timePassed = SystemClock.uptimeMillis() - mDownTime;
if (timePassed < ViewConfiguration.getLongPressTimeout()) {
// Lets show the user that he can actually expand the panel
@@ -499,7 +496,7 @@
// We need to collapse the panel since we peeked to the small height.
postOnAnimation(mPostCollapseRunnable);
}
- } else {
+ } else if (!mStatusBar.isBouncerShowing()) {
boolean expands = onEmptySpaceClick(mInitialTouchX);
onTrackingStopped(expands);
}
@@ -1099,6 +1096,10 @@
mStatusBar.onUnlockHintStarted();
}
+ public boolean isUnlockHintRunning() {
+ return mHintAnimationRunning;
+ }
+
/**
* Phase 1: Move everything upwards.
*/
@@ -1190,6 +1191,13 @@
mBar.panelExpansionChanged(mExpandedFraction, mExpandedFraction > 0f
|| mPeekAnimator != null || mInstantExpanding || isPanelVisibleBecauseOfHeadsUp()
|| mTracking || mHeightAnimator != null);
+ if (mExpansionListener != null) {
+ mExpansionListener.accept(mExpandedFraction, mTracking);
+ }
+ }
+
+ public void setExpansionListener(BiConsumer<Float, Boolean> consumer) {
+ mExpansionListener = consumer;
}
protected abstract boolean isPanelVisibleBecauseOfHeadsUp();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index e59a6b5..71376a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -35,7 +35,6 @@
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
@@ -97,14 +96,6 @@
* The most common scrim, the one under the keyguard.
*/
protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
- /**
- * We fade out the bottom scrim when the bouncer is visible.
- */
- protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
- /**
- * Opacity of the scrim behind the bouncer (the one doing actual background protection.)
- */
- protected static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
static final int TAG_KEY_ANIM = R.id.scrim;
private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
@@ -130,7 +121,6 @@
protected float mScrimBehindAlpha;
protected float mScrimBehindAlphaResValue;
protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
- protected float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
// Assuming the shade is expanded during initialization
private float mExpansionFraction = 1f;
@@ -177,6 +167,7 @@
mScrimVisibleListener = scrimVisibleListener;
mContext = scrimBehind.getContext();
mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
+ mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
mLightBarController = lightBarController;
mScrimBehindAlphaResValue = mContext.getResources().getFloat(R.dimen.scrim_behind_alpha);
@@ -300,10 +291,8 @@
return mState;
}
- protected void setScrimBehindValues(float scrimBehindAlphaKeyguard,
- float scrimBehindAlphaUnlocking) {
+ protected void setScrimBehindValues(float scrimBehindAlphaKeyguard) {
mScrimBehindAlphaKeyguard = scrimBehindAlphaKeyguard;
- mScrimBehindAlphaUnlocking = scrimBehindAlphaUnlocking;
ScrimState[] states = ScrimState.values();
for (int i = 0; i < states.length; i++) {
states[i].setScrimBehindAlphaKeyguard(scrimBehindAlphaKeyguard);
@@ -404,9 +393,9 @@
float interpolatedFract = getInterpolatedFraction();
float alphaBehind = mState.getBehindAlpha(mNotificationDensity);
if (mDarkenWhileDragging) {
- mCurrentBehindAlpha = MathUtils.lerp(mScrimBehindAlphaUnlocking, alphaBehind,
+ mCurrentBehindAlpha = MathUtils.lerp(GRADIENT_SCRIM_ALPHA_BUSY, alphaBehind,
interpolatedFract);
- mCurrentInFrontAlpha = (1f - interpolatedFract) * SCRIM_IN_FRONT_ALPHA_LOCKED;
+ mCurrentInFrontAlpha = 0;
} else {
mCurrentBehindAlpha = MathUtils.lerp(0 /* start */, alphaBehind,
interpolatedFract);
@@ -455,7 +444,8 @@
if (mNeedsDrawableColorUpdate) {
mNeedsDrawableColorUpdate = false;
final GradientColors currentScrimColors;
- if (mState == ScrimState.KEYGUARD || mState == ScrimState.BOUNCER) {
+ if (mState == ScrimState.KEYGUARD || mState == ScrimState.BOUNCER_OCCLUDED
+ || mState == ScrimState.BOUNCER) {
// Always animate color changes if we're seeing the keyguard
mScrimInFront.setColors(mLockColors, true /* animated */);
mScrimBehind.setColors(mLockColors, true /* animated */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 053c5a3..58100ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -66,20 +66,31 @@
},
/**
- * Showing password challenge.
+ * Showing password challenge on the keyguard.
*/
BOUNCER(1) {
@Override
public void prepare(ScrimState previousState) {
- mCurrentBehindAlpha = ScrimController.SCRIM_BEHIND_ALPHA_UNLOCKING;
- mCurrentInFrontAlpha = ScrimController.SCRIM_IN_FRONT_ALPHA_LOCKED;
+ mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
+ mCurrentInFrontAlpha = 0f;
+ }
+ },
+
+ /**
+ * Showing password challenge on top of a FLAG_SHOW_WHEN_LOCKED activity.
+ */
+ BOUNCER_OCCLUDED(2) {
+ @Override
+ public void prepare(ScrimState previousState) {
+ mCurrentBehindAlpha = 0;
+ mCurrentInFrontAlpha = ScrimController.GRADIENT_SCRIM_ALPHA_BUSY;
}
},
/**
* Changing screen brightness from quick settings.
*/
- BRIGHTNESS_MIRROR(2) {
+ BRIGHTNESS_MIRROR(3) {
@Override
public void prepare(ScrimState previousState) {
mCurrentBehindAlpha = 0;
@@ -90,7 +101,7 @@
/**
* Always on display or screen off.
*/
- AOD(3) {
+ AOD(4) {
@Override
public void prepare(ScrimState previousState) {
final boolean alwaysOnEnabled = mDozeParameters.getAlwaysOn();
@@ -110,7 +121,7 @@
/**
* When phone wakes up because you received a notification.
*/
- PULSING(4) {
+ PULSING(5) {
@Override
public void prepare(ScrimState previousState) {
mCurrentInFrontAlpha = 0;
@@ -125,7 +136,7 @@
/**
* Unlocked on top of an app (launcher or any other activity.)
*/
- UNLOCKED(5) {
+ UNLOCKED(6) {
@Override
public void prepare(ScrimState previousState) {
mCurrentBehindAlpha = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 899b936..a305bfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1296,7 +1296,7 @@
mDozeScrimController, keyguardViewMediator,
mScrimController, this, UnlockMethodCache.getInstance(mContext));
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
- getBouncerContainer(), mFingerprintUnlockController);
+ getBouncerContainer(), mNotificationPanel, mFingerprintUnlockController);
mKeyguardIndicationController
.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
@@ -4619,7 +4619,8 @@
== FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
if (mBouncerShowing) {
- mScrimController.transitionTo(ScrimState.BOUNCER);
+ mScrimController.transitionTo(
+ mIsOccluded ? ScrimState.BOUNCER_OCCLUDED : ScrimState.BOUNCER);
} else if (mLaunchCameraOnScreenTurningOn || isInLaunchTransition()) {
mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
} else if (mBrightnessMirrorVisible) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index a009d80..8d536d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -31,10 +31,10 @@
import android.view.ViewRootImpl;
import android.view.WindowManagerGlobal;
+import com.android.internal.util.LatencyTracker;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.internal.util.LatencyTracker;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dependency;
@@ -75,6 +75,7 @@
protected LockPatternUtils mLockPatternUtils;
protected ViewMediatorCallback mViewMediatorCallback;
protected StatusBar mStatusBar;
+ private NotificationPanelView mNotificationPanelView;
private FingerprintUnlockController mFingerprintUnlockController;
private ViewGroup mContainer;
@@ -88,6 +89,7 @@
protected boolean mFirstUpdate = true;
protected boolean mLastShowing;
protected boolean mLastOccluded;
+ private boolean mLastTracking;
private boolean mLastBouncerShowing;
private boolean mLastBouncerDismissible;
protected boolean mLastRemoteInputActive;
@@ -124,6 +126,7 @@
public void registerStatusBar(StatusBar statusBar,
ViewGroup container,
+ NotificationPanelView notificationPanelView,
FingerprintUnlockController fingerprintUnlockController,
DismissCallbackRegistry dismissCallbackRegistry) {
mStatusBar = statusBar;
@@ -131,6 +134,32 @@
mFingerprintUnlockController = fingerprintUnlockController;
mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext,
mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry);
+ mNotificationPanelView = notificationPanelView;
+ notificationPanelView.setExpansionListener(this::onPanelExpansionChanged);
+ }
+
+ private void onPanelExpansionChanged(float expansion, boolean tracking) {
+ // We don't want to translate the bounce when the keyguard is occluded, because we're in
+ // a FLAG_SHOW_WHEN_LOCKED activity and need to conserve the original animation.
+ // We also don't want to show the bouncer when the user quickly taps on the display.
+ final boolean noLongerTracking = mLastTracking != tracking && !tracking;
+ if (mOccluded || mNotificationPanelView.isUnlockHintRunning()) {
+ mBouncer.setExpansion(0);
+ } else if (mShowing && mStatusBar.isKeyguardCurrentlySecure() && !mDozing) {
+ mBouncer.setExpansion(expansion);
+ if (expansion == 1) {
+ mBouncer.onFullyHidden();
+ updateStates();
+ } else if (!mBouncer.isShowing()) {
+ mBouncer.show(true /* resetSecuritySelection */, false /* notifyFalsing */);
+ } else if (noLongerTracking) {
+ // Notify that falsing manager should stop its session when user stops touching,
+ // even before the animation ends, to guarantee that we're not recording sensitive
+ // data.
+ mBouncer.onFullyShown();
+ }
+ }
+ mLastTracking = tracking;
}
/**