Update active unlock triggers

Add extra logging and make the triggers configurable via adb.

Test: manual
Bug: 222459888
Change-Id: Ia572c113bc1e664e64034b697bd10ae1f77ea06d
This commit is contained in:
Beverly
2022-03-10 15:13:25 +00:00
committed by Beverly Tai
parent 3fb8f5d5db
commit e0660e24c2
9 changed files with 180 additions and 42 deletions

View File

@@ -63,7 +63,8 @@ data class KeyguardFaceListenModel(
val primaryUser: Boolean,
val scanningAllowedByStrongAuth: Boolean,
val secureCameraLaunched: Boolean,
val switchingUser: Boolean
val switchingUser: Boolean,
val udfpsBouncerShowing: Boolean
) : KeyguardListenModel()
/**
* Verbose debug information associated with [KeyguardUpdateMonitor.shouldTriggerActiveUnlock].
@@ -73,6 +74,7 @@ data class KeyguardActiveUnlockModel(
override val userId: Int,
override val listening: Boolean,
// keep sorted
val awakeKeyguard: Boolean,
val authInterruptActive: Boolean,
val encryptedOrTimedOut: Boolean,
val fpLockout: Boolean,

View File

@@ -219,6 +219,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mKeyguardSecurityCallback.userActivity();
showMessage(null, null);
}
if (mUpdateMonitor.isFaceEnrolled()
&& mUpdateMonitor.mRequestActiveUnlockOnUnlockIntent) {
mUpdateMonitor.requestActiveUnlock("unlock-intent, reason=swipeUpOnBouncer",
true);
}
}
};
private ConfigurationController.ConfigurationListener mConfigurationListener =

View File

@@ -56,6 +56,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.SensorPrivacyManager;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
@@ -88,6 +89,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -246,6 +248,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
public final boolean mRequestActiveUnlockOnAssistant;
public final boolean mRequestActiveUnlockOnWakeup;
public final boolean mInitiateActiveUnlockOnWakeup;
public final boolean mRequestActiveUnlockOnUnlockIntent;
public final boolean mRequestActiveUnlockOnBioFail;
private final Context mContext;
private final boolean mIsPrimaryUser;
private final boolean mIsAutomotive;
@@ -281,6 +289,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private boolean mGoingToSleep;
private boolean mBouncerFullyShown;
private boolean mBouncerIsOrWillBeShowing;
private boolean mUdfpsBouncerShowing;
private boolean mAuthInterruptActive;
private boolean mNeedsSlowUnlockTransition;
private boolean mAssistantVisible;
@@ -451,10 +460,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
if (KeyguardUpdateMonitor.getCurrentUser() == userId && getUserHasTrust(userId)) {
if (KeyguardUpdateMonitor.getCurrentUser() == userId) {
CharSequence message = null;
if (trustGrantedMessages != null && trustGrantedMessages.size() > 0) {
message = trustGrantedMessages.get(0); // for now only shows the first in the list
final boolean userHasTrust = getUserHasTrust(userId);
if (userHasTrust && trustGrantedMessages != null) {
for (String msg : trustGrantedMessages) {
if (!TextUtils.isEmpty(msg)) {
message = msg;
break;
}
}
}
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -463,6 +478,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
}
}
@Override
@@ -1354,8 +1370,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
void setAssistantVisible(boolean assistantVisible) {
mAssistantVisible = assistantVisible;
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
if (mAssistantVisible) {
requestActiveUnlock();
if (mAssistantVisible && mRequestActiveUnlockOnAssistant) {
requestActiveUnlock("assistant", false);
}
}
@@ -1502,11 +1518,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void onAuthenticationFailed() {
if (mRequestActiveUnlockOnBioFail) {
requestActiveUnlock("biometric-failure, extra=fingerprintFailure",
true);
}
handleFingerprintAuthFailed();
// TODO(b/225231929): Refactor as needed, add tests, etc.
mTrustManager.reportUserRequestedUnlock(
KeyguardUpdateMonitor.getCurrentUser(), true);
}
@Override
@@ -1564,6 +1580,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void onAuthenticationFailed() {
if (shouldRequestActiveUnlockOnFaceError()) {
String reason =
mKeyguardBypassController.canBypass() ? "bypass"
: mUdfpsBouncerShowing ? "udfpsBouncer" :
mBouncerFullyShown ? "bouncer" : "udfpsFpDown";
requestActiveUnlock("biometric-failure"
+ ", extra=faceFailure-" + reason, true);
}
handleFaceAuthFailed();
if (mKeyguardBypassController != null) {
mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
@@ -1592,12 +1617,23 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (mKeyguardBypassController != null) {
mKeyguardBypassController.setUserHasDeviceEntryIntent(false);
}
if (errMsgId == BiometricFaceConstants.FACE_ERROR_TIMEOUT
&& shouldRequestActiveUnlockOnFaceError()) {
requestActiveUnlock("biometric-failure"
+ ", extra=faceError-" + errMsgId, true);
}
}
@Override
public void onAuthenticationAcquired(int acquireInfo) {
handleFaceAcquired(acquireInfo);
}
private boolean shouldRequestActiveUnlockOnFaceError() {
return mRequestActiveUnlockOnBioFail
&& (mKeyguardBypassController.canBypass() || mBouncerFullyShown
|| mUdfpsBouncerShowing || mAuthController.isUdfpsFingerDown());
}
};
@VisibleForTesting
@@ -1713,7 +1749,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Assert.isMainThread();
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
requestActiveUnlock();
if (mRequestActiveUnlockOnWakeup) {
requestActiveUnlock("wake-unlock");
} else if (mInitiateActiveUnlockOnWakeup) {
initiateActiveUnlock("wake-initiate");
}
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1860,6 +1900,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
dumpManager.registerDumpable(getClass().getName(), this);
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
// TODO, b/222459888: add official configurable names to Settings.java
mRequestActiveUnlockOnWakeup = Settings.Global.getInt(
mContext.getContentResolver(), "wake-unlock", 0) == 1;
mInitiateActiveUnlockOnWakeup = Settings.Global.getInt(
mContext.getContentResolver(), "wake-initiate", 1) == 1;
mRequestActiveUnlockOnUnlockIntent = Settings.Global.getInt(
mContext.getContentResolver(), "unlock-intent", 0) == 1;
mRequestActiveUnlockOnBioFail = Settings.Global.getInt(
mContext.getContentResolver(), "bio-fail", 0) == 1;
mRequestActiveUnlockOnAssistant = Settings.Global.getInt(
mContext.getContentResolver(), "assistant", 0) == 1;
mHandler = new Handler(mainLooper) {
@Override
public void handleMessage(Message msg) {
@@ -2240,7 +2292,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
mAuthInterruptActive = active;
updateFaceListeningState(BIOMETRIC_ACTION_UPDATE);
requestActiveUnlock();
if (mRequestActiveUnlockOnWakeup) {
requestActiveUnlock("wake-unlock, extra=onReach");
} else if (mInitiateActiveUnlockOnWakeup) {
initiateActiveUnlock("wake-initiate, extra=onReach");
}
}
/**
@@ -2290,25 +2346,69 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
/**
* Attempts to trigger active unlock.
* Initiates active unlock to get the unlock token ready.
*/
public void requestActiveUnlock() {
public void initiateActiveUnlock(String reason) {
// If this message exists, FP has already authenticated, so wait until that is handled
if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
return;
}
if (shouldTriggerActiveUnlock()) {
// TODO(b/225231929): Refactor surrounding code to reflect calling of new method
if (DEBUG) {
Log.d("ActiveUnlock", "initiate active unlock triggerReason=" + reason);
}
mTrustManager.reportUserMayRequestUnlock(KeyguardUpdateMonitor.getCurrentUser());
}
}
/**
* Attempts to trigger active unlock from trust agent.
*/
public void requestActiveUnlock(String reason, boolean dismissKeyguard) {
// If this message exists, FP has already authenticated, so wait until that is handled
if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
return;
}
if (shouldTriggerActiveUnlock()) {
if (DEBUG) {
Log.d("ActiveUnlock", "reportUserRequestedUnlock triggerReason=" + reason
+ " dismissKeyguard=" + dismissKeyguard);
}
mTrustManager.reportUserRequestedUnlock(KeyguardUpdateMonitor.getCurrentUser(),
dismissKeyguard);
}
}
/**
* Attempts to trigger active unlock from trust agent.
* Only dismisses the keyguard if only face is enrolled (no FP) and bypass is enabled.
*/
public void requestActiveUnlock(String reason) {
requestActiveUnlock(reason, isFaceEnrolled() && !isUdfpsEnrolled()
&& mKeyguardBypassController.getBypassEnabled());
}
/**
* Whether the UDFPS bouncer is showing.
*/
public void setUdfpsBouncerShowing(boolean showing) {
mUdfpsBouncerShowing = showing;
if (mUdfpsBouncerShowing) {
updateFaceListeningState(BIOMETRIC_ACTION_START);
if (mRequestActiveUnlockOnUnlockIntent) {
requestActiveUnlock("unlock-intent, extra=udfpsBouncer", true);
}
}
}
private boolean shouldTriggerActiveUnlock() {
// Triggers:
final boolean triggerActiveUnlockForAssistant = shouldTriggerActiveUnlockForAssistant();
final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep
&& mStatusBarState != StatusBarState.SHADE_LOCKED;
final boolean awakeKeyguard = mBouncerFullyShown || mUdfpsBouncerShowing
|| (mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep
&& mStatusBarState != StatusBarState.SHADE_LOCKED);
// Gates:
final int user = getCurrentUser();
@@ -2341,20 +2441,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
&& !mSecureCameraLaunched;
// Aggregate relevant fields for debug logging.
if (DEBUG_ACTIVE_UNLOCK || DEBUG_SPEW) {
maybeLogListenerModelData(
new KeyguardActiveUnlockModel(
System.currentTimeMillis(),
user,
shouldTriggerActiveUnlock,
mAuthInterruptActive,
isEncryptedOrTimedOut,
fpLockedout,
isLockDown,
mSwitchingUser,
triggerActiveUnlockForAssistant,
userCanDismissLockScreen));
}
maybeLogListenerModelData(
new KeyguardActiveUnlockModel(
System.currentTimeMillis(),
user,
shouldTriggerActiveUnlock,
awakeKeyguard,
mAuthInterruptActive,
isEncryptedOrTimedOut,
fpLockedout,
isLockDown,
mSwitchingUser,
triggerActiveUnlockForAssistant,
userCanDismissLockScreen));
return shouldTriggerActiveUnlock;
}
@@ -2507,7 +2606,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|| mOccludingAppRequestingFace
|| awakeKeyguard
|| shouldListenForFaceAssistant
|| mAuthController.isUdfpsFingerDown())
|| mAuthController.isUdfpsFingerDown()
|| mUdfpsBouncerShowing)
&& !mSwitchingUser && !faceDisabledForUser && becauseCannotSkipBouncer
&& !mKeyguardGoingAway && biometricEnabledForUser && !mLockIconPressed
&& strongAuthAllowsScanning && mIsPrimaryUser
@@ -2537,7 +2637,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mIsPrimaryUser,
strongAuthAllowsScanning,
mSecureCameraLaunched,
mSwitchingUser));
mSwitchingUser,
mUdfpsBouncerShowing));
}
return shouldListen;
@@ -2550,8 +2651,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
if (DEBUG_ACTIVE_UNLOCK
&& model instanceof KeyguardActiveUnlockModel
&& model.getListening()) {
&& model instanceof KeyguardActiveUnlockModel) {
mListenModels.add(model);
return;
}
@@ -3133,6 +3233,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
if (wasBouncerFullyShown != mBouncerFullyShown) {
if (mBouncerFullyShown && mRequestActiveUnlockOnUnlockIntent) {
requestActiveUnlock("unlock-intent, reason=bouncerFullyShown", true);
}
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -3641,6 +3744,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true));
pw.println(" mBouncerIsOrWillBeShowing=" + mBouncerIsOrWillBeShowing);
pw.println(" mStatusBarState=" + StatusBarState.toString(mStatusBarState));
pw.println(" mUdfpsBouncerShowing=" + mUdfpsBouncerShowing);
}
}
if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
@@ -3667,6 +3771,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
mListenModels.print(pw);
pw.println("Enabled active unlock triggers:");
pw.println(" mRequestActiveUnlockOnWakeup=" + mRequestActiveUnlockOnWakeup);
pw.println(" mInitiateActiveUnlockOnWakeup=" + mInitiateActiveUnlockOnWakeup);
pw.println(" mRequestActiveUnlockOnUnlockIntent=" + mRequestActiveUnlockOnUnlockIntent);
pw.println(" mRequestActiveUnlockOnBiometricFail=" + mRequestActiveUnlockOnBioFail);
pw.println(" mRequestActiveUnlockOnAssistant=" + mRequestActiveUnlockOnAssistant);
if (mIsAutomotive) {
pw.println(" Running on Automotive build");
}

