GPay activity can use passive biometric auth

- User can face authenticate immediately after tapping the gpay icon on
the LS
- User can use rear fp sensor to authenticate while the GPay activity
from LS is showing
- Update udfps bouncer logic so that longpress on a notification works
with udfps
- Never listen for UDFPS on the keyguard if the device already has trust

Test: atest SystemUITests
Test: atest KeyguardUpdateMonitorTest
Test: manual (unlock with and withou biometric on notification, shade,
bouncer, gpay surfaces)
Fixes: 187020022
Fixes: 183112863
Bug: 183024921
Bug: 185433347

Change-Id: I47aa58505535267c56b88c021791066c36a6c717
This commit is contained in:
Beverly
2021-05-06 15:35:54 -04:00
parent 357a7d7bae
commit e2ddaa2ee7
20 changed files with 188 additions and 76 deletions

View File

@@ -12,6 +12,7 @@ data class KeyguardFaceListenModel(
val isListeningForFace: Boolean,
val isBouncer: Boolean,
val isAuthInterruptActive: Boolean,
val isOccludingAppRequestingFaceAuth: Boolean,
val isKeyguardAwake: Boolean,
val isListeningForFaceAssistant: Boolean,
val isSwitchingUser: Boolean,

View File

@@ -276,6 +276,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private boolean mHasLockscreenWallpaper;
private boolean mAssistantVisible;
private boolean mKeyguardOccluded;
private boolean mOccludingAppRequestingFp;
private boolean mOccludingAppRequestingFace;
private boolean mSecureCameraLaunched;
@VisibleForTesting
protected boolean mTelephonyCapable;
@@ -587,6 +589,29 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
updateBiometricListeningState();
}
/**
* Request to listen for face authentication when an app is occluding keyguard.
* @param request if true and mKeyguardOccluded, request face auth listening, else default
* to normal behavior.
* See {@link KeyguardUpdateMonitor#shouldListenForFace()}
*/
public void requestFaceAuthOnOccludingApp(boolean request) {
mOccludingAppRequestingFace = request;
updateFaceListeningState();
}
/**
* Request to listen for fingerprint when an app is occluding keyguard.
* @param request if true and mKeyguardOccluded, request fingerprint listening, else default
* to normal behavior.
* See {@link KeyguardUpdateMonitor#shouldListenForFingerprint(boolean)}
*/
public void requestFingerprintAuthOnOccludingApp(boolean request) {
mOccludingAppRequestingFp = request;
updateFingerprintListeningState();
}
/**
* Invoked when the secure camera is launched.
*/
@@ -2093,14 +2118,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@VisibleForTesting
protected boolean shouldListenForFingerprint(boolean isUdfps) {
final boolean userDoesNotHaveTrust = !getUserHasTrust(getCurrentUser());
final boolean shouldListenKeyguardState =
mKeyguardIsVisible
|| !mDeviceInteractive
|| (mBouncer && !mKeyguardGoingAway)
|| mGoingToSleep
|| shouldListenForFingerprintAssistant()
|| (mKeyguardOccluded && mIsDreaming)
|| (isUdfps && mKeyguardOccluded);
mKeyguardIsVisible
|| !mDeviceInteractive
|| (mBouncer && !mKeyguardGoingAway)
|| mGoingToSleep
|| shouldListenForFingerprintAssistant()
|| (mKeyguardOccluded && mIsDreaming)
|| (mKeyguardOccluded && userDoesNotHaveTrust
&& (mOccludingAppRequestingFp || isUdfps));
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -2116,8 +2143,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
final boolean shouldListenUdfpsState = !isUdfps
|| (!getUserCanSkipBouncer(getCurrentUser())
&& !isEncryptedOrLockdown(getCurrentUser())
&& mStrongAuthTracker.hasUserAuthenticatedSinceBoot());
&& !isEncryptedOrLockdown(getCurrentUser())
&& mStrongAuthTracker.hasUserAuthenticatedSinceBoot()
&& userDoesNotHaveTrust);
return shouldListenKeyguardState && shouldListenUserState && shouldListenBouncerState
&& shouldListenUdfpsState;
@@ -2166,7 +2194,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
final boolean shouldListen =
(mBouncer || mAuthInterruptActive || awakeKeyguard
(mBouncer || mAuthInterruptActive || mOccludingAppRequestingFace || awakeKeyguard
|| shouldListenForFaceAssistant())
&& !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
&& !mKeyguardGoingAway && mBiometricEnabledForUser.get(user) && !mLockIconPressed
@@ -2181,6 +2209,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
shouldListen,
mBouncer,
mAuthInterruptActive,
mOccludingAppRequestingFace,
awakeKeyguard,
shouldListenForFaceAssistant(),
mSwitchingUser,

View File

@@ -169,7 +169,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mView.announceForAccessibility(mView.getContext().getString(
R.string.accessibility_fingerprint_bouncer));
} else {
mView.animateAwayUdfpsBouncer(() -> mKeyguardViewManager.cancelPostAuthActions());
mView.animateAwayUdfpsBouncer(null);
}
return true;
}
@@ -231,8 +231,8 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
*/
private void maybeShowInputBouncer() {
if (mShowingUdfpsBouncer) {
mKeyguardViewManager.resetAlternateAuth(false);
mKeyguardViewManager.showBouncer(true);
mKeyguardViewManager.resetAlternateAuth(false);
}
}

