LockSettingsService.java revision 945490c12e32b1c13b9097c00702558260b2011f
152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani/* 252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Copyright (C) 2012 The Android Open Source Project 352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * 452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); 552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * you may not use this file except in compliance with the License. 652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * You may obtain a copy of the License at 752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * 852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * http://www.apache.org/licenses/LICENSE-2.0 952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * 1052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Unless required by applicable law or agreed to in writing, software 1152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, 1252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * See the License for the specific language governing permissions and 1452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * limitations under the License. 1552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani */ 1652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 177a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeypackage com.android.server; 1852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 1952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.content.ContentResolver; 2052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.content.ContentValues; 2152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.content.Context; 22158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Millerimport android.content.pm.PackageManager; 23187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport android.content.pm.UserInfo; 24187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller 25187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport static android.content.Context.USER_SERVICE; 26158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Millerimport static android.Manifest.permission.READ_PROFILE; 2752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.database.Cursor; 2852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.database.sqlite.SQLiteDatabase; 2952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.database.sqlite.SQLiteOpenHelper; 30f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Millerimport android.database.sqlite.SQLiteStatement; 3152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.os.Binder; 3261f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasaniimport android.os.Environment; 33945490c12e32b1c13b9097c00702558260b2011fPaul Lawrenceimport android.os.IBinder; 3452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.os.RemoteException; 35945490c12e32b1c13b9097c00702558260b2011fPaul Lawrenceimport android.os.storage.IMountService; 36945490c12e32b1c13b9097c00702558260b2011fPaul Lawrenceimport android.os.ServiceManager; 37945490c12e32b1c13b9097c00702558260b2011fPaul Lawrenceimport android.os.storage.StorageManager; 38d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasaniimport android.os.SystemProperties; 39f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 40187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport android.os.UserManager; 4152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.provider.Settings; 4252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.provider.Settings.Secure; 43187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport android.provider.Settings.SettingNotFoundException; 44de1af08dd3a073f007ae4b8a114352cae3775028Jim Millerimport android.security.KeyStore; 4552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.text.TextUtils; 46f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Millerimport android.util.Log; 4752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.util.Slog; 4852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 497a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport com.android.internal.widget.ILockSettings; 507a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport com.android.internal.widget.LockPatternUtils; 517a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey 5252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport java.io.File; 5352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport java.io.FileNotFoundException; 5452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport java.io.IOException; 5552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport java.io.RandomAccessFile; 5652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport java.util.Arrays; 57187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport java.util.List; 5852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 5952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani/** 6052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Keeps the lock pattern/password data and related settings for each user. 6152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Used by LockPatternUtils. Needs to be a service because Settings app also needs 6252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * to be able to save lockscreen information for secondary users. 6352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * @hide 6452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani */ 6552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasanipublic class LockSettingsService extends ILockSettings.Stub { 6652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 675ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller private static final String PERMISSION = "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"; 6852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private final DatabaseHelper mOpenHelper; 6952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String TAG = "LockSettingsService"; 7052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 7152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String TABLE = "locksettings"; 7252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String COLUMN_KEY = "name"; 7352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String COLUMN_USERID = "user"; 7452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String COLUMN_VALUE = "value"; 7552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 7652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String[] COLUMNS_FOR_QUERY = { 7752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani COLUMN_VALUE 7852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani }; 7952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 8052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String SYSTEM_DIRECTORY = "/system/"; 8152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String LOCK_PATTERN_FILE = "gesture.key"; 8252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String LOCK_PASSWORD_FILE = "password.key"; 8352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 8452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private final Context mContext; 85de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller private LockPatternUtils mLockPatternUtils; 86945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence private boolean mFirstCallToVold; 8752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 8852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public LockSettingsService(Context context) { 8952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani mContext = context; 9052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Open the database 9152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani mOpenHelper = new DatabaseHelper(mContext); 92de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller 93de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller mLockPatternUtils = new LockPatternUtils(context); 94945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence mFirstCallToVold = true; 9552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 9652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 9752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public void systemReady() { 9852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani migrateOldData(); 9952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 10052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 10152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private void migrateOldData() { 10252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 103187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller // These Settings moved before multi-user was enabled, so we only have to do it for the 104187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller // root user. 105187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller if (getString("migrated", null, 0) == null) { 106187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller final ContentResolver cr = mContext.getContentResolver(); 107187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller for (String validSetting : VALID_SETTINGS) { 108187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller String value = Settings.Secure.getString(cr, validSetting); 109187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller if (value != null) { 110187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller setString(validSetting, value, 0); 111187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller } 112187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller } 113187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller // No need to move the password / pattern files. They're already in the right place. 114187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller setString("migrated", "true", 0); 115187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller Slog.i(TAG, "Migrated lock settings to new location"); 11652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 11752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 118187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller // These Settings changed after multi-user was enabled, hence need to be moved per user. 119187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller if (getString("migrated_user_specific", null, 0) == null) { 120187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); 121187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller final ContentResolver cr = mContext.getContentResolver(); 122187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller List<UserInfo> users = um.getUsers(); 123187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller for (int user = 0; user < users.size(); user++) { 1242d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller // Migrate owner info 1252d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller final int userId = users.get(user).id; 1262d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO; 1272d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId); 1282d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller if (ownerInfo != null) { 1292d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller setString(OWNER_INFO, ownerInfo, userId); 1302d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller Settings.Secure.putStringForUser(cr, ownerInfo, "", userId); 1312d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller } 132187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller 1332d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller // Migrate owner info enabled. Note there was a bug where older platforms only 1342d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller // stored this value if the checkbox was toggled at least once. The code detects 1352d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller // this case by handling the exception. 1362d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED; 1372d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller boolean enabled; 1382d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller try { 1392d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId); 1402d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller enabled = ivalue != 0; 1412d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId); 1422d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller } catch (SettingNotFoundException e) { 1432d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller // Setting was never stored. Store it if the string is not empty. 1442d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller if (!TextUtils.isEmpty(ownerInfo)) { 1452d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller setLong(OWNER_INFO_ENABLED, 1, userId); 146187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller } 147187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller } 1482d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId); 14952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 150187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller // No need to move the password / pattern files. They're already in the right place. 151187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller setString("migrated_user_specific", "true", 0); 152187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller Slog.i(TAG, "Migrated per-user lock settings to new location"); 15352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 15452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (RemoteException re) { 155187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller Slog.e(TAG, "Unable to migrate old data", re); 15652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 15752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 15852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 1595ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller private final void checkWritePermission(int userId) { 160505329b21b743c6e74e0d1b14bea78a22f7b4145Jim Miller mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite"); 16152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 16252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 1635ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller private final void checkPasswordReadPermission(int userId) { 164505329b21b743c6e74e0d1b14bea78a22f7b4145Jim Miller mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead"); 16552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 16652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 167158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller private final void checkReadPermission(String requestedKey, int userId) { 16852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani final int callingUid = Binder.getCallingUid(); 169158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller for (int i = 0; i < READ_PROFILE_PROTECTED_SETTINGS.length; i++) { 170158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller String key = READ_PROFILE_PROTECTED_SETTINGS[i]; 171158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_PROFILE) 172158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller != PackageManager.PERMISSION_GRANTED) { 173158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller throw new SecurityException("uid=" + callingUid 174158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller + " needs permission " + READ_PROFILE + " to read " 175158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller + requestedKey + " for user " + userId); 176158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller } 17752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 17852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 17952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 18052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 18152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public void setBoolean(String key, boolean value, int userId) throws RemoteException { 18252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani checkWritePermission(userId); 18352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 18452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani writeToDb(key, value ? "1" : "0", userId); 18552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 18652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 18752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 18852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public void setLong(String key, long value, int userId) throws RemoteException { 18952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani checkWritePermission(userId); 19052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 19152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani writeToDb(key, Long.toString(value), userId); 19252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 19352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 19452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 19552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public void setString(String key, String value, int userId) throws RemoteException { 19652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani checkWritePermission(userId); 19752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 19852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani writeToDb(key, value, userId); 19952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 20052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 20152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 20252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException { 203158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller checkReadPermission(key, userId); 20452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 20552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani String value = readFromDb(key, null, userId); 20652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return TextUtils.isEmpty(value) ? 20752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani defaultValue : (value.equals("1") || value.equals("true")); 20852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 20952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 21052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 21152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public long getLong(String key, long defaultValue, int userId) throws RemoteException { 212158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller checkReadPermission(key, userId); 21352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 21452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani String value = readFromDb(key, null, userId); 21552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value); 21652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 21752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 21852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 21952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public String getString(String key, String defaultValue, int userId) throws RemoteException { 220158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller checkReadPermission(key, userId); 22152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 22252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return readFromDb(key, defaultValue, userId); 22352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 22452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 22552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private String getLockPatternFilename(int userId) { 22652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani String dataSystemDirectory = 22752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani android.os.Environment.getDataDirectory().getAbsolutePath() + 22852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani SYSTEM_DIRECTORY; 22952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (userId == 0) { 23052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Leave it in the same place for user 0 23152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return dataSystemDirectory + LOCK_PATTERN_FILE; 23252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } else { 23361f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani return new File(Environment.getUserSystemDirectory(userId), LOCK_PATTERN_FILE) 23461f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani .getAbsolutePath(); 23552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 23652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 23752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 23852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private String getLockPasswordFilename(int userId) { 23952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani String dataSystemDirectory = 24052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani android.os.Environment.getDataDirectory().getAbsolutePath() + 24152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani SYSTEM_DIRECTORY; 24252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (userId == 0) { 24352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Leave it in the same place for user 0 24452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return dataSystemDirectory + LOCK_PASSWORD_FILE; 24552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } else { 24661f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani return new File(Environment.getUserSystemDirectory(userId), LOCK_PASSWORD_FILE) 24761f57379ca2c5b6290c8da7548fa17128f7ab24fAmith Yamasani .getAbsolutePath(); 24852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 24952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 25052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 25152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 25252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public boolean havePassword(int userId) throws RemoteException { 25352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Do we need a permissions check here? 25452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 25552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return new File(getLockPasswordFilename(userId)).length() > 0; 25652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 25752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 25852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 25952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public boolean havePattern(int userId) throws RemoteException { 26052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Do we need a permissions check here? 26152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 26252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return new File(getLockPatternFilename(userId)).length() > 0; 26352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 26452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 265de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller private void maybeUpdateKeystore(String password, int userId) { 266de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller if (userId == UserHandle.USER_OWNER) { 267de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller final KeyStore keyStore = KeyStore.getInstance(); 268de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller // Conditionally reset the keystore if empty. If non-empty, we are just 269de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller // switching key guard type 270de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller if (TextUtils.isEmpty(password) && keyStore.isEmpty()) { 271de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller keyStore.reset(); 272de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller } else { 273de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller // Update the keystore password 274de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller keyStore.password(password); 275de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller } 276de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller } 277de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller } 278de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller 27952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 280de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller public void setLockPattern(String pattern, int userId) throws RemoteException { 28152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani checkWritePermission(userId); 28252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 283de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller maybeUpdateKeystore(pattern, userId); 284de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller 285de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller final byte[] hash = LockPatternUtils.patternToHash( 286de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller LockPatternUtils.stringToPattern(pattern)); 28752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani writeFile(getLockPatternFilename(userId), hash); 28852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 28952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 29052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 291de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller public void setLockPassword(String password, int userId) throws RemoteException { 292de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller checkWritePermission(userId); 293de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller 294de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller maybeUpdateKeystore(password, userId); 295de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller 296de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller writeFile(getLockPasswordFilename(userId), mLockPatternUtils.passwordToHash(password)); 297de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller } 298de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller 299de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller @Override 300de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller public boolean checkPattern(String pattern, int userId) throws RemoteException { 30152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani checkPasswordReadPermission(userId); 30252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 30352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Read all the bytes from the file 30452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani RandomAccessFile raf = new RandomAccessFile(getLockPatternFilename(userId), "r"); 30552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani final byte[] stored = new byte[(int) raf.length()]; 30652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani int got = raf.read(stored, 0, stored.length); 30752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani raf.close(); 30852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (got <= 0) { 30952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return true; 31052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 31152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Compare the hash from the file with the entered pattern's hash 312de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller final byte[] hash = LockPatternUtils.patternToHash( 313de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller LockPatternUtils.stringToPattern(pattern)); 314de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller final boolean matched = Arrays.equals(stored, hash); 315de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller if (matched && !TextUtils.isEmpty(pattern)) { 316de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller maybeUpdateKeystore(pattern, userId); 317de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller } 318de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller return matched; 31952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (FileNotFoundException fnfe) { 32052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Slog.e(TAG, "Cannot read file " + fnfe); 32152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (IOException ioe) { 32252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Slog.e(TAG, "Cannot read file " + ioe); 32352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 324de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller return true; 32552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 32652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 32752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 328de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller public boolean checkPassword(String password, int userId) throws RemoteException { 32952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani checkPasswordReadPermission(userId); 33052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 33152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 33252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Read all the bytes from the file 33352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani RandomAccessFile raf = new RandomAccessFile(getLockPasswordFilename(userId), "r"); 33452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani final byte[] stored = new byte[(int) raf.length()]; 33552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani int got = raf.read(stored, 0, stored.length); 33652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani raf.close(); 33752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (got <= 0) { 33852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return true; 33952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 34052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Compare the hash from the file with the entered password's hash 341de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller final byte[] hash = mLockPatternUtils.passwordToHash(password); 342de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller final boolean matched = Arrays.equals(stored, hash); 343de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller if (matched && !TextUtils.isEmpty(password)) { 344de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller maybeUpdateKeystore(password, userId); 345de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller } 346de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller return matched; 34752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (FileNotFoundException fnfe) { 34852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Slog.e(TAG, "Cannot read file " + fnfe); 34952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (IOException ioe) { 35052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Slog.e(TAG, "Cannot read file " + ioe); 35152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 352de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller return true; 35352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 35452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 35552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 356945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence public boolean checkVoldPassword(int userId) throws RemoteException { 357945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence if (!mFirstCallToVold) { 358945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return false; 359945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 360945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence mFirstCallToVold = false; 361945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence 362945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence checkPasswordReadPermission(userId); 363945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence 364945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence // There's no guarantee that this will safely connect, but if it fails 365945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence // we will simply show the lock screen when we shouldn't, so relatively 366945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence // benign. There is an outside chance something nasty would happen if 367945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence // this service restarted before vold stales out the password in this 368945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence // case. The nastiness is limited to not showing the lock screen when 369945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence // we should, within the first minute of decrypting the phone if this 370945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence // service can't connect to vold, it restarts, and then the new instance 371945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence // does successfully connect. 372945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence final IMountService service = getMountService(); 373945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence String password = service.getPassword(); 374945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence service.clearPassword(); 375945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence if (password == null) { 376945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return false; 377945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 378945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence 379945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence try { 380945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence if (mLockPatternUtils.isLockPatternEnabled()) { 381945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence if (checkPattern(password, userId)) { 382945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return true; 383945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 384945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 385945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } catch (Exception e) { 386945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 387945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence 388945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence try { 389945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence if (mLockPatternUtils.isLockPasswordEnabled()) { 390945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence if (checkPassword(password, userId)) { 391945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return true; 392945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 393945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 394945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } catch (Exception e) { 395945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 396945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence 397945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return false; 398945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 399945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence 400945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence @Override 40152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public void removeUser(int userId) { 40252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani checkWritePermission(userId); 40352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 40452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 40552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 40652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani File file = new File(getLockPasswordFilename(userId)); 40752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (file.exists()) { 40852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani file.delete(); 40952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 41052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani file = new File(getLockPatternFilename(userId)); 41152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (file.exists()) { 41252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani file.delete(); 41352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 41452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 41552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.beginTransaction(); 41652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.delete(TABLE, COLUMN_USERID + "='" + userId + "'", null); 41752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.setTransactionSuccessful(); 41852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } finally { 41952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.endTransaction(); 42052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 42152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 42252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 42352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private void writeFile(String name, byte[] hash) { 42452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 42552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Write the hash to file 42652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani RandomAccessFile raf = new RandomAccessFile(name, "rw"); 42752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani // Truncate the file if pattern is null, to clear the lock 42852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (hash == null || hash.length == 0) { 42952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani raf.setLength(0); 43052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } else { 43152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani raf.write(hash, 0, hash.length); 43252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 43352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani raf.close(); 43452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } catch (IOException ioe) { 43552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Slog.e(TAG, "Error writing to file " + ioe); 43652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 43752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 43852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 43952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private void writeToDb(String key, String value, int userId) { 440d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani writeToDb(mOpenHelper.getWritableDatabase(), key, value, userId); 441d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani } 442d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani 443d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani private void writeToDb(SQLiteDatabase db, String key, String value, int userId) { 44452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani ContentValues cv = new ContentValues(); 44552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani cv.put(COLUMN_KEY, key); 44652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani cv.put(COLUMN_USERID, userId); 44752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani cv.put(COLUMN_VALUE, value); 44852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 44952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.beginTransaction(); 45052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani try { 45152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?", 45252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani new String[] {key, Integer.toString(userId)}); 45352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.insert(TABLE, null, cv); 45452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.setTransactionSuccessful(); 45552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } finally { 45652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.endTransaction(); 45752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 45852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 45952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 46052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private String readFromDb(String key, String defaultValue, int userId) { 46152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Cursor cursor; 46252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani String result = defaultValue; 46352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 46452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if ((cursor = db.query(TABLE, COLUMNS_FOR_QUERY, 46552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani COLUMN_USERID + "=? AND " + COLUMN_KEY + "=?", 46652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani new String[] { Integer.toString(userId), key }, 46752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani null, null, null)) != null) { 46852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani if (cursor.moveToFirst()) { 46952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani result = cursor.getString(0); 47052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 47152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani cursor.close(); 47252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 47352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani return result; 47452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 47552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 47652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani class DatabaseHelper extends SQLiteOpenHelper { 47752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String TAG = "LockSettingsDB"; 47852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String DATABASE_NAME = "locksettings.db"; 47952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 480f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller private static final int DATABASE_VERSION = 2; 48152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 48252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public DatabaseHelper(Context context) { 48352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani super(context, DATABASE_NAME, null, DATABASE_VERSION); 48452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani setWriteAheadLoggingEnabled(true); 48552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 48652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 48752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private void createTable(SQLiteDatabase db) { 48852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani db.execSQL("CREATE TABLE " + TABLE + " (" + 48952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani "_id INTEGER PRIMARY KEY AUTOINCREMENT," + 49052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani COLUMN_KEY + " TEXT," + 49152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani COLUMN_USERID + " INTEGER," + 49252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani COLUMN_VALUE + " TEXT" + 49352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani ");"); 49452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 49552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 49652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 49752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public void onCreate(SQLiteDatabase db) { 49852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani createTable(db); 499d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani initializeDefaults(db); 500d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani } 501d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani 502d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani private void initializeDefaults(SQLiteDatabase db) { 503d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani // Get the lockscreen default from a system property, if available 504d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani boolean lockScreenDisable = SystemProperties.getBoolean("ro.lockscreen.disable.default", 505d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani false); 506d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani if (lockScreenDisable) { 507d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani writeToDb(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0); 508d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasani } 50952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 51052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 51152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani @Override 51252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) { 513f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller int upgradeVersion = oldVersion; 514f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller if (upgradeVersion == 1) { 515f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller // Set the initial value for {@link LockPatternUtils#LOCKSCREEN_WIDGETS_ENABLED} 516f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller // during upgrade based on whether each user previously had widgets in keyguard. 517f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller maybeEnableWidgetSettingForUsers(db); 518f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller upgradeVersion = 2; 519f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller } 520f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller 521f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller if (upgradeVersion != DATABASE_VERSION) { 522f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller Log.w(TAG, "Failed to upgrade database!"); 523f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller } 524f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller } 525f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller 526f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) { 527f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); 528f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller final ContentResolver cr = mContext.getContentResolver(); 529f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller final List<UserInfo> users = um.getUsers(); 530f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller for (int i = 0; i < users.size(); i++) { 531f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller final int userId = users.get(i).id; 532de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller final boolean enabled = mLockPatternUtils.hasWidgetsEnabledInKeyguard(userId); 533f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled=" 534de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller + enabled + ", w[]=" + mLockPatternUtils.getAppWidgets()); 535f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled); 536f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller } 537f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller } 538f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller 539f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller private void loadSetting(SQLiteDatabase db, String key, int userId, boolean value) { 540f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller SQLiteStatement stmt = null; 541f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller try { 542f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller stmt = db.compileStatement( 543f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller "INSERT OR REPLACE INTO locksettings(name,user,value) VALUES(?,?,?);"); 544f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller stmt.bindString(1, key); 545f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller stmt.bindLong(2, userId); 546f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller stmt.bindLong(3, value ? 1 : 0); 547f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller stmt.execute(); 548f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller } finally { 549f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller if (stmt != null) stmt.close(); 550f45bb403884f30ecb383698ef1bcb1c7dc1964b8Jim Miller } 55152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 55252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani } 55352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani 55452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani private static final String[] VALID_SETTINGS = new String[] { 55552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.LOCKOUT_PERMANENT_KEY, 55652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE, 55752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.PATTERN_EVER_CHOSEN_KEY, 55852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.PASSWORD_TYPE_KEY, 55952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY, 56052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.LOCK_PASSWORD_SALT_KEY, 56152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.DISABLE_LOCKSCREEN_KEY, 56252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.LOCKSCREEN_OPTIONS, 56352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, 56452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY, 56552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, 56652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani LockPatternUtils.PASSWORD_HISTORY_KEY, 56752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Secure.LOCK_PATTERN_ENABLED, 56852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Secure.LOCK_BIOMETRIC_WEAK_FLAGS, 56952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Secure.LOCK_PATTERN_VISIBLE, 57052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED 571187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller }; 572187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller 5732d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller // These are protected with a read permission 5742d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller private static final String[] READ_PROFILE_PROTECTED_SETTINGS = new String[] { 575187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, 576187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller Secure.LOCK_SCREEN_OWNER_INFO 577187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller }; 578945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence 579945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence private IMountService getMountService() { 580945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence final IBinder service = ServiceManager.getService("mount"); 581945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence if (service != null) { 582945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return IMountService.Stub.asInterface(service); 583945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 584945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence return null; 585945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence } 58652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani} 587