View File

@@ -799,6 +799,11 @@ public class UdfpsController implements DozeReceiver {
if (!mKeyguardUpdateMonitor.isFaceDetectionRunning()) {
mKeyguardUpdateMonitor.requestFaceAuth(/* userInitiatedRequest */ false);
}
if (mKeyguardUpdateMonitor.mRequestActiveUnlockOnUnlockIntent) {
mKeyguardUpdateMonitor.requestActiveUnlock("unlock-intent extra=udfpsFingerDown",
true);
}
}
mOnFingerDown = true;
mFingerprintManager.onPointerDown(requestId, mSensorProps.sensorId, x, y, minor, major);

View File

@@ -502,8 +502,8 @@ public class KeyguardIndicationController {
private void updateLockScreenTrustMsg(int userId, CharSequence trustGrantedIndication,
CharSequence trustManagedIndication) {
if (!TextUtils.isEmpty(trustGrantedIndication)
&& mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
final boolean userHasTrust = mKeyguardUpdateMonitor.getUserHasTrust(userId);
if (!TextUtils.isEmpty(trustGrantedIndication) && userHasTrust) {
mRotateTextViewController.updateIndication(
INDICATION_TYPE_TRUST,
new KeyguardIndication.Builder()
@@ -513,7 +513,7 @@ public class KeyguardIndicationController {
false);
} else if (!TextUtils.isEmpty(trustManagedIndication)
&& mKeyguardUpdateMonitor.getUserTrustIsManaged(userId)
&& !mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
&& !userHasTrust) {
mRotateTextViewController.updateIndication(
INDICATION_TYPE_TRUST,
new KeyguardIndication.Builder()

View File

@@ -71,7 +71,13 @@ class KeyguardLiftController @Inject constructor(
isListening = false
updateListeningState()
keyguardUpdateMonitor.requestFaceAuth(true)
keyguardUpdateMonitor.requestActiveUnlock()
if (keyguardUpdateMonitor.mRequestActiveUnlockOnWakeup) {
keyguardUpdateMonitor.requestActiveUnlock("wake-unlock," +
" extra=KeyguardLiftController")
} else if (keyguardUpdateMonitor.mInitiateActiveUnlockOnWakeup) {
keyguardUpdateMonitor.initiateActiveUnlock("wake-initiate," +
" extra=KeyguardLiftController")
}
}
}

View File

@@ -3341,6 +3341,12 @@ public class NotificationPanelViewController extends PanelViewController {
.log(LockscreenUiEvent.LOCKSCREEN_LOCK_SHOW_HINT);
startUnlockHintAnimation();
}
if (mUpdateMonitor.isFaceEnrolled()
&& mUpdateMonitor.mRequestActiveUnlockOnUnlockIntent
&& mKeyguardBypassController.canBypass()) {
mUpdateMonitor.requestActiveUnlock("unlock-intent,"
+ " extra=lockScreenEmptySpaceTap", true);
}
}
return true;
case StatusBarState.SHADE_LOCKED:

View File

@@ -591,10 +591,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
private void updateAlternateAuthShowing(boolean updateScrim) {
final boolean isShowingAltAuth = isShowingAlternateAuth();
if (mKeyguardMessageAreaController != null) {
mKeyguardMessageAreaController.setAltBouncerShowing(isShowingAlternateAuth());
mKeyguardMessageAreaController.setAltBouncerShowing(isShowingAltAuth);
}
mBypassController.setAltBouncerShowing(isShowingAlternateAuth());
mBypassController.setAltBouncerShowing(isShowingAltAuth);
mKeyguardUpdateManager.setUdfpsBouncerShowing(isShowingAltAuth);
if (updateScrim) {
mCentralSurfaces.updateScrimController();

View File

@@ -97,5 +97,6 @@ private fun faceModel(user: Int) = KeyguardFaceListenModel(
primaryUser = false,
scanningAllowedByStrongAuth = false,
secureCameraLaunched = false,
switchingUser = false
switchingUser = false,
udfpsBouncerShowing = false
)