View File

@@ -428,7 +428,7 @@ public class MediaControlPanel {
mMediaDataManagerLazy.get().dismissMediaData(mKey,
MediaViewController.GUTS_ANIMATION_DURATION + 100);
return true;
}, /* requiresShadeOpen */ true);
}, /* requiresShadeOpen */ true, false);
} else {
Log.w(TAG, "Dismiss media with null notification. Token uid="
+ data.getToken().getUid());
@@ -564,7 +564,7 @@ public class MediaControlPanel {
mMediaDataManagerLazy.get().dismissSmartspaceRecommendation(
MediaViewController.GUTS_ANIMATION_DURATION + 100L);
return true;
}, true /* requiresShadeOpen */);
}, true /* requiresShadeOpen */, false);
});
mController = null;

View File

@@ -142,7 +142,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState>
mHost.getUserContext().startActivity(intent);
return false;
};
mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false);
mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false, false);
}
private void cancelCountdown() {

View File

@@ -189,7 +189,7 @@ public class RecordingService extends Service implements MediaRecorder.OnInfoLis
// Remove notification
mNotificationManager.cancelAsUser(null, NOTIFICATION_VIEW_ID, currentUser);
return false;
}, false);
}, false, false);
// Close quick shade
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));

View File

@@ -181,7 +181,7 @@ class SensorUseStartedActivity @Inject constructor(
keyguardDismissUtil.executeWhenUnlocked({
disableSensorPrivacy()
false
}, false)
}, false, false)
} else {
disableSensorPrivacy()
}

View File

@@ -38,7 +38,6 @@ import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardViewController;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -250,16 +249,20 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
KeyguardUpdateMonitor keyguardUpdateMonitor,
@Main Resources resources,
KeyguardBypassController keyguardBypassController, DozeParameters dozeParameters,
MetricsLogger metricsLogger, DumpManager dumpManager) {
MetricsLogger metricsLogger, DumpManager dumpManager,
PowerManager powerManager,
NotificationMediaManager notificationMediaManager,
WakefulnessLifecycle wakefulnessLifecycle,
ScreenLifecycle screenLifecycle) {
mContext = context;
mPowerManager = context.getSystemService(PowerManager.class);
mPowerManager = powerManager;
mShadeController = shadeController;
mUpdateMonitor = keyguardUpdateMonitor;
mDozeParameters = dozeParameters;
mUpdateMonitor.registerCallback(this);
mMediaManager = Dependency.get(NotificationMediaManager.class);
Dependency.get(WakefulnessLifecycle.class).addObserver(mWakefulnessObserver);
Dependency.get(ScreenLifecycle.class).addObserver(mScreenObserver);
mMediaManager = notificationMediaManager;
wakefulnessLifecycle.addObserver(mWakefulnessObserver);
screenLifecycle.addObserver(mScreenObserver);
mNotificationShadeWindowController = notificationShadeWindowController;
mDozeScrimController = dozeScrimController;
@@ -415,7 +418,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
if (!wasDeviceInteractive) {
mPendingShowBouncer = true;
} else {
showBouncer();
mPendingShowBouncer = false;
mKeyguardViewController.notifyKeyguardAuthenticated(
false /* strongAuth */);
}

View File

@@ -25,6 +25,8 @@ public interface KeyguardDismissHandler {
* Executes an action that requres the screen to be unlocked, showing the keyguard if
* necessary. Does not close the notification shade (in case it was open).
* @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
* @param afterKeyguardGone run the dismiss action after keyguard is gone?
*/
void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen);
void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
boolean afterKeyguardGone);
}

View File

