Loading services/core/java/com/android/server/LockSettingsService.java +57 −278 Original line number Diff line number Diff line Loading @@ -18,49 +18,38 @@ package com.android.server; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; import static android.content.Context.USER_SERVICE; import static android.Manifest.permission.READ_PROFILE; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; import android.os.Binder; import android.os.Environment; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.storage.IMountService; import android.os.ServiceManager; import android.os.storage.StorageManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.provider.Settings.Secure; import android.provider.Settings.SettingNotFoundException; import android.security.KeyChain; import android.security.KeyChain.KeyChainConnection; import android.security.KeyStore; import android.text.TextUtils; import android.util.Log; import android.util.Slog; import com.android.internal.os.BackgroundThread; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.ILockSettingsObserver; import com.android.internal.widget.LockPatternUtils; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.Arrays; import java.util.List; Loading @@ -73,27 +62,17 @@ import java.util.List; */ public class LockSettingsService extends ILockSettings.Stub { private static final String PERMISSION = "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"; private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE; private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; private final DatabaseHelper mOpenHelper; private static final String TAG = "LockSettingsService"; private static final String TABLE = "locksettings"; private static final String COLUMN_KEY = "name"; private static final String COLUMN_USERID = "user"; private static final String COLUMN_VALUE = "value"; private static final String TAG = "LockSettingsService"; private static final String[] COLUMNS_FOR_QUERY = { COLUMN_VALUE }; private final Context mContext; private static final String SYSTEM_DIRECTORY = "/system/"; private static final String LOCK_PATTERN_FILE = "gesture.key"; private static final String LOCK_PASSWORD_FILE = "password.key"; private final LockSettingsStorage mStorage; private final Context mContext; private LockPatternUtils mLockPatternUtils; private boolean mFirstCallToVold; Loading @@ -102,7 +81,6 @@ public class LockSettingsService extends ILockSettings.Stub { public LockSettingsService(Context context) { mContext = context; // Open the database mOpenHelper = new DatabaseHelper(mContext); mLockPatternUtils = new LockPatternUtils(context); mFirstCallToVold = true; Loading @@ -110,6 +88,18 @@ public class LockSettingsService extends ILockSettings.Stub { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_ADDED); mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() { @Override public void initialize(SQLiteDatabase db) { // Get the lockscreen default from a system property, if available boolean lockScreenDisable = SystemProperties.getBoolean( "ro.lockscreen.disable.default", false); if (lockScreenDisable) { mStorage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0); } } }); } private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { Loading Loading @@ -220,29 +210,31 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void setBoolean(String key, boolean value, int userId) throws RemoteException { checkWritePermission(userId); writeToDb(key, value ? "1" : "0", userId); setStringUnchecked(key, userId, value ? "1" : "0"); } @Override public void setLong(String key, long value, int userId) throws RemoteException { checkWritePermission(userId); writeToDb(key, Long.toString(value), userId); setStringUnchecked(key, userId, Long.toString(value)); } @Override public void setString(String key, String value, int userId) throws RemoteException { checkWritePermission(userId); setStringUnchecked(key, userId, value); } writeToDb(key, value, userId); private void setStringUnchecked(String key, int userId, String value) { mStorage.writeKeyValue(key, value, userId); notifyObservers(key, userId); } @Override public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException { checkReadPermission(key, userId); String value = readFromDb(key, null, userId); String value = mStorage.readKeyValue(key, null, userId); return TextUtils.isEmpty(value) ? defaultValue : (value.equals("1") || value.equals("true")); } Loading @@ -251,7 +243,7 @@ public class LockSettingsService extends ILockSettings.Stub { public long getLong(String key, long defaultValue, int userId) throws RemoteException { checkReadPermission(key, userId); String value = readFromDb(key, null, userId); String value = mStorage.readKeyValue(key, null, userId); return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value); } Loading @@ -259,7 +251,7 @@ public class LockSettingsService extends ILockSettings.Stub { public String getString(String key, String defaultValue, int userId) throws RemoteException { checkReadPermission(key, userId); return readFromDb(key, defaultValue, userId); return mStorage.readKeyValue(key, defaultValue, userId); } @Override Loading Loading @@ -308,57 +300,18 @@ public class LockSettingsService extends ILockSettings.Stub { } } private int getUserParentOrSelfId(int userId) { if (userId != 0) { final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); final UserInfo pi = um.getProfileParent(userId); if (pi != null) { return pi.id; } } return userId; } private String getLockPatternFilename(int userId) { String dataSystemDirectory = android.os.Environment.getDataDirectory().getAbsolutePath() + SYSTEM_DIRECTORY; userId = getUserParentOrSelfId(userId); if (userId == 0) { // Leave it in the same place for user 0 return dataSystemDirectory + LOCK_PATTERN_FILE; } else { return new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE) .getAbsolutePath(); } } private String getLockPasswordFilename(int userId) { userId = getUserParentOrSelfId(userId); String dataSystemDirectory = android.os.Environment.getDataDirectory().getAbsolutePath() + SYSTEM_DIRECTORY; if (userId == 0) { // Leave it in the same place for user 0 return dataSystemDirectory + LOCK_PASSWORD_FILE; } else { return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE) .getAbsolutePath(); } } @Override public boolean havePassword(int userId) throws RemoteException { // Do we need a permissions check here? return new File(getLockPasswordFilename(userId)).length() > 0; return mStorage.hasPassword(userId); } @Override public boolean havePattern(int userId) throws RemoteException { // Do we need a permissions check here? return new File(getLockPatternFilename(userId)).length() > 0; return mStorage.hasPattern(userId); } private void maybeUpdateKeystore(String password, int userHandle) { Loading Loading @@ -394,7 +347,7 @@ public class LockSettingsService extends ILockSettings.Stub { final byte[] hash = LockPatternUtils.patternToHash( LockPatternUtils.stringToPattern(pattern)); writeFile(getLockPatternFilename(userId), hash); mStorage.writePatternHash(hash, userId); } @Override Loading @@ -403,64 +356,42 @@ public class LockSettingsService extends ILockSettings.Stub { maybeUpdateKeystore(password, userId); writeFile(getLockPasswordFilename(userId), mLockPatternUtils.passwordToHash(password, userId)); mStorage.writePasswordHash(mLockPatternUtils.passwordToHash(password, userId), userId); } @Override public boolean checkPattern(String pattern, int userId) throws RemoteException { checkPasswordReadPermission(userId); try { // Read all the bytes from the file RandomAccessFile raf = new RandomAccessFile(getLockPatternFilename(userId), "r"); final byte[] stored = new byte[(int) raf.length()]; int got = raf.read(stored, 0, stored.length); raf.close(); if (got <= 0) { byte[] hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(pattern)); byte[] storedHash = mStorage.readPatternHash(userId); if (storedHash == null) { return true; } // Compare the hash from the file with the entered pattern's hash final byte[] hash = LockPatternUtils.patternToHash( LockPatternUtils.stringToPattern(pattern)); final boolean matched = Arrays.equals(stored, hash); boolean matched = Arrays.equals(hash, storedHash); if (matched && !TextUtils.isEmpty(pattern)) { maybeUpdateKeystore(pattern, userId); } return matched; } catch (FileNotFoundException fnfe) { Slog.e(TAG, "Cannot read file " + fnfe); } catch (IOException ioe) { Slog.e(TAG, "Cannot read file " + ioe); } return true; } @Override public boolean checkPassword(String password, int userId) throws RemoteException { checkPasswordReadPermission(userId); try { // Read all the bytes from the file RandomAccessFile raf = new RandomAccessFile(getLockPasswordFilename(userId), "r"); final byte[] stored = new byte[(int) raf.length()]; int got = raf.read(stored, 0, stored.length); raf.close(); if (got <= 0) { byte[] hash = mLockPatternUtils.passwordToHash(password, userId); byte[] storedHash = mStorage.readPasswordHash(userId); if (storedHash == null) { return true; } // Compare the hash from the file with the entered password's hash final byte[] hash = mLockPatternUtils.passwordToHash(password, userId); final boolean matched = Arrays.equals(stored, hash); boolean matched = Arrays.equals(hash, storedHash); if (matched && !TextUtils.isEmpty(password)) { maybeUpdateKeystore(password, userId); } return matched; } catch (FileNotFoundException fnfe) { Slog.e(TAG, "Cannot read file " + fnfe); } catch (IOException ioe) { Slog.e(TAG, "Cannot read file " + ioe); } return true; } @Override Loading Loading @@ -512,166 +443,14 @@ public class LockSettingsService extends ILockSettings.Stub { public void removeUser(int userId) { checkWritePermission(userId); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); try { final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); final UserInfo parentInfo = um.getProfileParent(userId); if (parentInfo == null) { // This user owns its lock settings files - safe to delete them File file = new File(getLockPasswordFilename(userId)); if (file.exists()) { file.delete(); } file = new File(getLockPatternFilename(userId)); if (file.exists()) { file.delete(); } } db.beginTransaction(); db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null); db.setTransactionSuccessful(); } finally { db.endTransaction(); } mStorage.removeUser(userId); notifyObservers(null /* key */, userId); final KeyStore ks = KeyStore.getInstance(); final int userUid = UserHandle.getUid(userId, Process.SYSTEM_UID); ks.resetUid(userUid); } private void writeFile(String name, byte[] hash) { try { // Write the hash to file RandomAccessFile raf = new RandomAccessFile(name, "rw"); // Truncate the file if pattern is null, to clear the lock if (hash == null || hash.length == 0) { raf.setLength(0); } else { raf.write(hash, 0, hash.length); } raf.close(); } catch (IOException ioe) { Slog.e(TAG, "Error writing to file " + ioe); } } private void writeToDb(String key, String value, int userId) { writeToDb(mOpenHelper.getWritableDatabase(), key, value, userId); notifyObservers(key, userId); } private void writeToDb(SQLiteDatabase db, String key, String value, int userId) { ContentValues cv = new ContentValues(); cv.put(COLUMN_KEY, key); cv.put(COLUMN_USERID, userId); cv.put(COLUMN_VALUE, value); db.beginTransaction(); try { db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?", new String[] {key, Integer.toString(userId)}); db.insert(TABLE, null, cv); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } private String readFromDb(String key, String defaultValue, int userId) { Cursor cursor; String result = defaultValue; SQLiteDatabase db = mOpenHelper.getReadableDatabase(); if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY, COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?", new String[] { Integer.toString(userId), key }, null, null, null)) != null) { if (cursor.moveToFirst()) { result = cursor.getString(0); } cursor.close(); } return result; } class DatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "LockSettingsDB"; private static final String DATABASE_NAME = "locksettings.db"; private static final int DATABASE_VERSION = 2; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); setWriteAheadLoggingEnabled(true); } private void createTable(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE + " (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_KEY + " TEXT," + COLUMN_USERID + " INTEGER," + COLUMN_VALUE + " TEXT" + ");"); } @Override public void onCreate(SQLiteDatabase db) { createTable(db); initializeDefaults(db); } private void initializeDefaults(SQLiteDatabase db) { // Get the lockscreen default from a system property, if available boolean lockScreenDisable = SystemProperties.getBoolean("ro.lockscreen.disable.default", false); if (lockScreenDisable) { writeToDb(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) { int upgradeVersion = oldVersion; if (upgradeVersion == 1) { // Set the initial value for {@link LockPatternUtils#LOCKSCREEN_WIDGETS_ENABLED} // during upgrade based on whether each user previously had widgets in keyguard. maybeEnableWidgetSettingForUsers(db); upgradeVersion = 2; } if (upgradeVersion != DATABASE_VERSION) { Log.w(TAG, "Failed to upgrade database!"); } } private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) { final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); final ContentResolver cr = mContext.getContentResolver(); final List<UserInfo> users = um.getUsers(); for (int i = 0; i < users.size(); i++) { final int userId = users.get(i).id; final boolean enabled = mLockPatternUtils.hasWidgetsEnabledInKeyguard(userId); Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled=" + enabled + ", w[]=" + mLockPatternUtils.getAppWidgets()); loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled); } } private void loadSetting(SQLiteDatabase db, String key, int userId, boolean value) { SQLiteStatement stmt = null; try { stmt = db.compileStatement( "INSERT OR REPLACE INTO locksettings(name,user,value) VALUES(?,?,?);"); stmt.bindString(1, key); stmt.bindLong(2, userId); stmt.bindLong(3, value ? 1 : 0); stmt.execute(); } finally { if (stmt != null) stmt.close(); } } } private static final String[] VALID_SETTINGS = new String[] { LockPatternUtils.LOCKOUT_PERMANENT_KEY, LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE, Loading services/core/java/com/android/server/LockSettingsStorage.java 0 → 100644 +307 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/LockSettingsService.java +57 −278 Original line number Diff line number Diff line Loading @@ -18,49 +18,38 @@ package com.android.server; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; import static android.content.Context.USER_SERVICE; import static android.Manifest.permission.READ_PROFILE; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; import android.os.Binder; import android.os.Environment; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.storage.IMountService; import android.os.ServiceManager; import android.os.storage.StorageManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.provider.Settings.Secure; import android.provider.Settings.SettingNotFoundException; import android.security.KeyChain; import android.security.KeyChain.KeyChainConnection; import android.security.KeyStore; import android.text.TextUtils; import android.util.Log; import android.util.Slog; import com.android.internal.os.BackgroundThread; import com.android.internal.widget.ILockSettings; import com.android.internal.widget.ILockSettingsObserver; import com.android.internal.widget.LockPatternUtils; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.Arrays; import java.util.List; Loading @@ -73,27 +62,17 @@ import java.util.List; */ public class LockSettingsService extends ILockSettings.Stub { private static final String PERMISSION = "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"; private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE; private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; private final DatabaseHelper mOpenHelper; private static final String TAG = "LockSettingsService"; private static final String TABLE = "locksettings"; private static final String COLUMN_KEY = "name"; private static final String COLUMN_USERID = "user"; private static final String COLUMN_VALUE = "value"; private static final String TAG = "LockSettingsService"; private static final String[] COLUMNS_FOR_QUERY = { COLUMN_VALUE }; private final Context mContext; private static final String SYSTEM_DIRECTORY = "/system/"; private static final String LOCK_PATTERN_FILE = "gesture.key"; private static final String LOCK_PASSWORD_FILE = "password.key"; private final LockSettingsStorage mStorage; private final Context mContext; private LockPatternUtils mLockPatternUtils; private boolean mFirstCallToVold; Loading @@ -102,7 +81,6 @@ public class LockSettingsService extends ILockSettings.Stub { public LockSettingsService(Context context) { mContext = context; // Open the database mOpenHelper = new DatabaseHelper(mContext); mLockPatternUtils = new LockPatternUtils(context); mFirstCallToVold = true; Loading @@ -110,6 +88,18 @@ public class LockSettingsService extends ILockSettings.Stub { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_ADDED); mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() { @Override public void initialize(SQLiteDatabase db) { // Get the lockscreen default from a system property, if available boolean lockScreenDisable = SystemProperties.getBoolean( "ro.lockscreen.disable.default", false); if (lockScreenDisable) { mStorage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0); } } }); } private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { Loading Loading @@ -220,29 +210,31 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void setBoolean(String key, boolean value, int userId) throws RemoteException { checkWritePermission(userId); writeToDb(key, value ? "1" : "0", userId); setStringUnchecked(key, userId, value ? "1" : "0"); } @Override public void setLong(String key, long value, int userId) throws RemoteException { checkWritePermission(userId); writeToDb(key, Long.toString(value), userId); setStringUnchecked(key, userId, Long.toString(value)); } @Override public void setString(String key, String value, int userId) throws RemoteException { checkWritePermission(userId); setStringUnchecked(key, userId, value); } writeToDb(key, value, userId); private void setStringUnchecked(String key, int userId, String value) { mStorage.writeKeyValue(key, value, userId); notifyObservers(key, userId); } @Override public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException { checkReadPermission(key, userId); String value = readFromDb(key, null, userId); String value = mStorage.readKeyValue(key, null, userId); return TextUtils.isEmpty(value) ? defaultValue : (value.equals("1") || value.equals("true")); } Loading @@ -251,7 +243,7 @@ public class LockSettingsService extends ILockSettings.Stub { public long getLong(String key, long defaultValue, int userId) throws RemoteException { checkReadPermission(key, userId); String value = readFromDb(key, null, userId); String value = mStorage.readKeyValue(key, null, userId); return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value); } Loading @@ -259,7 +251,7 @@ public class LockSettingsService extends ILockSettings.Stub { public String getString(String key, String defaultValue, int userId) throws RemoteException { checkReadPermission(key, userId); return readFromDb(key, defaultValue, userId); return mStorage.readKeyValue(key, defaultValue, userId); } @Override Loading Loading @@ -308,57 +300,18 @@ public class LockSettingsService extends ILockSettings.Stub { } } private int getUserParentOrSelfId(int userId) { if (userId != 0) { final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); final UserInfo pi = um.getProfileParent(userId); if (pi != null) { return pi.id; } } return userId; } private String getLockPatternFilename(int userId) { String dataSystemDirectory = android.os.Environment.getDataDirectory().getAbsolutePath() + SYSTEM_DIRECTORY; userId = getUserParentOrSelfId(userId); if (userId == 0) { // Leave it in the same place for user 0 return dataSystemDirectory + LOCK_PATTERN_FILE; } else { return new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE) .getAbsolutePath(); } } private String getLockPasswordFilename(int userId) { userId = getUserParentOrSelfId(userId); String dataSystemDirectory = android.os.Environment.getDataDirectory().getAbsolutePath() + SYSTEM_DIRECTORY; if (userId == 0) { // Leave it in the same place for user 0 return dataSystemDirectory + LOCK_PASSWORD_FILE; } else { return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE) .getAbsolutePath(); } } @Override public boolean havePassword(int userId) throws RemoteException { // Do we need a permissions check here? return new File(getLockPasswordFilename(userId)).length() > 0; return mStorage.hasPassword(userId); } @Override public boolean havePattern(int userId) throws RemoteException { // Do we need a permissions check here? return new File(getLockPatternFilename(userId)).length() > 0; return mStorage.hasPattern(userId); } private void maybeUpdateKeystore(String password, int userHandle) { Loading Loading @@ -394,7 +347,7 @@ public class LockSettingsService extends ILockSettings.Stub { final byte[] hash = LockPatternUtils.patternToHash( LockPatternUtils.stringToPattern(pattern)); writeFile(getLockPatternFilename(userId), hash); mStorage.writePatternHash(hash, userId); } @Override Loading @@ -403,64 +356,42 @@ public class LockSettingsService extends ILockSettings.Stub { maybeUpdateKeystore(password, userId); writeFile(getLockPasswordFilename(userId), mLockPatternUtils.passwordToHash(password, userId)); mStorage.writePasswordHash(mLockPatternUtils.passwordToHash(password, userId), userId); } @Override public boolean checkPattern(String pattern, int userId) throws RemoteException { checkPasswordReadPermission(userId); try { // Read all the bytes from the file RandomAccessFile raf = new RandomAccessFile(getLockPatternFilename(userId), "r"); final byte[] stored = new byte[(int) raf.length()]; int got = raf.read(stored, 0, stored.length); raf.close(); if (got <= 0) { byte[] hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(pattern)); byte[] storedHash = mStorage.readPatternHash(userId); if (storedHash == null) { return true; } // Compare the hash from the file with the entered pattern's hash final byte[] hash = LockPatternUtils.patternToHash( LockPatternUtils.stringToPattern(pattern)); final boolean matched = Arrays.equals(stored, hash); boolean matched = Arrays.equals(hash, storedHash); if (matched && !TextUtils.isEmpty(pattern)) { maybeUpdateKeystore(pattern, userId); } return matched; } catch (FileNotFoundException fnfe) { Slog.e(TAG, "Cannot read file " + fnfe); } catch (IOException ioe) { Slog.e(TAG, "Cannot read file " + ioe); } return true; } @Override public boolean checkPassword(String password, int userId) throws RemoteException { checkPasswordReadPermission(userId); try { // Read all the bytes from the file RandomAccessFile raf = new RandomAccessFile(getLockPasswordFilename(userId), "r"); final byte[] stored = new byte[(int) raf.length()]; int got = raf.read(stored, 0, stored.length); raf.close(); if (got <= 0) { byte[] hash = mLockPatternUtils.passwordToHash(password, userId); byte[] storedHash = mStorage.readPasswordHash(userId); if (storedHash == null) { return true; } // Compare the hash from the file with the entered password's hash final byte[] hash = mLockPatternUtils.passwordToHash(password, userId); final boolean matched = Arrays.equals(stored, hash); boolean matched = Arrays.equals(hash, storedHash); if (matched && !TextUtils.isEmpty(password)) { maybeUpdateKeystore(password, userId); } return matched; } catch (FileNotFoundException fnfe) { Slog.e(TAG, "Cannot read file " + fnfe); } catch (IOException ioe) { Slog.e(TAG, "Cannot read file " + ioe); } return true; } @Override Loading Loading @@ -512,166 +443,14 @@ public class LockSettingsService extends ILockSettings.Stub { public void removeUser(int userId) { checkWritePermission(userId); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); try { final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); final UserInfo parentInfo = um.getProfileParent(userId); if (parentInfo == null) { // This user owns its lock settings files - safe to delete them File file = new File(getLockPasswordFilename(userId)); if (file.exists()) { file.delete(); } file = new File(getLockPatternFilename(userId)); if (file.exists()) { file.delete(); } } db.beginTransaction(); db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null); db.setTransactionSuccessful(); } finally { db.endTransaction(); } mStorage.removeUser(userId); notifyObservers(null /* key */, userId); final KeyStore ks = KeyStore.getInstance(); final int userUid = UserHandle.getUid(userId, Process.SYSTEM_UID); ks.resetUid(userUid); } private void writeFile(String name, byte[] hash) { try { // Write the hash to file RandomAccessFile raf = new RandomAccessFile(name, "rw"); // Truncate the file if pattern is null, to clear the lock if (hash == null || hash.length == 0) { raf.setLength(0); } else { raf.write(hash, 0, hash.length); } raf.close(); } catch (IOException ioe) { Slog.e(TAG, "Error writing to file " + ioe); } } private void writeToDb(String key, String value, int userId) { writeToDb(mOpenHelper.getWritableDatabase(), key, value, userId); notifyObservers(key, userId); } private void writeToDb(SQLiteDatabase db, String key, String value, int userId) { ContentValues cv = new ContentValues(); cv.put(COLUMN_KEY, key); cv.put(COLUMN_USERID, userId); cv.put(COLUMN_VALUE, value); db.beginTransaction(); try { db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?", new String[] {key, Integer.toString(userId)}); db.insert(TABLE, null, cv); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } private String readFromDb(String key, String defaultValue, int userId) { Cursor cursor; String result = defaultValue; SQLiteDatabase db = mOpenHelper.getReadableDatabase(); if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY, COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?", new String[] { Integer.toString(userId), key }, null, null, null)) != null) { if (cursor.moveToFirst()) { result = cursor.getString(0); } cursor.close(); } return result; } class DatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "LockSettingsDB"; private static final String DATABASE_NAME = "locksettings.db"; private static final int DATABASE_VERSION = 2; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); setWriteAheadLoggingEnabled(true); } private void createTable(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE + " (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_KEY + " TEXT," + COLUMN_USERID + " INTEGER," + COLUMN_VALUE + " TEXT" + ");"); } @Override public void onCreate(SQLiteDatabase db) { createTable(db); initializeDefaults(db); } private void initializeDefaults(SQLiteDatabase db) { // Get the lockscreen default from a system property, if available boolean lockScreenDisable = SystemProperties.getBoolean("ro.lockscreen.disable.default", false); if (lockScreenDisable) { writeToDb(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) { int upgradeVersion = oldVersion; if (upgradeVersion == 1) { // Set the initial value for {@link LockPatternUtils#LOCKSCREEN_WIDGETS_ENABLED} // during upgrade based on whether each user previously had widgets in keyguard. maybeEnableWidgetSettingForUsers(db); upgradeVersion = 2; } if (upgradeVersion != DATABASE_VERSION) { Log.w(TAG, "Failed to upgrade database!"); } } private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) { final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); final ContentResolver cr = mContext.getContentResolver(); final List<UserInfo> users = um.getUsers(); for (int i = 0; i < users.size(); i++) { final int userId = users.get(i).id; final boolean enabled = mLockPatternUtils.hasWidgetsEnabledInKeyguard(userId); Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled=" + enabled + ", w[]=" + mLockPatternUtils.getAppWidgets()); loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled); } } private void loadSetting(SQLiteDatabase db, String key, int userId, boolean value) { SQLiteStatement stmt = null; try { stmt = db.compileStatement( "INSERT OR REPLACE INTO locksettings(name,user,value) VALUES(?,?,?);"); stmt.bindString(1, key); stmt.bindLong(2, userId); stmt.bindLong(3, value ? 1 : 0); stmt.execute(); } finally { if (stmt != null) stmt.close(); } } } private static final String[] VALID_SETTINGS = new String[] { LockPatternUtils.LOCKOUT_PERMANENT_KEY, LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE, Loading
services/core/java/com/android/server/LockSettingsStorage.java 0 → 100644 +307 −0 File added.Preview size limit exceeded, changes collapsed. Show changes