LockSettingsService: move database storage
The database storage commands are part of ILockSettings, but the actual
storage takes place on LockSettingsStorage. Redirect the calls in
LockSettingsService to LockSettingsStorage to make the ownership a bit
more clear.
(cherry picked from commit 366c310e4a)
Bug: 149833390
Test: atest LockSettingsStorageTests LockSettingsServiceTests
Change-Id: Ibc9236a171cedd3b09b1afed70895bc91e895a1c
Merged-In: Ibc9236a171cedd3b09b1afed70895bc91e895a1c
This commit is contained in:
@@ -50,7 +50,6 @@ import android.app.admin.DevicePolicyManager;
|
|||||||
import android.app.admin.DevicePolicyManagerInternal;
|
import android.app.admin.DevicePolicyManagerInternal;
|
||||||
import android.app.admin.DeviceStateCache;
|
import android.app.admin.DeviceStateCache;
|
||||||
import android.app.admin.PasswordMetrics;
|
import android.app.admin.PasswordMetrics;
|
||||||
import android.app.backup.BackupManager;
|
|
||||||
import android.app.trust.IStrongAuthTracker;
|
import android.app.trust.IStrongAuthTracker;
|
||||||
import android.app.trust.TrustManager;
|
import android.app.trust.TrustManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
@@ -112,10 +111,8 @@ import com.android.internal.annotations.GuardedBy;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||||
import com.android.internal.notification.SystemNotificationChannels;
|
import com.android.internal.notification.SystemNotificationChannels;
|
||||||
import com.android.internal.util.ArrayUtils;
|
|
||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
import com.android.internal.util.Preconditions;
|
|
||||||
import com.android.internal.widget.ICheckCredentialProgressCallback;
|
import com.android.internal.widget.ICheckCredentialProgressCallback;
|
||||||
import com.android.internal.widget.ILockSettings;
|
import com.android.internal.widget.ILockSettings;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
@@ -701,7 +698,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
// Serial number is never reusued, so we can use it as a distinguisher for user Id reuse.
|
// Serial number is never reusued, so we can use it as a distinguisher for user Id reuse.
|
||||||
int serialNumber = mUserManager.getUserSerialNumber(userId);
|
int serialNumber = mUserManager.getUserSerialNumber(userId);
|
||||||
|
|
||||||
int storedSerialNumber = getIntUnchecked(USER_SERIAL_NUMBER_KEY, -1, userId);
|
int storedSerialNumber = mStorage.getInt(USER_SERIAL_NUMBER_KEY, -1, userId);
|
||||||
if (storedSerialNumber != serialNumber) {
|
if (storedSerialNumber != serialNumber) {
|
||||||
// If LockSettingsStorage does not have a copy of the serial number, it could be either
|
// If LockSettingsStorage does not have a copy of the serial number, it could be either
|
||||||
// this is a user created before the serial number recording logic is introduced, or
|
// this is a user created before the serial number recording logic is introduced, or
|
||||||
@@ -710,7 +707,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
if (storedSerialNumber != -1) {
|
if (storedSerialNumber != -1) {
|
||||||
removeUser(userId, /* unknownUser */ true);
|
removeUser(userId, /* unknownUser */ true);
|
||||||
}
|
}
|
||||||
setIntUnchecked(USER_SERIAL_NUMBER_KEY, serialNumber, userId);
|
mStorage.setInt(USER_SERIAL_NUMBER_KEY, serialNumber, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,7 +1066,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
|
|
||||||
private boolean getSeparateProfileChallengeEnabledInternal(int userId) {
|
private boolean getSeparateProfileChallengeEnabledInternal(int userId) {
|
||||||
synchronized (mSeparateChallengeLock) {
|
synchronized (mSeparateChallengeLock) {
|
||||||
return getBooleanUnchecked(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
|
return mStorage.getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1122,94 +1119,49 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public void setBoolean(String key, boolean value, int userId) {
|
public void setBoolean(String key, boolean value, int userId) {
|
||||||
checkWritePermission(userId);
|
checkWritePermission(userId);
|
||||||
setStringUnchecked(key, userId, value ? "1" : "0");
|
mStorage.setBoolean(key, value, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLong(String key, long value, int userId) {
|
public void setLong(String key, long value, int userId) {
|
||||||
checkWritePermission(userId);
|
checkWritePermission(userId);
|
||||||
setLongUnchecked(key, value, userId);
|
mStorage.setLong(key, value, userId);
|
||||||
}
|
|
||||||
|
|
||||||
private void setLongUnchecked(String key, long value, int userId) {
|
|
||||||
setStringUnchecked(key, userId, Long.toString(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setIntUnchecked(String key, int value, int userId) {
|
|
||||||
setStringUnchecked(key, userId, Integer.toString(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setString(String key, String value, int userId) {
|
public void setString(String key, String value, int userId) {
|
||||||
checkWritePermission(userId);
|
checkWritePermission(userId);
|
||||||
setStringUnchecked(key, userId, value);
|
mStorage.setString(key, value, userId);
|
||||||
}
|
|
||||||
|
|
||||||
private void setStringUnchecked(String key, int userId, String value) {
|
|
||||||
Preconditions.checkArgument(userId != USER_FRP, "cannot store lock settings for FRP user");
|
|
||||||
|
|
||||||
mStorage.writeKeyValue(key, value, userId);
|
|
||||||
if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
|
|
||||||
BackupManager.dataChanged("com.android.providers.settings");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getBoolean(String key, boolean defaultValue, int userId) {
|
public boolean getBoolean(String key, boolean defaultValue, int userId) {
|
||||||
checkReadPermission(key, userId);
|
checkReadPermission(key, userId);
|
||||||
return getBooleanUnchecked(key, defaultValue, userId);
|
if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
|
||||||
}
|
return getCredentialTypeInternal(userId) == CREDENTIAL_TYPE_PATTERN;
|
||||||
|
}
|
||||||
private boolean getBooleanUnchecked(String key, boolean defaultValue, int userId) {
|
return mStorage.getBoolean(key, defaultValue, userId);
|
||||||
String value = getStringUnchecked(key, null, userId);
|
|
||||||
return TextUtils.isEmpty(value) ?
|
|
||||||
defaultValue : (value.equals("1") || value.equals("true"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLong(String key, long defaultValue, int userId) {
|
public long getLong(String key, long defaultValue, int userId) {
|
||||||
checkReadPermission(key, userId);
|
checkReadPermission(key, userId);
|
||||||
return getLongUnchecked(key, defaultValue, userId);
|
return mStorage.getLong(key, defaultValue, userId);
|
||||||
}
|
|
||||||
|
|
||||||
private long getLongUnchecked(String key, long defaultValue, int userId) {
|
|
||||||
String value = getStringUnchecked(key, null, userId);
|
|
||||||
return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getIntUnchecked(String key, int defaultValue, int userId) {
|
|
||||||
String value = getStringUnchecked(key, null, userId);
|
|
||||||
return TextUtils.isEmpty(value) ? defaultValue : Integer.parseInt(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(String key, String defaultValue, int userId) {
|
public String getString(String key, String defaultValue, int userId) {
|
||||||
checkReadPermission(key, userId);
|
checkReadPermission(key, userId);
|
||||||
return getStringUnchecked(key, defaultValue, userId);
|
return mStorage.getString(key, defaultValue, userId);
|
||||||
}
|
|
||||||
|
|
||||||
private String getStringUnchecked(String key, String defaultValue, int userId) {
|
|
||||||
if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) {
|
|
||||||
return getCredentialTypeInternal(userId) == CREDENTIAL_TYPE_PATTERN ? "1" : "0";
|
|
||||||
}
|
|
||||||
if (userId == USER_FRP) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
|
|
||||||
key = Settings.Secure.LOCK_PATTERN_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mStorage.readKeyValue(key, defaultValue, userId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setKeyguardStoredQuality(int quality, int userId) {
|
private void setKeyguardStoredQuality(int quality, int userId) {
|
||||||
if (DEBUG) Slog.d(TAG, "setKeyguardStoredQuality: user=" + userId + " quality=" + quality);
|
if (DEBUG) Slog.d(TAG, "setKeyguardStoredQuality: user=" + userId + " quality=" + quality);
|
||||||
setLongUnchecked(LockPatternUtils.PASSWORD_TYPE_KEY, quality, userId);
|
mStorage.setLong(LockPatternUtils.PASSWORD_TYPE_KEY, quality, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getKeyguardStoredQuality(int userId) {
|
private int getKeyguardStoredQuality(int userId) {
|
||||||
return (int) getLongUnchecked(LockPatternUtils.PASSWORD_TYPE_KEY,
|
return (int) mStorage.getLong(LockPatternUtils.PASSWORD_TYPE_KEY,
|
||||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
|
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2493,13 +2445,6 @@ public class LockSettingsService extends ILockSettings.Stub {
|
|||||||
SEPARATE_PROFILE_CHALLENGE_KEY
|
SEPARATE_PROFILE_CHALLENGE_KEY
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] SETTINGS_TO_BACKUP = new String[] {
|
|
||||||
Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
|
|
||||||
Secure.LOCK_SCREEN_OWNER_INFO,
|
|
||||||
Secure.LOCK_PATTERN_VISIBLE,
|
|
||||||
LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
|
|
||||||
};
|
|
||||||
|
|
||||||
private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
|
private class GateKeeperDiedRecipient implements IBinder.DeathRecipient {
|
||||||
@Override
|
@Override
|
||||||
public void binderDied() {
|
public void binderDied() {
|
||||||
|
|||||||
@@ -18,8 +18,12 @@ package com.android.server.locksettings;
|
|||||||
|
|
||||||
import static android.content.Context.USER_SERVICE;
|
import static android.content.Context.USER_SERVICE;
|
||||||
|
|
||||||
|
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
|
||||||
|
import static com.android.internal.widget.LockPatternUtils.USER_FRP;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.app.backup.BackupManager;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
@@ -29,6 +33,8 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
@@ -87,6 +93,13 @@ class LockSettingsStorage {
|
|||||||
|
|
||||||
private static final Object DEFAULT = new Object();
|
private static final Object DEFAULT = new Object();
|
||||||
|
|
||||||
|
private static final String[] SETTINGS_TO_BACKUP = new String[] {
|
||||||
|
Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
|
||||||
|
Settings.Secure.LOCK_SCREEN_OWNER_INFO,
|
||||||
|
Settings.Secure.LOCK_PATTERN_VISIBLE,
|
||||||
|
LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
|
||||||
|
};
|
||||||
|
|
||||||
private final DatabaseHelper mOpenHelper;
|
private final DatabaseHelper mOpenHelper;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final Cache mCache = new Cache();
|
private final Cache mCache = new Cache();
|
||||||
@@ -136,10 +149,12 @@ class LockSettingsStorage {
|
|||||||
mOpenHelper.setCallback(callback);
|
mOpenHelper.setCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(visibility = PACKAGE)
|
||||||
public void writeKeyValue(String key, String value, int userId) {
|
public void writeKeyValue(String key, String value, int userId) {
|
||||||
writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
|
writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
|
public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
|
||||||
ContentValues cv = new ContentValues();
|
ContentValues cv = new ContentValues();
|
||||||
cv.put(COLUMN_KEY, key);
|
cv.put(COLUMN_KEY, key);
|
||||||
@@ -159,6 +174,7 @@ class LockSettingsStorage {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
public String readKeyValue(String key, String defaultValue, int userId) {
|
public String readKeyValue(String key, String defaultValue, int userId) {
|
||||||
int version;
|
int version;
|
||||||
synchronized (mCache) {
|
synchronized (mCache) {
|
||||||
@@ -184,6 +200,28 @@ class LockSettingsStorage {
|
|||||||
return result == DEFAULT ? defaultValue : (String) result;
|
return result == DEFAULT ? defaultValue : (String) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void removeKey(String key, int userId) {
|
||||||
|
removeKey(mOpenHelper.getWritableDatabase(), key, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeKey(SQLiteDatabase db, String key, int userId) {
|
||||||
|
ContentValues cv = new ContentValues();
|
||||||
|
cv.put(COLUMN_KEY, key);
|
||||||
|
cv.put(COLUMN_USERID, userId);
|
||||||
|
|
||||||
|
db.beginTransaction();
|
||||||
|
try {
|
||||||
|
db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
|
||||||
|
new String[] {key, Integer.toString(userId)});
|
||||||
|
db.setTransactionSuccessful();
|
||||||
|
mCache.removeKey(key, userId);
|
||||||
|
} finally {
|
||||||
|
db.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void prefetchUser(int userId) {
|
public void prefetchUser(int userId) {
|
||||||
int version;
|
int version;
|
||||||
synchronized (mCache) {
|
synchronized (mCache) {
|
||||||
@@ -537,6 +575,55 @@ class LockSettingsStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBoolean(String key, boolean value, int userId) {
|
||||||
|
setString(key, value ? "1" : "0", userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLong(String key, long value, int userId) {
|
||||||
|
setString(key, Long.toString(value), userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInt(String key, int value, int userId) {
|
||||||
|
setString(key, Integer.toString(value), userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setString(String key, String value, int userId) {
|
||||||
|
Preconditions.checkArgument(userId != USER_FRP, "cannot store lock settings for FRP user");
|
||||||
|
|
||||||
|
writeKeyValue(key, value, userId);
|
||||||
|
if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
|
||||||
|
BackupManager.dataChanged("com.android.providers.settings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBoolean(String key, boolean defaultValue, int userId) {
|
||||||
|
String value = getString(key, null, userId);
|
||||||
|
return TextUtils.isEmpty(value)
|
||||||
|
? defaultValue : (value.equals("1") || value.equals("true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong(String key, long defaultValue, int userId) {
|
||||||
|
String value = getString(key, null, userId);
|
||||||
|
return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(String key, int defaultValue, int userId) {
|
||||||
|
String value = getString(key, null, userId);
|
||||||
|
return TextUtils.isEmpty(value) ? defaultValue : Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString(String key, String defaultValue, int userId) {
|
||||||
|
if (userId == USER_FRP) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LockPatternUtils.LEGACY_LOCK_PATTERN_ENABLED.equals(key)) {
|
||||||
|
key = Settings.Secure.LOCK_PATTERN_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return readKeyValue(key, defaultValue, userId);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void closeDatabase() {
|
void closeDatabase() {
|
||||||
mOpenHelper.close();
|
mOpenHelper.close();
|
||||||
@@ -764,6 +851,10 @@ class LockSettingsStorage {
|
|||||||
putIfUnchanged(CacheKey.TYPE_KEY_VALUE, key, value, userId, version);
|
putIfUnchanged(CacheKey.TYPE_KEY_VALUE, key, value, userId, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeKey(String key, int userId) {
|
||||||
|
remove(CacheKey.TYPE_KEY_VALUE, key, userId);
|
||||||
|
}
|
||||||
|
|
||||||
byte[] peekFile(String fileName) {
|
byte[] peekFile(String fileName) {
|
||||||
return copyOf((byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */));
|
return copyOf((byte[]) peek(CacheKey.TYPE_FILE, fileName, -1 /* userId */));
|
||||||
}
|
}
|
||||||
@@ -788,6 +879,9 @@ class LockSettingsStorage {
|
|||||||
return contains(CacheKey.TYPE_FETCHED, "", userId);
|
return contains(CacheKey.TYPE_FETCHED, "", userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized void remove(int type, String key, int userId) {
|
||||||
|
mCache.remove(mCacheKey.set(type, key, userId));
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized void put(int type, String key, Object value, int userId) {
|
private synchronized void put(int type, String key, Object value, int userId) {
|
||||||
// Create a new CachKey here because it may be saved in the map if the key is absent.
|
// Create a new CachKey here because it may be saved in the map if the key is absent.
|
||||||
|
|||||||
Reference in New Issue
Block a user