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
getMetricsCategory()176     public int getMetricsCategory() {
177         return MetricsEvent.SECURITY;
178     }
179 
180     @Override
onCreate(Bundle savedInstanceState)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 
getResIdForLockUnlockScreen(Context context, LockPatternUtils lockPatternUtils, ManagedLockPasswordProvider managedPasswordProvider, int userId)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      */
createPreferenceHierarchy()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
initTrustAgentPreference(PreferenceScreen root, int numberOfTrustAgent)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
setLockscreenPreferencesSummary(PreferenceGroup group)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      */
disableIfPasswordQualityManaged(String preferenceKey, int userId)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 
maybeAddFingerprintPreference(PreferenceGroup securityCategory, int userId)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
addTrustAgentSettings(PreferenceGroup securityCategory)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      */
isSimIccReady()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      */
isSimReady()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 
getActiveTrustAgents(Context context, TrustAgentManager trustAgentManager, LockPatternUtils utils, DevicePolicyManager dpm)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 
getActiveTrustAgentLabel(Context context, TrustAgentManager trustAgentManager, LockPatternUtils utils, DevicePolicyManager dpm)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
onGearClick(GearPreference p)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
onSaveInstanceState(Bundle outState)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
onResume()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 
updateUnificationPreference()612     private void updateUnificationPreference() {
613         if (mUnifyProfile != null) {
614             mUnifyProfile.setChecked(!mLockPatternUtils.isSeparateProfileChallengeEnabled(
615                     mProfileChallengeUserId));
616         }
617     }
618 
619     @Override
onPreferenceTreeClick(Preference preference)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
onActivityResult(int requestCode, int resultCode, Intent data)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 
launchConfirmDeviceLockForUnification()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 
launchConfirmProfileLockForUnification()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 
unifyLocks()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 
unifyUncompliantLocks()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 
ununifyLocks()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
onPreferenceChange(Preference preference, Object value)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
getHelpResource()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
getXmlResourcesToIndex( Context context, boolean enabled)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 
getSearchResource(Context context, int xmlResId)857         private SearchIndexableResource getSearchResource(Context context, int xmlResId) {
858             final SearchIndexableResource sir = new SearchIndexableResource(context);
859             sir.xmlResId = xmlResId;
860             return sir;
861         }
862 
isPasswordManaged(int userId, Context context, DevicePolicyManager dpm)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
getRawDataToIndex(Context context, boolean enabled)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
getNonIndexableKeys(Context context)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
getMetricsCategory()990         public int getMetricsCategory() {
991             return MetricsEvent.SECURITY;
992         }
993 
994         @Override
onCreate(Bundle icicle)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
onResume()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
onActivityResult(int requestCode, int resultCode, Intent data)1026         public void onActivityResult(int requestCode, int resultCode, Intent data) {
1027             super.onActivityResult(requestCode, resultCode, data);
1028 
1029             createPreferenceHierarchy();
1030         }
1031 
createPreferenceHierarchy()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 
setupLockAfterPreference()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 
updateLockAfterPreferenceSummary()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
onOwnerInfoUpdated()1130         public void onOwnerInfoUpdated() {
1131             mOwnerInfoPreferenceController.updateSummary();
1132         }
1133 
getResIdForLockUnlockSubScreen(Context context, LockPatternUtils lockPatternUtils, ManagedLockPasswordProvider managedPasswordProvider)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
onPreferenceChange(Preference preference, Object value)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 
newIntance(boolean compliant)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
show(FragmentManager manager, String tag)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
onCreateDialog(Bundle savedInstanceState)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