• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.screenlock;
18 
19 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
20 
21 import android.app.admin.DevicePolicyManager;
22 import android.content.Context;
23 import android.os.UserHandle;
24 import android.provider.Settings;
25 import android.support.v7.preference.Preference;
26 import android.text.TextUtils;
27 import android.util.Log;
28 
29 import com.android.internal.widget.LockPatternUtils;
30 import com.android.settings.R;
31 import com.android.settings.TimeoutListPreference;
32 import com.android.settings.core.PreferenceControllerMixin;
33 import com.android.settings.overlay.FeatureFactory;
34 import com.android.settings.security.trustagent.TrustAgentManager;
35 import com.android.settingslib.RestrictedLockUtils;
36 import com.android.settingslib.core.AbstractPreferenceController;
37 
38 public class LockAfterTimeoutPreferenceController extends AbstractPreferenceController
39         implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
40 
41     private static final String KEY_LOCK_AFTER_TIMEOUT = "lock_after_timeout";
42 
43     private final int mUserId;
44     private final LockPatternUtils mLockPatternUtils;
45     private final TrustAgentManager mTrustAgentManager;
46     private final DevicePolicyManager mDPM;
47 
LockAfterTimeoutPreferenceController(Context context, int userId, LockPatternUtils lockPatternUtils)48     public LockAfterTimeoutPreferenceController(Context context, int userId,
49             LockPatternUtils lockPatternUtils) {
50         super(context);
51         mUserId = userId;
52         mLockPatternUtils = lockPatternUtils;
53         mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
54         mTrustAgentManager = FeatureFactory.getFactory(context)
55                 .getSecurityFeatureProvider().getTrustAgentManager();
56     }
57 
58     @Override
isAvailable()59     public boolean isAvailable() {
60         if (!mLockPatternUtils.isSecure(mUserId)) {
61             return false;
62         }
63         switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)) {
64             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
65             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
66             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
67             case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
68             case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
69             case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
70             case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
71                 return true;
72             default:
73                 return false;
74         }
75     }
76 
77     @Override
getPreferenceKey()78     public String getPreferenceKey() {
79         return KEY_LOCK_AFTER_TIMEOUT;
80     }
81 
82     @Override
updateState(Preference preference)83     public void updateState(Preference preference) {
84         setupLockAfterPreference((TimeoutListPreference) preference);
85         updateLockAfterPreferenceSummary((TimeoutListPreference) preference);
86     }
87 
88     @Override
onPreferenceChange(Preference preference, Object newValue)89     public boolean onPreferenceChange(Preference preference, Object newValue) {
90         try {
91             final int timeout = Integer.parseInt((String) newValue);
92             Settings.Secure.putInt(mContext.getContentResolver(),
93                     Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, timeout);
94             updateState(preference);
95         } catch (NumberFormatException e) {
96             Log.e(TAG, "could not persist lockAfter timeout setting", e);
97         }
98         return true;
99     }
100 
setupLockAfterPreference(TimeoutListPreference preference)101     private void setupLockAfterPreference(TimeoutListPreference preference) {
102         // Compatible with pre-Froyo
103         long currentTimeout = Settings.Secure.getLong(mContext.getContentResolver(),
104                 Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
105         preference.setValue(String.valueOf(currentTimeout));
106         if (mDPM != null) {
107             final RestrictedLockUtils.EnforcedAdmin admin =
108                     RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
109             final long adminTimeout =
110                     mDPM.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
111             final long displayTimeout = Math.max(0,
112                     Settings.System.getInt(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, 0));
113             // This setting is a slave to display timeout when a device policy is enforced.
114             // As such, maxLockTimeout = adminTimeout - displayTimeout.
115             // If there isn't enough time, shows "immediately" setting.
116             final long maxTimeout = Math.max(0, adminTimeout - displayTimeout);
117             preference.removeUnusableTimeouts(maxTimeout, admin);
118         }
119     }
120 
updateLockAfterPreferenceSummary(TimeoutListPreference preference)121     private void updateLockAfterPreferenceSummary(TimeoutListPreference preference) {
122         final CharSequence summary;
123         if (preference.isDisabledByAdmin()) {
124             summary = mContext.getText(R.string.disabled_by_policy_title);
125         } else {
126             // Update summary message with current value
127             long currentTimeout = Settings.Secure.getLong(mContext.getContentResolver(),
128                     Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
129             final CharSequence[] entries = preference.getEntries();
130             final CharSequence[] values = preference.getEntryValues();
131             int best = 0;
132             for (int i = 0; i < values.length; i++) {
133                 long timeout = Long.valueOf(values[i].toString());
134                 if (currentTimeout >= timeout) {
135                     best = i;
136                 }
137             }
138 
139             final CharSequence trustAgentLabel = mTrustAgentManager
140                     .getActiveTrustAgentLabel(mContext, mLockPatternUtils);
141             if (!TextUtils.isEmpty(trustAgentLabel)) {
142                 if (Long.valueOf(values[best].toString()) == 0) {
143                     summary = mContext.getString(R.string.lock_immediately_summary_with_exception,
144                             trustAgentLabel);
145                 } else {
146                     summary = mContext.getString(R.string.lock_after_timeout_summary_with_exception,
147                             entries[best], trustAgentLabel);
148                 }
149             } else {
150                 summary = mContext.getString(R.string.lock_after_timeout_summary, entries[best]);
151             }
152         }
153         preference.setSummary(summary);
154     }
155 }
156