Home | History | Annotate | Download | only in settings
      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 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
     20 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
     21 
     22 import android.app.Activity;
     23 import android.app.AlertDialog;
     24 import android.app.Dialog;
     25 import android.app.FragmentManager;
     26 import android.app.admin.DevicePolicyManager;
     27 import android.content.ComponentName;
     28 import android.content.Context;
     29 import android.content.DialogInterface;
     30 import android.content.Intent;
     31 import android.content.pm.PackageManager;
     32 import android.content.pm.ResolveInfo;
     33 import android.content.res.Resources;
     34 import android.hardware.fingerprint.FingerprintManager;
     35 import android.os.Bundle;
     36 import android.os.PersistableBundle;
     37 import android.os.UserHandle;
     38 import android.os.UserManager;
     39 import android.os.storage.StorageManager;
     40 import android.provider.SearchIndexableResource;
     41 import android.provider.Settings;
     42 import android.service.trust.TrustAgentService;
     43 import android.support.annotation.VisibleForTesting;
     44 import android.support.v14.preference.SwitchPreference;
     45 import android.support.v7.preference.Preference;
     46 import android.support.v7.preference.Preference.OnPreferenceChangeListener;
     47 import android.support.v7.preference.PreferenceGroup;
     48 import android.support.v7.preference.PreferenceScreen;
     49 import android.telephony.CarrierConfigManager;
     50 import android.telephony.SubscriptionInfo;
     51 import android.telephony.SubscriptionManager;
     52 import android.telephony.TelephonyManager;
     53 import android.text.TextUtils;
     54 import android.util.Log;
     55 
     56 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     57 import com.android.internal.widget.LockPatternUtils;
     58 import com.android.settings.TrustAgentUtils.TrustAgentComponentInfo;
     59 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
     60 import com.android.settings.dashboard.DashboardFeatureProvider;
     61 import com.android.settings.dashboard.SummaryLoader;
     62 import com.android.settings.enterprise.EnterprisePrivacyPreferenceController;
     63 import com.android.settings.enterprise.ManageDeviceAdminPreferenceController;
     64 import com.android.settings.fingerprint.FingerprintSettings;
     65 import com.android.settings.location.LocationPreferenceController;
     66 import com.android.settings.notification.LockScreenNotificationPreferenceController;
     67 import com.android.settings.overlay.FeatureFactory;
     68 import com.android.settings.search.BaseSearchIndexProvider;
     69 import com.android.settings.search.Indexable;
     70 import com.android.settings.search.SearchIndexableRaw;
     71 import com.android.settings.security.OwnerInfoPreferenceController;
     72 import com.android.settings.security.SecurityFeatureProvider;
     73 import com.android.settings.trustagent.TrustAgentManager;
     74 import com.android.settings.widget.GearPreference;
     75 import com.android.settingslib.RestrictedLockUtils;
     76 import com.android.settingslib.RestrictedPreference;
     77 import com.android.settingslib.drawer.CategoryKey;
     78 
     79 import java.util.ArrayList;
     80 import java.util.List;
     81 
     82 /**
     83  * Gesture lock pattern settings.
     84  */
     85 public class SecuritySettings extends SettingsPreferenceFragment
     86         implements OnPreferenceChangeListener, Indexable,
     87         GearPreference.OnGearClickListener {
     88 
     89     private static final String TAG = "SecuritySettings";
     90 
     91     private static final String TRUST_AGENT_CLICK_INTENT = "trust_agent_click_intent";
     92     private static final Intent TRUST_AGENT_INTENT =
     93             new Intent(TrustAgentService.SERVICE_INTERFACE);
     94 
     95     // Lock Settings
     96     private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
     97     private static final String KEY_UNLOCK_SET_OR_CHANGE_PROFILE = "unlock_set_or_change_profile";
     98     private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
     99     private static final String KEY_SECURITY_CATEGORY = "security_category";
    100     @VisibleForTesting
    101     static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents";
    102     private static final String KEY_UNIFICATION = "unification";
    103     @VisibleForTesting
    104     static final String KEY_LOCKSCREEN_PREFERENCES = "lockscreen_preferences";
    105     private static final String KEY_ENCRYPTION_AND_CREDENTIALS = "encryption_and_credential";
    106     private static final String KEY_LOCATION_SCANNING  = "location_scanning";
    107 
    108     private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
    109     private static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
    110     private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE = 127;
    111     private static final int UNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 128;
    112     private static final int UNIFY_LOCK_CONFIRM_PROFILE_REQUEST = 129;
    113     private static final int UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST = 130;
    114     private static final String TAG_UNIFICATION_DIALOG = "unification_dialog";
    115 
    116     // Misc Settings
    117     private static final String KEY_SIM_LOCK = "sim_lock_settings";
    118     private static final String KEY_SHOW_PASSWORD = "show_password";
    119     private static final String KEY_TRUST_AGENT = "trust_agent";
    120     private static final String KEY_SCREEN_PINNING = "screen_pinning_settings";
    121 
    122     // Security status
    123     private static final String KEY_SECURITY_STATUS = "security_status";
    124     private static final String SECURITY_STATUS_KEY_PREFIX = "security_status_";
    125 
    126     // Package verifier Settings
    127     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    128     static final String KEY_PACKAGE_VERIFIER_STATUS = "security_status_package_verifier";
    129     private static final int PACKAGE_VERIFIER_STATE_ENABLED = 1;
    130 
    131     // Device management settings
    132     private static final String KEY_ENTERPRISE_PRIVACY = "enterprise_privacy";
    133     private static final String KEY_MANAGE_DEVICE_ADMIN = "manage_device_admin";
    134 
    135     // These switch preferences need special handling since they're not all stored in Settings.
    136     private static final String SWITCH_PREFERENCE_KEYS[] = {
    137             KEY_SHOW_PASSWORD, KEY_UNIFICATION, KEY_VISIBLE_PATTERN_PROFILE
    138     };
    139 
    140     // Only allow one trust agent on the platform.
    141     private static final boolean ONLY_ONE_TRUST_AGENT = true;
    142 
    143     private static final int MY_USER_ID = UserHandle.myUserId();
    144 
    145     private DashboardFeatureProvider mDashboardFeatureProvider;
    146     private DevicePolicyManager mDPM;
    147     private SecurityFeatureProvider mSecurityFeatureProvider;
    148     private TrustAgentManager mTrustAgentManager;
    149     private SubscriptionManager mSubscriptionManager;
    150     private UserManager mUm;
    151 
    152     private ChooseLockSettingsHelper mChooseLockSettingsHelper;
    153     private LockPatternUtils mLockPatternUtils;
    154     private ManagedLockPasswordProvider mManagedPasswordProvider;
    155 
    156     private SwitchPreference mVisiblePatternProfile;
    157     private SwitchPreference mUnifyProfile;
    158 
    159     private SwitchPreference mShowPassword;
    160 
    161     private boolean mIsAdmin;
    162 
    163     private Intent mTrustAgentClickIntent;
    164 
    165     private int mProfileChallengeUserId;
    166 
    167     private String mCurrentDevicePassword;
    168     private String mCurrentProfilePassword;
    169 
    170     private LocationPreferenceController mLocationcontroller;
    171     private ManageDeviceAdminPreferenceController mManageDeviceAdminPreferenceController;
    172     private EnterprisePrivacyPreferenceController mEnterprisePrivacyPreferenceController;
    173     private LockScreenNotificationPreferenceController mLockScreenNotificationPreferenceController;
    174 
    175     @Override
    176     public int getMetricsCategory() {
    177         return MetricsEvent.SECURITY;
    178     }
    179 
    180     @Override
    181     public void onCreate(Bundle savedInstanceState) {
    182         super.onCreate(savedInstanceState);
    183 
    184         final Activity activity = getActivity();
    185 
    186         mSubscriptionManager = SubscriptionManager.from(activity);
    187 
    188         mLockPatternUtils = new LockPatternUtils(activity);
    189 
    190         mManagedPasswordProvider = ManagedLockPasswordProvider.get(activity, MY_USER_ID);
    191 
    192         mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
    193 
    194         mUm = UserManager.get(activity);
    195 
    196         mChooseLockSettingsHelper = new ChooseLockSettingsHelper(activity);
    197 
    198         mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
    199                 .getDashboardFeatureProvider(activity);
    200 
    201         mSecurityFeatureProvider = FeatureFactory.getFactory(activity).getSecurityFeatureProvider();
    202 
    203         mTrustAgentManager = mSecurityFeatureProvider.getTrustAgentManager();
    204 
    205         if (savedInstanceState != null
    206                 && savedInstanceState.containsKey(TRUST_AGENT_CLICK_INTENT)) {
    207             mTrustAgentClickIntent = savedInstanceState.getParcelable(TRUST_AGENT_CLICK_INTENT);
    208         }
    209 
    210         mLocationcontroller = new LocationPreferenceController(activity);
    211         mManageDeviceAdminPreferenceController
    212                 = new ManageDeviceAdminPreferenceController(activity);
    213         mEnterprisePrivacyPreferenceController
    214                 = new EnterprisePrivacyPreferenceController(activity, null /* lifecycle */);
    215         mLockScreenNotificationPreferenceController
    216                 = new LockScreenNotificationPreferenceController(activity);
    217     }
    218 
    219     private static int getResIdForLockUnlockScreen(Context context,
    220             LockPatternUtils lockPatternUtils, ManagedLockPasswordProvider managedPasswordProvider,
    221             int userId) {
    222         final boolean isMyUser = userId == MY_USER_ID;
    223         int resid = 0;
    224         if (!lockPatternUtils.isSecure(userId)) {
    225             if (!isMyUser) {
    226                 resid = R.xml.security_settings_lockscreen_profile;
    227             } else if (lockPatternUtils.isLockScreenDisabled(userId)) {
    228                 resid = R.xml.security_settings_lockscreen;
    229             } else {
    230                 resid = R.xml.security_settings_chooser;
    231             }
    232         } else {
    233             switch (lockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
    234                 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
    235                     resid = isMyUser ? R.xml.security_settings_pattern
    236                             : R.xml.security_settings_pattern_profile;
    237                     break;
    238                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
    239                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
    240                     resid = isMyUser ? R.xml.security_settings_pin
    241                             : R.xml.security_settings_pin_profile;
    242                     break;
    243                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
    244                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
    245                 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
    246                     resid = isMyUser ? R.xml.security_settings_password
    247                             : R.xml.security_settings_password_profile;
    248                     break;
    249                 case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
    250                     resid = managedPasswordProvider.getResIdForLockUnlockScreen(!isMyUser);
    251                     break;
    252             }
    253         }
    254         return resid;
    255     }
    256 
    257     /**
    258      * Important!
    259      *
    260      * Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the
    261      * logic or adding/removing preferences here.
    262      */
    263     private PreferenceScreen createPreferenceHierarchy() {
    264         PreferenceScreen root = getPreferenceScreen();
    265         if (root != null) {
    266             root.removeAll();
    267         }
    268         addPreferencesFromResource(R.xml.security_settings);
    269         root = getPreferenceScreen();
    270 
    271         // Add category for security status
    272         addPreferencesFromResource(R.xml.security_settings_status);
    273 
    274         // Add options for lock/unlock screen
    275         final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils,
    276                 mManagedPasswordProvider, MY_USER_ID);
    277         addPreferencesFromResource(resid);
    278 
    279         // DO or PO installed in the user may disallow to change password.
    280         disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, MY_USER_ID);
    281 
    282         mProfileChallengeUserId = Utils.getManagedProfileId(mUm, MY_USER_ID);
    283         if (mProfileChallengeUserId != UserHandle.USER_NULL
    284                 && mLockPatternUtils.isSeparateProfileChallengeAllowed(mProfileChallengeUserId)) {
    285             addPreferencesFromResource(R.xml.security_settings_profile);
    286             addPreferencesFromResource(R.xml.security_settings_unification);
    287             final int profileResid = getResIdForLockUnlockScreen(
    288                     getActivity(), mLockPatternUtils, mManagedPasswordProvider,
    289                     mProfileChallengeUserId);
    290             addPreferencesFromResource(profileResid);
    291             maybeAddFingerprintPreference(root, mProfileChallengeUserId);
    292             if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
    293                 final Preference lockPreference =
    294                         root.findPreference(KEY_UNLOCK_SET_OR_CHANGE_PROFILE);
    295                 final String summary = getContext().getString(
    296                         R.string.lock_settings_profile_unified_summary);
    297                 lockPreference.setSummary(summary);
    298                 lockPreference.setEnabled(false);
    299                 // PO may disallow to change password for the profile, but screen lock and managed
    300                 // profile's lock is the same. Disable main "Screen lock" menu.
    301                 disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE, mProfileChallengeUserId);
    302             } else {
    303                 // PO may disallow to change profile password, and the profile's password is
    304                 // separated from screen lock password. Disable profile specific "Screen lock" menu.
    305                 disableIfPasswordQualityManaged(KEY_UNLOCK_SET_OR_CHANGE_PROFILE,
    306                         mProfileChallengeUserId);
    307             }
    308         }
    309 
    310         Preference unlockSetOrChange = findPreference(KEY_UNLOCK_SET_OR_CHANGE);
    311         if (unlockSetOrChange instanceof GearPreference) {
    312             ((GearPreference) unlockSetOrChange).setOnGearClickListener(this);
    313         }
    314 
    315         mIsAdmin = mUm.isAdminUser();
    316 
    317         // Fingerprint and trust agents
    318         int numberOfTrustAgent = 0;
    319         PreferenceGroup securityCategory = (PreferenceGroup)
    320                 root.findPreference(KEY_SECURITY_CATEGORY);
    321         if (securityCategory != null) {
    322             maybeAddFingerprintPreference(securityCategory, UserHandle.myUserId());
    323             numberOfTrustAgent = addTrustAgentSettings(securityCategory);
    324             setLockscreenPreferencesSummary(securityCategory);
    325         }
    326 
    327         mVisiblePatternProfile =
    328                 (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN_PROFILE);
    329         mUnifyProfile = (SwitchPreference) root.findPreference(KEY_UNIFICATION);
    330 
    331         // Append the rest of the settings
    332         addPreferencesFromResource(R.xml.security_settings_misc);
    333 
    334         // Do not display SIM lock for devices without an Icc card
    335         TelephonyManager tm = TelephonyManager.getDefault();
    336         CarrierConfigManager cfgMgr = (CarrierConfigManager)
    337                 getActivity().getSystemService(Context.CARRIER_CONFIG_SERVICE);
    338         PersistableBundle b = cfgMgr.getConfig();
    339         if (!mIsAdmin || !isSimIccReady() ||
    340                 b.getBoolean(CarrierConfigManager.KEY_HIDE_SIM_LOCK_SETTINGS_BOOL)) {
    341             root.removePreference(root.findPreference(KEY_SIM_LOCK));
    342         } else {
    343             // Disable SIM lock if there is no ready SIM card.
    344             root.findPreference(KEY_SIM_LOCK).setEnabled(isSimReady());
    345         }
    346         if (Settings.System.getInt(getContentResolver(),
    347                 Settings.System.LOCK_TO_APP_ENABLED, 0) != 0) {
    348             root.findPreference(KEY_SCREEN_PINNING).setSummary(
    349                     getResources().getString(R.string.switch_on_text));
    350         }
    351 
    352         // Show password
    353         mShowPassword = (SwitchPreference) root.findPreference(KEY_SHOW_PASSWORD);
    354 
    355         // Credential storage
    356         final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
    357 
    358         // Advanced Security features
    359         initTrustAgentPreference(root, numberOfTrustAgent);
    360 
    361         // The above preferences come and go based on security state, so we need to update
    362         // the index. This call is expected to be fairly cheap, but we may want to do something
    363         // smarter in the future.
    364         final Activity activity = getActivity();
    365         FeatureFactory.getFactory(activity).getSearchFeatureProvider().getIndexingManager(activity)
    366                 .updateFromClassNameResource(SecuritySettings.class.getName(),
    367                         true /* includeInSearchResults */);
    368 
    369         PreferenceGroup securityStatusPreferenceGroup =
    370                 (PreferenceGroup) root.findPreference(KEY_SECURITY_STATUS);
    371         final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
    372             getActivity(), getPrefContext(), getMetricsCategory(),
    373             CategoryKey.CATEGORY_SECURITY);
    374         int numSecurityStatusPrefs = 0;
    375         if (tilePrefs != null && !tilePrefs.isEmpty()) {
    376             for (Preference preference : tilePrefs) {
    377                 if (!TextUtils.isEmpty(preference.getKey())
    378                     && preference.getKey().startsWith(SECURITY_STATUS_KEY_PREFIX)) {
    379                     // Injected security status settings are placed under the Security status
    380                     // category.
    381                     securityStatusPreferenceGroup.addPreference(preference);
    382                     numSecurityStatusPrefs++;
    383                 } else {
    384                     // Other injected settings are placed under the Security preference screen.
    385                     root.addPreference(preference);
    386                 }
    387             }
    388         }
    389 
    390         if (numSecurityStatusPrefs == 0) {
    391             root.removePreference(securityStatusPreferenceGroup);
    392         } else if (numSecurityStatusPrefs > 0) {
    393             // Update preference data with tile data. Security feature provider only updates the
    394             // data if it actually needs to be changed.
    395             mSecurityFeatureProvider.updatePreferences(getActivity(), root,
    396                 mDashboardFeatureProvider.getTilesForCategory(
    397                     CategoryKey.CATEGORY_SECURITY));
    398         }
    399 
    400         for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
    401             final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
    402             if (pref != null) pref.setOnPreferenceChangeListener(this);
    403         }
    404 
    405         mLocationcontroller.displayPreference(root);
    406         mManageDeviceAdminPreferenceController.updateState(
    407                 root.findPreference(KEY_MANAGE_DEVICE_ADMIN));
    408         mEnterprisePrivacyPreferenceController.displayPreference(root);
    409         mEnterprisePrivacyPreferenceController.onResume();
    410 
    411         return root;
    412     }
    413 
    414     @VisibleForTesting
    415     void initTrustAgentPreference(PreferenceScreen root, int numberOfTrustAgent) {
    416         Preference manageAgents = root.findPreference(KEY_MANAGE_TRUST_AGENTS);
    417         if (manageAgents != null) {
    418             if (!mLockPatternUtils.isSecure(MY_USER_ID)) {
    419                 manageAgents.setEnabled(false);
    420                 manageAgents.setSummary(R.string.disabled_because_no_backup_security);
    421             } else if (numberOfTrustAgent > 0) {
    422                 manageAgents.setSummary(getActivity().getResources().getQuantityString(
    423                     R.plurals.manage_trust_agents_summary_on,
    424                     numberOfTrustAgent, numberOfTrustAgent));
    425             } else {
    426                 manageAgents.setSummary(R.string.manage_trust_agents_summary);
    427             }
    428         }
    429     }
    430 
    431     @VisibleForTesting
    432     void setLockscreenPreferencesSummary(PreferenceGroup group) {
    433         final Preference lockscreenPreferences = group.findPreference(KEY_LOCKSCREEN_PREFERENCES);
    434         if (lockscreenPreferences != null) {
    435             lockscreenPreferences.setSummary(
    436                 mLockScreenNotificationPreferenceController.getSummaryResource());
    437         }
    438     }
    439 
    440     /*
    441      * Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
    442      * The preference must be a RestrictedPreference.
    443      */
    444     private void disableIfPasswordQualityManaged(String preferenceKey, int userId) {
    445         final EnforcedAdmin admin = RestrictedLockUtils.checkIfPasswordQualityIsSet(
    446                 getActivity(), userId);
    447         if (admin != null && mDPM.getPasswordQuality(admin.component, userId) ==
    448                 DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
    449             final RestrictedPreference pref =
    450                     (RestrictedPreference) getPreferenceScreen().findPreference(preferenceKey);
    451             pref.setDisabledByAdmin(admin);
    452         }
    453     }
    454 
    455     private void maybeAddFingerprintPreference(PreferenceGroup securityCategory, int userId) {
    456         Preference fingerprintPreference =
    457                 FingerprintSettings.getFingerprintPreferenceForUser(
    458                         securityCategory.getContext(), userId);
    459         if (fingerprintPreference != null) {
    460             securityCategory.addPreference(fingerprintPreference);
    461         }
    462     }
    463 
    464     // Return the number of trust agents being added
    465     private int addTrustAgentSettings(PreferenceGroup securityCategory) {
    466         final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID);
    467         ArrayList<TrustAgentComponentInfo> agents = getActiveTrustAgents(
    468             getActivity(), mTrustAgentManager, mLockPatternUtils, mDPM);
    469         for (int i = 0; i < agents.size(); i++) {
    470             final TrustAgentComponentInfo agent = agents.get(i);
    471             RestrictedPreference trustAgentPreference =
    472                     new RestrictedPreference(securityCategory.getContext());
    473             trustAgentPreference.setKey(KEY_TRUST_AGENT);
    474             trustAgentPreference.setTitle(agent.title);
    475             trustAgentPreference.setSummary(agent.summary);
    476             // Create intent for this preference.
    477             Intent intent = new Intent();
    478             intent.setComponent(agent.componentName);
    479             intent.setAction(Intent.ACTION_MAIN);
    480             trustAgentPreference.setIntent(intent);
    481             // Add preference to the settings menu.
    482             securityCategory.addPreference(trustAgentPreference);
    483 
    484             trustAgentPreference.setDisabledByAdmin(agent.admin);
    485             if (!trustAgentPreference.isDisabledByAdmin() && !hasSecurity) {
    486                 trustAgentPreference.setEnabled(false);
    487                 trustAgentPreference.setSummary(R.string.disabled_because_no_backup_security);
    488             }
    489         }
    490         return agents.size();
    491     }
    492 
    493     /* Return true if a there is a Slot that has Icc.
    494      */
    495     private boolean isSimIccReady() {
    496         TelephonyManager tm = TelephonyManager.getDefault();
    497         final List<SubscriptionInfo> subInfoList =
    498                 mSubscriptionManager.getActiveSubscriptionInfoList();
    499 
    500         if (subInfoList != null) {
    501             for (SubscriptionInfo subInfo : subInfoList) {
    502                 if (tm.hasIccCard(subInfo.getSimSlotIndex())) {
    503                     return true;
    504                 }
    505             }
    506         }
    507 
    508         return false;
    509     }
    510 
    511     /* Return true if a SIM is ready for locking.
    512      * TODO: consider adding to TelephonyManager or SubscritpionManasger.
    513      */
    514     private boolean isSimReady() {
    515         int simState = TelephonyManager.SIM_STATE_UNKNOWN;
    516         final List<SubscriptionInfo> subInfoList =
    517                 mSubscriptionManager.getActiveSubscriptionInfoList();
    518         if (subInfoList != null) {
    519             for (SubscriptionInfo subInfo : subInfoList) {
    520                 simState = TelephonyManager.getDefault().getSimState(subInfo.getSimSlotIndex());
    521                 if((simState != TelephonyManager.SIM_STATE_ABSENT) &&
    522                             (simState != TelephonyManager.SIM_STATE_UNKNOWN)){
    523                     return true;
    524                 }
    525             }
    526         }
    527         return false;
    528     }
    529 
    530     private static ArrayList<TrustAgentComponentInfo> getActiveTrustAgents(Context context,
    531         TrustAgentManager trustAgentManager, LockPatternUtils utils,
    532         DevicePolicyManager dpm) {
    533         PackageManager pm = context.getPackageManager();
    534         ArrayList<TrustAgentComponentInfo> result = new ArrayList<TrustAgentComponentInfo>();
    535         List<ResolveInfo> resolveInfos = pm.queryIntentServices(TRUST_AGENT_INTENT,
    536                 PackageManager.GET_META_DATA);
    537         List<ComponentName> enabledTrustAgents = utils.getEnabledTrustAgents(MY_USER_ID);
    538 
    539         EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(context,
    540                 DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId());
    541 
    542         if (enabledTrustAgents != null && !enabledTrustAgents.isEmpty()) {
    543             for (int i = 0; i < resolveInfos.size(); i++) {
    544                 ResolveInfo resolveInfo = resolveInfos.get(i);
    545                 if (resolveInfo.serviceInfo == null) continue;
    546                 if (!trustAgentManager.shouldProvideTrust(resolveInfo, pm)) {
    547                     continue;
    548                 }
    549                 TrustAgentComponentInfo trustAgentComponentInfo =
    550                         TrustAgentUtils.getSettingsComponent(pm, resolveInfo);
    551                 if (trustAgentComponentInfo.componentName == null ||
    552                         !enabledTrustAgents.contains(
    553                                 TrustAgentUtils.getComponentName(resolveInfo)) ||
    554                         TextUtils.isEmpty(trustAgentComponentInfo.title)) continue;
    555                 if (admin != null && dpm.getTrustAgentConfiguration(
    556                         null, TrustAgentUtils.getComponentName(resolveInfo)) == null) {
    557                     trustAgentComponentInfo.admin = admin;
    558                 }
    559                 result.add(trustAgentComponentInfo);
    560                 if (ONLY_ONE_TRUST_AGENT) break;
    561             }
    562         }
    563         return result;
    564     }
    565 
    566     private static CharSequence getActiveTrustAgentLabel(Context context,
    567             TrustAgentManager trustAgentManager, LockPatternUtils utils,
    568             DevicePolicyManager dpm) {
    569         ArrayList<TrustAgentComponentInfo> agents = getActiveTrustAgents(context,
    570                 trustAgentManager, utils, dpm);
    571         return agents.isEmpty() ? null : agents.get(0).title;
    572     }
    573 
    574     @Override
    575     public void onGearClick(GearPreference p) {
    576         if (KEY_UNLOCK_SET_OR_CHANGE.equals(p.getKey())) {
    577             startFragment(this, SecuritySubSettings.class.getName(), 0, 0, null);
    578         }
    579     }
    580 
    581     @Override
    582     public void onSaveInstanceState(Bundle outState) {
    583         super.onSaveInstanceState(outState);
    584         if (mTrustAgentClickIntent != null) {
    585             outState.putParcelable(TRUST_AGENT_CLICK_INTENT, mTrustAgentClickIntent);
    586         }
    587     }
    588 
    589     @Override
    590     public void onResume() {
    591         super.onResume();
    592 
    593         // Make sure we reload the preference hierarchy since some of these settings
    594         // depend on others...
    595         createPreferenceHierarchy();
    596 
    597         if (mVisiblePatternProfile != null) {
    598             mVisiblePatternProfile.setChecked(mLockPatternUtils.isVisiblePatternEnabled(
    599                     mProfileChallengeUserId));
    600         }
    601 
    602         updateUnificationPreference();
    603 
    604         if (mShowPassword != null) {
    605             mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
    606                     Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
    607         }
    608 
    609         mLocationcontroller.updateSummary();
    610     }
    611 
    612     private void updateUnificationPreference() {
    613         if (mUnifyProfile != null) {
    614             mUnifyProfile.setChecked(!mLockPatternUtils.isSeparateProfileChallengeEnabled(
    615                     mProfileChallengeUserId));
    616         }
    617     }
    618 
    619     @Override
    620     public boolean onPreferenceTreeClick(Preference preference) {
    621         final String key = preference.getKey();
    622         if (KEY_UNLOCK_SET_OR_CHANGE.equals(key)) {
    623             // TODO(b/35930129): Remove once existing password can be passed into vold directly.
    624             // Currently we need this logic to ensure that the QUIET_MODE is off for any work
    625             // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
    626             // able to complete the operation due to the lack of (old) encryption key.
    627             if (mProfileChallengeUserId != UserHandle.USER_NULL
    628                     && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
    629                     && StorageManager.isFileEncryptedNativeOnly()) {
    630                 if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
    631                         mProfileChallengeUserId)) {
    632                     return false;
    633                 }
    634             }
    635             startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
    636                     R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
    637         } else if (KEY_UNLOCK_SET_OR_CHANGE_PROFILE.equals(key)) {
    638             if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
    639                     mProfileChallengeUserId)) {
    640                 return false;
    641             }
    642             Bundle extras = new Bundle();
    643             extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
    644             startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
    645                     R.string.lock_settings_picker_title_profile,
    646                     SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
    647         } else if (KEY_TRUST_AGENT.equals(key)) {
    648             ChooseLockSettingsHelper helper =
    649                     new ChooseLockSettingsHelper(this.getActivity(), this);
    650             mTrustAgentClickIntent = preference.getIntent();
    651             boolean confirmationLaunched = helper.launchConfirmationActivity(
    652                     CHANGE_TRUST_AGENT_SETTINGS, preference.getTitle());
    653             if (!confirmationLaunched&&  mTrustAgentClickIntent != null) {
    654                 // If this returns false, it means no password confirmation is required.
    655                 startActivity(mTrustAgentClickIntent);
    656                 mTrustAgentClickIntent = null;
    657             }
    658         } else {
    659             // If we didn't handle it, let preferences handle it.
    660             return super.onPreferenceTreeClick(preference);
    661         }
    662         return true;
    663     }
    664 
    665     /**
    666      * see confirmPatternThenDisableAndClear
    667      */
    668     @Override
    669     public void onActivityResult(int requestCode, int resultCode, Intent data) {
    670         super.onActivityResult(requestCode, resultCode, data);
    671         if (requestCode == CHANGE_TRUST_AGENT_SETTINGS && resultCode == Activity.RESULT_OK) {
    672             if (mTrustAgentClickIntent != null) {
    673                 startActivity(mTrustAgentClickIntent);
    674                 mTrustAgentClickIntent = null;
    675             }
    676             return;
    677         } else if (requestCode == UNIFY_LOCK_CONFIRM_DEVICE_REQUEST
    678                 && resultCode == Activity.RESULT_OK) {
    679             mCurrentDevicePassword =
    680                     data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
    681             launchConfirmProfileLockForUnification();
    682             return;
    683         } else if (requestCode == UNIFY_LOCK_CONFIRM_PROFILE_REQUEST
    684                 && resultCode == Activity.RESULT_OK) {
    685             mCurrentProfilePassword =
    686                     data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
    687             unifyLocks();
    688             return;
    689         } else if (requestCode == UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST
    690                 && resultCode == Activity.RESULT_OK) {
    691             ununifyLocks();
    692             return;
    693         }
    694         createPreferenceHierarchy();
    695     }
    696 
    697     private void launchConfirmDeviceLockForUnification() {
    698         final String title = getActivity().getString(
    699                 R.string.unlock_set_unlock_launch_picker_title);
    700         final ChooseLockSettingsHelper helper =
    701                 new ChooseLockSettingsHelper(getActivity(), this);
    702         if (!helper.launchConfirmationActivity(
    703                 UNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
    704             launchConfirmProfileLockForUnification();
    705         }
    706     }
    707 
    708     private void launchConfirmProfileLockForUnification() {
    709         final String title = getActivity().getString(
    710                 R.string.unlock_set_unlock_launch_picker_title_profile);
    711         final ChooseLockSettingsHelper helper =
    712                 new ChooseLockSettingsHelper(getActivity(), this);
    713         if (!helper.launchConfirmationActivity(
    714                 UNIFY_LOCK_CONFIRM_PROFILE_REQUEST, title, true, mProfileChallengeUserId)) {
    715             unifyLocks();
    716             createPreferenceHierarchy();
    717         }
    718     }
    719 
    720     private void unifyLocks() {
    721         int profileQuality =
    722                 mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId);
    723         if (profileQuality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
    724             mLockPatternUtils.saveLockPattern(
    725                     LockPatternUtils.stringToPattern(mCurrentProfilePassword),
    726                     mCurrentDevicePassword, MY_USER_ID);
    727         } else {
    728             mLockPatternUtils.saveLockPassword(
    729                     mCurrentProfilePassword, mCurrentDevicePassword,
    730                     profileQuality, MY_USER_ID);
    731         }
    732         mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
    733                 mCurrentProfilePassword);
    734         final boolean profilePatternVisibility =
    735                 mLockPatternUtils.isVisiblePatternEnabled(mProfileChallengeUserId);
    736         mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
    737         mCurrentDevicePassword = null;
    738         mCurrentProfilePassword = null;
    739     }
    740 
    741     private void unifyUncompliantLocks() {
    742         mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
    743                 mCurrentProfilePassword);
    744         startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
    745                 R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
    746     }
    747 
    748     private void ununifyLocks() {
    749         Bundle extras = new Bundle();
    750         extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
    751         startFragment(this,
    752                 "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
    753                 R.string.lock_settings_picker_title_profile,
    754                 SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
    755     }
    756 
    757     @Override
    758     public boolean onPreferenceChange(Preference preference, Object value) {
    759         boolean result = true;
    760         final String key = preference.getKey();
    761         final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
    762         if (KEY_VISIBLE_PATTERN_PROFILE.equals(key)) {
    763             if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
    764                     mProfileChallengeUserId)) {
    765                 return false;
    766             }
    767             lockPatternUtils.setVisiblePatternEnabled((Boolean) value, mProfileChallengeUserId);
    768         } else if (KEY_UNIFICATION.equals(key)) {
    769             if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
    770                     mProfileChallengeUserId)) {
    771                 return false;
    772             }
    773             if ((Boolean) value) {
    774                 final boolean compliantForDevice =
    775                         (mLockPatternUtils.getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
    776                                 >= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
    777                         && mLockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
    778                                 mProfileChallengeUserId));
    779                 UnificationConfirmationDialog dialog =
    780                         UnificationConfirmationDialog.newIntance(compliantForDevice);
    781                 dialog.show(getChildFragmentManager(), TAG_UNIFICATION_DIALOG);
    782             } else {
    783                 final String title = getActivity().getString(
    784                         R.string.unlock_set_unlock_launch_picker_title);
    785                 final ChooseLockSettingsHelper helper =
    786                         new ChooseLockSettingsHelper(getActivity(), this);
    787                 if(!helper.launchConfirmationActivity(
    788                         UNUNIFY_LOCK_CONFIRM_DEVICE_REQUEST, title, true, MY_USER_ID)) {
    789                     ununifyLocks();
    790                 }
    791             }
    792         } else if (KEY_SHOW_PASSWORD.equals(key)) {
    793             Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
    794                     ((Boolean) value) ? 1 : 0);
    795             lockPatternUtils.setVisiblePasswordEnabled((Boolean) value, MY_USER_ID);
    796         }
    797         return result;
    798     }
    799 
    800     @Override
    801     protected int getHelpResource() {
    802         return R.string.help_url_security;
    803     }
    804 
    805     /**
    806      * For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
    807      */
    808     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
    809             new SecuritySearchIndexProvider();
    810 
    811     private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider {
    812 
    813         @Override
    814         public List<SearchIndexableResource> getXmlResourcesToIndex(
    815                 Context context, boolean enabled) {
    816             final List<SearchIndexableResource> index = new ArrayList<SearchIndexableResource>();
    817 
    818             final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
    819             final ManagedLockPasswordProvider managedPasswordProvider =
    820                     ManagedLockPasswordProvider.get(context, MY_USER_ID);
    821             final DevicePolicyManager dpm = (DevicePolicyManager)
    822                     context.getSystemService(Context.DEVICE_POLICY_SERVICE);
    823             final UserManager um = UserManager.get(context);
    824             final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
    825 
    826             // To add option for unlock screen, user's password must not be managed and
    827             // must not be unified with managed profile, whose password is managed.
    828             if (!isPasswordManaged(MY_USER_ID, context, dpm)
    829                     && (profileUserId == UserHandle.USER_NULL
    830                             || lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
    831                             || !isPasswordManaged(profileUserId, context, dpm))) {
    832                 // Add options for lock/unlock screen
    833                 final int resId = getResIdForLockUnlockScreen(context, lockPatternUtils,
    834                         managedPasswordProvider, MY_USER_ID);
    835                 index.add(getSearchResource(context, resId));
    836             }
    837 
    838             if (profileUserId != UserHandle.USER_NULL
    839                     && lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)
    840                     && !isPasswordManaged(profileUserId, context, dpm)) {
    841                 index.add(getSearchResource(context, getResIdForLockUnlockScreen(context,
    842                         lockPatternUtils, managedPasswordProvider, profileUserId)));
    843             }
    844 
    845             final SearchIndexableResource sir = getSearchResource(context,
    846                     SecuritySubSettings.getResIdForLockUnlockSubScreen(context, lockPatternUtils,
    847                             managedPasswordProvider));
    848             sir.className = SecuritySubSettings.class.getName();
    849             index.add(sir);
    850 
    851             // Append the rest of the settings
    852             index.add(getSearchResource(context, R.xml.security_settings_misc));
    853 
    854             return index;
    855         }
    856 
    857         private SearchIndexableResource getSearchResource(Context context, int xmlResId) {
    858             final SearchIndexableResource sir = new SearchIndexableResource(context);
    859             sir.xmlResId = xmlResId;
    860             return sir;
    861         }
    862 
    863         private boolean isPasswordManaged(int userId, Context context, DevicePolicyManager dpm) {
    864             final EnforcedAdmin admin = RestrictedLockUtils.checkIfPasswordQualityIsSet(
    865                     context, userId);
    866             return admin != null && dpm.getPasswordQuality(admin.component, userId) ==
    867                     DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
    868         }
    869 
    870         @Override
    871         public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
    872             final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
    873             final Resources res = context.getResources();
    874 
    875             final String screenTitle = res.getString(R.string.security_settings_title);
    876 
    877             SearchIndexableRaw data = new SearchIndexableRaw(context);
    878             data.title = screenTitle;
    879             data.screenTitle = screenTitle;
    880             result.add(data);
    881 
    882             final UserManager um = UserManager.get(context);
    883 
    884             // Fingerprint
    885             final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context);
    886             if (fpm != null && fpm.isHardwareDetected()) {
    887                 // This catches the title which can be overloaded in an overlay
    888                 data = new SearchIndexableRaw(context);
    889                 data.title = res.getString(R.string.security_settings_fingerprint_preference_title);
    890                 data.screenTitle = screenTitle;
    891                 result.add(data);
    892                 // Fallback for when the above doesn't contain "fingerprint"
    893                 data = new SearchIndexableRaw(context);
    894                 data.title = res.getString(R.string.fingerprint_manage_category_title);
    895                 data.screenTitle = screenTitle;
    896                 result.add(data);
    897             }
    898 
    899             final LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
    900             final int profileUserId = Utils.getManagedProfileId(um, MY_USER_ID);
    901             if (profileUserId != UserHandle.USER_NULL
    902                     && lockPatternUtils.isSeparateProfileChallengeAllowed(profileUserId)) {
    903                 if (lockPatternUtils.getKeyguardStoredPasswordQuality(profileUserId)
    904                         >= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
    905                         && lockPatternUtils.isSeparateProfileChallengeAllowedToUnify(
    906                                 profileUserId)) {
    907                     data = new SearchIndexableRaw(context);
    908                     data.title = res.getString(R.string.lock_settings_profile_unification_title);
    909                     data.screenTitle = screenTitle;
    910                     result.add(data);
    911                 }
    912             }
    913 
    914             // Advanced
    915             if (lockPatternUtils.isSecure(MY_USER_ID)) {
    916                 final TrustAgentManager trustAgentManager =
    917                     FeatureFactory.getFactory(context).getSecurityFeatureProvider()
    918                         .getTrustAgentManager();
    919                 final List<TrustAgentComponentInfo> agents =
    920                         getActiveTrustAgents(context, trustAgentManager, lockPatternUtils,
    921                                 context.getSystemService(DevicePolicyManager.class));
    922                 for (int i = 0; i < agents.size(); i++) {
    923                     final TrustAgentComponentInfo agent = agents.get(i);
    924                     data = new SearchIndexableRaw(context);
    925                     data.title = agent.title;
    926                     data.screenTitle = screenTitle;
    927                     result.add(data);
    928                 }
    929             }
    930             return result;
    931         }
    932 
    933         @Override
    934         public List<String> getNonIndexableKeys(Context context) {
    935             final List<String> keys = super.getNonIndexableKeys(context);
    936 
    937             LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
    938 
    939             // Do not display SIM lock for devices without an Icc card
    940             final UserManager um = UserManager.get(context);
    941             final TelephonyManager tm = TelephonyManager.from(context);
    942             if (!um.isAdminUser() || !tm.hasIccCard()) {
    943                 keys.add(KEY_SIM_LOCK);
    944             }
    945 
    946             // TrustAgent settings disappear when the user has no primary security.
    947             if (!lockPatternUtils.isSecure(MY_USER_ID)) {
    948                 keys.add(KEY_TRUST_AGENT);
    949                 keys.add(KEY_MANAGE_TRUST_AGENTS);
    950             }
    951 
    952             if (!(new EnterprisePrivacyPreferenceController(context, null /* lifecycle */))
    953                     .isAvailable()) {
    954                 keys.add(KEY_ENTERPRISE_PRIVACY);
    955             }
    956 
    957             // Duplicate in special app access
    958             keys.add(KEY_MANAGE_DEVICE_ADMIN);
    959             // Duplicates between parent-child
    960             keys.add((new LocationPreferenceController(context)).getPreferenceKey());
    961             keys.add(KEY_ENCRYPTION_AND_CREDENTIALS);
    962             keys.add(KEY_SCREEN_PINNING);
    963             keys.add(KEY_LOCATION_SCANNING);
    964 
    965             return keys;
    966         }
    967     }
    968 
    969     public static class SecuritySubSettings extends SettingsPreferenceFragment
    970             implements OnPreferenceChangeListener, OwnerInfoPreferenceController.OwnerInfoCallback {
    971 
    972         private static final String KEY_VISIBLE_PATTERN = "visiblepattern";
    973         private static final String KEY_LOCK_AFTER_TIMEOUT = "lock_after_timeout";
    974         private static final String KEY_POWER_INSTANTLY_LOCKS = "power_button_instantly_locks";
    975 
    976         // These switch preferences need special handling since they're not all stored in Settings.
    977         private static final String SWITCH_PREFERENCE_KEYS[] = { KEY_LOCK_AFTER_TIMEOUT,
    978                 KEY_VISIBLE_PATTERN, KEY_POWER_INSTANTLY_LOCKS };
    979 
    980         private TimeoutListPreference mLockAfter;
    981         private SwitchPreference mVisiblePattern;
    982         private SwitchPreference mPowerButtonInstantlyLocks;
    983 
    984         private TrustAgentManager mTrustAgentManager;
    985         private LockPatternUtils mLockPatternUtils;
    986         private DevicePolicyManager mDPM;
    987         private OwnerInfoPreferenceController mOwnerInfoPreferenceController;
    988 
    989         @Override
    990         public int getMetricsCategory() {
    991             return MetricsEvent.SECURITY;
    992         }
    993 
    994         @Override
    995         public void onCreate(Bundle icicle) {
    996             super.onCreate(icicle);
    997             SecurityFeatureProvider securityFeatureProvider =
    998                     FeatureFactory.getFactory(getActivity()).getSecurityFeatureProvider();
    999             mTrustAgentManager = securityFeatureProvider.getTrustAgentManager();
   1000             mLockPatternUtils = new LockPatternUtils(getContext());
   1001             mDPM = getContext().getSystemService(DevicePolicyManager.class);
   1002             mOwnerInfoPreferenceController =
   1003                 new OwnerInfoPreferenceController(getContext(), this, null /* lifecycle */);
   1004             createPreferenceHierarchy();
   1005         }
   1006 
   1007         @Override
   1008         public void onResume() {
   1009             super.onResume();
   1010 
   1011             createPreferenceHierarchy();
   1012 
   1013             if (mVisiblePattern != null) {
   1014                 mVisiblePattern.setChecked(mLockPatternUtils.isVisiblePatternEnabled(
   1015                         MY_USER_ID));
   1016             }
   1017             if (mPowerButtonInstantlyLocks != null) {
   1018                 mPowerButtonInstantlyLocks.setChecked(
   1019                         mLockPatternUtils.getPowerButtonInstantlyLocks(MY_USER_ID));
   1020             }
   1021 
   1022             mOwnerInfoPreferenceController.updateSummary();
   1023         }
   1024 
   1025         @Override
   1026         public void onActivityResult(int requestCode, int resultCode, Intent data) {
   1027             super.onActivityResult(requestCode, resultCode, data);
   1028 
   1029             createPreferenceHierarchy();
   1030         }
   1031 
   1032         private void createPreferenceHierarchy() {
   1033             PreferenceScreen root = getPreferenceScreen();
   1034             if (root != null) {
   1035                 root.removeAll();
   1036             }
   1037 
   1038             final int resid = getResIdForLockUnlockSubScreen(getActivity(),
   1039                     new LockPatternUtils(getContext()),
   1040                     ManagedLockPasswordProvider.get(getContext(), MY_USER_ID));
   1041             addPreferencesFromResource(resid);
   1042 
   1043             // lock after preference
   1044             mLockAfter = (TimeoutListPreference) findPreference(KEY_LOCK_AFTER_TIMEOUT);
   1045             if (mLockAfter != null) {
   1046                 setupLockAfterPreference();
   1047                 updateLockAfterPreferenceSummary();
   1048             }
   1049 
   1050             // visible pattern
   1051             mVisiblePattern = (SwitchPreference) findPreference(KEY_VISIBLE_PATTERN);
   1052 
   1053             // lock instantly on power key press
   1054             mPowerButtonInstantlyLocks = (SwitchPreference) findPreference(
   1055                     KEY_POWER_INSTANTLY_LOCKS);
   1056             CharSequence trustAgentLabel = getActiveTrustAgentLabel(getContext(),
   1057                     mTrustAgentManager, mLockPatternUtils, mDPM);
   1058             if (mPowerButtonInstantlyLocks != null && !TextUtils.isEmpty(trustAgentLabel)) {
   1059                 mPowerButtonInstantlyLocks.setSummary(getString(
   1060                         R.string.lockpattern_settings_power_button_instantly_locks_summary,
   1061                         trustAgentLabel));
   1062             }
   1063 
   1064             mOwnerInfoPreferenceController.displayPreference(getPreferenceScreen());
   1065             mOwnerInfoPreferenceController.updateEnableState();
   1066 
   1067             for (int i = 0; i < SWITCH_PREFERENCE_KEYS.length; i++) {
   1068                 final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]);
   1069                 if (pref != null) pref.setOnPreferenceChangeListener(this);
   1070             }
   1071         }
   1072 
   1073         private void setupLockAfterPreference() {
   1074             // Compatible with pre-Froyo
   1075             long currentTimeout = Settings.Secure.getLong(getContentResolver(),
   1076                     Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
   1077             mLockAfter.setValue(String.valueOf(currentTimeout));
   1078             mLockAfter.setOnPreferenceChangeListener(this);
   1079             if (mDPM != null) {
   1080                 final EnforcedAdmin admin = RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(
   1081                         getActivity());
   1082                 final long adminTimeout = mDPM
   1083                         .getMaximumTimeToLockForUserAndProfiles(UserHandle.myUserId());
   1084                 final long displayTimeout = Math.max(0,
   1085                         Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0));
   1086                 // This setting is a slave to display timeout when a device policy is enforced.
   1087                 // As such, maxLockTimeout = adminTimeout - displayTimeout.
   1088                 // If there isn't enough time, shows "immediately" setting.
   1089                 final long maxTimeout = Math.max(0, adminTimeout - displayTimeout);
   1090                 mLockAfter.removeUnusableTimeouts(maxTimeout, admin);
   1091             }
   1092         }
   1093 
   1094         private void updateLockAfterPreferenceSummary() {
   1095             final String summary;
   1096             if (mLockAfter.isDisabledByAdmin()) {
   1097                 summary = getString(R.string.disabled_by_policy_title);
   1098             } else {
   1099                 // Update summary message with current value
   1100                 long currentTimeout = Settings.Secure.getLong(getContentResolver(),
   1101                         Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
   1102                 final CharSequence[] entries = mLockAfter.getEntries();
   1103                 final CharSequence[] values = mLockAfter.getEntryValues();
   1104                 int best = 0;
   1105                 for (int i = 0; i < values.length; i++) {
   1106                     long timeout = Long.valueOf(values[i].toString());
   1107                     if (currentTimeout >= timeout) {
   1108                         best = i;
   1109                     }
   1110                 }
   1111 
   1112                 CharSequence trustAgentLabel = getActiveTrustAgentLabel(getContext(),
   1113                         mTrustAgentManager, mLockPatternUtils, mDPM);
   1114                 if (!TextUtils.isEmpty(trustAgentLabel)) {
   1115                     if (Long.valueOf(values[best].toString()) == 0) {
   1116                         summary = getString(R.string.lock_immediately_summary_with_exception,
   1117                                 trustAgentLabel);
   1118                     } else {
   1119                         summary = getString(R.string.lock_after_timeout_summary_with_exception,
   1120                                 entries[best], trustAgentLabel);
   1121                     }
   1122                 } else {
   1123                     summary = getString(R.string.lock_after_timeout_summary, entries[best]);
   1124                 }
   1125             }
   1126             mLockAfter.setSummary(summary);
   1127         }
   1128 
   1129         @Override
   1130         public void onOwnerInfoUpdated() {
   1131             mOwnerInfoPreferenceController.updateSummary();
   1132         }
   1133 
   1134         private static int getResIdForLockUnlockSubScreen(Context context,
   1135                 LockPatternUtils lockPatternUtils,
   1136                 ManagedLockPasswordProvider managedPasswordProvider) {
   1137             if (lockPatternUtils.isSecure(MY_USER_ID)) {
   1138                 switch (lockPatternUtils.getKeyguardStoredPasswordQuality(MY_USER_ID)) {
   1139                     case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
   1140                         return R.xml.security_settings_pattern_sub;
   1141                     case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
   1142                     case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
   1143                         return R.xml.security_settings_pin_sub;
   1144                     case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
   1145                     case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
   1146                     case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
   1147                         return R.xml.security_settings_password_sub;
   1148                     case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
   1149                         return managedPasswordProvider.getResIdForLockUnlockSubScreen();
   1150                 }
   1151             } else if (!lockPatternUtils.isLockScreenDisabled(MY_USER_ID)) {
   1152                 return R.xml.security_settings_slide_sub;
   1153             }
   1154             return 0;
   1155         }
   1156 
   1157         @Override
   1158         public boolean onPreferenceChange(Preference preference, Object value) {
   1159             String key = preference.getKey();
   1160             if (KEY_POWER_INSTANTLY_LOCKS.equals(key)) {
   1161                 mLockPatternUtils.setPowerButtonInstantlyLocks((Boolean) value, MY_USER_ID);
   1162             } else if (KEY_LOCK_AFTER_TIMEOUT.equals(key)) {
   1163                 int timeout = Integer.parseInt((String) value);
   1164                 try {
   1165                     Settings.Secure.putInt(getContentResolver(),
   1166                             Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout);
   1167                 } catch (NumberFormatException e) {
   1168                     Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e);
   1169                 }
   1170                 setupLockAfterPreference();
   1171                 updateLockAfterPreferenceSummary();
   1172             } else if (KEY_VISIBLE_PATTERN.equals(key)) {
   1173                 mLockPatternUtils.setVisiblePatternEnabled((Boolean) value, MY_USER_ID);
   1174             }
   1175             return true;
   1176         }
   1177     }
   1178 
   1179     public static class UnificationConfirmationDialog extends InstrumentedDialogFragment {
   1180         private static final String EXTRA_COMPLIANT = "compliant";
   1181 
   1182         public static UnificationConfirmationDialog newIntance(boolean compliant) {
   1183             UnificationConfirmationDialog dialog = new UnificationConfirmationDialog();
   1184             Bundle args = new Bundle();
   1185             args.putBoolean(EXTRA_COMPLIANT, compliant);
   1186             dialog.setArguments(args);
   1187             return dialog;
   1188         }
   1189 
   1190         @Override
   1191         public void show(FragmentManager manager, String tag) {
   1192             if (manager.findFragmentByTag(tag) == null) {
   1193                 // Prevent opening multiple dialogs if tapped on button quickly
   1194                 super.show(manager, tag);
   1195             }
   1196         }
   1197 
   1198         @Override
   1199         public Dialog onCreateDialog(Bundle savedInstanceState) {
   1200             final SecuritySettings parentFragment = ((SecuritySettings) getParentFragment());
   1201             final boolean compliant = getArguments().getBoolean(EXTRA_COMPLIANT);
   1202             return new AlertDialog.Builder(getActivity())
   1203                     .setTitle(R.string.lock_settings_profile_unification_dialog_title)
   1204                     .setMessage(compliant ? R.string.lock_settings_profile_unification_dialog_body
   1205                             : R.string.lock_settings_profile_unification_dialog_uncompliant_body)
   1206                     .setPositiveButton(
   1207                             compliant ? R.string.lock_settings_profile_unification_dialog_confirm
   1208                             : R.string.lock_settings_profile_unification_dialog_uncompliant_confirm,
   1209                             new DialogInterface.OnClickListener() {
   1210                                 @Override
   1211                                 public void onClick(DialogInterface dialog, int whichButton) {
   1212                                     if (compliant) {
   1213                                         parentFragment.launchConfirmDeviceLockForUnification();
   1214                                     }    else {
   1215                                         parentFragment.unifyUncompliantLocks();
   1216                                     }
   1217                                 }
   1218                             }
   1219                     )
   1220                     .setNegativeButton(R.string.cancel, null)
   1221                     .create();
   1222         }
   1223 
   1224         @Override
   1225         public void onDismiss(DialogInterface dialog) {
   1226             super.onDismiss(dialog);
   1227             ((SecuritySettings) getParentFragment()).updateUnificationPreference();
   1228         }
   1229 
   1230         @Override
   1231         public int getMetricsCategory() {
   1232             return MetricsEvent.DIALOG_UNIFICATION_CONFIRMATION;
   1233         }
   1234     }
   1235 
   1236     static class SummaryProvider implements SummaryLoader.SummaryProvider {
   1237 
   1238         private final Context mContext;
   1239         private final SummaryLoader mSummaryLoader;
   1240 
   1241         public SummaryProvider(Context context, SummaryLoader summaryLoader) {
   1242             mContext = context;
   1243             mSummaryLoader = summaryLoader;
   1244         }
   1245 
   1246         @Override
   1247         public void setListening(boolean listening) {
   1248             if (listening) {
   1249                 final FingerprintManager fpm =
   1250                     Utils.getFingerprintManagerOrNull(mContext);
   1251                 if (fpm != null && fpm.isHardwareDetected()) {
   1252                     mSummaryLoader.setSummary(this,
   1253                         mContext.getString(R.string.security_dashboard_summary));
   1254                 } else {
   1255                     mSummaryLoader.setSummary(this, mContext.getString(
   1256                         R.string.security_dashboard_summary_no_fingerprint));
   1257                 }
   1258             }
   1259         }
   1260     }
   1261 
   1262     public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
   1263             new SummaryLoader.SummaryProviderFactory() {
   1264         @Override
   1265         public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
   1266                 SummaryLoader summaryLoader) {
   1267             return new SummaryProvider(activity, summaryLoader);
   1268         }
   1269     };
   1270 
   1271 }
   1272