Loading core/java/com/android/internal/widget/LockPatternUtils.java +43 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PropertyInvalidatedCache; import android.app.admin.DevicePolicyManager; import android.app.admin.PasswordMetrics; import android.app.trust.IStrongAuthTracker; Loading Loading @@ -941,11 +942,12 @@ public class LockPatternUtils { } /** * Returns the credential type of the user, can be one of {@link #CREDENTIAL_TYPE_NONE}, * {@link #CREDENTIAL_TYPE_PATTERN}, {@link #CREDENTIAL_TYPE_PIN} and * {@link #CREDENTIAL_TYPE_PASSWORD} * Retrieve the credential type of a user. */ public @CredentialType int getCredentialTypeForUser(int userHandle) { private final PropertyInvalidatedCache.QueryHandler<Integer, Integer> mCredentialTypeQuery = new PropertyInvalidatedCache.QueryHandler<>() { @Override public Integer apply(Integer userHandle) { try { return getLockSettings().getCredentialType(userHandle); } catch (RemoteException re) { Loading @@ -953,6 +955,41 @@ public class LockPatternUtils { return CREDENTIAL_TYPE_NONE; } } @Override public boolean shouldBypassCache(Integer userHandle) { return userHandle == USER_FRP; } }; /** * The API that is cached. */ private final static String CREDENTIAL_TYPE_API = "getCredentialType"; /** * Cache the credential type of a user. */ private final PropertyInvalidatedCache<Integer, Integer> mCredentialTypeCache = new PropertyInvalidatedCache<>(4, PropertyInvalidatedCache.MODULE_SYSTEM, CREDENTIAL_TYPE_API, CREDENTIAL_TYPE_API, mCredentialTypeQuery); /** * Invalidate the credential cache * @hide */ public final static void invalidateCredentialTypeCache() { PropertyInvalidatedCache.invalidateCache(PropertyInvalidatedCache.MODULE_SYSTEM, CREDENTIAL_TYPE_API); } /** * Returns the credential type of the user, can be one of {@link #CREDENTIAL_TYPE_NONE}, * {@link #CREDENTIAL_TYPE_PATTERN}, {@link #CREDENTIAL_TYPE_PIN} and * {@link #CREDENTIAL_TYPE_PASSWORD} */ public @CredentialType int getCredentialTypeForUser(int userHandle) { return mCredentialTypeCache.query(userHandle); } /** * @param userId the user for which to report the value Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +24 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,8 @@ import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationTo import com.android.server.locksettings.SyntheticPasswordManager.TokenType; import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager; import com.android.server.pm.UserManagerInternal; import com.android.server.utils.Watchable; import com.android.server.utils.Watcher; import com.android.server.wm.WindowManagerInternal; import libcore.util.HexEncoding; Loading Loading @@ -230,6 +232,7 @@ public class LockSettingsService extends ILockSettings.Stub { protected final Handler mHandler; @VisibleForTesting protected final LockSettingsStorage mStorage; private final Watcher mStorageWatcher; private final LockSettingsStrongAuth mStrongAuth; private final SynchronizedStrongAuthTracker mStrongAuthTracker; private final BiometricDeferredQueue mBiometricDeferredQueue; Loading Loading @@ -573,6 +576,12 @@ public class LockSettingsService extends ILockSettings.Stub { } } private class StorageWatcher extends Watcher { public void onChange(Watchable what) { LockSettingsService.this.onChange(); } } public LockSettingsService(Context context) { this(new Injector(context)); } Loading Loading @@ -614,6 +623,16 @@ public class LockSettingsService extends ILockSettings.Stub { mStorage); LocalServices.addService(LockSettingsInternal.class, new LocalService()); mStorageWatcher = new StorageWatcher(); mStorage.registerObserver(mStorageWatcher); } /** * Invalidate caches if the storage has changed. */ private void onChange() { LockPatternUtils.invalidateCredentialTypeCache(); } /** Loading Loading @@ -1278,6 +1297,11 @@ public class LockSettingsService extends ILockSettings.Stub { DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId); } /** * This API is cached; whenever the result would change, * {@link com.android.internal.widget.LockPatternUtils#invalidateCredentialTypeCache} * must be called. */ @Override public int getCredentialType(int userId) { checkPasswordHavePermission(userId); Loading services/core/java/com/android/server/locksettings/LockSettingsStorage.java +10 −3 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils.CredentialType; import com.android.server.LocalServices; import com.android.server.PersistentDataBlockManagerInternal; import com.android.server.utils.WatchableImpl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; Loading @@ -66,7 +67,7 @@ import java.util.Map; /** * Storage for the lock settings service. */ class LockSettingsStorage { class LockSettingsStorage extends WatchableImpl { private static final String TAG = "LockSettingsStorage"; private static final String TABLE = "locksettings"; Loading Loading @@ -173,7 +174,7 @@ class LockSettingsStorage { } finally { db.endTransaction(); } dispatchChange(this); } @VisibleForTesting Loading Loading @@ -221,7 +222,7 @@ class LockSettingsStorage { } finally { db.endTransaction(); } dispatchChange(this); } public void prefetchUser(int userId) { Loading Loading @@ -412,6 +413,7 @@ class LockSettingsStorage { } } mCache.putFile(name, hash); dispatchChange(this); } } Loading @@ -423,6 +425,7 @@ class LockSettingsStorage { file.delete(); mCache.putFile(name, null); } dispatchChange(this); } } Loading Loading @@ -500,6 +503,7 @@ class LockSettingsStorage { Slog.w(TAG, "Failed to zeroize " + path, e); } finally { file.delete(); dispatchChange(this); } mCache.putFile(path, null); } Loading Loading @@ -587,6 +591,7 @@ class LockSettingsStorage { } finally { db.endTransaction(); } dispatchChange(this); } private void deleteFilesAndRemoveCache(String... names) { Loading @@ -595,6 +600,7 @@ class LockSettingsStorage { if (file.exists()) { file.delete(); mCache.putFile(name, null); dispatchChange(this); } } } Loading Loading @@ -675,6 +681,7 @@ class LockSettingsStorage { } persistentDataBlock.setFrpCredentialHandle(PersistentData.toBytes( persistentType, userId, qualityForUi, payload)); dispatchChange(this); } public PersistentData readPersistentDataBlock() { Loading services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +7 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import android.app.PropertyInvalidatedCache; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.service.gatekeeper.GateKeeperResponse; Loading @@ -47,6 +48,7 @@ import com.android.internal.widget.VerifyCredentialResponse; import com.android.server.locksettings.FakeGateKeeperService.VerifyHandle; import com.android.server.locksettings.LockSettingsStorage.CredentialHash; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -57,6 +59,11 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(AndroidJUnit4.class) public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { @Before public void disableProcessCaches() { PropertyInvalidatedCache.disableForTestMode(); } @Test public void testCreatePasswordPrimaryUser() throws RemoteException { testCreateCredential(PRIMARY_USER_ID, newPassword("password")); Loading services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java +6 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.android.internal.widget.LockPatternUtils.USER_FRP; import static org.junit.Assert.assertEquals; import android.app.PropertyInvalidatedCache; import android.app.admin.DevicePolicyManager; import androidx.test.runner.AndroidJUnit4; Loading @@ -46,6 +47,11 @@ public class LockscreenFrpTest extends BaseLockSettingsServiceTests { mSettings.setDeviceProvisioned(false); } @Before public void disableProcessCaches() { PropertyInvalidatedCache.disableForTestMode(); } @Test public void testFrpCredential_setPin() { mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID); Loading Loading
core/java/com/android/internal/widget/LockPatternUtils.java +43 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.PropertyInvalidatedCache; import android.app.admin.DevicePolicyManager; import android.app.admin.PasswordMetrics; import android.app.trust.IStrongAuthTracker; Loading Loading @@ -941,11 +942,12 @@ public class LockPatternUtils { } /** * Returns the credential type of the user, can be one of {@link #CREDENTIAL_TYPE_NONE}, * {@link #CREDENTIAL_TYPE_PATTERN}, {@link #CREDENTIAL_TYPE_PIN} and * {@link #CREDENTIAL_TYPE_PASSWORD} * Retrieve the credential type of a user. */ public @CredentialType int getCredentialTypeForUser(int userHandle) { private final PropertyInvalidatedCache.QueryHandler<Integer, Integer> mCredentialTypeQuery = new PropertyInvalidatedCache.QueryHandler<>() { @Override public Integer apply(Integer userHandle) { try { return getLockSettings().getCredentialType(userHandle); } catch (RemoteException re) { Loading @@ -953,6 +955,41 @@ public class LockPatternUtils { return CREDENTIAL_TYPE_NONE; } } @Override public boolean shouldBypassCache(Integer userHandle) { return userHandle == USER_FRP; } }; /** * The API that is cached. */ private final static String CREDENTIAL_TYPE_API = "getCredentialType"; /** * Cache the credential type of a user. */ private final PropertyInvalidatedCache<Integer, Integer> mCredentialTypeCache = new PropertyInvalidatedCache<>(4, PropertyInvalidatedCache.MODULE_SYSTEM, CREDENTIAL_TYPE_API, CREDENTIAL_TYPE_API, mCredentialTypeQuery); /** * Invalidate the credential cache * @hide */ public final static void invalidateCredentialTypeCache() { PropertyInvalidatedCache.invalidateCache(PropertyInvalidatedCache.MODULE_SYSTEM, CREDENTIAL_TYPE_API); } /** * Returns the credential type of the user, can be one of {@link #CREDENTIAL_TYPE_NONE}, * {@link #CREDENTIAL_TYPE_PATTERN}, {@link #CREDENTIAL_TYPE_PIN} and * {@link #CREDENTIAL_TYPE_PASSWORD} */ public @CredentialType int getCredentialTypeForUser(int userHandle) { return mCredentialTypeCache.query(userHandle); } /** * @param userId the user for which to report the value Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +24 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,8 @@ import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationTo import com.android.server.locksettings.SyntheticPasswordManager.TokenType; import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager; import com.android.server.pm.UserManagerInternal; import com.android.server.utils.Watchable; import com.android.server.utils.Watcher; import com.android.server.wm.WindowManagerInternal; import libcore.util.HexEncoding; Loading Loading @@ -230,6 +232,7 @@ public class LockSettingsService extends ILockSettings.Stub { protected final Handler mHandler; @VisibleForTesting protected final LockSettingsStorage mStorage; private final Watcher mStorageWatcher; private final LockSettingsStrongAuth mStrongAuth; private final SynchronizedStrongAuthTracker mStrongAuthTracker; private final BiometricDeferredQueue mBiometricDeferredQueue; Loading Loading @@ -573,6 +576,12 @@ public class LockSettingsService extends ILockSettings.Stub { } } private class StorageWatcher extends Watcher { public void onChange(Watchable what) { LockSettingsService.this.onChange(); } } public LockSettingsService(Context context) { this(new Injector(context)); } Loading Loading @@ -614,6 +623,16 @@ public class LockSettingsService extends ILockSettings.Stub { mStorage); LocalServices.addService(LockSettingsInternal.class, new LocalService()); mStorageWatcher = new StorageWatcher(); mStorage.registerObserver(mStorageWatcher); } /** * Invalidate caches if the storage has changed. */ private void onChange() { LockPatternUtils.invalidateCredentialTypeCache(); } /** Loading Loading @@ -1278,6 +1297,11 @@ public class LockSettingsService extends ILockSettings.Stub { DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId); } /** * This API is cached; whenever the result would change, * {@link com.android.internal.widget.LockPatternUtils#invalidateCredentialTypeCache} * must be called. */ @Override public int getCredentialType(int userId) { checkPasswordHavePermission(userId); Loading
services/core/java/com/android/server/locksettings/LockSettingsStorage.java +10 −3 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils.CredentialType; import com.android.server.LocalServices; import com.android.server.PersistentDataBlockManagerInternal; import com.android.server.utils.WatchableImpl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; Loading @@ -66,7 +67,7 @@ import java.util.Map; /** * Storage for the lock settings service. */ class LockSettingsStorage { class LockSettingsStorage extends WatchableImpl { private static final String TAG = "LockSettingsStorage"; private static final String TABLE = "locksettings"; Loading Loading @@ -173,7 +174,7 @@ class LockSettingsStorage { } finally { db.endTransaction(); } dispatchChange(this); } @VisibleForTesting Loading Loading @@ -221,7 +222,7 @@ class LockSettingsStorage { } finally { db.endTransaction(); } dispatchChange(this); } public void prefetchUser(int userId) { Loading Loading @@ -412,6 +413,7 @@ class LockSettingsStorage { } } mCache.putFile(name, hash); dispatchChange(this); } } Loading @@ -423,6 +425,7 @@ class LockSettingsStorage { file.delete(); mCache.putFile(name, null); } dispatchChange(this); } } Loading Loading @@ -500,6 +503,7 @@ class LockSettingsStorage { Slog.w(TAG, "Failed to zeroize " + path, e); } finally { file.delete(); dispatchChange(this); } mCache.putFile(path, null); } Loading Loading @@ -587,6 +591,7 @@ class LockSettingsStorage { } finally { db.endTransaction(); } dispatchChange(this); } private void deleteFilesAndRemoveCache(String... names) { Loading @@ -595,6 +600,7 @@ class LockSettingsStorage { if (file.exists()) { file.delete(); mCache.putFile(name, null); dispatchChange(this); } } } Loading Loading @@ -675,6 +681,7 @@ class LockSettingsStorage { } persistentDataBlock.setFrpCredentialHandle(PersistentData.toBytes( persistentType, userId, qualityForUi, payload)); dispatchChange(this); } public PersistentData readPersistentDataBlock() { Loading
services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +7 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import android.app.PropertyInvalidatedCache; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.service.gatekeeper.GateKeeperResponse; Loading @@ -47,6 +48,7 @@ import com.android.internal.widget.VerifyCredentialResponse; import com.android.server.locksettings.FakeGateKeeperService.VerifyHandle; import com.android.server.locksettings.LockSettingsStorage.CredentialHash; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -57,6 +59,11 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(AndroidJUnit4.class) public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { @Before public void disableProcessCaches() { PropertyInvalidatedCache.disableForTestMode(); } @Test public void testCreatePasswordPrimaryUser() throws RemoteException { testCreateCredential(PRIMARY_USER_ID, newPassword("password")); Loading
services/tests/servicestests/src/com/android/server/locksettings/LockscreenFrpTest.java +6 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.android.internal.widget.LockPatternUtils.USER_FRP; import static org.junit.Assert.assertEquals; import android.app.PropertyInvalidatedCache; import android.app.admin.DevicePolicyManager; import androidx.test.runner.AndroidJUnit4; Loading @@ -46,6 +47,11 @@ public class LockscreenFrpTest extends BaseLockSettingsServiceTests { mSettings.setDeviceProvisioned(false); } @Before public void disableProcessCaches() { PropertyInvalidatedCache.disableForTestMode(); } @Test public void testFrpCredential_setPin() { mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID); Loading