Merge "Add a binder cache to ILockSettings#getCredentialType"
This commit is contained in:
@@ -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;
|
||||
@@ -940,18 +941,54 @@ public class LockPatternUtils {
|
||||
return Long.toHexString(salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the credential type of a user.
|
||||
*/
|
||||
private final PropertyInvalidatedCache.QueryHandler<Integer, Integer> mCredentialTypeQuery =
|
||||
new PropertyInvalidatedCache.QueryHandler<>() {
|
||||
@Override
|
||||
public Integer apply(Integer userHandle) {
|
||||
try {
|
||||
return getLockSettings().getCredentialType(userHandle);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "failed to get credential type", re);
|
||||
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) {
|
||||
try {
|
||||
return getLockSettings().getCredentialType(userHandle);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "failed to get credential type", re);
|
||||
return CREDENTIAL_TYPE_NONE;
|
||||
}
|
||||
return mCredentialTypeCache.query(userHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -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";
|
||||
@@ -173,7 +174,7 @@ class LockSettingsStorage {
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
dispatchChange(this);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -221,7 +222,7 @@ class LockSettingsStorage {
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
dispatchChange(this);
|
||||
}
|
||||
|
||||
public void prefetchUser(int userId) {
|
||||
@@ -412,6 +413,7 @@ class LockSettingsStorage {
|
||||
}
|
||||
}
|
||||
mCache.putFile(name, hash);
|
||||
dispatchChange(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,6 +425,7 @@ class LockSettingsStorage {
|
||||
file.delete();
|
||||
mCache.putFile(name, null);
|
||||
}
|
||||
dispatchChange(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,6 +503,7 @@ class LockSettingsStorage {
|
||||
Slog.w(TAG, "Failed to zeroize " + path, e);
|
||||
} finally {
|
||||
file.delete();
|
||||
dispatchChange(this);
|
||||
}
|
||||
mCache.putFile(path, null);
|
||||
}
|
||||
@@ -587,6 +591,7 @@ class LockSettingsStorage {
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
dispatchChange(this);
|
||||
}
|
||||
|
||||
private void deleteFilesAndRemoveCache(String... names) {
|
||||
@@ -595,6 +600,7 @@ class LockSettingsStorage {
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
mCache.putFile(name, null);
|
||||
dispatchChange(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -675,6 +681,7 @@ class LockSettingsStorage {
|
||||
}
|
||||
persistentDataBlock.setFrpCredentialHandle(PersistentData.toBytes(
|
||||
persistentType, userId, qualityForUi, payload));
|
||||
dispatchChange(this);
|
||||
}
|
||||
|
||||
public PersistentData readPersistentDataBlock() {
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -36,6 +36,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.admin.PasswordMetrics;
|
||||
import android.app.PropertyInvalidatedCache;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
@@ -49,6 +50,7 @@ import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationRe
|
||||
import com.android.server.locksettings.SyntheticPasswordManager.AuthenticationToken;
|
||||
import com.android.server.locksettings.SyntheticPasswordManager.PasswordData;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -68,6 +70,11 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
public static final byte[] PAYLOAD = new byte[] {1, 2, -1, -2, 55};
|
||||
public static final byte[] PAYLOAD2 = new byte[] {2, 3, -2, -3, 44, 1};
|
||||
|
||||
@Before
|
||||
public void disableProcessCaches() {
|
||||
PropertyInvalidatedCache.disableForTestMode();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordBasedSyntheticPassword() throws RemoteException {
|
||||
final int USER_ID = 10;
|
||||
|
||||
Reference in New Issue
Block a user