1 /* 2 * Copyright (C) 2022 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.content.Intent; 22 import android.os.UserHandle; 23 import android.os.UserManager; 24 import android.os.storage.StorageManager; 25 26 import androidx.annotation.StringRes; 27 28 import com.android.internal.app.UnlaunchableAppActivity; 29 import com.android.internal.widget.LockPatternUtils; 30 import com.android.settings.R; 31 import com.android.settings.Utils; 32 import com.android.settings.core.SubSettingLauncher; 33 import com.android.settings.overlay.FeatureFactory; 34 import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment; 35 import com.android.settings.security.screenlock.ScreenLockSettings; 36 import com.android.settingslib.RestrictedLockUtils; 37 import com.android.settingslib.transition.SettingsTransitionHelper; 38 39 /** 40 * Utilities for screen lock details shared between Security Settings and Safety Center. 41 */ 42 public class ScreenLockPreferenceDetailsUtils { 43 44 private final int mUserId = UserHandle.myUserId(); 45 private final Context mContext; 46 private final LockPatternUtils mLockPatternUtils; 47 private final int mProfileChallengeUserId; 48 private final UserManager mUm; 49 ScreenLockPreferenceDetailsUtils(Context context)50 public ScreenLockPreferenceDetailsUtils(Context context) { 51 mContext = context; 52 mUm = context.getSystemService(UserManager.class); 53 mLockPatternUtils = FeatureFactory.getFeatureFactory() 54 .getSecurityFeatureProvider() 55 .getLockPatternUtils(context); 56 mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId); 57 } 58 59 /** 60 * Returns whether the screen lock settings entity should be shown. 61 */ isAvailable()62 public boolean isAvailable() { 63 return mContext.getResources().getBoolean(R.bool.config_show_unlock_set_or_change); 64 } 65 66 /** 67 * Returns the summary of screen lock settings entity. 68 */ getSummary(int userId)69 public String getSummary(int userId) { 70 final Integer summaryResId = getSummaryResId(userId); 71 return summaryResId != null ? mContext.getResources().getString(summaryResId) : null; 72 } 73 74 /** 75 * Returns whether the password quality is managed by device admin. 76 */ isPasswordQualityManaged(int userId, RestrictedLockUtils.EnforcedAdmin admin)77 public boolean isPasswordQualityManaged(int userId, RestrictedLockUtils.EnforcedAdmin admin) { 78 final DevicePolicyManager dpm = (DevicePolicyManager) mContext 79 .getSystemService(Context.DEVICE_POLICY_SERVICE); 80 return admin != null && dpm.getPasswordQuality(admin.component, userId) 81 == DevicePolicyManager.PASSWORD_QUALITY_MANAGED; 82 } 83 84 /** 85 * Returns whether the lock pattern is secure. 86 */ isLockPatternSecure()87 public boolean isLockPatternSecure() { 88 return mLockPatternUtils.isSecure(mUserId); 89 } 90 91 /** 92 * Returns whether the Gear Menu should be shown. 93 */ shouldShowGearMenu()94 public boolean shouldShowGearMenu() { 95 return isLockPatternSecure(); 96 } 97 98 /** 99 * Launches the {@link ScreenLockSettings}. 100 */ openScreenLockSettings(int sourceMetricsCategory)101 public void openScreenLockSettings(int sourceMetricsCategory) { 102 mContext.startActivity(getLaunchScreenLockSettingsIntent(sourceMetricsCategory)); 103 } 104 105 /** 106 * Returns {@link Intent} to launch the {@link ScreenLockSettings}. 107 */ getLaunchScreenLockSettingsIntent(int sourceMetricsCategory)108 public Intent getLaunchScreenLockSettingsIntent(int sourceMetricsCategory) { 109 return new SubSettingLauncher(mContext) 110 .setDestination(ScreenLockSettings.class.getName()) 111 .setSourceMetricsCategory(sourceMetricsCategory) 112 .toIntent(); 113 } 114 115 /** 116 * Tries to launch the {@link ChooseLockGenericFragment} if Quiet Mode is not enabled 117 * for managed profile, otherwise shows a dialog to disable the Quiet Mode. 118 * 119 * @return true if the {@link ChooseLockGenericFragment} is launching. 120 */ openChooseLockGenericFragment(int sourceMetricsCategory)121 public boolean openChooseLockGenericFragment(int sourceMetricsCategory) { 122 final Intent quietModeDialogIntent = getQuietModeDialogIntent(); 123 if (quietModeDialogIntent != null) { 124 mContext.startActivity(quietModeDialogIntent); 125 return false; 126 } 127 mContext.startActivity(getChooseLockGenericFragmentIntent(sourceMetricsCategory)); 128 return true; 129 } 130 131 /** 132 * Returns {@link Intent} to launch an appropriate Settings screen. 133 * 134 * <p>If Quiet Mode is enabled for managed profile, returns {@link Intent} to launch a dialog 135 * to disable the Quiet Mode, otherwise returns {@link Intent} to launch 136 * {@link ChooseLockGenericFragment}. 137 */ getLaunchChooseLockGenericFragmentIntent(int sourceMetricsCategory)138 public Intent getLaunchChooseLockGenericFragmentIntent(int sourceMetricsCategory) { 139 final Intent quietModeDialogIntent = getQuietModeDialogIntent(); 140 return quietModeDialogIntent != null ? quietModeDialogIntent 141 : getChooseLockGenericFragmentIntent(sourceMetricsCategory); 142 } 143 getQuietModeDialogIntent()144 private Intent getQuietModeDialogIntent() { 145 // TODO(b/35930129): Remove once existing password can be passed into vold directly. 146 // Currently we need this logic to ensure that the QUIET_MODE is off for any work 147 // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be 148 // able to complete the operation due to the lack of (old) encryption key. 149 if (mProfileChallengeUserId != UserHandle.USER_NULL 150 && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId) 151 && StorageManager.isFileEncrypted()) { 152 if (mUm.isQuietModeEnabled(UserHandle.of(mProfileChallengeUserId))) { 153 return UnlaunchableAppActivity.createInQuietModeDialogIntent( 154 mProfileChallengeUserId); 155 } 156 } 157 return null; 158 } 159 getChooseLockGenericFragmentIntent(int sourceMetricsCategory)160 private Intent getChooseLockGenericFragmentIntent(int sourceMetricsCategory) { 161 return new SubSettingLauncher(mContext) 162 .setDestination(ChooseLockGenericFragment.class.getName()) 163 .setSourceMetricsCategory(sourceMetricsCategory) 164 .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE) 165 .toIntent(); 166 } 167 168 @StringRes getSummaryResId(int userId)169 private Integer getSummaryResId(int userId) { 170 if (!mLockPatternUtils.isSecure(userId)) { 171 if (userId == mProfileChallengeUserId 172 || mLockPatternUtils.isLockScreenDisabled(userId)) { 173 return R.string.unlock_set_unlock_mode_off; 174 } else { 175 return R.string.unlock_set_unlock_mode_none; 176 } 177 } else { 178 int keyguardStoredPasswordQuality = 179 mLockPatternUtils.getKeyguardStoredPasswordQuality(userId); 180 switch (keyguardStoredPasswordQuality) { 181 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 182 return R.string.unlock_set_unlock_mode_pattern; 183 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 184 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: 185 return R.string.unlock_set_unlock_mode_pin; 186 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 187 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 188 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 189 case DevicePolicyManager.PASSWORD_QUALITY_MANAGED: 190 return R.string.unlock_set_unlock_mode_password; 191 default: 192 return null; 193 } 194 } 195 } 196 } 197