@@ -50,13 +50,14 @@ public class KeyguardDismissUtil implements KeyguardDismissHandler {
* @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
*/
@Override
public void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen) {
public void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
boolean afterKeyguardGone) {
KeyguardDismissHandler dismissHandler = mDismissHandler;
if (dismissHandler == null) {
Log.wtf(TAG, "KeyguardDismissHandler not set.");
action.onDismiss();
return;
}
dismissHandler.executeWhenUnlocked(action, requiresShadeOpen);
dismissHandler.executeWhenUnlocked(action, requiresShadeOpen, afterKeyguardGone);
}
}

View File

@@ -2988,11 +2988,13 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationsController.resetUserExpandedStates();
}
private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen) {
private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen,
boolean afterKeyguardGone) {
if (mStatusBarKeyguardViewManager.isShowing() && requiresShadeOpen) {
mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
}
dismissKeyguardThenExecute(action, null /* cancelAction */, false /* afterKeyguardGone */);
dismissKeyguardThenExecute(action, null /* cancelAction */,
afterKeyguardGone /* afterKeyguardGone */);
}
protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {

View File

@@ -132,6 +132,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public void onVisibilityChanged(boolean isVisible) {
if (!isVisible) {
cancelPostAuthActions();
}
if (mAlternateAuthInterceptor != null) {
mAlternateAuthInterceptor.onBouncerVisibilityChanged();
}
@@ -406,21 +409,25 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
return;
}
mAfterKeyguardGoneAction = r;
mKeyguardGoneCancelAction = cancelAction;
if (mAlternateAuthInterceptor != null) {
mAfterKeyguardGoneAction = r;
mKeyguardGoneCancelAction = cancelAction;
if (mAlternateAuthInterceptor.showAlternateAuthBouncer()) {
mStatusBar.updateScrimController();
}
return;
}
if (!afterKeyguardGone) {
mBouncer.showWithDismissAction(r, cancelAction);
} else {
mAfterKeyguardGoneAction = r;
mKeyguardGoneCancelAction = cancelAction;
if (afterKeyguardGone) {
// we'll handle the dismiss action after keyguard is gone, so just show the bouncer
mBouncer.show(false /* resetSecuritySelection */);
} else {
// after authentication success, run dismiss action with the option to defer
// hiding the keyguard based on the return value of the OnDismissAction
mBouncer.showWithDismissAction(mAfterKeyguardGoneAction, mKeyguardGoneCancelAction);
// bouncer will handle the dismiss action, so we no longer need to track it here
mAfterKeyguardGoneAction = null;
mKeyguardGoneCancelAction = null;
}
}
updateStates();
@@ -1133,15 +1140,21 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
/**
* Request to show the udfps affordance in a particular color. This can be used if an
* occluding app on the keyguard would like to request udfps. This method does nothing if
* {@link KeyguardUpdateMonitor#shouldListenForFingerprint} is false.
* Request to authenticate using face.
*/
public void requestUdfps(boolean request, int color) {
if (mAlternateAuthInterceptor == null) {
return;
public void requestFace(boolean request) {
mKeyguardUpdateManager.requestFaceAuthOnOccludingApp(request);
}
/**
* Request to authenticate using the fingerprint sensor. If the fingerprint sensor is udfps,
* uses the color provided by udfpsColor for the fingerprint icon.
*/
public void requestFp(boolean request, int udfpsColor) {
mKeyguardUpdateManager.requestFingerprintAuthOnOccludingApp(request);
if (mAlternateAuthInterceptor != null) {
mAlternateAuthInterceptor.requestUdfps(request, udfpsColor);
}
mAlternateAuthInterceptor.requestUdfps(request, color);
}
/**

View File

@@ -482,7 +482,7 @@ private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
private fun KeyguardDismissUtil.executeWhenUnlocked(
requiresShadeOpen: Boolean,
onDismissAction: () -> Boolean
) = executeWhenUnlocked(onDismissAction, requiresShadeOpen)
) = executeWhenUnlocked(onDismissAction, requiresShadeOpen, false)
// convenience function that swaps parameter order so that lambda can be placed at the end
private fun ActivityStarter.startPendingIntentDismissingKeyguard(

View File

@@ -99,6 +99,7 @@ public class WalletActivity extends LifecycleActivity {
getActionBar().setHomeAsUpIndicator(getHomeIndicatorDrawable());
getActionBar().setHomeActionContentDescription(R.string.accessibility_desc_close);
WalletView walletView = requireViewById(R.id.wallet_view);
mWalletScreenController = new WalletScreenController(
this,
walletView,
@@ -116,20 +117,31 @@ public class WalletActivity extends LifecycleActivity {
&& mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return;
}
mActivityStarter.startActivity(
mQuickAccessWalletClient.createWalletIntent(), true);
finish();
if (mKeyguardStateController.isUnlocked()) {
mActivityStarter.startActivity(
mQuickAccessWalletClient.createWalletIntent(), true);
finish();
} else {
mKeyguardDismissUtil.executeWhenUnlocked(() -> {
mActivityStarter.startActivity(
mQuickAccessWalletClient.createWalletIntent(), true);
finish();
return false;
}, false, true);
}
});
// Click the action button to re-render the screen when the device is unlocked.
if (!mKeyguardStateController.isUnlocked()) {
walletView.getActionButton().setOnClickListener(
v -> {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return;
}
mKeyguardDismissUtil.executeWhenUnlocked(() -> false, false);
});
}
walletView.setDeviceLockedActionOnClickListener(
v -> {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return;
}
mKeyguardDismissUtil.executeWhenUnlocked(() -> false, false,
false);
});
}
@Override
@@ -142,13 +154,15 @@ public class WalletActivity extends LifecycleActivity {
protected void onResume() {
super.onResume();
mWalletScreenController.queryWalletCards();
mKeyguardViewManager.requestUdfps(true, Color.BLACK);
mKeyguardViewManager.requestFp(true, Color.BLACK);
mKeyguardViewManager.requestFace(true);
}
@Override
protected void onPause() {
super.onPause();
mKeyguardViewManager.requestUdfps(false, -1);
mKeyguardViewManager.requestFp(false, -1);
mKeyguardViewManager.requestFace(false);
}
@Override

View File

@@ -177,6 +177,11 @@ public class WalletScreenController implements
queryWalletCards();
}
@Override
public void onUnlockedChanged() {
queryWalletCards();
}
@Override
public void onCardSelected(@NonNull WalletCardViewInfo card) {
if (mIsDismissed) {

View File

@@ -63,6 +63,7 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
private final ViewGroup mEmptyStateView;
private CharSequence mCenterCardText;
private boolean mIsDeviceLocked = false;
private OnClickListener mDeviceLockedActionOnClickListener;
public WalletView(Context context) {
this(context, null);
@@ -178,6 +179,10 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
mEmptyStateView.setVisibility(GONE);
}
void setDeviceLockedActionOnClickListener(OnClickListener onClickListener) {
mDeviceLockedActionOnClickListener = onClickListener;
}
void hide() {
setVisibility(GONE);
}
@@ -238,6 +243,7 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
if (isDeviceLocked) {
mActionButton.setVisibility(VISIBLE);
mActionButton.setText(R.string.wallet_action_button_label_unlock);
mActionButton.setOnClickListener(mDeviceLockedActionOnClickListener);
} else if (actionButtonText != null) {
mActionButton.setText(actionButtonText);
mActionButton.setVisibility(VISIBLE);

View File

@@ -842,10 +842,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void testStartUdfpsServiceBeginsOnKeyguard() {
// GIVEN
// - bouncer isn't showing
// - status bar state is on the keyguard
// - user has authenticated since boot
setKeyguardBouncerVisibility(false /* isVisible */);
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
@@ -853,12 +851,45 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
}
@Test
public void testOccludingAppFingerprintListeningState() {
// GIVEN keyguard isn't visible (app occluding)
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mKeyguardUpdateMonitor.setKeyguardOccluded(true);
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(false);
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
// THEN we shouldn't listen for fingerprints
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(false);
// THEN we should listen for udfps (hiding of mechanism to actually auth is
// controlled by UdfpsKeyguardViewController)
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
}
@Test
public void testOccludingAppRequestsFingerprint() {
// GIVEN keyguard isn't visible (app occluding)
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mKeyguardUpdateMonitor.setKeyguardOccluded(true);
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(false);
// WHEN an occluding app requests fp
mKeyguardUpdateMonitor.requestFingerprintAuthOnOccludingApp(true);
// THEN we should listen for fingerprints
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(true);
// WHEN an occluding app stops requesting fp
mKeyguardUpdateMonitor.requestFingerprintAuthOnOccludingApp(false);
// THEN we shouldn't listen for fingeprints
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(false);
}
@Test
public void testStartUdfpsServiceNoAuthenticationSinceLastBoot() {
// GIVEN
// - bouncer isn't showing
// - status bar state is on the keyguard
setKeyguardBouncerVisibility(false /* isVisible */);
// GIVEN status bar state is on the keyguard
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
// WHEN user hasn't authenticated since last boot
@@ -871,7 +902,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void testShouldNotListenForUdfps_whenTrustEnabled() {
// GIVEN a "we should listen for udfps" state
setKeyguardBouncerVisibility(false /* isVisible */);
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
@@ -886,7 +916,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void testShouldNotListenForUdfps_whenFaceAuthenticated() {
// GIVEN a "we should listen for udfps" state
setKeyguardBouncerVisibility(false /* isVisible */);
mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);

View File

@@ -325,7 +325,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
assertThat(dismiss.isEnabled).isEqualTo(true)
dismiss.callOnClick()
val captor = ArgumentCaptor.forClass(ActivityStarter.OnDismissAction::class.java)
verify(keyguardDismissUtil).executeWhenUnlocked(captor.capture(), anyBoolean())
verify(keyguardDismissUtil).executeWhenUnlocked(captor.capture(), anyBoolean(),
eq(false))
captor.value.onDismiss()
verify(mediaDataManager).dismissMediaData(eq(mediaKey), anyLong())

View File

@@ -42,6 +42,8 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -90,6 +92,12 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
private DozeParameters mDozeParameters;
@Mock
private MetricsLogger mMetricsLogger;
@Mock
private NotificationMediaManager mNotificationMediaManager;
@Mock
private WakefulnessLifecycle mWakefulnessLifecycle;
@Mock
private ScreenLifecycle mScreenLifecycle;
private BiometricUnlockController mBiometricUnlockController;
@Before
@@ -109,7 +117,8 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
mKeyguardViewMediator, mScrimController, mShadeController,
mNotificationShadeWindowController, mKeyguardStateController, mHandler,
mUpdateMonitor, res.getResources(), mKeyguardBypassController, mDozeParameters,
mMetricsLogger, mDumpManager);
mMetricsLogger, mDumpManager, mPowerManager,
mNotificationMediaManager, mWakefulnessLifecycle, mScreenLifecycle);
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
mBiometricUnlockController.setBiometricModeListener(mBiometricModeListener);
}
@@ -121,8 +130,6 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
verify(mStatusBarKeyguardViewManager).showBouncer(eq(false));
verify(mShadeController).animateCollapsePanels(anyInt(), anyBoolean(), anyBoolean(),
anyFloat());
verify(mStatusBarKeyguardViewManager, never()).notifyKeyguardAuthenticated(anyBoolean());
assertThat(mBiometricUnlockController.getMode())
.isEqualTo(BiometricUnlockController.MODE_SHOW_BOUNCER);
@@ -161,7 +168,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
}
@Test
public void onBiometricAuthenticated_whenFingerprint_dismissKeyguard() {
public void onBiometricAuthenticated_whenFingerprint_notifyKeyguardAuthenticated() {
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
// the value of isStrongBiometric doesn't matter here since we only care about the returned
// value of isUnlockingWithBiometricAllowed()
@@ -169,8 +176,6 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
BiometricSourceType.FINGERPRINT, true /* isStrongBiometric */);
verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
verify(mShadeController).animateCollapsePanels(anyInt(), anyBoolean(), anyBoolean(),
anyFloat());
verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
assertThat(mBiometricUnlockController.getMode())
.isEqualTo(BiometricUnlockController.MODE_UNLOCK_COLLAPSING);

View File

@@ -120,7 +120,7 @@ public class SmartReplyViewTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
mReceiver = new BlockingQueueIntentReceiver();
mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION));
mKeyguardDismissUtil.setDismissHandler((action, unused) -> action.onDismiss());
mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone) -> action.onDismiss());
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
mDependency.injectMockDependency(ShadeController.class);
mDependency.injectMockDependency(NotificationRemoteInputManager.class);
@@ -183,7 +183,7 @@ public class SmartReplyViewTest extends SysuiTestCase {
@Test
public void testSendSmartReply_keyguardCancelled() throws InterruptedException {
mKeyguardDismissUtil.setDismissHandler((action, unused) -> { });
mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone) -> { });
setSmartReplies(TEST_CHOICES);
mView.getChildAt(2).performClick();
@@ -195,7 +195,8 @@ public class SmartReplyViewTest extends SysuiTestCase {
public void testSendSmartReply_waitsForKeyguard() throws InterruptedException {
AtomicReference<OnDismissAction> actionRef = new AtomicReference<>();
mKeyguardDismissUtil.setDismissHandler((action, unused) -> actionRef.set(action));
mKeyguardDismissUtil.setDismissHandler((action, unused, afterKgGone)
-> actionRef.set(action));
setSmartReplies(TEST_CHOICES);
mView.getChildAt(2).performClick();