Home | History | Annotate | Download | only in screenlock
      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 
     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