diff options
| -rw-r--r-- | services/core/java/com/android/server/locksettings/LockSettingsService.java | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 28fa86b3a893..61d4a1058a34 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -1887,7 +1887,7 @@ public class LockSettingsService extends ILockSettings.Stub { mSpManager.removeUser(userId); mStorage.removeUser(userId); mStrongAuth.removeUser(userId); - cleanSpCache(); + tryRemoveUserFromSpCacheLater(userId); final KeyStore ks = KeyStore.getInstance(); ks.onUserRemoved(userId); @@ -2141,6 +2141,13 @@ public class LockSettingsService extends ILockSettings.Stub { private SparseArray<AuthenticationToken> mSpCache = new SparseArray(); private void onAuthTokenKnownForUser(@UserIdInt int userId, AuthenticationToken auth) { + // Preemptively cache the SP and then try to remove it in a handler. + Slog.i(TAG, "Caching SP for user " + userId); + synchronized (mSpManager) { + mSpCache.put(userId, auth); + } + tryRemoveUserFromSpCacheLater(userId); + // Pass the primary user's auth secret to the HAL if (mAuthSecretService != null && mUserManager.getUserInfo(userId).isPrimary()) { try { @@ -2154,33 +2161,25 @@ public class LockSettingsService extends ILockSettings.Stub { Slog.w(TAG, "Failed to pass primary user secret to AuthSecret HAL", e); } } - - // Update the SP cache, removing the entry when allowed - synchronized (mSpManager) { - if (shouldCacheSpForUser(userId)) { - Slog.i(TAG, "Caching SP for user " + userId); - mSpCache.put(userId, auth); - } else { - Slog.i(TAG, "Not caching SP for user " + userId); - mSpCache.delete(userId); - } - } } - /** Clean up the SP cache by removing unneeded entries. */ - private void cleanSpCache() { - synchronized (mSpManager) { - // Preserve indicies after removal by iterating backwards - for (int i = mSpCache.size() - 1; i >= 0; --i) { - final int userId = mSpCache.keyAt(i); - if (!shouldCacheSpForUser(userId)) { - Slog.i(TAG, "Uncaching SP for user " + userId); - mSpCache.removeAt(i); + private void tryRemoveUserFromSpCacheLater(@UserIdInt int userId) { + mHandler.post(() -> { + if (!shouldCacheSpForUser(userId)) { + // The transition from 'should not cache' to 'should cache' can only happen if + // certain admin apps are installed after provisioning e.g. via adb. This is not + // a common case and we do not seamlessly support; it may result in the SP not + // being cached when it is needed. The cache can be re-populated by verifying + // the credential again. + Slog.i(TAG, "Removing SP from cache for user " + userId); + synchronized (mSpManager) { + mSpCache.remove(userId); } } - } + }); } + /** Do not hold any of the locks from this service when calling. */ private boolean shouldCacheSpForUser(@UserIdInt int userId) { // Before the user setup has completed, an admin could be installed that requires the SP to // be cached (see below). @@ -2731,7 +2730,7 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override - public void onChange(boolean selfChange, Uri uri) { + public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { if (mDeviceProvisionedUri.equals(uri)) { updateRegistration(); @@ -2741,7 +2740,7 @@ public class LockSettingsService extends ILockSettings.Stub { clearFrpCredentialIfOwnerNotSecure(); } } else if (mUserSetupCompleteUri.equals(uri)) { - cleanSpCache(); + tryRemoveUserFromSpCacheLater(userId); } } |