Cancel touches on the unlocked animation

On the lock screen, users are able to drag
their finger to the UDFPS location which can leave
the panel expansion in a transition state while
the device is being transioned to the home screen.
therefore, we need to:

* on unlock, instantCollapse notification panel if it's already in the
middle of being flung away so there aren't overriding animators.

* don't expand the bouncer if the device is unlocking

* cancel launch transition end runnables on going to sleep
in case the user presses the power button quickly after
unlocking, before the launch transition end runnable gets
to run. We don't end up in a bad state where we hide the
keyguard (due to the launchTransitionEndRunnable) when we
actually wanted to show it

* don't update the UNLOCKED scrim when the device is
updating the panel expansion during the unlock animation

Fixes: 222324260
Test: atest SystemUITests
Test: manually authenticate UDFPS from dragging finger
from diagonally above/right of UDFPS (and from below)

Change-Id: I8f0b50c01544c3cf206bb764b2c5e5554dcd256d
This commit is contained in:
Beverly
2022-03-04 17:36:54 +00:00
committed by Beverly Tai
parent c3cf521667
commit df83af614f
11 changed files with 139 additions and 25 deletions

View File

@@ -5026,6 +5026,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
.append(" qsExpandFraction=").append(mQsExpansionFraction)
.append(" isCurrentUserSetup=").append(mIsCurrentUserSetup)
.append(" hideAmount=").append(mAmbientState.getHideAmount())
.append(" ambientStateSwipingUp=").append(mAmbientState.isSwipingUp())
.append("]");
pw.println(sb.toString());
DumpUtilsKt.withIncreasedIndent(pw, () -> {

View File

@@ -641,6 +641,7 @@ public class CentralSurfaces extends CoreStartable implements
private boolean mWallpaperSupported;
private Runnable mLaunchTransitionEndRunnable;
private Runnable mLaunchTransitionCancelRunnable;
private boolean mLaunchCameraWhenFinishedWaking;
private boolean mLaunchCameraOnFinishedGoingToSleep;
private boolean mLaunchEmergencyActionWhenFinishedWaking;
@@ -2967,12 +2968,15 @@ public class CentralSurfaces extends CoreStartable implements
*
* @param beforeFading the runnable to be run when the circle is fully expanded and the fading
* starts
* @param endRunnable the runnable to be run when the transition is done
* @param endRunnable the runnable to be run when the transition is done. Will not run
* if the transition is cancelled, instead cancelRunnable will run
* @param cancelRunnable the runnable to be run if the transition is cancelled
*/
public void fadeKeyguardAfterLaunchTransition(final Runnable beforeFading,
Runnable endRunnable) {
Runnable endRunnable, Runnable cancelRunnable) {
mMessageRouter.cancelMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
mLaunchTransitionEndRunnable = endRunnable;
mLaunchTransitionCancelRunnable = cancelRunnable;
Runnable hideRunnable = () -> {
mKeyguardStateController.setLaunchTransitionFadingAway(true);
if (beforeFading != null) {
@@ -2994,6 +2998,15 @@ public class CentralSurfaces extends CoreStartable implements
}
}
private void cancelAfterLaunchTransitionRunnables() {
if (mLaunchTransitionCancelRunnable != null) {
mLaunchTransitionCancelRunnable.run();
}
mLaunchTransitionEndRunnable = null;
mLaunchTransitionCancelRunnable = null;
mNotificationPanelViewController.setLaunchTransitionEndRunnable(null);
}
/**
* Fades the content of the Keyguard while we are dozing and makes it invisible when finished
* fading.
@@ -3033,6 +3046,7 @@ public class CentralSurfaces extends CoreStartable implements
}
private void runLaunchTransitionEndRunnable() {
mLaunchTransitionCancelRunnable = null;
if (mLaunchTransitionEndRunnable != null) {
Runnable r = mLaunchTransitionEndRunnable;
@@ -3524,6 +3538,10 @@ public class CentralSurfaces extends CoreStartable implements
public void onStartedGoingToSleep() {
String tag = "CentralSurfaces#onStartedGoingToSleep";
DejankUtils.startDetectingBlockingIpcs(tag);
// cancel stale runnables that could put the device in the wrong state
cancelAfterLaunchTransitionRunnables();
updateRevealEffect(false /* wakingUp */);
updateNotificationPanelTouchState();
maybeEscalateHeadsUp();

View File

@@ -894,10 +894,17 @@ public class NotificationPanelViewController extends PanelViewController {
mDepthController.setBlursDisabledForUnlock(mTracking);
if (playingCannedAnimation && !isWakeAndUnlock) {
// Fling the panel away so it's not in the way or the surface behind the
// Hide the panel so it's not in the way or the surface behind the
// keyguard, which will be appearing. If we're wake and unlocking, the
// lock screen is hidden instantly so should not be flung away.
fling(0f, false, 0.7f, false);
if (isTracking() || isFlinging()) {
// Instant collpase the notification panel since the notification
// panel is already in the middle animating
onTrackingStopped(false);
instantCollapse();
} else {
fling(0f, false, 0.7f, false);
}
}
}
});

