1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings; 18 19 20 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 21 22 import android.app.Activity; 23 import android.app.ActivityManager; 24 import android.app.AlertDialog; 25 import android.app.admin.DevicePolicyManager; 26 import android.content.Context; 27 import android.content.DialogInterface; 28 import android.content.Intent; 29 import android.content.pm.PackageManager; 30 import android.content.pm.ResolveInfo; 31 import android.content.pm.UserInfo; 32 import android.os.Bundle; 33 import android.os.UserHandle; 34 import android.os.UserManager; 35 import android.preference.CheckBoxPreference; 36 import android.preference.ListPreference; 37 import android.preference.Preference; 38 import android.preference.Preference.OnPreferenceChangeListener; 39 import android.preference.PreferenceGroup; 40 import android.preference.PreferenceScreen; 41 import android.provider.Settings; 42 import android.security.KeyStore; 43 import android.telephony.TelephonyManager; 44 import android.util.Log; 45 46 import com.android.internal.widget.LockPatternUtils; 47 48 import java.util.ArrayList; 49 import java.util.List; 50 51 /** 52 * Gesture lock pattern settings. 53 */ 54 public class SecuritySettings extends RestrictedSettingsFragment 55 implements OnPreferenceChangeListener, DialogInterface.OnClickListener { 56 static final String TAG = "SecuritySettings"; 57 58 // Lock Settings 59 private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change"; 60 private static final String KEY_BIOMETRIC_WEAK_IMPROVE_MATCHING = 61 "biometric_weak_improve_matching"; 62 private static final String KEY_BIOMETRIC_WEAK_LIVELINESS = "biometric_weak_liveliness"; 63 private static final String KEY_LOCK_ENABLED = "lockenabled"; 64 private static final String KEY_VISIBLE_PATTERN = "visiblepattern"; 65 private static final String KEY_SECURITY_CATEGORY = "security_category"; 66 private static final String KEY_DEVICE_ADMIN_CATEGORY = "device_admin_category"; 67 private static final String KEY_LOCK_AFTER_TIMEOUT = "lock_after_timeout"; 68 private static final String KEY_OWNER_INFO_SETTINGS = "owner_info_settings"; 69 private static final String KEY_ENABLE_WIDGETS = "keyguard_enable_widgets"; 70 71 private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123; 72 private static final int CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_IMPROVE_REQUEST = 124; 73 private static final int CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_LIVELINESS_OFF = 125; 74 75 // Misc Settings 76 private static final String KEY_SIM_LOCK = "sim_lock"; 77 private static final String KEY_SHOW_PASSWORD = "show_password"; 78 private static final String KEY_CREDENTIAL_STORAGE_TYPE = "credential_storage_type"; 79 private static final String KEY_RESET_CREDENTIALS = "reset_credentials"; 80 private static final String KEY_CREDENTIALS_INSTALL = "credentials_install"; 81 private static final String KEY_TOGGLE_INSTALL_APPLICATIONS = "toggle_install_applications"; 82 private static final String KEY_TOGGLE_VERIFY_APPLICATIONS = "toggle_verify_applications"; 83 private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks"; 84 private static final String KEY_CREDENTIALS_MANAGER = "credentials_management"; 85 private static final String KEY_NOTIFICATION_ACCESS = "manage_notification_access"; 86 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 87 88 private PackageManager mPM; 89 private DevicePolicyManager mDPM; 90 91 private ChooseLockSettingsHelper mChooseLockSettingsHelper; 92 private LockPatternUtils mLockPatternUtils; 93 private ListPreference mLockAfter; 94 95 private CheckBoxPreference mBiometricWeakLiveliness; 96 private CheckBoxPreference mVisiblePattern; 97 98 private CheckBoxPreference mShowPassword; 99 100 private KeyStore mKeyStore; 101 private Preference mResetCredentials; 102 103 private CheckBoxPreference mToggleAppInstallation; 104 private DialogInterface mWarnInstallApps; 105 private CheckBoxPreference mToggleVerifyApps; 106 private CheckBoxPreference mPowerButtonInstantlyLocks; 107 private CheckBoxPreference mEnableKeyguardWidgets; 108 109 private Preference mNotificationAccess; 110 111 private boolean mIsPrimary; 112 113 public SecuritySettings() { 114 super(null /* Don't ask for restrictions pin on creation. */); 115 } 116 117 @Override 118 public void onCreate(Bundle savedInstanceState) { 119 super.onCreate(savedInstanceState); 120 121 mLockPatternUtils = new LockPatternUtils(getActivity()); 122 123 mPM = getActivity().getPackageManager(); 124 mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE); 125 126 mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity()); 127 } 128 129 private PreferenceScreen createPreferenceHierarchy() { 130 PreferenceScreen root = getPreferenceScreen(); 131 if (root != null) { 132 root.removeAll(); 133 } 134 addPreferencesFromResource(R.xml.security_settings); 135 root = getPreferenceScreen(); 136 137 // Add options for lock/unlock screen 138 int resid = 0; 139 if (!mLockPatternUtils.isSecure()) { 140 // if there are multiple users, disable "None" setting 141 UserManager mUm = (UserManager) getSystemService(Context.USER_SERVICE); 142 List<UserInfo> users = mUm.getUsers(true); 143 final boolean singleUser = users.size() == 1; 144 145 if (singleUser && mLockPatternUtils.isLockScreenDisabled()) { 146 resid = R.xml.security_settings_lockscreen; 147 } else { 148 resid = R.xml.security_settings_chooser; 149 } 150 } else if (mLockPatternUtils.usingBiometricWeak() && 151 mLockPatternUtils.isBiometricWeakInstalled()) { 152 resid = R.xml.security_settings_biometric_weak; 153 } else { 154 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) { 155 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 156 resid = R.xml.security_settings_pattern; 157 break; 158 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 159 resid = R.xml.security_settings_pin; 160 break; 161 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 162 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 163 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 164 resid = R.xml.security_settings_password; 165 break; 166 } 167 } 168 addPreferencesFromResource(resid); 169 170 171 // Add options for device encryption 172 mIsPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER; 173 174 if (!mIsPrimary) { 175 // Rename owner info settings 176 Preference ownerInfoPref = findPreference(KEY_OWNER_INFO_SETTINGS); 177 if (ownerInfoPref != null) { 178 if (UserManager.get(getActivity()).isLinkedUser()) { 179 ownerInfoPref.setTitle(R.string.profile_info_settings_title); 180 } else { 181 ownerInfoPref.setTitle(R.string.user_info_settings_title); 182 } 183 } 184 } 185 186 if (mIsPrimary) { 187 switch (mDPM.getStorageEncryptionStatus()) { 188 case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: 189 // The device is currently encrypted. 190 addPreferencesFromResource(R.xml.security_settings_encrypted); 191 break; 192 case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: 193 // This device supports encryption but isn't encrypted. 194 addPreferencesFromResource(R.xml.security_settings_unencrypted); 195 break; 196 } 197 } 198 199 // lock after preference 200 mLockAfter = (ListPreference) root.findPreference(KEY_LOCK_AFTER_TIMEOUT); 201 if (mLockAfter != null) { 202 setupLockAfterPreference(); 203 updateLockAfterPreferenceSummary(); 204 } 205 206 // biometric weak liveliness 207 mBiometricWeakLiveliness = 208 (CheckBoxPreference) root.findPreference(KEY_BIOMETRIC_WEAK_LIVELINESS); 209 210 // visible pattern 211 mVisiblePattern = (CheckBoxPreference) root.findPreference(KEY_VISIBLE_PATTERN); 212 213 // lock instantly on power key press 214 mPowerButtonInstantlyLocks = (CheckBoxPreference) root.findPreference( 215 KEY_POWER_INSTANTLY_LOCKS); 216 217 // don't display visible pattern if biometric and backup is not pattern 218 if (resid == R.xml.security_settings_biometric_weak && 219 mLockPatternUtils.getKeyguardStoredPasswordQuality() != 220 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { 221 PreferenceGroup securityCategory = (PreferenceGroup) 222 root.findPreference(KEY_SECURITY_CATEGORY); 223 if (securityCategory != null && mVisiblePattern != null) { 224 securityCategory.removePreference(root.findPreference(KEY_VISIBLE_PATTERN)); 225 } 226 } 227 228 // Append the rest of the settings 229 addPreferencesFromResource(R.xml.security_settings_misc); 230 231 // Do not display SIM lock for devices without an Icc card 232 TelephonyManager tm = TelephonyManager.getDefault(); 233 if (!mIsPrimary || !tm.hasIccCard()) { 234 root.removePreference(root.findPreference(KEY_SIM_LOCK)); 235 } else { 236 // Disable SIM lock if sim card is missing or unknown 237 if ((TelephonyManager.getDefault().getSimState() == 238 TelephonyManager.SIM_STATE_ABSENT) || 239 (TelephonyManager.getDefault().getSimState() == 240 TelephonyManager.SIM_STATE_UNKNOWN)) { 241 root.findPreference(KEY_SIM_LOCK).setEnabled(false); 242 } 243 } 244 245 // Enable or disable keyguard widget checkbox based on DPM state 246 mEnableKeyguardWidgets = (CheckBoxPreference) root.findPreference(KEY_ENABLE_WIDGETS); 247 if (mEnableKeyguardWidgets != null) { 248 if (ActivityManager.isLowRamDeviceStatic() 249 || mLockPatternUtils.isLockScreenDisabled()) { 250 // Widgets take a lot of RAM, so disable them on low-memory devices 251 PreferenceGroup securityCategory 252 = (PreferenceGroup) root.findPreference(KEY_SECURITY_CATEGORY); 253 if (securityCategory != null) { 254 securityCategory.removePreference(root.findPreference(KEY_ENABLE_WIDGETS)); 255 mEnableKeyguardWidgets = null; 256 } 257 } else { 258 final boolean disabled = (0 != (mDPM.getKeyguardDisabledFeatures(null) 259 & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL)); 260 if (disabled) { 261 mEnableKeyguardWidgets.setSummary( 262 R.string.security_enable_widgets_disabled_summary); 263 } else { 264 mEnableKeyguardWidgets.setSummary(""); 265 } 266 mEnableKeyguardWidgets.setEnabled(!disabled); 267 } 268 } 269 270 // Show password 271 mShowPassword = (CheckBoxPreference) root.findPreference(KEY_SHOW_PASSWORD); 272 mResetCredentials = root.findPreference(KEY_RESET_CREDENTIALS); 273 274 // Credential storage 275 final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); 276 mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume() 277 if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { 278 Preference credentialStorageType = root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE); 279 280 final int storageSummaryRes = 281 mKeyStore.isHardwareBacked() ? R.string.credential_storage_type_hardware 282 : R.string.credential_storage_type_software; 283 credentialStorageType.setSummary(storageSummaryRes); 284 285 } else { 286 removePreference(KEY_CREDENTIALS_MANAGER); 287 } 288 289 // Application install 290 PreferenceGroup deviceAdminCategory= (PreferenceGroup) 291 root.findPreference(KEY_DEVICE_ADMIN_CATEGORY); 292 mToggleAppInstallation = (CheckBoxPreference) findPreference( 293 KEY_TOGGLE_INSTALL_APPLICATIONS); 294 mToggleAppInstallation.setChecked(isNonMarketAppsAllowed()); 295 296 // Side loading of apps. 297 mToggleAppInstallation.setEnabled(mIsPrimary); 298 299 // Package verification, only visible to primary user and if enabled 300 mToggleVerifyApps = (CheckBoxPreference) findPreference(KEY_TOGGLE_VERIFY_APPLICATIONS); 301 if (mIsPrimary && showVerifierSetting()) { 302 if (isVerifierInstalled()) { 303 mToggleVerifyApps.setChecked(isVerifyAppsEnabled()); 304 } else { 305 mToggleVerifyApps.setChecked(false); 306 mToggleVerifyApps.setEnabled(false); 307 } 308 } else { 309 if (deviceAdminCategory != null) { 310 deviceAdminCategory.removePreference(mToggleVerifyApps); 311 } else { 312 mToggleVerifyApps.setEnabled(false); 313 } 314 } 315 316 mNotificationAccess = findPreference(KEY_NOTIFICATION_ACCESS); 317 if (mNotificationAccess != null) { 318 final int total = NotificationAccessSettings.getListenersCount(mPM); 319 if (total == 0) { 320 if (deviceAdminCategory != null) { 321 deviceAdminCategory.removePreference(mNotificationAccess); 322 } 323 } else { 324 final int n = getNumEnabledNotificationListeners(); 325 if (n == 0) { 326 mNotificationAccess.setSummary(getResources().getString( 327 R.string.manage_notification_access_summary_zero)); 328 } else { 329 mNotificationAccess.setSummary(String.format(getResources().getQuantityString( 330 R.plurals.manage_notification_access_summary_nonzero, 331 n, n))); 332 } 333 } 334 } 335 336 if (shouldBePinProtected(RESTRICTIONS_PIN_SET)) { 337 protectByRestrictions(mToggleAppInstallation); 338 protectByRestrictions(mToggleVerifyApps); 339 protectByRestrictions(mResetCredentials); 340 protectByRestrictions(root.findPreference(KEY_CREDENTIALS_INSTALL)); 341 } 342 return root; 343 } 344 345 private int getNumEnabledNotificationListeners() { 346 final String flat = Settings.Secure.getString(getContentResolver(), 347 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS); 348 if (flat == null || "".equals(flat)) return 0; 349 final String[] components = flat.split(":"); 350 return components.length; 351 } 352 353 private boolean isNonMarketAppsAllowed() { 354 return Settings.Global.getInt(getContentResolver(), 355 Settings.Global.INSTALL_NON_MARKET_APPS, 0) > 0; 356 } 357 358 private void setNonMarketAppsAllowed(boolean enabled) { 359 final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); 360 if (um.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)) { 361 return; 362 } 363 // Change the system setting 364 Settings.Global.putInt(getContentResolver(), Settings.Global.INSTALL_NON_MARKET_APPS, 365 enabled ? 1 : 0); 366 } 367 368 private boolean isVerifyAppsEnabled() { 369 return Settings.Global.getInt(getContentResolver(), 370 Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) > 0; 371 } 372 373 private boolean isVerifierInstalled() { 374 final PackageManager pm = getPackageManager(); 375 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 376 verification.setType(PACKAGE_MIME_TYPE); 377 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 378 final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0); 379 return (receivers.size() > 0) ? true : false; 380 } 381 382 private boolean showVerifierSetting() { 383 return Settings.Global.getInt(getContentResolver(), 384 Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0; 385 } 386 387 private void warnAppInstallation() { 388 // TODO: DialogFragment? 389 mWarnInstallApps = new AlertDialog.Builder(getActivity()).setTitle( 390 getResources().getString(R.string.error_title)) 391 .setIcon(com.android.internal.R.drawable.ic_dialog_alert) 392 .setMessage(getResources().getString(R.string.install_all_warning)) 393 .setPositiveButton(android.R.string.yes, this) 394 .setNegativeButton(android.R.string.no, null) 395 .show(); 396 } 397 398 @Override 399 public void onClick(DialogInterface dialog, int which) { 400 if (dialog == mWarnInstallApps && which == DialogInterface.BUTTON_POSITIVE) { 401 setNonMarketAppsAllowed(true); 402 if (mToggleAppInstallation != null) { 403 mToggleAppInstallation.setChecked(true); 404 } 405 } 406 } 407 408 @Override 409 public void onDestroy() { 410 super.onDestroy(); 411 if (mWarnInstallApps != null) { 412 mWarnInstallApps.dismiss(); 413 } 414 } 415 416 private void setupLockAfterPreference() { 417 // Compatible with pre-Froyo 418 long currentTimeout = Settings.Secure.getLong(getContentResolver(), 419 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000); 420 mLockAfter.setValue(String.valueOf(currentTimeout)); 421 mLockAfter.setOnPreferenceChangeListener(this); 422 final long adminTimeout = (mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0); 423 final long displayTimeout = Math.max(0, 424 Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0)); 425 if (adminTimeout > 0) { 426 // This setting is a slave to display timeout when a device policy is enforced. 427 // As such, maxLockTimeout = adminTimeout - displayTimeout. 428 // If there isn't enough time, shows "immediately" setting. 429 disableUnusableTimeouts(Math.max(0, adminTimeout - displayTimeout)); 430 } 431 } 432 433 private void updateLockAfterPreferenceSummary() { 434 // Update summary message with current value 435 long currentTimeout = Settings.Secure.getLong(getContentResolver(), 436 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000); 437 final CharSequence[] entries = mLockAfter.getEntries(); 438 final CharSequence[] values = mLockAfter.getEntryValues(); 439 int best = 0; 440 for (int i = 0; i < values.length; i++) { 441 long timeout = Long.valueOf(values[i].toString()); 442 if (currentTimeout >= timeout) { 443 best = i; 444 } 445 } 446 mLockAfter.setSummary(getString(R.string.lock_after_timeout_summary, entries[best])); 447 } 448 449 private void disableUnusableTimeouts(long maxTimeout) { 450 final CharSequence[] entries = mLockAfter.getEntries(); 451 final CharSequence[] values = mLockAfter.getEntryValues(); 452 ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>(); 453 ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>(); 454 for (int i = 0; i < values.length; i++) { 455 long timeout = Long.valueOf(values[i].toString()); 456 if (timeout <= maxTimeout) { 457 revisedEntries.add(entries[i]); 458 revisedValues.add(values[i]); 459 } 460 } 461 if (revisedEntries.size() != entries.length || revisedValues.size() != values.length) { 462 mLockAfter.setEntries( 463 revisedEntries.toArray(new CharSequence[revisedEntries.size()])); 464 mLockAfter.setEntryValues( 465 revisedValues.toArray(new CharSequence[revisedValues.size()])); 466 final int userPreference = Integer.valueOf(mLockAfter.getValue()); 467 if (userPreference <= maxTimeout) { 468 mLockAfter.setValue(String.valueOf(userPreference)); 469 } else { 470 // There will be no highlighted selection since nothing in the list matches 471 // maxTimeout. The user can still select anything less than maxTimeout. 472 // TODO: maybe append maxTimeout to the list and mark selected. 473 } 474 } 475 mLockAfter.setEnabled(revisedEntries.size() > 0); 476 } 477 478 @Override 479 public void onResume() { 480 super.onResume(); 481 482 // Make sure we reload the preference hierarchy since some of these settings 483 // depend on others... 484 createPreferenceHierarchy(); 485 486 final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); 487 if (mBiometricWeakLiveliness != null) { 488 mBiometricWeakLiveliness.setChecked( 489 lockPatternUtils.isBiometricWeakLivelinessEnabled()); 490 } 491 if (mVisiblePattern != null) { 492 mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled()); 493 } 494 if (mPowerButtonInstantlyLocks != null) { 495 mPowerButtonInstantlyLocks.setChecked(lockPatternUtils.getPowerButtonInstantlyLocks()); 496 } 497 498 if (mShowPassword != null) { 499 mShowPassword.setChecked(Settings.System.getInt(getContentResolver(), 500 Settings.System.TEXT_SHOW_PASSWORD, 1) != 0); 501 } 502 503 if (mResetCredentials != null) { 504 mResetCredentials.setEnabled(!mKeyStore.isEmpty()); 505 } 506 507 if (mEnableKeyguardWidgets != null) { 508 mEnableKeyguardWidgets.setChecked(lockPatternUtils.getWidgetsEnabled()); 509 } 510 } 511 512 @Override 513 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 514 if (ensurePinRestrictedPreference(preference)) { 515 return true; 516 } 517 final String key = preference.getKey(); 518 519 final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); 520 if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) { 521 startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment", 522 SET_OR_CHANGE_LOCK_METHOD_REQUEST, null); 523 } else if (KEY_BIOMETRIC_WEAK_IMPROVE_MATCHING.equals(key)) { 524 ChooseLockSettingsHelper helper = 525 new ChooseLockSettingsHelper(this.getActivity(), this); 526 if (!helper.launchConfirmationActivity( 527 CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_IMPROVE_REQUEST, null, null)) { 528 // If this returns false, it means no password confirmation is required, so 529 // go ahead and start improve. 530 // Note: currently a backup is required for biometric_weak so this code path 531 // can't be reached, but is here in case things change in the future 532 startBiometricWeakImprove(); 533 } 534 } else if (KEY_BIOMETRIC_WEAK_LIVELINESS.equals(key)) { 535 if (isToggled(preference)) { 536 lockPatternUtils.setBiometricWeakLivelinessEnabled(true); 537 } else { 538 // In this case the user has just unchecked the checkbox, but this action requires 539 // them to confirm their password. We need to re-check the checkbox until 540 // they've confirmed their password 541 mBiometricWeakLiveliness.setChecked(true); 542 ChooseLockSettingsHelper helper = 543 new ChooseLockSettingsHelper(this.getActivity(), this); 544 if (!helper.launchConfirmationActivity( 545 CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_LIVELINESS_OFF, null, null)) { 546 // If this returns false, it means no password confirmation is required, so 547 // go ahead and uncheck it here. 548 // Note: currently a backup is required for biometric_weak so this code path 549 // can't be reached, but is here in case things change in the future 550 lockPatternUtils.setBiometricWeakLivelinessEnabled(false); 551 mBiometricWeakLiveliness.setChecked(false); 552 } 553 } 554 } else if (KEY_LOCK_ENABLED.equals(key)) { 555 lockPatternUtils.setLockPatternEnabled(isToggled(preference)); 556 } else if (KEY_VISIBLE_PATTERN.equals(key)) { 557 lockPatternUtils.setVisiblePatternEnabled(isToggled(preference)); 558 } else if (KEY_POWER_INSTANTLY_LOCKS.equals(key)) { 559 lockPatternUtils.setPowerButtonInstantlyLocks(isToggled(preference)); 560 } else if (KEY_ENABLE_WIDGETS.equals(key)) { 561 lockPatternUtils.setWidgetsEnabled(mEnableKeyguardWidgets.isChecked()); 562 } else if (preference == mShowPassword) { 563 Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, 564 mShowPassword.isChecked() ? 1 : 0); 565 } else if (preference == mToggleAppInstallation) { 566 if (mToggleAppInstallation.isChecked()) { 567 mToggleAppInstallation.setChecked(false); 568 warnAppInstallation(); 569 } else { 570 setNonMarketAppsAllowed(false); 571 } 572 } else if (KEY_TOGGLE_VERIFY_APPLICATIONS.equals(key)) { 573 Settings.Global.putInt(getContentResolver(), Settings.Global.PACKAGE_VERIFIER_ENABLE, 574 mToggleVerifyApps.isChecked() ? 1 : 0); 575 } else { 576 // If we didn't handle it, let preferences handle it. 577 return super.onPreferenceTreeClick(preferenceScreen, preference); 578 } 579 580 return true; 581 } 582 583 private boolean isToggled(Preference pref) { 584 return ((CheckBoxPreference) pref).isChecked(); 585 } 586 587 /** 588 * see confirmPatternThenDisableAndClear 589 */ 590 @Override 591 public void onActivityResult(int requestCode, int resultCode, Intent data) { 592 super.onActivityResult(requestCode, resultCode, data); 593 if (requestCode == CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_IMPROVE_REQUEST && 594 resultCode == Activity.RESULT_OK) { 595 startBiometricWeakImprove(); 596 return; 597 } else if (requestCode == CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_LIVELINESS_OFF && 598 resultCode == Activity.RESULT_OK) { 599 final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); 600 lockPatternUtils.setBiometricWeakLivelinessEnabled(false); 601 // Setting the mBiometricWeakLiveliness checked value to false is handled when onResume 602 // is called by grabbing the value from lockPatternUtils. We can't set it here 603 // because mBiometricWeakLiveliness could be null 604 return; 605 } 606 createPreferenceHierarchy(); 607 } 608 609 @Override 610 public boolean onPreferenceChange(Preference preference, Object value) { 611 if (preference == mLockAfter) { 612 int timeout = Integer.parseInt((String) value); 613 try { 614 Settings.Secure.putInt(getContentResolver(), 615 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout); 616 } catch (NumberFormatException e) { 617 Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e); 618 } 619 updateLockAfterPreferenceSummary(); 620 } 621 return true; 622 } 623 624 @Override 625 protected int getHelpResource() { 626 return R.string.help_url_security; 627 } 628 629 public void startBiometricWeakImprove(){ 630 Intent intent = new Intent(); 631 intent.setClassName("com.android.facelock", "com.android.facelock.AddToSetup"); 632 startActivity(intent); 633 } 634 } 635