Merge "Refactor ChooseLockGenericController" into sc-dev am: b3b59d6edd

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/14269154

Change-Id: Iaf50c89889b985c638211a9101fa9f8f664097ac
This commit is contained in:
TreeHugger Robot
2021-05-07 00:12:02 +00:00
committed by Automerger Merge Worker
18 changed files with 386 additions and 319 deletions

View File

@@ -1311,16 +1311,16 @@
<!-- Title for security picker to choose the unlock method: None/Pattern/PIN/Password [CHAR LIMIT=22] --> <!-- Title for security picker to choose the unlock method: None/Pattern/PIN/Password [CHAR LIMIT=22] -->
<string name="lock_settings_picker_title">Choose screen lock</string> <string name="lock_settings_picker_title">Choose screen lock</string>
<!-- Screen title. This title is asking the user to choose a type of screen lock for their device, such as a pattern, PIN, or password. [CHAR LIMIT=27] --> <!-- Screen title. This title is asking the user to choose a type of screen lock for their device, such as a pattern, PIN, or password. [CHAR LIMIT=55] -->
<string name="lock_settings_picker_new_lock_title">Choose a screen lock</string> <string name="lock_settings_picker_new_lock_title">Choose a screen lock</string>
<!-- Screen title. This title is asking the user to choose a new screen lock for their device, such as a pattern, PIN, or password. [CHAR LIMIT=27] --> <!-- Screen title. This title is asking the user to choose a new screen lock for their device, such as a pattern, PIN, or password. [CHAR LIMIT=55] -->
<string name="lock_settings_picker_update_lock_title">Choose a new screen lock</string> <string name="lock_settings_picker_update_lock_title">Choose a new screen lock</string>
<!-- Screen title. This title is asking the user to choose a type of screen lock (such as a pattern, PIN, or password) that they need to enter to use their work apps. [CHAR LIMIT=27] --> <!-- Screen title. This title is asking the user to choose a type of screen lock (such as a pattern, PIN, or password) that they need to enter to use their work apps. [CHAR LIMIT=56] -->
<string name="lock_settings_picker_new_profile_lock_title">Choose a lock for work apps</string> <string name="lock_settings_picker_new_profile_lock_title">Choose a lock for work apps</string>
<!-- Screen title. This title is asking the user to choose a new screen lock (such as a pattern, PIN, or password) that they need to enter to use their work apps. [CHAR LIMIT=27] --> <!-- Screen title. This title is asking the user to choose a new screen lock (such as a pattern, PIN, or password) that they need to enter to use their work apps. [CHAR LIMIT=55] -->
<string name="lock_settings_picker_update_profile_lock_title">Choose a new work lock</string> <string name="lock_settings_picker_update_profile_lock_title">Choose a new work lock</string>
<!-- Title for security picker in setup wizard to choose the unlock method: None/Pattern/PIN/Password (tablet) [CHAR LIMIT=22] --> <!-- Title for security picker in setup wizard to choose the unlock method: None/Pattern/PIN/Password (tablet) [CHAR LIMIT=22] -->

View File

@@ -298,9 +298,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
private void launchChooseLock() { private void launchChooseLock() {
Log.d(TAG, "launchChooseLock"); Log.d(TAG, "launchChooseLock");
Intent intent = BiometricUtils.getChooseLockIntent(this, getIntent()); Intent intent = BiometricUtils.getChooseLockIntent(this, getIntent());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);
@@ -350,8 +348,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
final Intent intent; final Intent intent;
// If only device credential was specified, ask the user to only set that up. // If only device credential was specified, ask the user to only set that up.
intent = new Intent(this, ChooseLockGeneric.class); intent = new Intent(this, ChooseLockGeneric.class);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
launchEnrollActivity(intent); launchEnrollActivity(intent);
} }

View File

