FileDocCategorySizeDatePackage
LockSettingsStorage.javaAPI DocAndroid 5.1 API17097Thu Mar 12 22:22:42 GMT 2015com.android.server

LockSettingsStorage

public class LockSettingsStorage extends Object
Storage for the lock settings service.

Fields Summary
private static final String
TAG
private static final String
TABLE
private static final String
COLUMN_KEY
private static final String
COLUMN_USERID
private static final String
COLUMN_VALUE
private static final String[]
COLUMNS_FOR_QUERY
private static final String[]
COLUMNS_FOR_PREFETCH
private static final String
SYSTEM_DIRECTORY
private static final String
LOCK_PATTERN_FILE
private static final String
LOCK_PASSWORD_FILE
private static final Object
DEFAULT
private final DatabaseHelper
mOpenHelper
private final android.content.Context
mContext
private final Cache
mCache
private final Object
mFileWriteLock
Constructors Summary
public LockSettingsStorage(android.content.Context context, Callback callback)


         
        mContext = context;
        mOpenHelper = new DatabaseHelper(context, callback);
    
Methods Summary
voidclearCache()

        mCache.clear();
    
voidcloseDatabase()

        mOpenHelper.close();
    
private java.lang.StringgetLockCredentialFilePathForUser(int userId, java.lang.String basename)

        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 + basename;
        } else {
            return new File(Environment.getUserSystemDirectory(userId), basename).getAbsolutePath();
        }
    
java.lang.StringgetLockPasswordFilename(int userId)

        return getLockCredentialFilePathForUser(userId, LOCK_PASSWORD_FILE);
    
java.lang.StringgetLockPatternFilename(int userId)

        return getLockCredentialFilePathForUser(userId, LOCK_PATTERN_FILE);
    
private intgetUserParentOrSelfId(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 booleanhasFile(java.lang.String name)

        byte[] contents = readFile(name);
        return contents != null && contents.length > 0;
    
public booleanhasPassword(int userId)

        return hasFile(getLockPasswordFilename(userId));
    
public booleanhasPattern(int userId)

        return hasFile(getLockPatternFilename(userId));
    
public voidprefetchUser(int userId)

        int version;
        synchronized (mCache) {
            if (mCache.isFetched(userId)) {
                return;
            }
            mCache.setFetched(userId);
            version = mCache.getVersion();
        }

        Cursor cursor;
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        if ((cursor = db.query(TABLE, COLUMNS_FOR_PREFETCH,
                COLUMN_USERID + "=?",
                new String[] { Integer.toString(userId) },
                null, null, null)) != null) {
            while (cursor.moveToNext()) {
                String key = cursor.getString(0);
                String value = cursor.getString(1);
                mCache.putKeyValueIfUnchanged(key, value, userId, version);
            }
            cursor.close();
        }

        // Populate cache by reading the password and pattern files.
        readPasswordHash(userId);
        readPatternHash(userId);
    
private byte[]readFile(java.lang.String name)

        int version;
        synchronized (mCache) {
            if (mCache.hasFile(name)) {
                return mCache.peekFile(name);
            }
            version = mCache.getVersion();
        }

        RandomAccessFile raf = null;
        byte[] stored = null;
        try {
            raf = new RandomAccessFile(name, "r");
            stored = new byte[(int) raf.length()];
            raf.readFully(stored, 0, stored.length);
            raf.close();
        } catch (IOException e) {
            Slog.e(TAG, "Cannot read file " + e);
        } finally {
            if (raf != null) {
                try {
                    raf.close();
                } catch (IOException e) {
                    Slog.e(TAG, "Error closing file " + e);
                }
            }
        }
        mCache.putFileIfUnchanged(name, stored, version);
        return stored;
    
public java.lang.StringreadKeyValue(java.lang.String key, java.lang.String defaultValue, int userId)

        int version;
        synchronized (mCache) {
            if (mCache.hasKeyValue(key, userId)) {
                return mCache.peekKeyValue(key, defaultValue, userId);
            }
            version = mCache.getVersion();
        }

        Cursor cursor;
        Object result = DEFAULT;
        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();
        }
        mCache.putKeyValueIfUnchanged(key, result, userId, version);
        return result == DEFAULT ? defaultValue : (String) result;
    
public byte[]readPasswordHash(int userId)

        final byte[] stored = readFile(getLockPasswordFilename(userId));
        if (stored != null && stored.length > 0) {
            return stored;
        }
        return null;
    
public byte[]readPatternHash(int userId)

        final byte[] stored = readFile(getLockPatternFilename(userId));
        if (stored != null && stored.length > 0) {
            return stored;
        }
        return null;
    
public voidremoveUser(int userId)

        SQLiteDatabase db = mOpenHelper.getWritableDatabase();

        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
        final UserInfo parentInfo = um.getProfileParent(userId);

        synchronized (mFileWriteLock) {
            if (parentInfo == null) {
                // This user owns its lock settings files - safe to delete them
                String name = getLockPasswordFilename(userId);
                File file = new File(name);
                if (file.exists()) {
                    file.delete();
                    mCache.putFile(name, null);
                }
                name = getLockPatternFilename(userId);
                file = new File(name);
                if (file.exists()) {
                    file.delete();
                    mCache.putFile(name, null);
                }
            }
        }

        try {
            db.beginTransaction();
            db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null);
            db.setTransactionSuccessful();
            mCache.removeUser(userId);
        } finally {
            db.endTransaction();
        }
    
private voidwriteFile(java.lang.String name, byte[] hash)

        synchronized (mFileWriteLock) {
            RandomAccessFile raf = null;
            try {
                // Write the hash to file
                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 e) {
                Slog.e(TAG, "Error writing to file " + e);
            } finally {
                if (raf != null) {
                    try {
                        raf.close();
                    } catch (IOException e) {
                        Slog.e(TAG, "Error closing file " + e);
                    }
                }
            }
            mCache.putFile(name, hash);
        }
    
public voidwriteKeyValue(java.lang.String key, java.lang.String value, int userId)

        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
    
public voidwriteKeyValue(android.database.sqlite.SQLiteDatabase db, java.lang.String key, java.lang.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();
            mCache.putKeyValue(key, value, userId);
        } finally {
            db.endTransaction();
        }

    
public voidwritePasswordHash(byte[] hash, int userId)

        writeFile(getLockPasswordFilename(userId), hash);
    
public voidwritePatternHash(byte[] hash, int userId)

        writeFile(getLockPatternFilename(userId), hash);