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:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -181,7 +181,7 @@ class SensorUseStartedActivity @Inject constructor(
|
||||
keyguardDismissUtil.executeWhenUnlocked({
|
||||
disableSensorPrivacy()
|
||||
false
|
||||
}, false)
|
||||
}, false, false)
|
||||
} else {
|
||||
disableSensorPrivacy()
|
||||
}
|
||||
|
||||
@@ -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 */);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -177,6 +177,11 @@ public class WalletScreenController implements
|
||||
queryWalletCards();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnlockedChanged() {
|
||||
queryWalletCards();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCardSelected(@NonNull WalletCardViewInfo card) {
|
||||
if (mIsDismissed) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user