From 62622226f016eedfad3346d24235617e13649ed4 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Thu, 29 Aug 2019 14:46:29 -0700 Subject: [PATCH] Do not show status bar on first bypass attempt The keyguard status bar has different paddings. Showing it for 0.5 seconds feels janky. From now on, if we're bypassing, we'll only show it after face auth fails Test: reach, press power, look at status bar: gone Test: reboot, reach, press power, look at status bar: visible Test: reach, press power, wait for auth filure, look at status bar: visible Test: reach, pull down, wait for auth filure, look at status bar: visible Fixes: 140259100 Change-Id: I52b3eee95a3ee67c3ec215d8b582967f900da4c8 Merged-In: I52b3eee95a3ee67c3ec215d8b582967f900da4c8 --- .../keyguard/KeyguardUpdateMonitor.java | 5 ++- .../phone/NotificationPanelView.java | 33 ++++++++++++++++-- .../phone/NotificationPanelViewTest.java | 34 +++++++++++++++---- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 0d456ff29914c..8d858dcb25df3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -1688,7 +1688,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { return shouldListen; } - private boolean shouldListenForFace() { + /** + * If face auth is allows to scan on this exact moment. + */ + public boolean shouldListenForFace() { final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep; final int user = getCurrentUser(); final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user); 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 d0626ed780e24..33b437277dded 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -39,6 +39,7 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.Region; +import android.hardware.biometrics.BiometricSourceType; import android.os.PowerManager; import android.os.SystemClock; import android.util.AttributeSet; @@ -59,6 +60,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.DejankUtils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; @@ -164,6 +166,25 @@ public class NotificationPanelView extends PanelView implements R.id.keyguard_hun_animator_start_tag); private static final AnimationProperties KEYGUARD_HUN_PROPERTIES = new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); + @VisibleForTesting + final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback = + new KeyguardUpdateMonitorCallback() { + @Override + public void onBiometricRunningStateChanged(boolean running, + BiometricSourceType biometricSourceType) { + boolean keyguardOrShadeLocked = mBarState == StatusBarState.KEYGUARD + || mBarState == StatusBarState.SHADE_LOCKED; + if (!running && mFirstBypassAttempt && keyguardOrShadeLocked && !mDozing) { + mFirstBypassAttempt = false; + animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD); + } + } + + @Override + public void onFinishedGoingToSleep(int why) { + mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled(); + } + }; private final InjectionInflationController mInjectionInflationController; private final PowerManager mPowerManager; @@ -171,8 +192,8 @@ public class NotificationPanelView extends PanelView implements private final NotificationWakeUpCoordinator mWakeUpCoordinator; private final PulseExpansionHandler mPulseExpansionHandler; private final KeyguardBypassController mKeyguardBypassController; - private final KeyguardUpdateMonitor mUpdateMonitor; - + @VisibleForTesting + protected KeyguardUpdateMonitor mUpdateMonitor; @VisibleForTesting protected KeyguardAffordanceHelper mAffordanceHelper; private KeyguardUserSwitcher mKeyguardUserSwitcher; @@ -383,6 +404,7 @@ public class NotificationPanelView extends PanelView implements private boolean mShowingKeyguardHeadsUp; private boolean mAllowExpandForSmallExpansion; private Runnable mExpandAfterLayoutRunnable; + private boolean mFirstBypassAttempt; @Inject public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, @@ -413,6 +435,7 @@ public class NotificationPanelView extends PanelView implements mThemeResId = context.getThemeResId(); mKeyguardBypassController = bypassController; mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext); + mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled(); dynamicPrivacyController.addListener(this); mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0); @@ -485,6 +508,7 @@ public class NotificationPanelView extends PanelView implements Dependency.get(StatusBarStateController.class).addCallback(this); Dependency.get(ZenModeController.class).addCallback(this); Dependency.get(ConfigurationController.class).addCallback(this); + mUpdateMonitor.registerCallback(mKeyguardUpdateCallback); // Theme might have changed between inflating this view and attaching it to the window, so // force a call to onThemeChanged onThemeChanged(); @@ -497,6 +521,7 @@ public class NotificationPanelView extends PanelView implements Dependency.get(StatusBarStateController.class).removeCallback(this); Dependency.get(ZenModeController.class).removeCallback(this); Dependency.get(ConfigurationController.class).removeCallback(this); + mUpdateMonitor.removeCallback(mKeyguardUpdateCallback); } @Override @@ -2237,7 +2262,9 @@ public class NotificationPanelView extends PanelView implements * mKeyguardStatusBarAnimateAlpha; newAlpha *= 1.0f - mKeyguardHeadsUpShowingAmount; mKeyguardStatusBar.setAlpha(newAlpha); - mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing ? VISIBLE : INVISIBLE); + boolean hideForBypass = mFirstBypassAttempt && mUpdateMonitor.shouldListenForFace(); + mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing && !hideForBypass + ? VISIBLE : INVISIBLE); } private void updateKeyguardBottomAreaAlpha() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index a96efd7d2fc2d..0334d49ce9dfb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -21,19 +21,23 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.StatusBarManager; +import android.hardware.biometrics.BiometricSourceType; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.MotionEvent; +import android.view.View; import android.view.ViewGroup; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardStatusView; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.FalsingManager; @@ -50,7 +54,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationRoundnessMa import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.systemui.tuner.TunerService; import com.android.systemui.util.InjectionInflationController; import org.junit.Before; @@ -100,7 +103,11 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private KeyguardAffordanceHelper mAffordanceHelper; @Mock + private KeyguardUpdateMonitor mUpdateMonitor; + @Mock private FalsingManager mFalsingManager; + @Mock + private KeyguardBypassController mKeyguardBypassController; private NotificationPanelView mNotificationPanelView; @Before @@ -115,18 +122,16 @@ public class NotificationPanelViewTest extends SysuiTestCase { mDependency.injectMockDependency(NotificationLockscreenUserManager.class); mDependency.injectMockDependency(ConfigurationController.class); mDependency.injectMockDependency(ZenModeController.class); - KeyguardBypassController bypassController = new KeyguardBypassController(mContext, - mock(TunerService.class), mStatusBarStateController, - mock(NotificationLockscreenUserManager.class)); NotificationWakeUpCoordinator coordinator = new NotificationWakeUpCoordinator(mContext, mock(HeadsUpManagerPhone.class), new StatusBarStateControllerImpl(), - bypassController); + mKeyguardBypassController); PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator, - bypassController, mHeadsUpManager, mock(NotificationRoundnessManager.class)); + mKeyguardBypassController, mHeadsUpManager, + mock(NotificationRoundnessManager.class)); mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler, - bypassController); + mKeyguardBypassController); mNotificationPanelView.setHeadsUpManager(mHeadsUpManager); mNotificationPanelView.setBar(mPanelBar); @@ -186,6 +191,20 @@ public class NotificationPanelViewTest extends SysuiTestCase { assertThat(mNotificationPanelView.isTrackingBlocked()).isFalse(); } + @Test + public void testKeyguardStatusBarVisibility_hiddenForBypass() { + when(mUpdateMonitor.shouldListenForFace()).thenReturn(true); + mNotificationPanelView.mKeyguardUpdateCallback.onBiometricRunningStateChanged(true, + BiometricSourceType.FACE); + verify(mKeyguardStatusBar, never()).setVisibility(View.VISIBLE); + + when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true); + mNotificationPanelView.mKeyguardUpdateCallback.onFinishedGoingToSleep(0); + mNotificationPanelView.mKeyguardUpdateCallback.onBiometricRunningStateChanged(true, + BiometricSourceType.FACE); + verify(mKeyguardStatusBar, never()).setVisibility(View.VISIBLE); + } + private class TestableNotificationPanelView extends NotificationPanelView { TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator, PulseExpansionHandler expansionHandler, @@ -203,6 +222,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mBigClockContainer = NotificationPanelViewTest.this.mBigClockContainer; mQsFrame = NotificationPanelViewTest.this.mQsFrame; mAffordanceHelper = NotificationPanelViewTest.this.mAffordanceHelper; + mUpdateMonitor = NotificationPanelViewTest.this.mUpdateMonitor; initDependencies(NotificationPanelViewTest.this.mStatusBar, NotificationPanelViewTest.this.mGroupManager, NotificationPanelViewTest.this.mNotificationShelf,