diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl index 9985cc02965be..1291766c00d80 100644 --- a/core/java/android/app/trust/ITrustManager.aidl +++ b/core/java/android/app/trust/ITrustManager.aidl @@ -36,5 +36,5 @@ interface ITrustManager { boolean isDeviceSecure(int userId); boolean isTrustUsuallyManaged(int userId); void unlockedByBiometricForUser(int userId, in BiometricSourceType source); - void clearAllBiometricRecognized(in BiometricSourceType target); + void clearAllBiometricRecognized(in BiometricSourceType target, int unlockedUser); } diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java index 177de835554bf..e214007c1850c 100644 --- a/core/java/android/app/trust/TrustManager.java +++ b/core/java/android/app/trust/TrustManager.java @@ -217,9 +217,9 @@ public class TrustManager { * Clears authentication by the specified biometric type for all users. */ @RequiresPermission(Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE) - public void clearAllBiometricRecognized(BiometricSourceType source) { + public void clearAllBiometricRecognized(BiometricSourceType source, int unlockedUser) { try { - mService.clearAllBiometricRecognized(source); + mService.clearAllBiometricRecognized(source, unlockedUser); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 5276679ea1041..a348b423d3c73 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -3294,11 +3294,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } public void clearBiometricRecognized() { + clearBiometricRecognized(UserHandle.USER_NULL); + } + + public void clearBiometricRecognizedWhenKeyguardDone(int unlockedUser) { + clearBiometricRecognized(unlockedUser); + } + + private void clearBiometricRecognized(int unlockedUser) { Assert.isMainThread(); mUserFingerprintAuthenticated.clear(); mUserFaceAuthenticated.clear(); - mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT); - mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE); + mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT, unlockedUser); + mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE, unlockedUser); for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index fdd6f65e13b7c..8376681e7bd4f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1761,7 +1761,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, } }; - public void keyguardDone() { + private void keyguardDone() { Trace.beginSection("KeyguardViewMediator#keyguardDone"); if (DEBUG) Log.d(TAG, "keyguardDone()"); userActivity(); @@ -1895,9 +1895,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, resetKeyguardDonePendingLocked(); } - if (mGoingToSleep) { - mUpdateMonitor.clearBiometricRecognized(); + mUpdateMonitor.clearBiometricRecognizedWhenKeyguardDone(currentUser); Log.i(TAG, "Device is going to sleep, aborting keyguardDone"); return; } @@ -1918,7 +1917,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, } handleHide(); - mUpdateMonitor.clearBiometricRecognized(); + mUpdateMonitor.clearBiometricRecognizedWhenKeyguardDone(currentUser); Trace.endSection(); } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 4b71742c86c82..fc87253825f46 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -46,6 +46,7 @@ import android.hardware.biometrics.BiometricSourceType; import android.net.Uri; import android.os.Binder; import android.os.Build; +import android.os.Bundle; import android.os.DeadObjectException; import android.os.Handler; import android.os.IBinder; @@ -123,6 +124,8 @@ public class TrustManagerService extends SystemService { private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14; private static final int MSG_SCHEDULE_TRUST_TIMEOUT = 15; + private static final String REFRESH_DEVICE_LOCKED_EXCEPT_USER = "except"; + private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000; private static final String TRUST_TIMEOUT_ALARM_TAG = "TrustManagerService.trustTimeoutForUser"; private static final long TRUST_TIMEOUT_IN_MILLIS = 4 * 60 * 60 * 1000; @@ -635,11 +638,18 @@ public class TrustManagerService extends SystemService { } } + private void refreshDeviceLockedForUser(int userId) { + refreshDeviceLockedForUser(userId, UserHandle.USER_NULL); + } + /** * Update the user's locked state. Only applicable to users with a real keyguard * ({@link UserInfo#supportsSwitchToByUser}) and unsecured managed profiles. + * + * If this is called due to an unlock operation set unlockedUser to prevent the lock from + * being prematurely reset for that user while keyguard is still in the process of going away. */ - private void refreshDeviceLockedForUser(int userId) { + private void refreshDeviceLockedForUser(int userId, int unlockedUser) { if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) { Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle," + " must be USER_ALL or a specific user.", new Throwable("here")); @@ -675,6 +685,7 @@ public class TrustManagerService extends SystemService { boolean trusted = aggregateIsTrusted(id); boolean showingKeyguard = true; boolean biometricAuthenticated = false; + boolean currentUserIsUnlocked = false; if (mCurrentUser == id) { synchronized(mUsersUnlockedByBiometric) { @@ -683,10 +694,17 @@ public class TrustManagerService extends SystemService { try { showingKeyguard = wm.isKeyguardLocked(); } catch (RemoteException e) { + Log.w(TAG, "Unable to check keyguard lock state", e); } + currentUserIsUnlocked = unlockedUser == id; } - boolean deviceLocked = secure && showingKeyguard && !trusted && - !biometricAuthenticated; + final boolean deviceLocked = secure && showingKeyguard && !trusted + && !biometricAuthenticated; + if (deviceLocked && currentUserIsUnlocked) { + // keyguard is finishing but may not have completed going away yet + continue; + } + setDeviceLockedForUser(id, deviceLocked); } } @@ -1306,13 +1324,20 @@ public class TrustManagerService extends SystemService { } @Override - public void clearAllBiometricRecognized(BiometricSourceType biometricSource) { + public void clearAllBiometricRecognized( + BiometricSourceType biometricSource, int unlockedUser) { enforceReportPermission(); synchronized(mUsersUnlockedByBiometric) { mUsersUnlockedByBiometric.clear(); } - mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL, - 0 /* arg2 */).sendToTarget(); + Message message = mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, + UserHandle.USER_ALL, 0 /* arg2 */); + if (unlockedUser >= 0) { + Bundle bundle = new Bundle(); + bundle.putInt(REFRESH_DEVICE_LOCKED_EXCEPT_USER, unlockedUser); + message.setData(bundle); + } + message.sendToTarget(); } }; @@ -1404,9 +1429,11 @@ public class TrustManagerService extends SystemService { break; case MSG_REFRESH_DEVICE_LOCKED_FOR_USER: if (msg.arg2 == 1) { - updateTrust(msg.arg1, 0 /* flags */, true); + updateTrust(msg.arg1, 0 /* flags */, true /* isFromUnlock */); } - refreshDeviceLockedForUser(msg.arg1); + final int unlockedUser = msg.getData().getInt( + REFRESH_DEVICE_LOCKED_EXCEPT_USER, UserHandle.USER_NULL); + refreshDeviceLockedForUser(msg.arg1, unlockedUser); break; case MSG_SCHEDULE_TRUST_TIMEOUT: handleScheduleTrustTimeout(msg.arg1, msg.arg2);