• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.security;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.content.Context;
21 import android.os.UserHandle;
22 import android.os.UserManager;
23 import android.os.storage.StorageManager;
24 import android.support.v7.preference.Preference;
25 import android.support.v7.preference.PreferenceScreen;
26 import android.text.TextUtils;
27 
28 import com.android.internal.widget.LockPatternUtils;
29 import com.android.settings.R;
30 import com.android.settings.Utils;
31 import com.android.settings.core.PreferenceControllerMixin;
32 import com.android.settings.core.SubSettingLauncher;
33 import com.android.settings.overlay.FeatureFactory;
34 import com.android.settings.password.ChooseLockGeneric;
35 import com.android.settings.security.screenlock.ScreenLockSettings;
36 import com.android.settings.widget.GearPreference;
37 import com.android.settingslib.RestrictedLockUtils;
38 import com.android.settingslib.RestrictedPreference;
39 import com.android.settingslib.core.AbstractPreferenceController;
40 
41 public class ChangeScreenLockPreferenceController extends AbstractPreferenceController implements
42         PreferenceControllerMixin, GearPreference.OnGearClickListener {
43 
44     private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
45 
46     protected final DevicePolicyManager mDPM;
47     protected final SecuritySettings mHost;
48     protected final UserManager mUm;
49     protected final LockPatternUtils mLockPatternUtils;
50 
51     protected final int mUserId = UserHandle.myUserId();
52     protected final int mProfileChallengeUserId;
53 
54     protected RestrictedPreference mPreference;
55 
ChangeScreenLockPreferenceController(Context context, SecuritySettings host)56     public ChangeScreenLockPreferenceController(Context context, SecuritySettings host) {
57         super(context);
58         mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
59         mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
60         mLockPatternUtils = FeatureFactory.getFactory(context)
61                 .getSecurityFeatureProvider()
62                 .getLockPatternUtils(context);
63         mHost = host;
64         mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
65     }
66 
67     @Override
isAvailable()68     public boolean isAvailable() {
69         return mContext.getResources().getBoolean(R.bool.config_show_unlock_set_or_change);
70     }
71 
72     @Override
getPreferenceKey()73     public String getPreferenceKey() {
74         return KEY_UNLOCK_SET_OR_CHANGE;
75     }
76 
77     @Override
displayPreference(PreferenceScreen screen)78     public void displayPreference(PreferenceScreen screen) {
79         super.displayPreference(screen);
80         mPreference = (RestrictedPreference) screen.findPreference(getPreferenceKey());
81     }
82 
83     @Override
updateState(Preference preference)84     public void updateState(Preference preference) {
85         if (mPreference != null && mPreference instanceof GearPreference) {
86             if (mLockPatternUtils.isSecure(mUserId)
87                     || !mLockPatternUtils.isLockScreenDisabled(mUserId)) {
88                 ((GearPreference) mPreference).setOnGearClickListener(this);
89             } else {
90                 ((GearPreference) mPreference).setOnGearClickListener(null);
91             }
92         }
93 
94         updateSummary(preference, mUserId);
95         disableIfPasswordQualityManaged(mUserId);
96         if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)) {
97             // PO may disallow to change password for the profile, but screen lock and managed
98             // profile's lock is the same. Disable main "Screen lock" menu.
99             disableIfPasswordQualityManaged(mProfileChallengeUserId);
100         }
101     }
102 
103     @Override
onGearClick(GearPreference p)104     public void onGearClick(GearPreference p) {
105         if (TextUtils.equals(p.getKey(), getPreferenceKey())) {
106             new SubSettingLauncher(mContext)
107                     .setDestination(ScreenLockSettings.class.getName())
108                     .setSourceMetricsCategory(mHost.getMetricsCategory())
109                     .launch();
110         }
111     }
112 
113     @Override
handlePreferenceTreeClick(Preference preference)114     public boolean handlePreferenceTreeClick(Preference preference) {
115         if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
116             return super.handlePreferenceTreeClick(preference);
117         }
118         // TODO(b/35930129): Remove once existing password can be passed into vold directly.
119         // Currently we need this logic to ensure that the QUIET_MODE is off for any work
120         // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
121         // able to complete the operation due to the lack of (old) encryption key.
122         if (mProfileChallengeUserId != UserHandle.USER_NULL
123                 && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
124                 && StorageManager.isFileEncryptedNativeOnly()) {
125             if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
126                 return false;
127             }
128         }
129 
130         new SubSettingLauncher(mContext)
131                 .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName())
132                 .setTitle(R.string.lock_settings_picker_title)
133                 .setSourceMetricsCategory(mHost.getMetricsCategory())
134                 .launch();
135         return true;
136     }
137 
updateSummary(Preference preference, int userId)138     protected void updateSummary(Preference preference, int userId) {
139         if (!mLockPatternUtils.isSecure(userId)) {
140             if (userId == mProfileChallengeUserId
141                     || mLockPatternUtils.isLockScreenDisabled(userId)) {
142                 preference.setSummary(R.string.unlock_set_unlock_mode_off);
143             } else {
144                 preference.setSummary(R.string.unlock_set_unlock_mode_none);
145             }
146         } else {
147             switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
148                 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
149                     preference.setSummary(R.string.unlock_set_unlock_mode_pattern);
150                     break;
151                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
152                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
153                     preference.setSummary(R.string.unlock_set_unlock_mode_pin);
154                     break;
155                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
156                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
157                 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
158                 case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
159                     preference.setSummary(R.string.unlock_set_unlock_mode_password);
160                     break;
161             }
162         }
163         mPreference.setEnabled(true);
164     }
165 
166     /**
167      * Sets the preference as disabled by admin if PASSWORD_QUALITY_MANAGED is set.
168      * The preference must be a RestrictedPreference.
169      * <p/>
170      * DO or PO installed in the user may disallow to change password.
171      */
disableIfPasswordQualityManaged(int userId)172     void disableIfPasswordQualityManaged(int userId) {
173         final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtils
174                 .checkIfPasswordQualityIsSet(mContext, userId);
175         final DevicePolicyManager dpm = (DevicePolicyManager) mContext
176                 .getSystemService(Context.DEVICE_POLICY_SERVICE);
177         if (admin != null && dpm.getPasswordQuality(admin.component, userId)
178                 == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
179             mPreference.setDisabledByAdmin(admin);
180         }
181     }
182 }
183