@@ -222,9 +222,7 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase
private void launchChooseLock() { private void launchChooseLock() {
Intent intent = BiometricUtils.getChooseLockIntent(this, getIntent()); Intent intent = BiometricUtils.getChooseLockIntent(this, getIntent());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
intent.putExtra(getExtraKeyForBiometric(), true); intent.putExtra(getExtraKeyForBiometric(), true);
if (mUserId != UserHandle.USER_NULL) { if (mUserId != UserHandle.USER_NULL) {

View File

@@ -19,7 +19,6 @@ import static android.app.Activity.RESULT_OK;
import static com.android.settings.password.ChooseLockPattern.RESULT_FINISHED; import static com.android.settings.password.ChooseLockPattern.RESULT_FINISHED;
import android.app.admin.DevicePolicyManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.hardware.face.FaceManager; import android.hardware.face.FaceManager;
@@ -193,9 +192,8 @@ public abstract class BiometricsSettingsBase extends DashboardFragment {
if (!launched) { if (!launched) {
Intent intent = BiometricUtils.getChooseLockIntent(getActivity(), getIntent()); Intent intent = BiometricUtils.getChooseLockIntent(getActivity(), getIntent());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); true);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);

View File

@@ -685,9 +685,7 @@ public class FingerprintSettings extends SubSettings {
// TODO: This should be cleaned up. ChooseLockGeneric should provide a way of // TODO: This should be cleaned up. ChooseLockGeneric should provide a way of
// specifying arguments/requests, instead of relying on callers setting extras. // specifying arguments/requests, instead of relying on callers setting extras.
intent.setClassName(SETTINGS_PACKAGE_NAME, ChooseLockGeneric.class.getName()); intent.setClassName(SETTINGS_PACKAGE_NAME, ChooseLockGeneric.class.getName());
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS,
true); true);
intent.putExtra(Intent.EXTRA_USER_ID, mUserId); intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);

View File

@@ -75,8 +75,6 @@ import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.search.SearchFeatureProvider; import com.android.settings.search.SearchFeatureProvider;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedPreference;
import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -112,8 +110,7 @@ public class ChooseLockGeneric extends SettingsActivity {
private static final String KEY_SKIP_BIOMETRICS = "unlock_skip_biometrics"; private static final String KEY_SKIP_BIOMETRICS = "unlock_skip_biometrics";
private static final String PASSWORD_CONFIRMED = "password_confirmed"; private static final String PASSWORD_CONFIRMED = "password_confirmed";
private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation"; private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
public static final String MINIMUM_QUALITY_KEY = "minimum_quality"; public static final String HIDE_INSECURE_OPTIONS = "hide_insecure_options";
public static final String HIDE_DISABLED_PREFS = "hide_disabled_prefs";
public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog"; public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog";
public static final String KEY_LOCK_SETTINGS_FOOTER ="lock_settings_footer"; public static final String KEY_LOCK_SETTINGS_FOOTER ="lock_settings_footer";
@@ -277,21 +274,20 @@ public class ChooseLockGeneric extends SettingsActivity {
arguments, arguments,
intent.getExtras()).getIdentifier(); intent.getExtras()).getIdentifier();
mIsManagedProfile = UserManager.get(getActivity()).isManagedProfile(mUserId); mIsManagedProfile = UserManager.get(getActivity()).isManagedProfile(mUserId);
mController = new ChooseLockGenericController( mController = new ChooseLockGenericController.Builder(
getContext(), mUserId, mRequestedMinComplexity, getContext(), mUserId, mLockPatternUtils)
mOnlyEnforceDevicePasswordRequirement, .setAppRequestedMinComplexity(mRequestedMinComplexity)
mLockPatternUtils); .setEnforceDevicePasswordRequirementOnly(mOnlyEnforceDevicePasswordRequirement)
.setProfileToUnify(mUnificationProfileId)
final int aggregatedComplexity = mController.getAggregatedPasswordComplexity(); .setHideInsecureScreenLockTypes(alwaysHideInsecureScreenLockTypes()
final boolean isComplexityProvidedByAdmin = || intent.getBooleanExtra(HIDE_INSECURE_OPTIONS, false))
aggregatedComplexity > mRequestedMinComplexity .build();
&& aggregatedComplexity > PASSWORD_COMPLEXITY_NONE;
// If the complexity is provided by the admin, do not get the caller app's name. // If the complexity is provided by the admin, do not get the caller app's name.
// If the app requires, for example, low complexity, and the admin requires high // If the app requires, for example, low complexity, and the admin requires high
// complexity, it does not make sense to show a footer telling the user it's the app // complexity, it does not make sense to show a footer telling the user it's the app
// requesting a particular complexity because the admin-set complexity will override it. // requesting a particular complexity because the admin-set complexity will override it.
mCallerAppName = isComplexityProvidedByAdmin ? null : mCallerAppName = mController.isComplexityProvidedByAdmin() ? null :
intent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME); intent.getStringExtra(EXTRA_KEY_CALLER_APP_NAME);
mManagedPasswordProvider = ManagedLockPasswordProvider.get(activity, mUserId); mManagedPasswordProvider = ManagedLockPasswordProvider.get(activity, mUserId);
@@ -330,6 +326,10 @@ public class ChooseLockGeneric extends SettingsActivity {
return super.onCreateView(inflater, container, savedInstanceState); return super.onCreateView(inflater, container, savedInstanceState);
} }
protected boolean alwaysHideInsecureScreenLockTypes() {
return false;
}
private void updateActivityTitle() { private void updateActivityTitle() {
if (mLockPatternUtils == null) { if (mLockPatternUtils == null) {
// mLockPatternUtils will be uninitialized if ChooseLockGenericFragment.onCreate() // mLockPatternUtils will be uninitialized if ChooseLockGenericFragment.onCreate()
@@ -606,16 +606,12 @@ public class ChooseLockGeneric extends SettingsActivity {
} }
if (quality == -1) { if (quality == -1) {
// If caller didn't specify password quality, show UI and allow the user to choose. // If caller didn't specify password quality, show UI and allow the user to choose.
quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
quality = mController.upgradeQuality(quality);
final boolean hideDisabledPrefs = intent.getBooleanExtra(
HIDE_DISABLED_PREFS, false);
final PreferenceScreen prefScreen = getPreferenceScreen(); final PreferenceScreen prefScreen = getPreferenceScreen();
if (prefScreen != null) { if (prefScreen != null) {
prefScreen.removeAll(); prefScreen.removeAll();
} }
addPreferences(); addPreferences();
disableUnusablePreferences(quality, hideDisabledPrefs); disableUnusablePreferences();
updatePreferenceText(); updatePreferenceText();
updateCurrentPreference(); updateCurrentPreference();
updatePreferenceSummaryIfNeeded(); updatePreferenceSummaryIfNeeded();
@@ -746,71 +742,23 @@ public class ChooseLockGeneric extends SettingsActivity {
return lock != null ? lock.preferenceKey : null; return lock != null ? lock.preferenceKey : null;
} }
/***
* Disables preferences that are less secure than required quality. The actual
* implementation is in disableUnusablePreferenceImpl.
*
* @param quality the requested quality.
* @param hideDisabledPrefs if false preferences show why they were disabled; otherwise
* they're not shown at all.
*/
protected void disableUnusablePreferences(final int quality, boolean hideDisabledPrefs) {
disableUnusablePreferencesImpl(quality, hideDisabledPrefs);
}
/*** /***
* Disables preferences that are less secure than required quality. * Disables preferences that are less secure than required quality.
* *
* @param quality the requested quality.
* @param hideDisabled whether to hide disable screen lock options.
*/ */
protected void disableUnusablePreferencesImpl(final int quality, private void disableUnusablePreferences() {
boolean hideDisabled) {
final PreferenceScreen entries = getPreferenceScreen(); final PreferenceScreen entries = getPreferenceScreen();
int adminEnforcedQuality = LockPatternUtils.credentialTypeToPasswordQuality(
mLockPatternUtils.getRequestedPasswordMetrics(
mUserId, mOnlyEnforceDevicePasswordRequirement).credType);
EnforcedAdmin enforcedAdmin =
RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(getActivity(),
mUserId);
// If we are to unify a work challenge at the end of the credential enrollment, manually
// merge any password policy from that profile here, so we are enrolling a compliant
// password. This is because once unified, the profile's password policy will
// be enforced on the new credential.
if (mUnificationProfileId != UserHandle.USER_NULL) {
int profileEnforceQuality = mDpm.getPasswordQuality(null, mUnificationProfileId);
if (profileEnforceQuality > adminEnforcedQuality) {
adminEnforcedQuality = profileEnforceQuality;
enforcedAdmin = EnforcedAdmin.combine(enforcedAdmin,
RestrictedLockUtilsInternal.checkIfPasswordQualityIsSet(
getActivity(), mUnificationProfileId));
}
}
for (ScreenLockType lock : ScreenLockType.values()) { for (ScreenLockType lock : ScreenLockType.values()) {
String key = lock.preferenceKey; String key = lock.preferenceKey;
Preference pref = findPreference(key); Preference pref = findPreference(key);
if (pref instanceof RestrictedPreference) { if (pref instanceof RestrictedPreference) {
boolean visible = mController.isScreenLockVisible(lock); boolean visible = mController.isScreenLockVisible(lock);
boolean enabled = mController.isScreenLockEnabled(lock, quality); boolean enabled = mController.isScreenLockEnabled(lock);
boolean disabledByAdmin =
mController.isScreenLockDisabledByAdmin(lock, adminEnforcedQuality);
if (hideDisabled) {
visible = visible && enabled;
}
if (!visible) { if (!visible) {
entries.removePreference(pref); entries.removePreference(pref);
} else if (disabledByAdmin && enforcedAdmin != null) {
((RestrictedPreference) pref).setDisabledByAdmin(enforcedAdmin);
} else if (!enabled) { } else if (!enabled) {
// we need to setDisabledByAdmin to null first to disable the padlock
// in case it was set earlier.
((RestrictedPreference) pref).setDisabledByAdmin(null);
pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
pref.setEnabled(false); pref.setEnabled(false);
} else {
((RestrictedPreference) pref).setDisabledByAdmin(null);
} }
} }
} }

View File

@@ -17,6 +17,7 @@
package com.android.settings.password; package com.android.settings.password;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
@@ -24,6 +25,7 @@ import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.PasswordMetrics; import android.app.admin.PasswordMetrics;
import android.content.Context; import android.content.Context;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
@@ -36,84 +38,140 @@ import java.util.List;
/** /**
* A controller for ChooseLockGeneric, and other similar classes which shows a list of possible * A controller for ChooseLockGeneric, and other similar classes which shows a list of possible
* screen locks for the user to choose from. * screen lock types for the user to choose from. This is the main place where different
* restrictions on allowed screen lock types are aggregated in Settings.
*
* Each screen lock type has two states: whether it is visible and whether it is enabled.
* Visibility is affected by things like resource configs, whether it's for a managed profile,
* or whether the caller allows it or not. This is determined by
* {@link #isScreenLockVisible(ScreenLockType)}. For visible screen lock types, they can be disabled
* by a combination of admin policies and request from the calling app, which is determined by
* {@link #isScreenLockEnabled(ScreenLockType}.
*/ */
public class ChooseLockGenericController { public class ChooseLockGenericController {
private final Context mContext; private final Context mContext;
private final int mUserId; private final int mUserId;
@PasswordComplexity private final int mRequestedMinComplexity; private final boolean mHideInsecureScreenLockTypes;
@PasswordComplexity private final int mAppRequestedMinComplexity;
private final boolean mDevicePasswordRequirementOnly; private final boolean mDevicePasswordRequirementOnly;
private ManagedLockPasswordProvider mManagedPasswordProvider; private final int mUnificationProfileId;
private final ManagedLockPasswordProvider mManagedPasswordProvider;
private final LockPatternUtils mLockPatternUtils; private final LockPatternUtils mLockPatternUtils;
public ChooseLockGenericController(Context context, int userId) {
this(
context,
userId,
PASSWORD_COMPLEXITY_NONE,
/* mOnlyEnforceDevicePasswordRequirement */ false,
new LockPatternUtils(context));
}
/**
* @param requestedMinComplexity specifies the min password complexity to be taken into account
* when determining the available screen lock types
*/
public ChooseLockGenericController(Context context, int userId, public ChooseLockGenericController(Context context, int userId,
@PasswordComplexity int requestedMinComplexity, ManagedLockPasswordProvider managedPasswordProvider, LockPatternUtils lockPatternUtils,
boolean devicePasswordRequirementOnly, boolean hideInsecureScreenLockTypes, int appRequestedMinComplexity,
LockPatternUtils lockPatternUtils) { boolean devicePasswordRequirementOnly, int unificationProfileId) {
this(
context,
userId,
requestedMinComplexity,
devicePasswordRequirementOnly,
ManagedLockPasswordProvider.get(context, userId),
lockPatternUtils);
}
@VisibleForTesting
ChooseLockGenericController(
Context context,
int userId,
@PasswordComplexity int requestedMinComplexity,
boolean devicePasswordRequirementOnly,
ManagedLockPasswordProvider managedLockPasswordProvider,
LockPatternUtils lockPatternUtils) {
mContext = context; mContext = context;
mUserId = userId; mUserId = userId;
mRequestedMinComplexity = requestedMinComplexity; mManagedPasswordProvider = managedPasswordProvider;
mDevicePasswordRequirementOnly = devicePasswordRequirementOnly;
mManagedPasswordProvider = managedLockPasswordProvider;
mLockPatternUtils = lockPatternUtils; mLockPatternUtils = lockPatternUtils;
mHideInsecureScreenLockTypes = hideInsecureScreenLockTypes;
mAppRequestedMinComplexity = appRequestedMinComplexity;
mDevicePasswordRequirementOnly = devicePasswordRequirementOnly;
mUnificationProfileId = unificationProfileId;
}
/** Builder class for {@link ChooseLockGenericController} */
public static class Builder {
private final Context mContext;
private final int mUserId;
private final ManagedLockPasswordProvider mManagedPasswordProvider;
private final LockPatternUtils mLockPatternUtils;
private boolean mHideInsecureScreenLockTypes = false;
@PasswordComplexity private int mAppRequestedMinComplexity = PASSWORD_COMPLEXITY_NONE;
private boolean mDevicePasswordRequirementOnly = false;
private int mUnificationProfileId = UserHandle.USER_NULL;
public Builder(Context context, int userId) {
this(context, userId, new LockPatternUtils(context));
}
public Builder(Context context, int userId,
LockPatternUtils lockPatternUtils) {
this(
context,
userId,
ManagedLockPasswordProvider.get(context, userId),
lockPatternUtils);
}
@VisibleForTesting
Builder(
Context context,
int userId,
ManagedLockPasswordProvider managedLockPasswordProvider,
LockPatternUtils lockPatternUtils) {
mContext = context;
mUserId = userId;
mManagedPasswordProvider = managedLockPasswordProvider;
mLockPatternUtils = lockPatternUtils;
}
/**
* Sets the password complexity requested by the calling app via
* {@link android.app.admin.DevicePolicyManager#EXTRA_PASSWORD_COMPLEXITY}.
*/
public Builder setAppRequestedMinComplexity(int complexity) {
mAppRequestedMinComplexity = complexity;
return this;
}
/**
* Sets whether the enrolment flow should discard any password policies originating from the
* work profile, even if the work profile currently has unified challenge. This can be
* requested by the calling app via
* {@link android.app.admin.DevicePolicyManager#EXTRA_DEVICE_PASSWORD_REQUIREMENT_ONLY}.
*/
public Builder setEnforceDevicePasswordRequirementOnly(boolean deviceOnly) {
mDevicePasswordRequirementOnly = deviceOnly;
return this;
}
/**
* Sets the user ID of any profile whose work challenge should be unified at the end of this
* enrolment flow. This will lead to all password policies from that profile to be taken
* into consideration by this class, so that we are enrolling a compliant password. This is
* because once unified, the profile's password policy will be enforced on the new
* credential.
*/
public Builder setProfileToUnify(int profileId) {
mUnificationProfileId = profileId;
return this;
}
/**
* Sets whether insecure screen lock types (NONE and SWIPE) should be hidden in the UI.
*/
public Builder setHideInsecureScreenLockTypes(boolean hide) {
mHideInsecureScreenLockTypes = hide;
return this;
}
/** Creates {@link ChooseLockGenericController} instance. */
public ChooseLockGenericController build() {
return new ChooseLockGenericController(mContext, mUserId, mManagedPasswordProvider,
mLockPatternUtils, mHideInsecureScreenLockTypes, mAppRequestedMinComplexity,
mDevicePasswordRequirementOnly, mUnificationProfileId);
}
} }
/** /**
* Returns the highest quality among the specified {@code quality}, the password requirement * Returns whether the given screen lock type should be visible in the given context.
* set by device admins (legacy password quality metrics and password complexity), and the
* min password complexity requested by the calling app.
*/
public int upgradeQuality(int quality) {
// Compare specified quality and dpm quality
// TODO(b/142781408): convert from quality to credential type once PIN is supported.
int dpmUpgradedQuality = Math.max(quality, LockPatternUtils.credentialTypeToPasswordQuality(
getAggregatedPasswordMetrics().credType));
return Math.max(dpmUpgradedQuality,
PasswordMetrics.complexityLevelToMinQuality(getAggregatedPasswordComplexity()));
}
/**
* Whether the given screen lock type should be visible in the given context.
*/ */
public boolean isScreenLockVisible(ScreenLockType type) { public boolean isScreenLockVisible(ScreenLockType type) {
final boolean managedProfile = mUserId != UserHandle.myUserId(); final boolean managedProfile = mContext.getSystemService(UserManager.class)
.isManagedProfile(mUserId);
switch (type) { switch (type) {
case NONE: case NONE:
return !mContext.getResources().getBoolean(R.bool.config_hide_none_security_option) return !mHideInsecureScreenLockTypes
&& !mContext.getResources().getBoolean(R.bool.config_hide_none_security_option)
&& !managedProfile; // Profiles should use unified challenge instead. && !managedProfile; // Profiles should use unified challenge instead.
case SWIPE: case SWIPE:
return !mContext.getResources().getBoolean(R.bool.config_hide_swipe_security_option) return !mHideInsecureScreenLockTypes
&& !mContext.getResources().getBoolean(R.bool.config_hide_swipe_security_option)
&& !managedProfile; // Swipe doesn't make sense for profiles. && !managedProfile; // Swipe doesn't make sense for profiles.
case MANAGED: case MANAGED:
return mManagedPasswordProvider.isManagedPasswordChoosable(); return mManagedPasswordProvider.isManagedPasswordChoosable();
@@ -128,29 +186,27 @@ public class ChooseLockGenericController {
} }
/** /**
* Whether screen lock with {@code type} should be enabled. * Whether screen lock with {@code type} should be enabled assuming all relevant password
* * requirements. The lock's visibility ({@link #isScreenLockVisible}) is not considered here.
* @param type The screen lock type.
* @param quality The minimum required quality. This can either be requirement by device policy
* manager or because some flow only makes sense with secure lock screens.
*/ */
public boolean isScreenLockEnabled(ScreenLockType type, int quality) { public boolean isScreenLockEnabled(ScreenLockType type) {
return type.maxQuality >= quality; return type.maxQuality >= upgradeQuality(PASSWORD_QUALITY_UNSPECIFIED);
} }
/** /**
* Whether screen lock with {@code type} is disabled by device policy admin. * Increases the given quality to be as high as the combined quality from all relevant
* * password requirements.
* @param type The screen lock type.
* @param adminEnforcedQuality The minimum quality that the admin enforces.
*/ */
public boolean isScreenLockDisabledByAdmin(ScreenLockType type, int adminEnforcedQuality) { // TODO(b/142781408): convert from quality to credential type once PIN is supported.
boolean disabledByAdmin = type.maxQuality < adminEnforcedQuality; public int upgradeQuality(int quality) {
if (type == ScreenLockType.MANAGED) { return Math.max(quality,
disabledByAdmin = disabledByAdmin Math.max(
|| !mManagedPasswordProvider.isManagedPasswordChoosable(); LockPatternUtils.credentialTypeToPasswordQuality(
} getAggregatedPasswordMetrics().credType),
return disabledByAdmin; PasswordMetrics.complexityLevelToMinQuality(
getAggregatedPasswordComplexity())
)
);
} }
/** /**
@@ -175,43 +231,72 @@ public class ChooseLockGenericController {
} }
/** /**
* Gets a list of screen locks that should be visible for the given quality. The returned list * Gets a list of screen lock types that should be visible for the given quality. The returned
* is ordered in the natural order of the enum (the order those enums were defined). * list is ordered in the natural order of the enum (the order those enums were defined). Screen
* * locks disabled by password policy will not be returned.
* @param quality The minimum quality required in the context of the current flow. This should
* be one of the constants defined in
* {@code DevicePolicyManager#PASSWORD_QUALITY_*}.
* @param includeDisabled Whether to include screen locks disabled by {@code quality}
* requirements in the returned list.
*/ */
@NonNull @NonNull
public List<ScreenLockType> getVisibleScreenLockTypes(int quality, boolean includeDisabled) { public List<ScreenLockType> getVisibleAndEnabledScreenLockTypes() {
int upgradedQuality = upgradeQuality(quality);
List<ScreenLockType> locks = new ArrayList<>(); List<ScreenLockType> locks = new ArrayList<>();
// EnumSet's iterator guarantees the natural order of the enums // EnumSet's iterator guarantees the natural order of the enums
for (ScreenLockType lock : ScreenLockType.values()) { for (ScreenLockType lock : ScreenLockType.values()) {
if (isScreenLockVisible(lock)) { if (isScreenLockVisible(lock) && isScreenLockEnabled(lock)) {
if (includeDisabled || isScreenLockEnabled(lock, upgradedQuality)) { locks.add(lock);
locks.add(lock);
}
} }
} }
return locks; return locks;
} }
/**
* Returns the combined password metrics from all relevant policies which affects the current
* user. Normally password policies set on the current user's work profile instance will be
* taken into consideration here iff the work profile doesn't have its own work challenge.
* By setting {@link #mUnificationProfileId}, the work profile's password policy will always
* be combined here. Alternatively, by setting {@link #mDevicePasswordRequirementOnly}, its
* password policy will always be disregarded here.
*/
public PasswordMetrics getAggregatedPasswordMetrics() { public PasswordMetrics getAggregatedPasswordMetrics() {
return mLockPatternUtils.getRequestedPasswordMetrics(mUserId, PasswordMetrics metrics = mLockPatternUtils.getRequestedPasswordMetrics(mUserId,
mDevicePasswordRequirementOnly); mDevicePasswordRequirementOnly);
if (mUnificationProfileId != UserHandle.USER_NULL) {
metrics.maxWith(mLockPatternUtils.getRequestedPasswordMetrics(mUnificationProfileId));
}
return metrics;
} }
/**
* Returns the combined password complexity from all relevant policies which affects the current
* user. The same logic of handling work profile password policies as
* {@link #getAggregatedPasswordMetrics} applies here.
*/
public int getAggregatedPasswordComplexity() { public int getAggregatedPasswordComplexity() {
return Math.max(mRequestedMinComplexity, int complexity = Math.max(mAppRequestedMinComplexity,
mLockPatternUtils.getRequestedPasswordComplexity( mLockPatternUtils.getRequestedPasswordComplexity(
mUserId, mDevicePasswordRequirementOnly)); mUserId, mDevicePasswordRequirementOnly));
if (mUnificationProfileId != UserHandle.USER_NULL) {
complexity = Math.max(complexity,
mLockPatternUtils.getRequestedPasswordComplexity(mUnificationProfileId));
}
return complexity;
} }
/**
* Returns whether any screen lock type has been disabled only due to password policy
* from the admin. Will return {@code false} if the restriction is purely due to calling
* app's request.
*/
public boolean isScreenLockRestrictedByAdmin() { public boolean isScreenLockRestrictedByAdmin() {
return getAggregatedPasswordMetrics().credType != CREDENTIAL_TYPE_NONE return getAggregatedPasswordMetrics().credType != CREDENTIAL_TYPE_NONE
|| getAggregatedPasswordComplexity() != PASSWORD_COMPLEXITY_NONE; || isComplexityProvidedByAdmin();
}
/**
* Returns whether the aggregated password complexity is non-zero and comes from
* admin policy.
*/
public boolean isComplexityProvidedByAdmin() {
final int aggregatedComplexity = getAggregatedPasswordComplexity();
return aggregatedComplexity > mAppRequestedMinComplexity
&& aggregatedComplexity > PASSWORD_COMPLEXITY_NONE;
} }
} }

View File

@@ -416,19 +416,6 @@ public class ChooseLockPassword extends SettingsActivity {
mMinComplexity = intent.getIntExtra(EXTRA_KEY_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE); mMinComplexity = intent.getIntExtra(EXTRA_KEY_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE);
mMinMetrics = intent.getParcelableExtra(EXTRA_KEY_MIN_METRICS); mMinMetrics = intent.getParcelableExtra(EXTRA_KEY_MIN_METRICS);
if (mMinMetrics == null) mMinMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE); if (mMinMetrics == null) mMinMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE);
// If we are to unify a work challenge at the end of the credential enrollment, manually
// merge any password policy from that profile here, so we are enrolling a compliant
// password. This is because once unified, the profile's password policy will
// be enforced on the new credential.
//TODO: Move this logic to ChooseLockGeneric; let ChooseLockGeneric be the only place
//where password requirement mixing happens. ChooseLockPassword simply enforces what's
//set via IntentBuilder.setPasswordRequirement()
if (mUnificationProfileId != UserHandle.USER_NULL) {
mMinMetrics.maxWith(
mLockPatternUtils.getRequestedPasswordMetrics(mUnificationProfileId));
mMinComplexity = Math.max(mMinComplexity,
mLockPatternUtils.getRequestedPasswordComplexity(mUnificationProfileId));
}
if (intent.getBooleanExtra( if (intent.getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) { ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {

View File

@@ -18,7 +18,6 @@ package com.android.settings.password;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@@ -100,7 +99,9 @@ public class ChooseLockTypeDialogFragment extends InstrumentedDialogFragment
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
final int userId = getArguments().getInt(ARG_USER_ID); final int userId = getArguments().getInt(ARG_USER_ID);
mController = new ChooseLockGenericController(getContext(), userId); mController = new ChooseLockGenericController.Builder(getContext(), userId)
.setHideInsecureScreenLockTypes(true)
.build();
} }
@Override @Override
@@ -124,10 +125,7 @@ public class ChooseLockTypeDialogFragment extends InstrumentedDialogFragment
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
Context context = getContext(); Context context = getContext();
Builder builder = new Builder(context); Builder builder = new Builder(context);
List<ScreenLockType> locks = List<ScreenLockType> locks = mController.getVisibleAndEnabledScreenLockTypes();
mController.getVisibleScreenLockTypes(
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
false /* includeDisabled */);
mAdapter = new ScreenLockAdapter(context, locks, mController); mAdapter = new ScreenLockAdapter(context, locks, mController);
builder.setAdapter(mAdapter, this); builder.setAdapter(mAdapter, this);
builder.setTitle(R.string.setup_lock_settings_options_dialog_title); builder.setTitle(R.string.setup_lock_settings_options_dialog_title);

View File

@@ -19,7 +19,6 @@ package com.android.settings.password;
import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD; import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE; import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT; import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static com.android.internal.util.Preconditions.checkNotNull; import static com.android.internal.util.Preconditions.checkNotNull;
@@ -145,10 +144,8 @@ final class SetNewPasswordController {
private Bundle getBiometricChooseLockExtras() { private Bundle getBiometricChooseLockExtras() {
Bundle chooseLockExtras = new Bundle(); Bundle chooseLockExtras = new Bundle();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
PASSWORD_QUALITY_SOMETHING);
chooseLockExtras.putBoolean( chooseLockExtras.putBoolean(
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, true);
return chooseLockExtras; return chooseLockExtras;
@@ -156,10 +153,8 @@ final class SetNewPasswordController {
private Bundle getFingerprintChooseLockExtras() { private Bundle getFingerprintChooseLockExtras() {
Bundle chooseLockExtras = new Bundle(); Bundle chooseLockExtras = new Bundle();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
PASSWORD_QUALITY_SOMETHING);
chooseLockExtras.putBoolean( chooseLockExtras.putBoolean(
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
return chooseLockExtras; return chooseLockExtras;
@@ -167,10 +162,8 @@ final class SetNewPasswordController {
private Bundle getFaceChooseLockExtras() { private Bundle getFaceChooseLockExtras() {
Bundle chooseLockExtras = new Bundle(); Bundle chooseLockExtras = new Bundle();
chooseLockExtras.putInt(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
PASSWORD_QUALITY_SOMETHING);
chooseLockExtras.putBoolean( chooseLockExtras.putBoolean(
ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true); chooseLockExtras.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, true);
return chooseLockExtras; return chooseLockExtras;

View File

@@ -21,7 +21,6 @@ import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
import android.app.admin.DevicePolicyManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
@@ -160,22 +159,12 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric {
return SetupChooseLockGeneric.InternalActivity.class; return SetupChooseLockGeneric.InternalActivity.class;
} }
/***
* Disables preferences that are less secure than required quality and shows only secure
* screen lock options here.
*
* @param quality the requested quality.
*/
@Override @Override
protected void disableUnusablePreferences(final int quality, boolean hideDisabled) { protected boolean alwaysHideInsecureScreenLockTypes() {
// At this part of the flow, the user has already indicated they want to add a pin, // At this part of the flow, the user has already indicated they want to add a pin,
// pattern or password, so don't show "None" or "Slide". We disable them here and set // pattern or password, so don't show "None" or "Slide". We disable them here.
// the HIDE_DISABLED flag to true to hide them. This only happens for setup wizard. // This only happens for setup wizard.
// We do the following max check here since the device may already have a Device Admin return true;
// installed with a policy we need to honor.
final int newQuality = Math.max(quality,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
super.disableUnusablePreferencesImpl(newQuality, true /* hideDisabled */);
} }
@Override @Override

View File

@@ -17,7 +17,6 @@
package com.android.settings.password; package com.android.settings.password;
import android.app.Activity; import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@@ -81,9 +80,11 @@ public class SetupChooseLockPassword extends ChooseLockPassword {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
final Activity activity = getActivity(); final Activity activity = getActivity();
ChooseLockGenericController chooseLockGenericController = ChooseLockGenericController chooseLockGenericController =
new ChooseLockGenericController(activity, mUserId); new ChooseLockGenericController.Builder(activity, mUserId)
boolean anyOptionsShown = chooseLockGenericController.getVisibleScreenLockTypes( .setHideInsecureScreenLockTypes(true)
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false).size() > 0; .build();
boolean anyOptionsShown = chooseLockGenericController
.getVisibleAndEnabledScreenLockTypes().size() > 0;
boolean showOptionsButton = activity.getIntent().getBooleanExtra( boolean showOptionsButton = activity.getIntent().getBooleanExtra(
ChooseLockGeneric.ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false); ChooseLockGeneric.ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false);
if (!anyOptionsShown) { if (!anyOptionsShown) {

View File

@@ -136,8 +136,8 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
if (passwordQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { if (passwordQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
chooseLockIntent.putExtra( chooseLockIntent.putExtra(
ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); true);
startActivityForResult(chooseLockIntent, CHANGE_LOCK_METHOD_REQUEST); startActivityForResult(chooseLockIntent, CHANGE_LOCK_METHOD_REQUEST);
return false; return false;
} }

View File

@@ -432,8 +432,8 @@ public class UserSettings extends SettingsPreferenceFragment
private void launchChooseLockscreen() { private void launchChooseLockscreen() {
Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
chooseLockIntent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, chooseLockIntent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); true);
startActivityForResult(chooseLockIntent, REQUEST_CHOOSE_LOCK); startActivityForResult(chooseLockIntent, REQUEST_CHOOSE_LOCK);
} }

View File

@@ -20,23 +20,31 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage; import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application; import static org.robolectric.RuntimeEnvironment.application;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.PasswordPolicy; import android.app.admin.PasswordPolicy;
import android.os.UserHandle;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowUserManager;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -48,10 +56,11 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = SettingsShadowResources.class) @Config(shadows = {ShadowUserManager.class, SettingsShadowResources.class})
public class ChooseLockGenericControllerTest { public class ChooseLockGenericControllerTest {
private ChooseLockGenericController mController; private ChooseLockGenericController mController;
@@ -68,7 +77,7 @@ public class ChooseLockGenericControllerTest {
when(mLockPatternUtils.hasSecureLockScreen()).thenReturn(true); when(mLockPatternUtils.hasSecureLockScreen()).thenReturn(true);
setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
mController = createController(PASSWORD_COMPLEXITY_NONE); mController = createBuilder().build();
SettingsShadowResources.overrideResource(R.bool.config_hide_none_security_option, false); SettingsShadowResources.overrideResource(R.bool.config_hide_none_security_option, false);
SettingsShadowResources.overrideResource(R.bool.config_hide_swipe_security_option, false); SettingsShadowResources.overrideResource(R.bool.config_hide_swipe_security_option, false);
} }
@@ -95,8 +104,8 @@ public class ChooseLockGenericControllerTest {
} }
@Test @Test
public void isScreenLockVisible_notCurrentUser_shouldHideInsecure() { public void isScreenLockVisible_ManagedProfile_shouldHideInsecure() {
mController = new ChooseLockGenericController(application, 1 /* userId */); ShadowUserManager.getShadow().setManagedProfiles(Set.of(0));
assertWithMessage("SWIPE visible").that( assertWithMessage("SWIPE visible").that(
mController.isScreenLockVisible(ScreenLockType.SWIPE)).isFalse(); mController.isScreenLockVisible(ScreenLockType.SWIPE)).isFalse();
assertWithMessage("NONE visible").that(mController.isScreenLockVisible(ScreenLockType.NONE)) assertWithMessage("NONE visible").that(mController.isScreenLockVisible(ScreenLockType.NONE))
@@ -112,62 +121,116 @@ public class ChooseLockGenericControllerTest {
} }
@Test @Test
public void isScreenLockEnabled_lowerQuality_shouldReturnFalse() { public void isScreenLockEnabled_Default() {
for (ScreenLockType lock : ScreenLockType.values()) { assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isTrue();
assertWithMessage(lock + " enabled").that( assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isTrue();
mController.isScreenLockEnabled(lock, lock.maxQuality + 1)).isFalse(); assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
} assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
} }
@Test @Test
public void isScreenLockEnabled_equalQuality_shouldReturnTrue() { public void isScreenLockEnabled_QualityUnspecified() {
for (ScreenLockType lock : ScreenLockType.values()) { setDevicePolicyPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
assertWithMessage(lock + " enabled").that( assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isTrue();
mController.isScreenLockEnabled(lock, lock.defaultQuality)).isTrue(); assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isTrue();
} assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
} }
@Test @Test
public void isScreenLockEnabled_higherQuality_shouldReturnTrue() { public void isScreenLockEnabled_QualitySomething() {
for (ScreenLockType lock : ScreenLockType.values()) { setDevicePolicyPasswordQuality(PASSWORD_QUALITY_SOMETHING);
assertWithMessage(lock + " enabled").that( assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
mController.isScreenLockEnabled(lock, lock.maxQuality - 1)).isTrue(); assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
} assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
} }
@Test @Test
public void isScreenLockDisabledByAdmin_lowerQuality_shouldReturnTrue() { public void isScreenLockEnabled_QualityNumeric() {
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable(); setDevicePolicyPasswordQuality(PASSWORD_QUALITY_NUMERIC);
for (ScreenLockType lock : ScreenLockType.values()) { assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertWithMessage(lock + " disabledByAdmin").that( assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality + 1)).isTrue(); assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
} assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
} }
@Test @Test
public void isScreenLockDisabledByAdmin_equalQuality_shouldReturnFalse() { public void isScreenLockEnabled_QualityNumericComplex() {
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable(); setDevicePolicyPasswordQuality(PASSWORD_QUALITY_NUMERIC_COMPLEX);
for (ScreenLockType lock : ScreenLockType.values()) { assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertWithMessage(lock + " disabledByAdmin").that( assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality)).isFalse(); assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
} assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
} }
@Test @Test
public void isScreenLockDisabledByAdmin_higherQuality_shouldReturnFalse() { public void isScreenLockEnabled_QualityAlphabetic() {
doReturn(true).when(mManagedLockPasswordProvider).isManagedPasswordChoosable(); setDevicePolicyPasswordQuality(PASSWORD_QUALITY_ALPHABETIC);
for (ScreenLockType lock : ScreenLockType.values()) { assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertWithMessage(lock + " disabledByAdmin").that( assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
mController.isScreenLockDisabledByAdmin(lock, lock.maxQuality - 1)).isFalse(); assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
} assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
} }
@Test @Test
public void isScreenLockDisabledByAdmin_managedNotChoosable_shouldReturnTrue() { public void isScreenLockEnabled_QualityComplex() {
doReturn(false).when(mManagedLockPasswordProvider).isManagedPasswordChoosable(); setDevicePolicyPasswordQuality(PASSWORD_QUALITY_COMPLEX);
assertWithMessage("MANANGED disabledByAdmin").that(mController.isScreenLockDisabledByAdmin( assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
ScreenLockType.MANAGED, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)) assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
.isTrue(); assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_NoneComplexity() {
when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
.thenReturn(PASSWORD_COMPLEXITY_NONE);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_lowComplexity() {
when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
.thenReturn(PASSWORD_COMPLEXITY_LOW);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_mediumComplexity() {
when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
.thenReturn(PASSWORD_COMPLEXITY_MEDIUM);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
}
@Test
public void isScreenLockEnabled_highComplexity() {
when(mLockPatternUtils.getRequestedPasswordComplexity(anyInt(), anyBoolean()))
.thenReturn(PASSWORD_COMPLEXITY_HIGH);
assertThat(mController.isScreenLockEnabled(ScreenLockType.NONE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.SWIPE)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PATTERN)).isFalse();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PIN)).isTrue();
assertThat(mController.isScreenLockEnabled(ScreenLockType.PASSWORD)).isTrue();
} }
@Test @Test
@@ -181,8 +244,8 @@ public class ChooseLockGenericControllerTest {
@Test @Test
public void getVisibleScreenLockTypes_qualitySomething_shouldReturnPatterPinPassword() { public void getVisibleScreenLockTypes_qualitySomething_shouldReturnPatterPinPassword() {
assertThat(mController.getVisibleScreenLockTypes( mController = createBuilder().setHideInsecureScreenLockTypes(true).build();
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false)) assertThat(mController.getVisibleAndEnabledScreenLockTypes())
.isEqualTo(Arrays.asList( .isEqualTo(Arrays.asList(
ScreenLockType.PATTERN, ScreenLockType.PATTERN,
ScreenLockType.PIN, ScreenLockType.PIN,
@@ -191,8 +254,7 @@ public class ChooseLockGenericControllerTest {
@Test @Test
public void getVisibleScreenLockTypes_showDisabled_shouldReturnAllButManaged() { public void getVisibleScreenLockTypes_showDisabled_shouldReturnAllButManaged() {
assertThat(mController.getVisibleScreenLockTypes( assertThat(mController.getVisibleAndEnabledScreenLockTypes())
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, true))
.isEqualTo(Arrays.asList( .isEqualTo(Arrays.asList(
ScreenLockType.NONE, ScreenLockType.NONE,
ScreenLockType.SWIPE, ScreenLockType.SWIPE,
@@ -223,31 +285,68 @@ public class ChooseLockGenericControllerTest {
@Test @Test
public void upgradeQuality_complexityHigh_minQualityNumericComplex() { public void upgradeQuality_complexityHigh_minQualityNumericComplex() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_HIGH)
.build();
setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_HIGH);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)) assertThat(mController.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX); .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
} }
@Test @Test
public void upgradeQuality_complexityMedium_minQualityNumericComplex() { public void upgradeQuality_complexityMedium_minQualityNumericComplex() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_MEDIUM)
.build();
setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_MEDIUM);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)) assertThat(mController.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX); .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
} }
@Test @Test
public void upgradeQuality_complexityLow_minQualitySomething() { public void upgradeQuality_complexityLow_minQualitySomething() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_LOW)
.build();
setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); setDevicePolicyPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
ChooseLockGenericController controller = createController(PASSWORD_COMPLEXITY_LOW);
assertThat(controller.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)) assertThat(mController.upgradeQuality(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED))
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
} }
@Test
public void getAggregatedPasswordComplexity_AppRequest() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_HIGH)
.build();
assertThat(mController.getAggregatedPasswordComplexity())
.isEqualTo(PASSWORD_COMPLEXITY_HIGH);
}
@Test
public void getAggregatedPasswordComplexity_DevicePolicy() {
mController = createBuilder().setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_LOW)
.build();
when(mLockPatternUtils.getRequestedPasswordComplexity(eq(UserHandle.myUserId()), eq(false)))
.thenReturn(PASSWORD_COMPLEXITY_MEDIUM);
assertThat(mController.getAggregatedPasswordComplexity())
.isEqualTo(PASSWORD_COMPLEXITY_MEDIUM);
}
@Test
public void getAggregatedPasswordComplexity_ProfileUnification() {
mController = createBuilder()
.setProfileToUnify(123)
.setAppRequestedMinComplexity(PASSWORD_COMPLEXITY_LOW)
.build();
when(mLockPatternUtils.getRequestedPasswordComplexity(eq(UserHandle.myUserId()), eq(false)))
.thenReturn(PASSWORD_COMPLEXITY_MEDIUM);
when(mLockPatternUtils.getRequestedPasswordComplexity(eq(123)))
.thenReturn(PASSWORD_COMPLEXITY_HIGH);
assertThat(mController.getAggregatedPasswordComplexity())
.isEqualTo(PASSWORD_COMPLEXITY_HIGH);
}
private void setDevicePolicyPasswordQuality(int quality) { private void setDevicePolicyPasswordQuality(int quality) {
PasswordPolicy policy = new PasswordPolicy(); PasswordPolicy policy = new PasswordPolicy();
policy.quality = quality; policy.quality = quality;
@@ -256,13 +355,10 @@ public class ChooseLockGenericControllerTest {
.thenReturn(policy.getMinMetrics()); .thenReturn(policy.getMinMetrics());
} }
private ChooseLockGenericController createController( private ChooseLockGenericController.Builder createBuilder() {
@PasswordComplexity int minPasswordComplexity) { return new ChooseLockGenericController.Builder(
return new ChooseLockGenericController(
application, application,
0 /* userId */, 0 /* userId */,
minPasswordComplexity,
false,
mManagedLockPasswordProvider, mManagedLockPasswordProvider,
mLockPatternUtils); mLockPatternUtils);
} }

View File

@@ -30,7 +30,6 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
import static com.android.internal.widget.LockPatternUtils.PASSWORD_TYPE_KEY; import static com.android.internal.widget.LockPatternUtils.PASSWORD_TYPE_KEY;
import static com.android.settings.password.ChooseLockGeneric.CONFIRM_CREDENTIALS; import static com.android.settings.password.ChooseLockGeneric.CONFIRM_CREDENTIALS;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_UNIFICATION_PROFILE_ID;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage; import static com.google.common.truth.Truth.assertWithMessage;
@@ -429,18 +428,6 @@ public class ChooseLockPasswordTest {
"PIN must be at least 8 digits"); "PIN must be at least 8 digits");
} }
@Test
public void validateComplexityMergedFromUnificationUserOnCreate() {
ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
ShadowLockPatternUtils.setRequiredPasswordComplexity(123, PASSWORD_COMPLEXITY_HIGH);
Intent intent = createIntentForPasswordValidation(null, PASSWORD_COMPLEXITY_NONE,
PASSWORD_QUALITY_NUMERIC);
intent.putExtra(EXTRA_KEY_UNIFICATION_PROFILE_ID, 123);
assertPasswordValidationResultForIntent(LockscreenCredential.createNone(), intent,
"PIN must be at least 8 digits");
}
private ChooseLockPassword buildChooseLockPasswordActivity(Intent intent) { private ChooseLockPassword buildChooseLockPasswordActivity(Intent intent) {
return Robolectric.buildActivity(ChooseLockPassword.class, intent).setup().get(); return Robolectric.buildActivity(ChooseLockPassword.class, intent).setup().get();
} }

View File

@@ -19,8 +19,7 @@ package com.android.settings.password;
import static android.content.pm.PackageManager.FEATURE_FACE; import static android.content.pm.PackageManager.FEATURE_FACE;
import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS; import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.HIDE_INSECURE_OPTIONS;
import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT;
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE;
@@ -262,12 +261,9 @@ public final class SetNewPasswordControllerTest {
private void compareFingerprintExtras(Bundle actualBundle) { private void compareFingerprintExtras(Bundle actualBundle) {
assertEquals( assertEquals(
"Password quality must be something in order to config fingerprint.", "Insecure options must be disabled in order to config fingerprint.",
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, true,
actualBundle.getInt(MINIMUM_QUALITY_KEY)); actualBundle.getBoolean(HIDE_INSECURE_OPTIONS));
assertTrue(
"All disabled preference should be removed.",
actualBundle.getBoolean(HIDE_DISABLED_PREFS));
assertTrue( assertTrue(
"Fingerprint enroll must request Gatekeeper Password.", "Fingerprint enroll must request Gatekeeper Password.",
actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW_HANDLE)); actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW_HANDLE));
@@ -282,12 +278,9 @@ public final class SetNewPasswordControllerTest {
private void compareFaceExtras(Bundle actualBundle) { private void compareFaceExtras(Bundle actualBundle) {
assertEquals( assertEquals(
"Password quality must be something in order to config face.", "Insecure options must be disabled in order to config face.",
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, true,
actualBundle.getInt(MINIMUM_QUALITY_KEY)); actualBundle.getBoolean(HIDE_INSECURE_OPTIONS));
assertTrue(
"All disabled preference should be removed.",
actualBundle.getBoolean(HIDE_DISABLED_PREFS));
assertTrue( assertTrue(
"Face enroll must request Gatekeeper Password", "Face enroll must request Gatekeeper Password",
actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW_HANDLE)); actualBundle.getBoolean(EXTRA_KEY_REQUEST_GK_PW_HANDLE));

View File

@@ -198,8 +198,7 @@ public class SetupChooseLockPasswordTest {
@Implements(ChooseLockGenericController.class) @Implements(ChooseLockGenericController.class)
public static class ShadowChooseLockGenericController { public static class ShadowChooseLockGenericController {
@Implementation @Implementation
protected List<ScreenLockType> getVisibleScreenLockTypes(int quality, protected List<ScreenLockType> getVisibleScreenLockTypes() {
boolean includeDisabled) {
return Collections.emptyList(); return Collections.emptyList();
} }
} }