View File

@@ -36,12 +36,14 @@ import com.android.keyguard.LockIconViewController;
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.lowlightclock.LowLightClockController;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
@@ -71,6 +73,8 @@ public class NotificationShadeWindowViewController {
private final LockIconViewController mLockIconViewController;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private final StatusBarWindowStateController mStatusBarWindowStateController;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private final AmbientState mAmbientState;
private GestureDetector mGestureDetector;
private View mBrightnessMirror;
@@ -109,7 +113,9 @@ public class NotificationShadeWindowViewController {
LockIconViewController lockIconViewController,
Optional<LowLightClockController> lowLightClockController,
CentralSurfaces centralSurfaces,
NotificationShadeWindowController controller) {
NotificationShadeWindowController controller,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
AmbientState ambientState) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
mTunerService = tunerService;
@@ -126,6 +132,8 @@ public class NotificationShadeWindowViewController {
mLowLightClockController = lowLightClockController;
mService = centralSurfaces;
mNotificationShadeWindowController = controller;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mAmbientState = ambientState;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -203,7 +211,6 @@ public class NotificationShadeWindowViewController {
// Reset manual touch dispatch state here but make sure the UP/CANCEL event still
// gets
// delivered.
if (!isCancel && mService.shouldIgnoreTouch()) {
return false;
}
@@ -219,6 +226,16 @@ public class NotificationShadeWindowViewController {
return false;
}
if (mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
// If the user was sliding their finger across the lock screen,
// we may have been intercepting the touch and forwarding it to the
// UDFPS affordance via mStatusBarKeyguardViewManager.onTouch (see below).
// If this touch ended up unlocking the device, we want to cancel the touch
// immediately, so we don't cause swipe or expand animations afterwards.
cancelCurrentTouch();
return true;
}
mFalsingCollector.onTouchEvent(ev);
mGestureDetector.onTouchEvent(ev);
mStatusBarKeyguardViewManager.onTouch(ev);
@@ -430,6 +447,7 @@ public class NotificationShadeWindowViewController {
event.recycle();
mTouchCancelled = true;
}
mAmbientState.setSwipingUp(false);
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {

View File

@@ -865,6 +865,10 @@ public abstract class PanelViewController {
return mClosing || mIsLaunchAnimationRunning;
}
public boolean isFlinging() {
return mIsFlinging;
}
public boolean isTracking() {
return mTracking;
}

View File

@@ -52,6 +52,7 @@ import com.android.systemui.animation.ShadeInterpolation;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
@@ -195,6 +196,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private final Handler mHandler;
private final Executor mMainExecutor;
private final ScreenOffAnimationController mScreenOffAnimationController;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private GradientColors mColors;
private boolean mNeedsDrawableColorUpdate;
@@ -211,6 +213,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private float mPanelExpansionFraction = 1f; // Assume shade is expanded during initialization
private float mQsExpansion;
private boolean mQsBottomVisible;
private boolean mAnimatingPanelExpansionOnUnlock; // don't animate scrim
private boolean mDarkenWhileDragging;
private boolean mExpansionAffectsAlpha = true;
@@ -255,7 +258,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
ConfigurationController configurationController, @Main Executor mainExecutor,
ScreenOffAnimationController screenOffAnimationController,
PanelExpansionStateManager panelExpansionStateManager) {
PanelExpansionStateManager panelExpansionStateManager,
KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
mScrimStateListener = lightBarController::setScrimState;
mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;
@@ -273,6 +277,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
// to make sure that text on top of it is legible.
mDozeParameters = dozeParameters;
mDockManager = dockManager;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
public void onKeyguardFadingAwayChanged() {
@@ -497,6 +502,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
public void onTrackingStarted() {
mTracking = true;
mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen();
if (!mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
mAnimatingPanelExpansionOnUnlock = false;
}
}
public void onExpandingFinished() {
@@ -567,13 +575,20 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
if (mPanelExpansionFraction != panelExpansionFraction) {
if (panelExpansionFraction != 0f
&& mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
mAnimatingPanelExpansionOnUnlock = true;
} else if (panelExpansionFraction == 0f) {
mAnimatingPanelExpansionOnUnlock = false;
}
mPanelExpansionFraction = panelExpansionFraction;
boolean relevantState = (mState == ScrimState.UNLOCKED
|| mState == ScrimState.KEYGUARD
|| mState == ScrimState.SHADE_LOCKED
|| mState == ScrimState.PULSING);
if (!(relevantState && mExpansionAffectsAlpha)) {
if (!(relevantState && mExpansionAffectsAlpha) || mAnimatingPanelExpansionOnUnlock) {
return;
}
applyAndDispatchState();
@@ -721,8 +736,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
if (mState == ScrimState.UNLOCKED) {
// Darken scrim as you pull down the shade when unlocked, unless the shade is expanding
// because we're doing the screen off animation.
if (!mScreenOffAnimationController.shouldExpandNotifications()) {
// because we're doing the screen off animation OR the shade is collapsing because
// we're playing the unlock animation
if (!mScreenOffAnimationController.shouldExpandNotifications()
&& !mAnimatingPanelExpansionOnUnlock) {
float behindFraction = getInterpolatedFraction();
behindFraction = (float) Math.pow(behindFraction, 0.8f);
if (mClipsQsScrim) {
@@ -794,6 +811,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mNotificationsTint = ScrimState.KEYGUARD.getNotifTint();
}
}
if (mState != ScrimState.UNLOCKED) {
mAnimatingPanelExpansionOnUnlock = false;
}
assertAlphasValid();
}

View File

@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone;
import static android.view.WindowInsets.Type.navigationBars;
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_COLLAPSING;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_FADING;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
@@ -360,7 +361,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
} else if (bouncerNeedsScrimming()) {
mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
} else if (mShowing) {
if (!isWakeAndUnlocking() && !mCentralSurfaces.isInLaunchTransition()) {
if (!isWakeAndUnlocking()
&& !mCentralSurfaces.isInLaunchTransition()
&& !isUnlockCollapsing()) {
mBouncer.setExpansion(fraction);
}
if (fraction != KeyguardBouncer.EXPANSION_HIDDEN && tracking
@@ -528,6 +531,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
return mode == MODE_WAKE_AND_UNLOCK || mode == MODE_WAKE_AND_UNLOCK_PULSING;
}
private boolean isUnlockCollapsing() {
int mode = mBiometricUnlockController.getMode();
return mode == MODE_UNLOCK_COLLAPSING;
}
/**
* Adds a {@param runnable} to be executed after Keyguard is gone.
*/
@@ -657,14 +665,17 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__OCCLUDED);
if (mCentralSurfaces.isInLaunchTransition()) {
setOccludedAndUpdateStates(true);
mCentralSurfaces.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
new Runnable() {
@Override
public void run() {
mNotificationShadeWindowController.setKeyguardOccluded(mOccluded);
reset(true /* hideBouncerWhenShowing */);
}
});
final Runnable endRunnable = new Runnable() {
@Override
public void run() {
mNotificationShadeWindowController.setKeyguardOccluded(mOccluded);
reset(true /* hideBouncerWhenShowing */);
}
};
mCentralSurfaces.fadeKeyguardAfterLaunchTransition(
null /* beforeFading */,
endRunnable,
endRunnable);
return;
}
@@ -759,7 +770,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
hideBouncer(true /* destroyView */);
updateStates();
}
}, new Runnable() {
}, /* endRunnable */ new Runnable() {
@Override
public void run() {
mCentralSurfaces.hideKeyguard();
@@ -772,6 +783,15 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mViewMediatorCallback.keyguardGone();
executeAfterKeyguardGoneAction();
}
}, /* cancelRunnable */ new Runnable() {
@Override
public void run() {
mNotificationShadeWindowController.setKeyguardFadingAway(false);
if (wasFlingingToDismissKeyguard) {
mCentralSurfaces.finishKeyguardFadingAway();
}
cancelPostAuthActions();
}
});
} else {
executeAfterKeyguardGoneAction();

View File

@@ -207,6 +207,8 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
private void setKeyguardFadingAway(boolean keyguardFadingAway) {
if (mKeyguardFadingAway != keyguardFadingAway) {
Trace.traceCounter(Trace.TRACE_TAG_APP, "keyguardFadingAway",
keyguardFadingAway ? 1 : 0);
mKeyguardFadingAway = keyguardFadingAway;
ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
for (int i = 0; i < callbacks.size(); i++) {
@@ -217,7 +219,7 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
@Override
public void notifyKeyguardDoneFading() {
mKeyguardGoingAway = false;
notifyKeyguardGoingAway(false);
setKeyguardFadingAway(false);
}
@@ -318,7 +320,11 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
@Override
public void notifyKeyguardGoingAway(boolean keyguardGoingAway) {
mKeyguardGoingAway = keyguardGoingAway;
if (mKeyguardGoingAway != keyguardGoingAway) {
Trace.traceCounter(Trace.TRACE_TAG_APP, "keyguardGoingAway",
keyguardGoingAway ? 1 : 0);
mKeyguardGoingAway = keyguardGoingAway;
}
}
@Override
@@ -368,6 +374,8 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
pw.println(" mTrusted: " + mTrusted);
pw.println(" mDebugUnlocked: " + mDebugUnlocked);
pw.println(" mFaceAuthEnabled: " + mFaceAuthEnabled);
pw.println(" isKeyguardFadingAway: " + isKeyguardFadingAway());
pw.println(" isKeyguardGoingAway: " + isKeyguardGoingAway());
}
private class UpdateMonitorCallback extends KeyguardUpdateMonitorCallback {

View File

@@ -24,11 +24,13 @@ import com.android.keyguard.LockIconViewController
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollectorFake
import com.android.systemui.dock.DockManager
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.lowlightclock.LowLightClockController
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.NotificationShadeDepthController
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.NotificationShadeWindowView.InteractionEventHandler
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
@@ -71,6 +73,10 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
@Mock
private lateinit var mNotificationShadeWindowController: NotificationShadeWindowController
@Mock
private lateinit var mKeyguardUnlockAnimationController: KeyguardUnlockAnimationController
@Mock
private lateinit var mAmbientState: AmbientState
@Mock
private lateinit var stackScrollLayoutController: NotificationStackScrollLayoutController
@Mock
private lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
@@ -109,7 +115,9 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
mLockIconViewController,
Optional.of(mLowLightClockController),
mCentralSurfaces,
mNotificationShadeWindowController
mNotificationShadeWindowController,
mKeyguardUnlockAnimationController,
mAmbientState
)
mController.setupExpandedStatusBar()

View File

@@ -37,12 +37,14 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.lowlightclock.LowLightClockController;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
@@ -83,6 +85,8 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Mock private LockIconViewController mLockIconViewController;
@Mock private LowLightClockController mLowLightClockController;
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock private AmbientState mAmbientState;
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
mInteractionEventHandlerCaptor;
@@ -117,7 +121,9 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
mLockIconViewController,
Optional.of(mLowLightClockController),
mCentralSurfaces,
mNotificationShadeWindowController);
mNotificationShadeWindowController,
mKeyguardUnlockAnimationController,
mAmbientState);
mController.setupExpandedStatusBar();
mController.setDragDownHelper(mDragDownHelper);
}

View File

@@ -53,6 +53,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.DejankUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -112,6 +113,8 @@ public class ScrimControllerTest extends SysuiTestCase {
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
// event-dispatch-on-registration pattern caused some of these unit tests to fail.)
@Mock
@@ -229,7 +232,8 @@ public class ScrimControllerTest extends SysuiTestCase {
new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()),
mScreenOffAnimationController,
mPanelExpansionStateManager);
mPanelExpansionStateManager,
mKeyguardUnlockAnimationController);
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
mScrimController.setAnimatorListener(mAnimatorListener);