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 17package com.android.settings.security.screenlock; 18 19import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; 20 21import android.app.admin.DevicePolicyManager; 22import android.content.Context; 23import android.os.UserHandle; 24import android.provider.Settings; 25import android.support.v7.preference.Preference; 26import android.text.TextUtils; 27import android.util.Log; 28 29import com.android.internal.widget.LockPatternUtils; 30import com.android.settings.R; 31import com.android.settings.TimeoutListPreference; 32import com.android.settings.core.PreferenceControllerMixin; 33import com.android.settings.overlay.FeatureFactory; 34import com.android.settings.security.trustagent.TrustAgentManager; 35import com.android.settingslib.RestrictedLockUtils; 36import com.android.settingslib.core.AbstractPreferenceController; 37 38public 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 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 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 78 public String getPreferenceKey() { 79 return KEY_LOCK_AFTER_TIMEOUT; 80 } 81 82 @Override 83 public void updateState(Preference preference) { 84 setupLockAfterPreference((TimeoutListPreference) preference); 85 updateLockAfterPreferenceSummary((TimeoutListPreference) preference); 86 } 87 88 @Override 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 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 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