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 17package com.android.settings; 18 19 20import android.app.Activity; 21import android.app.AlertDialog; 22import android.app.admin.DevicePolicyManager; 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.DialogInterface; 26import android.content.Intent; 27import android.content.pm.PackageManager; 28import android.content.pm.ResolveInfo; 29import android.content.pm.UserInfo; 30import android.content.res.Resources; 31import android.os.Bundle; 32import android.os.UserHandle; 33import android.os.UserManager; 34import android.preference.SwitchPreference; 35import android.preference.ListPreference; 36import android.preference.Preference; 37import android.preference.Preference.OnPreferenceChangeListener; 38import android.preference.PreferenceGroup; 39import android.preference.PreferenceScreen; 40import android.provider.SearchIndexableResource; 41import android.provider.Settings; 42import android.provider.Settings.SettingNotFoundException; 43import android.security.KeyStore; 44import android.service.trust.TrustAgentService; 45import android.telephony.TelephonyManager; 46import android.text.TextUtils; 47import android.util.Log; 48 49import com.android.internal.widget.LockPatternUtils; 50import com.android.settings.TrustAgentUtils.TrustAgentComponentInfo; 51import com.android.settings.search.BaseSearchIndexProvider; 52import com.android.settings.search.Index; 53import com.android.settings.search.Indexable; 54import com.android.settings.search.SearchIndexableRaw; 55 56import java.util.ArrayList; 57import java.util.List; 58 59import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 60 61/** 62 * Gesture lock pattern settings. 63 */ 64public class SecuritySettings extends SettingsPreferenceFragment 65 implements OnPreferenceChangeListener, DialogInterface.OnClickListener, Indexable { 66 private static final String TRUST_AGENT_CLICK_INTENT = "trust_agent_click_intent"; 67 static final String TAG = "SecuritySettings"; 68 private static final Intent TRUST_AGENT_INTENT = 69 new Intent(TrustAgentService.SERVICE_INTERFACE); 70 71 // Lock Settings 72 private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change"; 73 private static final String KEY_BIOMETRIC_WEAK_IMPROVE_MATCHING = 74 "biometric_weak_improve_matching"; 75 private static final String KEY_BIOMETRIC_WEAK_LIVELINESS = "biometric_weak_liveliness"; 76 private static final String KEY_LOCK_ENABLED = "lockenabled"; 77 private static final String KEY_VISIBLE_PATTERN = "visiblepattern"; 78 private static final String KEY_SECURITY_CATEGORY = "security_category"; 79 private static final String KEY_DEVICE_ADMIN_CATEGORY = "device_admin_category"; 80 private static final String KEY_LOCK_AFTER_TIMEOUT = "lock_after_timeout"; 81 private static final String KEY_OWNER_INFO_SETTINGS = "owner_info_settings"; 82 private static final String KEY_ADVANCED_SECURITY = "advanced_security"; 83 private static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents"; 84 85 private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123; 86 private static final int CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_IMPROVE_REQUEST = 124; 87 private static final int CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_LIVELINESS_OFF = 125; 88 private static final int CHANGE_TRUST_AGENT_SETTINGS = 126; 89 90 // Misc Settings 91 private static final String KEY_SIM_LOCK = "sim_lock"; 92 private static final String KEY_SHOW_PASSWORD = "show_password"; 93 private static final String KEY_CREDENTIAL_STORAGE_TYPE = "credential_storage_type"; 94 private static final String KEY_RESET_CREDENTIALS = "credentials_reset"; 95 private static final String KEY_CREDENTIALS_INSTALL = "credentials_install"; 96 private static final String KEY_TOGGLE_INSTALL_APPLICATIONS = "toggle_install_applications"; 97 private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks"; 98 private static final String KEY_CREDENTIALS_MANAGER = "credentials_management"; 99 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 100 private static final String KEY_TRUST_AGENT = "trust_agent"; 101 private static final String KEY_SCREEN_PINNING = "screen_pinning_settings"; 102 103 // These switch preferences need special handling since they're not all stored in Settings. 104 private static final String SWITCH_PREFERENCE_KEYS[] = { KEY_LOCK_AFTER_TIMEOUT, 105 KEY_LOCK_ENABLED, KEY_VISIBLE_PATTERN, KEY_BIOMETRIC_WEAK_LIVELINESS, 106 KEY_POWER_INSTANTLY_LOCKS, KEY_SHOW_PASSWORD, KEY_TOGGLE_INSTALL_APPLICATIONS }; 107 108 // Only allow one trust agent on the platform. 109 private static final boolean ONLY_ONE_TRUST_AGENT = true; 110 111 private DevicePolicyManager mDPM; 112 113 private ChooseLockSettingsHelper mChooseLockSettingsHelper; 114 private LockPatternUtils mLockPatternUtils; 115 private ListPreference mLockAfter; 116 117 private SwitchPreference mBiometricWeakLiveliness; 118 private SwitchPreference mVisiblePattern; 119 120 private SwitchPreference mShowPassword; 121 122 private KeyStore mKeyStore; 123 private Preference mResetCredentials; 124 125 private SwitchPreference mToggleAppInstallation; 126 private DialogInterface mWarnInstallApps; 127 private SwitchPreference mPowerButtonInstantlyLocks; 128 129 private boolean mIsPrimary; 130 131 private Intent mTrustAgentClickIntent; 132 133 @Override 134 public void onCreate(Bundle savedInstanceState) { 135 super.onCreate(savedInstanceState); 136 137 mLockPatternUtils = new LockPatternUtils(getActivity()); 138 139 mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE); 140 141 mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity()); 142 143 if (savedInstanceState != null 144 && savedInstanceState.containsKey(TRUST_AGENT_CLICK_INTENT)) { 145 mTrustAgentClickIntent = savedInstanceState.getParcelable(TRUST_AGENT_CLICK_INTENT); 146 } 147 } 148 149 private static int getResIdForLockUnlockScreen(Context context, 150 LockPatternUtils lockPatternUtils) { 151 int resid = 0; 152 if (!lockPatternUtils.isSecure()) { 153 // if there are multiple users, disable "None" setting 154 UserManager mUm = (UserManager) context. getSystemService(Context.USER_SERVICE); 155 List<UserInfo> users = mUm.getUsers(true); 156 final boolean singleUser = users.size() == 1; 157 158 if (singleUser && lockPatternUtils.isLockScreenDisabled()) { 159 resid = R.xml.security_settings_lockscreen; 160 } else { 161 resid = R.xml.security_settings_chooser; 162 } 163 } else if (lockPatternUtils.usingBiometricWeak() && 164 lockPatternUtils.isBiometricWeakInstalled()) { 165 resid = R.xml.security_settings_biometric_weak; 166 } else { 167 switch (lockPatternUtils.getKeyguardStoredPasswordQuality()) { 168 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 169 resid = R.xml.security_settings_pattern; 170 break; 171 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 172 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: 173 resid = R.xml.security_settings_pin; 174 break; 175 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 176 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 177 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 178 resid = R.xml.security_settings_password; 179 break; 180 } 181 } 182 return resid; 183 } 184 185 /** 186 * Important! 187 * 188 * Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the 189 * logic or adding/removing preferences here. 190 */ 191 private PreferenceScreen createPreferenceHierarchy() { 192 PreferenceScreen root = getPreferenceScreen(); 193 if (root != null) { 194 root.removeAll(); 195 } 196 addPreferencesFromResource(R.xml.security_settings); 197 root = getPreferenceScreen(); 198 199 // Add options for lock/unlock screen 200 final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils); 201 addPreferencesFromResource(resid); 202 203 // Add options for device encryption 204 mIsPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER; 205 206 if (!mIsPrimary) { 207 // Rename owner info settings 208 Preference ownerInfoPref = findPreference(KEY_OWNER_INFO_SETTINGS); 209 if (ownerInfoPref != null) { 210 if (UserManager.get(getActivity()).isLinkedUser()) { 211 ownerInfoPref.setTitle(R.string.profile_info_settings_title); 212 } else { 213 ownerInfoPref.setTitle(R.string.user_info_settings_title); 214 } 215 } 216 } 217 218 if (mIsPrimary) { 219 if (LockPatternUtils.isDeviceEncryptionEnabled()) { 220 // The device is currently encrypted. 221 addPreferencesFromResource(R.xml.security_settings_encrypted); 222 } else { 223 // This device supports encryption but isn't encrypted. 224 addPreferencesFromResource(R.xml.security_settings_unencrypted); 225 } 226 } 227 228 // Trust Agent preferences 229 PreferenceGroup securityCategory = (PreferenceGroup) 230 root.findPreference(KEY_SECURITY_CATEGORY); 231 if (securityCategory != null) { 232 final boolean hasSecurity = mLockPatternUtils.isSecure(); 233 ArrayList<TrustAgentComponentInfo> agents = 234 getActiveTrustAgents(getPackageManager(), mLockPatternUtils); 235 for (int i = 0; i < agents.size(); i++) { 236 final TrustAgentComponentInfo agent = agents.get(i); 237 Preference trustAgentPreference = 238 new Preference(securityCategory.getContext()); 239 trustAgentPreference.setKey(KEY_TRUST_AGENT); 240 trustAgentPreference.setTitle(agent.title); 241 trustAgentPreference.setSummary(agent.summary); 242 // Create intent for this preference. 243 Intent intent = new Intent(); 244 intent.setComponent(agent.componentName); 245 intent.setAction(Intent.ACTION_MAIN); 246 trustAgentPreference.setIntent(intent); 247 // Add preference to the settings menu. 248 securityCategory.addPreference(trustAgentPreference); 249 if (!hasSecurity) { 250 trustAgentPreference.setEnabled(false); 251 trustAgentPreference.setSummary(R.string.disabled_because_no_backup_security); 252 } 253 } 254 } 255 256 // lock after preference 257 mLockAfter = (ListPreference) root.findPreference(KEY_LOCK_AFTER_TIMEOUT); 258 if (mLockAfter != null) { 259 setupLockAfterPreference(); 260 updateLockAfterPreferenceSummary(); 261 } 262 263 // biometric weak liveliness 264 mBiometricWeakLiveliness = 265 (SwitchPreference) root.findPreference(KEY_BIOMETRIC_WEAK_LIVELINESS); 266 267 // visible pattern 268 mVisiblePattern = (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN); 269 270 // lock instantly on power key press 271 mPowerButtonInstantlyLocks = (SwitchPreference) root.findPreference( 272 KEY_POWER_INSTANTLY_LOCKS); 273 Preference trustAgentPreference = root.findPreference(KEY_TRUST_AGENT); 274 if (mPowerButtonInstantlyLocks != null && 275 trustAgentPreference != null && 276 trustAgentPreference.getTitle().length() > 0) { 277 mPowerButtonInstantlyLocks.setSummary(getString( 278 R.string.lockpattern_settings_power_button_instantly_locks_summary, 279 trustAgentPreference.getTitle())); 280 } 281 282 // don't display visible pattern if biometric and backup is not pattern 283 if (resid == R.xml.security_settings_biometric_weak && 284 mLockPatternUtils.getKeyguardStoredPasswordQuality() != 285 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { 286 if (securityCategory != null && mVisiblePattern != null) { 287 securityCategory.removePreference(root.findPreference(KEY_VISIBLE_PATTERN)); 288 } 289 } 290 291 // Append the rest of the settings 292 addPreferencesFromResource(R.xml.security_settings_misc); 293 294 // Do not display SIM lock for devices without an Icc card 295 TelephonyManager tm = TelephonyManager.getDefault(); 296 if (!mIsPrimary || !tm.hasIccCard()) { 297 root.removePreference(root.findPreference(KEY_SIM_LOCK)); 298 } else { 299 // Disable SIM lock if sim card is missing or unknown 300 if ((TelephonyManager.getDefault().getSimState() == 301 TelephonyManager.SIM_STATE_ABSENT) || 302 (TelephonyManager.getDefault().getSimState() == 303 TelephonyManager.SIM_STATE_UNKNOWN)) { 304 root.findPreference(KEY_SIM_LOCK).setEnabled(false); 305 } 306 } 307 if (Settings.System.getInt(getContentResolver(), 308 Settings.System.LOCK_TO_APP_ENABLED, 0) != 0) { 309 root.findPreference(KEY_SCREEN_PINNING).setSummary( 310 getResources().getString(R.string.switch_on_text)); 311 } 312 313 // Show password 314 mShowPassword = (SwitchPreference) root.findPreference(KEY_SHOW_PASSWORD); 315 mResetCredentials = root.findPreference(KEY_RESET_CREDENTIALS); 316 317 // Credential storage 318 final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); 319 mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume() 320 if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { 321 Preference credentialStorageType = root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE); 322 323 final int storageSummaryRes = 324 mKeyStore.isHardwareBacked() ? R.string.credential_storage_type_hardware 325 : R.string.credential_storage_type_software; 326 credentialStorageType.setSummary(storageSummaryRes); 327 } else { 328 PreferenceGroup credentialsManager = (PreferenceGroup) 329 root.findPreference(KEY_CREDENTIALS_MANAGER); 330 credentialsManager.removePreference(root.findPreference(KEY_RESET_CREDENTIALS)); 331 credentialsManager.removePreference(root.findPreference(KEY_CREDENTIALS_INSTALL)); 332 credentialsManager.removePreference(root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE)); 333 } 334 335 // Application install 336 PreferenceGroup deviceAdminCategory = (PreferenceGroup) 337 root.findPreference(KEY_DEVICE_ADMIN_CATEGORY); 338 mToggleAppInstallation = (SwitchPreference) findPreference( 339 KEY_TOGGLE_INSTALL_APPLICATIONS); 340 mToggleAppInstallation.setChecked(isNonMarketAppsAllowed()); 341 // Side loading of apps. 342 mToggleAppInstallation.setEnabled(mIsPrimary); 343 if (um.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES) 344 || um.hasUserRestriction(UserManager.DISALLOW_INSTALL_APPS)) { 345 mToggleAppInstallation.setEnabled(false); 346 } 347 348 // Advanced Security features 349 PreferenceGroup advancedCategory = 350 (PreferenceGroup)root.findPreference(KEY_ADVANCED_SECURITY); 351 if (advancedCategory != null) { 352 Preference manageAgents = advancedCategory.findPreference(KEY_MANAGE_TRUST_AGENTS); 353 if (manageAgents != null && !mLockPatternUtils.isSecure()) { 354 manageAgents.setEnabled(false); 355 manageAgents.setSummary(R.string.disabled_because_no_backup_security); 356 } 357 } 358 359 // The above preferences come and go based on security state, so we need to update 360 // the index. This call is expected to be fairly cheap, but we may want to do something 361 // smarter in the future. 362 Index.getInstance(getActivity()) 363 .updateFromClassNameResource(SecuritySettings.class.getName(), true, true); 364 365 for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) { 366 final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]); 367 if (pref != null) pref.setOnPreferenceChangeListener(this); 368 } 369 return root; 370 } 371 372 private static ArrayList<TrustAgentComponentInfo> getActiveTrustAgents( 373 PackageManager pm, LockPatternUtils utils) { 374 ArrayList<TrustAgentComponentInfo> result = new ArrayList<TrustAgentComponentInfo>(); 375 List<ResolveInfo> resolveInfos = pm.queryIntentServices(TRUST_AGENT_INTENT, 376 PackageManager.GET_META_DATA); 377 List<ComponentName> enabledTrustAgents = utils.getEnabledTrustAgents(); 378 if (enabledTrustAgents != null && !enabledTrustAgents.isEmpty()) { 379 for (int i = 0; i < resolveInfos.size(); i++) { 380 ResolveInfo resolveInfo = resolveInfos.get(i); 381 if (resolveInfo.serviceInfo == null) continue; 382 if (!TrustAgentUtils.checkProvidePermission(resolveInfo, pm)) continue; 383 TrustAgentComponentInfo trustAgentComponentInfo = 384 TrustAgentUtils.getSettingsComponent(pm, resolveInfo); 385 if (trustAgentComponentInfo.componentName == null || 386 !enabledTrustAgents.contains( 387 TrustAgentUtils.getComponentName(resolveInfo)) || 388 TextUtils.isEmpty(trustAgentComponentInfo.title)) continue; 389 result.add(trustAgentComponentInfo); 390 if (ONLY_ONE_TRUST_AGENT) break; 391 } 392 } 393 return result; 394 } 395 396 private boolean isNonMarketAppsAllowed() { 397 return Settings.Global.getInt(getContentResolver(), 398 Settings.Global.INSTALL_NON_MARKET_APPS, 0) > 0; 399 } 400 401 private void setNonMarketAppsAllowed(boolean enabled) { 402 final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); 403 if (um.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)) { 404 return; 405 } 406 // Change the system setting 407 Settings.Global.putInt(getContentResolver(), Settings.Global.INSTALL_NON_MARKET_APPS, 408 enabled ? 1 : 0); 409 } 410 411 private void warnAppInstallation() { 412 // TODO: DialogFragment? 413 mWarnInstallApps = new AlertDialog.Builder(getActivity()).setTitle( 414 getResources().getString(R.string.error_title)) 415 .setIcon(com.android.internal.R.drawable.ic_dialog_alert) 416 .setMessage(getResources().getString(R.string.install_all_warning)) 417 .setPositiveButton(android.R.string.yes, this) 418 .setNegativeButton(android.R.string.no, this) 419 .show(); 420 } 421 422 @Override 423 public void onClick(DialogInterface dialog, int which) { 424 if (dialog == mWarnInstallApps) { 425 boolean turnOn = which == DialogInterface.BUTTON_POSITIVE; 426 setNonMarketAppsAllowed(turnOn); 427 if (mToggleAppInstallation != null) { 428 mToggleAppInstallation.setChecked(turnOn); 429 } 430 } 431 } 432 433 @Override 434 public void onDestroy() { 435 super.onDestroy(); 436 if (mWarnInstallApps != null) { 437 mWarnInstallApps.dismiss(); 438 } 439 } 440 441 private void setupLockAfterPreference() { 442 // Compatible with pre-Froyo 443 long currentTimeout = Settings.Secure.getLong(getContentResolver(), 444 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000); 445 mLockAfter.setValue(String.valueOf(currentTimeout)); 446 mLockAfter.setOnPreferenceChangeListener(this); 447 final long adminTimeout = (mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0); 448 final long displayTimeout = Math.max(0, 449 Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0)); 450 if (adminTimeout > 0) { 451 // This setting is a slave to display timeout when a device policy is enforced. 452 // As such, maxLockTimeout = adminTimeout - displayTimeout. 453 // If there isn't enough time, shows "immediately" setting. 454 disableUnusableTimeouts(Math.max(0, adminTimeout - displayTimeout)); 455 } 456 } 457 458 private void updateLockAfterPreferenceSummary() { 459 // Update summary message with current value 460 long currentTimeout = Settings.Secure.getLong(getContentResolver(), 461 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000); 462 final CharSequence[] entries = mLockAfter.getEntries(); 463 final CharSequence[] values = mLockAfter.getEntryValues(); 464 int best = 0; 465 for (int i = 0; i < values.length; i++) { 466 long timeout = Long.valueOf(values[i].toString()); 467 if (currentTimeout >= timeout) { 468 best = i; 469 } 470 } 471 472 Preference preference = getPreferenceScreen().findPreference(KEY_TRUST_AGENT); 473 if (preference != null && preference.getTitle().length() > 0) { 474 mLockAfter.setSummary(getString(R.string.lock_after_timeout_summary_with_exception, 475 entries[best], preference.getTitle())); 476 } else { 477 mLockAfter.setSummary(getString(R.string.lock_after_timeout_summary, entries[best])); 478 } 479 } 480 481 private void disableUnusableTimeouts(long maxTimeout) { 482 final CharSequence[] entries = mLockAfter.getEntries(); 483 final CharSequence[] values = mLockAfter.getEntryValues(); 484 ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>(); 485 ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>(); 486 for (int i = 0; i < values.length; i++) { 487 long timeout = Long.valueOf(values[i].toString()); 488 if (timeout <= maxTimeout) { 489 revisedEntries.add(entries[i]); 490 revisedValues.add(values[i]); 491 } 492 } 493 if (revisedEntries.size() != entries.length || revisedValues.size() != values.length) { 494 mLockAfter.setEntries( 495 revisedEntries.toArray(new CharSequence[revisedEntries.size()])); 496 mLockAfter.setEntryValues( 497 revisedValues.toArray(new CharSequence[revisedValues.size()])); 498 final int userPreference = Integer.valueOf(mLockAfter.getValue()); 499 if (userPreference <= maxTimeout) { 500 mLockAfter.setValue(String.valueOf(userPreference)); 501 } else { 502 // There will be no highlighted selection since nothing in the list matches 503 // maxTimeout. The user can still select anything less than maxTimeout. 504 // TODO: maybe append maxTimeout to the list and mark selected. 505 } 506 } 507 mLockAfter.setEnabled(revisedEntries.size() > 0); 508 } 509 510 @Override 511 public void onSaveInstanceState(Bundle outState) { 512 super.onSaveInstanceState(outState); 513 if (mTrustAgentClickIntent != null) { 514 outState.putParcelable(TRUST_AGENT_CLICK_INTENT, mTrustAgentClickIntent); 515 } 516 } 517 518 @Override 519 public void onResume() { 520 super.onResume(); 521 522 // Make sure we reload the preference hierarchy since some of these settings 523 // depend on others... 524 createPreferenceHierarchy(); 525 526 final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); 527 if (mBiometricWeakLiveliness != null) { 528 mBiometricWeakLiveliness.setChecked( 529 lockPatternUtils.isBiometricWeakLivelinessEnabled()); 530 } 531 if (mVisiblePattern != null) { 532 mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled()); 533 } 534 if (mPowerButtonInstantlyLocks != null) { 535 mPowerButtonInstantlyLocks.setChecked(lockPatternUtils.getPowerButtonInstantlyLocks()); 536 } 537 538 if (mShowPassword != null) { 539 mShowPassword.setChecked(Settings.System.getInt(getContentResolver(), 540 Settings.System.TEXT_SHOW_PASSWORD, 1) != 0); 541 } 542 543 if (mResetCredentials != null) { 544 mResetCredentials.setEnabled(!mKeyStore.isEmpty()); 545 } 546 } 547 548 @Override 549 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 550 final String key = preference.getKey(); 551 if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) { 552 startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment", 553 R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null); 554 } else if (KEY_BIOMETRIC_WEAK_IMPROVE_MATCHING.equals(key)) { 555 ChooseLockSettingsHelper helper = 556 new ChooseLockSettingsHelper(this.getActivity(), this); 557 if (!helper.launchConfirmationActivity( 558 CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_IMPROVE_REQUEST, null, null)) { 559 // If this returns false, it means no password confirmation is required, so 560 // go ahead and start improve. 561 // Note: currently a backup is required for biometric_weak so this code path 562 // can't be reached, but is here in case things change in the future 563 startBiometricWeakImprove(); 564 } 565 } else if (KEY_TRUST_AGENT.equals(key)) { 566 ChooseLockSettingsHelper helper = 567 new ChooseLockSettingsHelper(this.getActivity(), this); 568 mTrustAgentClickIntent = preference.getIntent(); 569 if (!helper.launchConfirmationActivity(CHANGE_TRUST_AGENT_SETTINGS, null, null) && 570 mTrustAgentClickIntent != null) { 571 // If this returns false, it means no password confirmation is required. 572 startActivity(mTrustAgentClickIntent); 573 mTrustAgentClickIntent = null; 574 } 575 } else { 576 // If we didn't handle it, let preferences handle it. 577 return super.onPreferenceTreeClick(preferenceScreen, preference); 578 } 579 return true; 580 } 581 582 /** 583 * see confirmPatternThenDisableAndClear 584 */ 585 @Override 586 public void onActivityResult(int requestCode, int resultCode, Intent data) { 587 super.onActivityResult(requestCode, resultCode, data); 588 if (requestCode == CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_IMPROVE_REQUEST && 589 resultCode == Activity.RESULT_OK) { 590 startBiometricWeakImprove(); 591 return; 592 } else if (requestCode == CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_LIVELINESS_OFF && 593 resultCode == Activity.RESULT_OK) { 594 final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); 595 lockPatternUtils.setBiometricWeakLivelinessEnabled(false); 596 // Setting the mBiometricWeakLiveliness checked value to false is handled when onResume 597 // is called by grabbing the value from lockPatternUtils. We can't set it here 598 // because mBiometricWeakLiveliness could be null 599 return; 600 } else if (requestCode == CHANGE_TRUST_AGENT_SETTINGS && resultCode == Activity.RESULT_OK) { 601 if (mTrustAgentClickIntent != null) { 602 startActivity(mTrustAgentClickIntent); 603 mTrustAgentClickIntent = null; 604 } 605 return; 606 } 607 createPreferenceHierarchy(); 608 } 609 610 @Override 611 public boolean onPreferenceChange(Preference preference, Object value) { 612 boolean result = true; 613 final String key = preference.getKey(); 614 final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); 615 if (KEY_LOCK_AFTER_TIMEOUT.equals(key)) { 616 int timeout = Integer.parseInt((String) value); 617 try { 618 Settings.Secure.putInt(getContentResolver(), 619 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout); 620 } catch (NumberFormatException e) { 621 Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e); 622 } 623 updateLockAfterPreferenceSummary(); 624 } else if (KEY_LOCK_ENABLED.equals(key)) { 625 lockPatternUtils.setLockPatternEnabled((Boolean) value); 626 } else if (KEY_VISIBLE_PATTERN.equals(key)) { 627 lockPatternUtils.setVisiblePatternEnabled((Boolean) value); 628 } else if (KEY_BIOMETRIC_WEAK_LIVELINESS.equals(key)) { 629 if ((Boolean) value) { 630 lockPatternUtils.setBiometricWeakLivelinessEnabled(true); 631 } else { 632 // In this case the user has just unchecked the checkbox, but this action requires 633 // them to confirm their password. We need to re-check the checkbox until 634 // they've confirmed their password 635 mBiometricWeakLiveliness.setChecked(true); 636 ChooseLockSettingsHelper helper = 637 new ChooseLockSettingsHelper(this.getActivity(), this); 638 if (!helper.launchConfirmationActivity( 639 CONFIRM_EXISTING_FOR_BIOMETRIC_WEAK_LIVELINESS_OFF, null, null)) { 640 // If this returns false, it means no password confirmation is required, so 641 // go ahead and uncheck it here. 642 // Note: currently a backup is required for biometric_weak so this code path 643 // can't be reached, but is here in case things change in the future 644 lockPatternUtils.setBiometricWeakLivelinessEnabled(false); 645 mBiometricWeakLiveliness.setChecked(false); 646 } 647 } 648 } else if (KEY_POWER_INSTANTLY_LOCKS.equals(key)) { 649 mLockPatternUtils.setPowerButtonInstantlyLocks((Boolean) value); 650 } else if (KEY_SHOW_PASSWORD.equals(key)) { 651 Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, 652 ((Boolean) value) ? 1 : 0); 653 } else if (KEY_TOGGLE_INSTALL_APPLICATIONS.equals(key)) { 654 if ((Boolean) value) { 655 mToggleAppInstallation.setChecked(false); 656 warnAppInstallation(); 657 // Don't change Switch status until user makes choice in dialog, so return false. 658 result = false; 659 } else { 660 setNonMarketAppsAllowed(false); 661 } 662 } 663 return result; 664 } 665 666 @Override 667 protected int getHelpResource() { 668 return R.string.help_url_security; 669 } 670 671 public void startBiometricWeakImprove(){ 672 Intent intent = new Intent(); 673 intent.setClassName("com.android.facelock", "com.android.facelock.AddToSetup"); 674 startActivity(intent); 675 } 676 677 /** 678 * For Search. Please keep it in sync when updating "createPreferenceHierarchy()" 679 */ 680 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 681 new SecuritySearchIndexProvider(); 682 683 private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider { 684 685 boolean mIsPrimary; 686 687 public SecuritySearchIndexProvider() { 688 super(); 689 690 mIsPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER; 691 } 692 693 @Override 694 public List<SearchIndexableResource> getXmlResourcesToIndex( 695 Context context, boolean enabled) { 696 697 List<SearchIndexableResource> result = new ArrayList<SearchIndexableResource>(); 698 699 LockPatternUtils lockPatternUtils = new LockPatternUtils(context); 700 // Add options for lock/unlock screen 701 int resId = getResIdForLockUnlockScreen(context, lockPatternUtils); 702 703 SearchIndexableResource sir = new SearchIndexableResource(context); 704 sir.xmlResId = resId; 705 result.add(sir); 706 707 if (mIsPrimary) { 708 DevicePolicyManager dpm = (DevicePolicyManager) 709 context.getSystemService(Context.DEVICE_POLICY_SERVICE); 710 711 switch (dpm.getStorageEncryptionStatus()) { 712 case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: 713 // The device is currently encrypted. 714 resId = R.xml.security_settings_encrypted; 715 break; 716 case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: 717 // This device supports encryption but isn't encrypted. 718 resId = R.xml.security_settings_unencrypted; 719 break; 720 } 721 722 sir = new SearchIndexableResource(context); 723 sir.xmlResId = resId; 724 result.add(sir); 725 } 726 727 // Append the rest of the settings 728 sir = new SearchIndexableResource(context); 729 sir.xmlResId = R.xml.security_settings_misc; 730 result.add(sir); 731 732 return result; 733 } 734 735 @Override 736 public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { 737 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); 738 final Resources res = context.getResources(); 739 740 final String screenTitle = res.getString(R.string.security_settings_title); 741 742 SearchIndexableRaw data = new SearchIndexableRaw(context); 743 data.title = screenTitle; 744 data.screenTitle = screenTitle; 745 result.add(data); 746 747 if (!mIsPrimary) { 748 int resId = (UserManager.get(context).isLinkedUser()) ? 749 R.string.profile_info_settings_title : R.string.user_info_settings_title; 750 751 data = new SearchIndexableRaw(context); 752 data.title = res.getString(resId); 753 data.screenTitle = screenTitle; 754 result.add(data); 755 } 756 757 // Credential storage 758 final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); 759 760 if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { 761 KeyStore keyStore = KeyStore.getInstance(); 762 763 final int storageSummaryRes = keyStore.isHardwareBacked() ? 764 R.string.credential_storage_type_hardware : 765 R.string.credential_storage_type_software; 766 767 data = new SearchIndexableRaw(context); 768 data.title = res.getString(storageSummaryRes); 769 data.screenTitle = screenTitle; 770 result.add(data); 771 } 772 773 // Advanced 774 final LockPatternUtils lockPatternUtils = new LockPatternUtils(context); 775 if (lockPatternUtils.isSecure()) { 776 ArrayList<TrustAgentComponentInfo> agents = 777 getActiveTrustAgents(context.getPackageManager(), lockPatternUtils); 778 for (int i = 0; i < agents.size(); i++) { 779 final TrustAgentComponentInfo agent = agents.get(i); 780 data = new SearchIndexableRaw(context); 781 data.title = agent.title; 782 data.screenTitle = screenTitle; 783 result.add(data); 784 } 785 } 786 return result; 787 } 788 789 @Override 790 public List<String> getNonIndexableKeys(Context context) { 791 final List<String> keys = new ArrayList<String>(); 792 793 LockPatternUtils lockPatternUtils = new LockPatternUtils(context); 794 // Add options for lock/unlock screen 795 int resId = getResIdForLockUnlockScreen(context, lockPatternUtils); 796 797 // don't display visible pattern if biometric and backup is not pattern 798 if (resId == R.xml.security_settings_biometric_weak && 799 lockPatternUtils.getKeyguardStoredPasswordQuality() != 800 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { 801 keys.add(KEY_VISIBLE_PATTERN); 802 } 803 804 // Do not display SIM lock for devices without an Icc card 805 TelephonyManager tm = TelephonyManager.getDefault(); 806 if (!mIsPrimary || !tm.hasIccCard()) { 807 keys.add(KEY_SIM_LOCK); 808 } 809 810 final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); 811 if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { 812 keys.add(KEY_CREDENTIALS_MANAGER); 813 } 814 815 // TrustAgent settings disappear when the user has no primary security. 816 if (!lockPatternUtils.isSecure()) { 817 keys.add(KEY_TRUST_AGENT); 818 keys.add(KEY_MANAGE_TRUST_AGENTS); 819 } 820 821 return keys; 822 } 823 } 824 825} 826