LockSettingsService.java revision 3dcae68501a1fc1c433d12a9d55a31c7eaab016c
1bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber/* 2bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * Copyright (C) 2012 The Android Open Source Project 3bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * 4bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * you may not use this file except in compliance with the License. 6bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * You may obtain a copy of the License at 7bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * 8bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * 10bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * Unless required by applicable law or agreed to in writing, software 11bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * See the License for the specific language governing permissions and 14bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * limitations under the License. 15bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber */ 16bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 17bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberpackage com.android.server; 18bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 19bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.content.BroadcastReceiver; 20bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.content.ContentResolver; 21bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.content.Context; 22bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.content.Intent; 234844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huberimport android.content.IntentFilter; 24bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.content.pm.PackageManager; 25bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.content.pm.UserInfo; 26bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 27bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; 28bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport static android.content.Context.USER_SERVICE; 29bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport static android.Manifest.permission.READ_PROFILE; 30bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 31bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.database.sqlite.SQLiteDatabase; 32bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.Binder; 33bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.IBinder; 34bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.Process; 35bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.RemoteException; 36bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.storage.IMountService; 37bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.ServiceManager; 38bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.SystemProperties; 39bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.UserHandle; 40bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.os.UserManager; 41bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.provider.Settings; 42bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.provider.Settings.Secure; 43bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.provider.Settings.SettingNotFoundException; 44bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.security.KeyStore; 45bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.text.TextUtils; 46bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.util.Log; 47bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport android.util.Slog; 48bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 49bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport com.android.internal.widget.ILockSettings; 50bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport com.android.internal.widget.ILockSettingsObserver; 51bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport com.android.internal.widget.LockPatternUtils; 52bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport com.android.internal.widget.LockPatternUtilsCache; 53bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 54bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport java.util.ArrayList; 55bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport java.util.Arrays; 56bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberimport java.util.List; 57bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 58bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber/** 59bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * Keeps the lock pattern/password data and related settings for each user. 60bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * Used by LockPatternUtils. Needs to be a service because Settings app also needs 61bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * to be able to save lockscreen information for secondary users. 62bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber * @hide 63bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber */ 64bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huberpublic class LockSettingsService extends ILockSettings.Stub { 65bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 66bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE; 67bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 68bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 69bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 70bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 71bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private static final String TAG = "LockSettingsService"; 72bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 73bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private final Context mContext; 74bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 75bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private final LockSettingsStorage mStorage; 76bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 77bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private LockPatternUtils mLockPatternUtils; 78bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private boolean mFirstCallToVold; 79bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 80bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private final ArrayList<LockSettingsObserver> mObservers = new ArrayList<>(); 81bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 82bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public LockSettingsService(Context context) { 83bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mContext = context; 84bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // Open the database 85bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 86bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mLockPatternUtils = new LockPatternUtils(context); 87bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mFirstCallToVold = true; 88bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 89bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber IntentFilter filter = new IntentFilter(); 90bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber filter.addAction(Intent.ACTION_USER_ADDED); 91bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber filter.addAction(Intent.ACTION_USER_STARTING); 92bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); 93bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 94bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() { 95bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 96bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void initialize(SQLiteDatabase db) { 97bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // Get the lockscreen default from a system property, if available 98bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber boolean lockScreenDisable = SystemProperties.getBoolean( 99bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber "ro.lockscreen.disable.default", false); 100bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (lockScreenDisable) { 101bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mStorage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0); 102bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 103bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 104bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber }); 105bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 106bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 107bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 108bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 109bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void onReceive(Context context, Intent intent) { 110bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) { 111bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 112bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final int userSysUid = UserHandle.getUid(userHandle, Process.SYSTEM_UID); 113bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final KeyStore ks = KeyStore.getInstance(); 114bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 115bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // Clear up keystore in case anything was left behind by previous users 116bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber ks.resetUid(userSysUid); 117bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 118bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // If this user has a parent, sync with its keystore password 119bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); 120bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final UserInfo parentInfo = um.getProfileParent(userHandle); 121bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (parentInfo != null) { 122bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final int parentSysUid = UserHandle.getUid(parentInfo.id, Process.SYSTEM_UID); 123bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber ks.syncUid(parentSysUid, userSysUid); 124bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 125bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) { 126bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 127bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mStorage.prefetchUser(userHandle); 128bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 129bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 130bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber }; 131bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 132bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void systemReady() { 133bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber migrateOldData(); 134bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mStorage.prefetchUser(UserHandle.USER_OWNER); 135bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 136bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 137bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private void migrateOldData() { 138bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber try { 139bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // These Settings moved before multi-user was enabled, so we only have to do it for the 140bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // root user. 141bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (getString("migrated", null, 0) == null) { 142bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final ContentResolver cr = mContext.getContentResolver(); 143bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber for (String validSetting : VALID_SETTINGS) { 144bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber String value = Settings.Secure.getString(cr, validSetting); 145bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (value != null) { 146bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setString(validSetting, value, 0); 147bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 148bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 149bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // No need to move the password / pattern files. They're already in the right place. 150bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setString("migrated", "true", 0); 151bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Slog.i(TAG, "Migrated lock settings to new location"); 152bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 153bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 154bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // These Settings changed after multi-user was enabled, hence need to be moved per user. 155bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (getString("migrated_user_specific", null, 0) == null) { 156bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); 157bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final ContentResolver cr = mContext.getContentResolver(); 158bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber List<UserInfo> users = um.getUsers(); 159bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber for (int user = 0; user < users.size(); user++) { 160bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // Migrate owner info 161bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final int userId = users.get(user).id; 162bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO; 163bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId); 164bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (ownerInfo != null) { 165bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setString(OWNER_INFO, ownerInfo, userId); 166bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Settings.Secure.putStringForUser(cr, ownerInfo, "", userId); 167bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 168bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 169bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // Migrate owner info enabled. Note there was a bug where older platforms only 170bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // stored this value if the checkbox was toggled at least once. The code detects 171bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // this case by handling the exception. 172bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED; 173bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber boolean enabled; 174bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber try { 175bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId); 176bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber enabled = ivalue != 0; 177bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId); 178bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } catch (SettingNotFoundException e) { 179bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // Setting was never stored. Store it if the string is not empty. 180bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (!TextUtils.isEmpty(ownerInfo)) { 181bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setLong(OWNER_INFO_ENABLED, 1, userId); 182bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 183bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 184bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId); 185bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 186bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // No need to move the password / pattern files. They're already in the right place. 187bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setString("migrated_user_specific", "true", 0); 188bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Slog.i(TAG, "Migrated per-user lock settings to new location"); 189bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 190bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } catch (RemoteException re) { 191bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Slog.e(TAG, "Unable to migrate old data", re); 192bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 193bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 194bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 195bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private final void checkWritePermission(int userId) { 196bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite"); 197bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 198bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 199bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private final void checkPasswordReadPermission(int userId) { 200bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead"); 201bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 202bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 203bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private final void checkReadPermission(String requestedKey, int userId) { 204bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final int callingUid = Binder.getCallingUid(); 205bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber for (int i = 0; i < READ_PROFILE_PROTECTED_SETTINGS.length; i++) { 206bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber String key = READ_PROFILE_PROTECTED_SETTINGS[i]; 207bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_PROFILE) 208bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber != PackageManager.PERMISSION_GRANTED) { 209bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber throw new SecurityException("uid=" + callingUid 210bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber + " needs permission " + READ_PROFILE + " to read " 211bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber + requestedKey + " for user " + userId); 212bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 213bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 214bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 215bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 216bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 217bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void setBoolean(String key, boolean value, int userId) throws RemoteException { 218bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkWritePermission(userId); 219bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setStringUnchecked(key, userId, value ? "1" : "0"); 220bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 221bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 222bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 223bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void setLong(String key, long value, int userId) throws RemoteException { 224bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkWritePermission(userId); 225bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setStringUnchecked(key, userId, Long.toString(value)); 226bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 227bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 228bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 229bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void setString(String key, String value, int userId) throws RemoteException { 230bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkWritePermission(userId); 231bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber setStringUnchecked(key, userId, value); 232bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 233bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 234bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private void setStringUnchecked(String key, int userId, String value) { 235bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mStorage.writeKeyValue(key, value, userId); 236bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber notifyObservers(key, userId); 237bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 238bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 239bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 240bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException { 241bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkReadPermission(key, userId); 242bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 243bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber String value = mStorage.readKeyValue(key, null, userId); 244bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return TextUtils.isEmpty(value) ? 245bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber defaultValue : (value.equals("1") || value.equals("true")); 246bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 247bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 248bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 249bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public long getLong(String key, long defaultValue, int userId) throws RemoteException { 250bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkReadPermission(key, userId); 251bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 252bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber String value = mStorage.readKeyValue(key, null, userId); 253bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value); 254bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 255bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 256bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 257bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public String getString(String key, String defaultValue, int userId) throws RemoteException { 258bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkReadPermission(key, userId); 259bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 260bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return mStorage.readKeyValue(key, defaultValue, userId); 261bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 262bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 263bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 264fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber public void registerObserver(ILockSettingsObserver remote) throws RemoteException { 265fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber synchronized (mObservers) { 266bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber for (int i = 0; i < mObservers.size(); i++) { 267bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (mObservers.get(i).remote.asBinder() == remote.asBinder()) { 268bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 269bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (isDebuggable) { 270bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber throw new IllegalStateException("Observer was already registered."); 271bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } else { 272bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Log.e(TAG, "Observer was already registered."); 273bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return; 274bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 275bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 276bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 277bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockSettingsObserver o = new LockSettingsObserver(); 278bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber o.remote = remote; 279bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber o.remote.asBinder().linkToDeath(o, 0); 280fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber mObservers.add(o); 281bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 282bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 283bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 284bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 285bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void unregisterObserver(ILockSettingsObserver remote) throws RemoteException { 286bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber synchronized (mObservers) { 287bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber for (int i = 0; i < mObservers.size(); i++) { 288bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (mObservers.get(i).remote.asBinder() == remote.asBinder()) { 289bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mObservers.remove(i); 290bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return; 291bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 292bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 293bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 294bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 295bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 296bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void notifyObservers(String key, int userId) { 297bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber synchronized (mObservers) { 298bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber for (int i = 0; i < mObservers.size(); i++) { 299bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber try { 300bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mObservers.get(i).remote.onLockSettingChanged(key, userId); 301bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } catch (RemoteException e) { 302fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber // The stack trace is not really helpful here. 303fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber Log.e(TAG, "Failed to notify ILockSettingsObserver: " + e); 304fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber } 305fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber } 306fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber } 307fd4a8e09a54469bbccea6248f84319a1eb78765eAndreas Huber } 308bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 309bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 310bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public boolean havePassword(int userId) throws RemoteException { 311bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // Do we need a permissions check here? 312bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 313bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return mStorage.hasPassword(userId); 314bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 315bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 316bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 317bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public boolean havePattern(int userId) throws RemoteException { 318bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // Do we need a permissions check here? 319bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 320bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return mStorage.hasPattern(userId); 321bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 322bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 3234844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber private void maybeUpdateKeystore(String password, int userHandle) { 3244844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); 3254844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber final KeyStore ks = KeyStore.getInstance(); 3264844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber 3274844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber final List<UserInfo> profiles = um.getProfiles(userHandle); 3284844ac54e8b5997c3b03872dbafe8ebed4787517Andreas Huber boolean shouldReset = TextUtils.isEmpty(password); 329bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 330bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // For historical reasons, don't wipe a non-empty keystore if we have a single user with a 331bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // single profile. 332bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (userHandle == UserHandle.USER_OWNER && profiles.size() == 1) { 333bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (!ks.isEmpty()) { 334bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber shouldReset = false; 335bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 336bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 337bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 338bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber for (UserInfo pi : profiles) { 339bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final int profileUid = UserHandle.getUid(pi.id, Process.SYSTEM_UID); 340bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (shouldReset) { 341bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber ks.resetUid(profileUid); 342bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } else { 343bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber ks.passwordUid(password, profileUid); 344bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 345bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 346bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 347bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 348bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 349bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void setLockPattern(String pattern, int userId) throws RemoteException { 350bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkWritePermission(userId); 351bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 352bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber maybeUpdateKeystore(pattern, userId); 353bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 354bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final byte[] hash = LockPatternUtils.patternToHash( 355bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.stringToPattern(pattern)); 356bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mStorage.writePatternHash(hash, userId); 357bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber notifyObservers(LockPatternUtilsCache.HAS_LOCK_PATTERN_CACHE_KEY, userId); 358bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 359bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 360bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 361bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void setLockPassword(String password, int userId) throws RemoteException { 362bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkWritePermission(userId); 363bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 364bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber maybeUpdateKeystore(password, userId); 365bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 366bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mStorage.writePasswordHash(mLockPatternUtils.passwordToHash(password, userId), userId); 367bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber notifyObservers(LockPatternUtilsCache.HAS_LOCK_PASSWORD_CACHE_KEY, userId); 368bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 369bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 370bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 371bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public boolean checkPattern(String pattern, int userId) throws RemoteException { 372bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkPasswordReadPermission(userId); 373bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber byte[] hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(pattern)); 374bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber byte[] storedHash = mStorage.readPatternHash(userId); 375bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 376bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (storedHash == null) { 377bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return true; 378bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 379bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 380bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber boolean matched = Arrays.equals(hash, storedHash); 381bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (matched && !TextUtils.isEmpty(pattern)) { 382bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber maybeUpdateKeystore(pattern, userId); 383bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 384bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return matched; 385bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 386bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 387bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 388bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public boolean checkPassword(String password, int userId) throws RemoteException { 389bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkPasswordReadPermission(userId); 390bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 391bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber byte[] hash = mLockPatternUtils.passwordToHash(password, userId); 392bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber byte[] storedHash = mStorage.readPasswordHash(userId); 393bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 394bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (storedHash == null) { 395bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return true; 396bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 397bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 398bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber boolean matched = Arrays.equals(hash, storedHash); 399bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (matched && !TextUtils.isEmpty(password)) { 400bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber maybeUpdateKeystore(password, userId); 401bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 402bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return matched; 403bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 404bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 405bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 406bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public boolean checkVoldPassword(int userId) throws RemoteException { 407bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (!mFirstCallToVold) { 408bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return false; 409bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 410bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mFirstCallToVold = false; 411bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 412bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkPasswordReadPermission(userId); 413bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 414bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // There's no guarantee that this will safely connect, but if it fails 415bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // we will simply show the lock screen when we shouldn't, so relatively 416bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // benign. There is an outside chance something nasty would happen if 417bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // this service restarted before vold stales out the password in this 418bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // case. The nastiness is limited to not showing the lock screen when 419bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // we should, within the first minute of decrypting the phone if this 420bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // service can't connect to vold, it restarts, and then the new instance 421bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // does successfully connect. 422bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final IMountService service = getMountService(); 423bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber String password = service.getPassword(); 424bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber service.clearPassword(); 425bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (password == null) { 426bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return false; 427bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 428bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 429bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber try { 430bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (mLockPatternUtils.isLockPatternEnabled()) { 431bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (checkPattern(password, userId)) { 432bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return true; 433bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 434bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 435bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } catch (Exception e) { 436bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 437bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 438bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber try { 439bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (mLockPatternUtils.isLockPasswordEnabled()) { 440bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (checkPassword(password, userId)) { 441bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return true; 442bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 443bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 444bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } catch (Exception e) { 445bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 446bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 447bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return false; 448bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 449bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 450bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 451bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void removeUser(int userId) { 452bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber checkWritePermission(userId); 453bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 454bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mStorage.removeUser(userId); 455bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber notifyObservers(null /* key */, userId); 456bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 457bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final KeyStore ks = KeyStore.getInstance(); 458bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final int userUid = UserHandle.getUid(userId, Process.SYSTEM_UID); 459bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber ks.resetUid(userUid); 460bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 461bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 462bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private static final String[] VALID_SETTINGS = new String[] { 463bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.LOCKOUT_PERMANENT_KEY, 464bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE, 465bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.PATTERN_EVER_CHOSEN_KEY, 466bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.PASSWORD_TYPE_KEY, 467bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY, 468bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.LOCK_PASSWORD_SALT_KEY, 469bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.DISABLE_LOCKSCREEN_KEY, 470bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.LOCKSCREEN_OPTIONS, 471bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, 472bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY, 473bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, 474bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber LockPatternUtils.PASSWORD_HISTORY_KEY, 475bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Secure.LOCK_PATTERN_ENABLED, 476bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Secure.LOCK_BIOMETRIC_WEAK_FLAGS, 477bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Secure.LOCK_PATTERN_VISIBLE, 478bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED 479bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber }; 480bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 481bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber // These are protected with a read permission 482bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private static final String[] READ_PROFILE_PROTECTED_SETTINGS = new String[] { 483bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, 484bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber Secure.LOCK_SCREEN_OWNER_INFO 485bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber }; 486bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 487bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private IMountService getMountService() { 488bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber final IBinder service = ServiceManager.getService("mount"); 489bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber if (service != null) { 490bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return IMountService.Stub.asInterface(service); 491bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 492bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber return null; 493bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 494bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 495bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber private class LockSettingsObserver implements DeathRecipient { 496bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber ILockSettingsObserver remote; 497bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber 498bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber @Override 499bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber public void binderDied() { 500bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber mObservers.remove(this); 501bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 502bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber } 503bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber} 504bfa6b2d7a1be1832ac40ed90aece1834f720b5c6Andreas Huber