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.password; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.Context; 21 import android.os.UserHandle; 22 import android.support.annotation.NonNull; 23 import android.support.annotation.VisibleForTesting; 24 25 import com.android.settings.R; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 30 /** 31 * A controller for ChooseLockGeneric, and other similar classes which shows a list of possible 32 * screen locks for the user to choose from. 33 */ 34 public class ChooseLockGenericController { 35 36 private final Context mContext; 37 private final int mUserId; 38 private ManagedLockPasswordProvider mManagedPasswordProvider; 39 private DevicePolicyManager mDpm; 40 41 public ChooseLockGenericController(Context context, int userId) { 42 this( 43 context, 44 userId, 45 context.getSystemService(DevicePolicyManager.class), 46 ManagedLockPasswordProvider.get(context, userId)); 47 } 48 49 @VisibleForTesting 50 ChooseLockGenericController( 51 Context context, 52 int userId, 53 DevicePolicyManager dpm, 54 ManagedLockPasswordProvider managedLockPasswordProvider) { 55 mContext = context; 56 mUserId = userId; 57 mManagedPasswordProvider = managedLockPasswordProvider; 58 mDpm = dpm; 59 } 60 61 /** 62 * @return The higher quality of either the specified {@code quality} or the quality required 63 * by {@link DevicePolicyManager#getPasswordQuality}. 64 */ 65 public int upgradeQuality(int quality) { 66 // Compare min allowed password quality 67 return Math.max(quality, mDpm.getPasswordQuality(null, mUserId)); 68 } 69 70 /** 71 * Whether the given screen lock type should be visible in the given context. 72 */ 73 public boolean isScreenLockVisible(ScreenLockType type) { 74 switch (type) { 75 case NONE: 76 return !mContext.getResources().getBoolean(R.bool.config_hide_none_security_option); 77 case SWIPE: 78 return !mContext.getResources().getBoolean(R.bool.config_hide_swipe_security_option) 79 // Swipe doesn't make sense for profiles. 80 && mUserId == UserHandle.myUserId(); 81 case MANAGED: 82 return mManagedPasswordProvider.isManagedPasswordChoosable(); 83 } 84 return true; 85 } 86 87 /** 88 * Whether screen lock with {@code type} should be enabled. 89 * 90 * @param type The screen lock type. 91 * @param quality The minimum required quality. This can either be requirement by device policy 92 * manager or because some flow only makes sense with secure lock screens. 93 */ 94 public boolean isScreenLockEnabled(ScreenLockType type, int quality) { 95 return type.maxQuality >= quality; 96 } 97 98 /** 99 * Whether screen lock with {@code type} is disabled by device policy admin. 100 * 101 * @param type The screen lock type. 102 * @param adminEnforcedQuality The minimum quality that the admin enforces. 103 */ 104 public boolean isScreenLockDisabledByAdmin(ScreenLockType type, int adminEnforcedQuality) { 105 boolean disabledByAdmin = type.maxQuality < adminEnforcedQuality; 106 if (type == ScreenLockType.MANAGED) { 107 disabledByAdmin = disabledByAdmin 108 || !mManagedPasswordProvider.isManagedPasswordChoosable(); 109 } 110 return disabledByAdmin; 111 } 112 113 /** 114 * User friendly title for the given screen lock type. 115 */ 116 public CharSequence getTitle(ScreenLockType type) { 117 switch (type) { 118 case NONE: 119 return mContext.getText(R.string.unlock_set_unlock_off_title); 120 case SWIPE: 121 return mContext.getText(R.string.unlock_set_unlock_none_title); 122 case PATTERN: 123 return mContext.getText(R.string.unlock_set_unlock_pattern_title); 124 case PIN: 125 return mContext.getText(R.string.unlock_set_unlock_pin_title); 126 case PASSWORD: 127 return mContext.getText(R.string.unlock_set_unlock_password_title); 128 case MANAGED: 129 return mManagedPasswordProvider.getPickerOptionTitle(false); 130 } 131 return null; 132 } 133 134 /** 135 * Gets a list of screen locks that should be visible for the given quality. The returned list 136 * is ordered in the natural order of the enum (the order those enums were defined). 137 * 138 * @param quality The minimum quality required in the context of the current flow. This should 139 * be one of the constants defined in 140 * {@code DevicePolicyManager#PASSWORD_QUALITY_*}. 141 * @param includeDisabled Whether to include screen locks disabled by {@code quality} 142 * requirements in the returned list. 143 */ 144 @NonNull 145 public List<ScreenLockType> getVisibleScreenLockTypes(int quality, boolean includeDisabled) { 146 int upgradedQuality = upgradeQuality(quality); 147 List<ScreenLockType> locks = new ArrayList<>(); 148 // EnumSet's iterator guarantees the natural order of the enums 149 for (ScreenLockType lock : ScreenLockType.values()) { 150 if (isScreenLockVisible(lock)) { 151 if (includeDisabled || isScreenLockEnabled(lock, upgradedQuality)) { 152 locks.add(lock); 153 } 154 } 155 } 156 return locks; 157 } 158 } 159