Merge "Too short error message on CDC is no longer red." into main

This commit is contained in:
Joshua Mccloskey
2024-07-19 21:38:01 +00:00
committed by Android (Google) Code Review
4 changed files with 79 additions and 5 deletions

View File

@@ -955,11 +955,16 @@
<item name="biometricsEnrollProgressHelpWithTalkback">@color/udfps_enroll_progress_help_with_talkback</item> <item name="biometricsEnrollProgressHelpWithTalkback">@color/udfps_enroll_progress_help_with_talkback</item>
</style> </style>
<style name="ScreenLockPasswordHintTextFontStyle"> <style name="ScreenLockPasswordHintTextFontStyleError">
<item name="android:textColor">?android:attr/colorError</item> <item name="android:textColor">?android:attr/colorError</item>
<item name="android:fontFamily">google-sans-text</item> <item name="android:fontFamily">google-sans-text</item>
</style> </style>
<style name="ScreenLockPasswordHintTextFontStyle">
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:fontFamily">google-sans-text</item>
</style>
<style name="PrivateSpaceSetupTextFontStyle" parent="@android:style/TextAppearance.DeviceDefault"> <style name="PrivateSpaceSetupTextFontStyle" parent="@android:style/TextAppearance.DeviceDefault">
<item name="android:textColor">?android:attr/textColorPrimary</item> <item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:fontFamily">google-sans-text</item> <item name="android:fontFamily">google-sans-text</item>

View File

@@ -271,6 +271,8 @@ public class ChooseLockPassword extends SettingsActivity {
private static final int CONFIRM_EXISTING_REQUEST = 58; private static final int CONFIRM_EXISTING_REQUEST = 58;
static final int RESULT_FINISHED = RESULT_FIRST_USER; static final int RESULT_FINISHED = RESULT_FIRST_USER;
private boolean mIsErrorTooShort = true;
/** Used to store the profile type for which pin/password is being set */ /** Used to store the profile type for which pin/password is being set */
protected enum ProfileType { protected enum ProfileType {
None, None,
@@ -672,6 +674,11 @@ public class ChooseLockPassword extends SettingsActivity {
view.addView(mPasswordRestrictionView); view.addView(mPasswordRestrictionView);
} }
@VisibleForTesting
View getPasswordRequirementsView() {
return mPasswordRestrictionView;
}
private void createHintMessageView(ViewGroup view) { private void createHintMessageView(ViewGroup view) {
if (mPasswordRestrictionView != null) { if (mPasswordRestrictionView != null) {
return; return;
@@ -855,6 +862,7 @@ public class ChooseLockPassword extends SettingsActivity {
*/ */
String[] convertErrorCodeToMessages() { String[] convertErrorCodeToMessages() {
List<String> messages = new ArrayList<>(); List<String> messages = new ArrayList<>();
mIsErrorTooShort = false;
for (PasswordValidationError error : mValidationErrors) { for (PasswordValidationError error : mValidationErrors) {
switch (error.errorCode) { switch (error.errorCode) {
case CONTAINS_INVALID_CHARACTERS: case CONTAINS_INVALID_CHARACTERS:
@@ -889,6 +897,7 @@ public class ChooseLockPassword extends SettingsActivity {
R.string.lockpassword_password_requires_nonnumerical)); R.string.lockpassword_password_requires_nonnumerical));
break; break;
case TOO_SHORT: case TOO_SHORT:
mIsErrorTooShort = true;
String message = StringUtil.getIcuPluralsString(getContext(), String message = StringUtil.getIcuPluralsString(getContext(),
error.requirement, error.requirement,
mIsAlphaMode mIsAlphaMode
@@ -951,12 +960,13 @@ public class ChooseLockPassword extends SettingsActivity {
? LockscreenCredential.createPassword(mPasswordEntry.getText()) ? LockscreenCredential.createPassword(mPasswordEntry.getText())
: LockscreenCredential.createPin(mPasswordEntry.getText()); : LockscreenCredential.createPin(mPasswordEntry.getText());
final int length = password.size(); final int length = password.size();
if (mUiStage == Stage.Introduction) { if (mUiStage == Stage.Introduction) {
mPasswordRestrictionView.setVisibility(View.VISIBLE); mPasswordRestrictionView.setVisibility(View.VISIBLE);
final boolean passwordCompliant = validatePassword(password); final boolean passwordCompliant = validatePassword(password);
String[] messages = convertErrorCodeToMessages(); String[] messages = convertErrorCodeToMessages();
// Update the fulfillment of requirements. // Update the fulfillment of requirements.
mPasswordRequirementAdapter.setRequirements(messages); mPasswordRequirementAdapter.setRequirements(messages, mIsErrorTooShort);
// set the visibility of pin_auto_confirm option accordingly // set the visibility of pin_auto_confirm option accordingly
setAutoPinConfirmOption(passwordCompliant, length); setAutoPinConfirmOption(passwordCompliant, length);
// Enable/Disable the next button accordingly. // Enable/Disable the next button accordingly.

View File

@@ -36,6 +36,7 @@ public class PasswordRequirementAdapter extends
private String[] mRequirements; private String[] mRequirements;
private Context mContext; private Context mContext;
private boolean mIsTooShortError = true;
public PasswordRequirementAdapter(Context context) { public PasswordRequirementAdapter(Context context) {
mContext = context; mContext = context;
@@ -54,8 +55,9 @@ public class PasswordRequirementAdapter extends
return mRequirements.length; return mRequirements.length;
} }
public void setRequirements(String[] requirements) { public void setRequirements(String[] requirements, boolean isPasswordShort) {
mRequirements = requirements; mRequirements = requirements;
mIsTooShortError = isPasswordShort;
notifyDataSetChanged(); notifyDataSetChanged();
} }
@@ -74,7 +76,12 @@ public class PasswordRequirementAdapter extends
final int fontSize = mContext.getResources().getDimensionPixelSize( final int fontSize = mContext.getResources().getDimensionPixelSize(
R.dimen.password_requirement_font_size); R.dimen.password_requirement_font_size);
holder.mDescriptionText.setText(mRequirements[position]); holder.mDescriptionText.setText(mRequirements[position]);
holder.mDescriptionText.setTextAppearance(R.style.ScreenLockPasswordHintTextFontStyle); if (mIsTooShortError) {
holder.mDescriptionText.setTextAppearance(R.style.ScreenLockPasswordHintTextFontStyle);
} else {
holder.mDescriptionText.
setTextAppearance(R.style.ScreenLockPasswordHintTextFontStyleError);
}
holder.mDescriptionText.setTextSize(fontSize / mContext.getResources() holder.mDescriptionText.setTextSize(fontSize / mContext.getResources()
.getDisplayMetrics().scaledDensity); .getDisplayMetrics().scaledDensity);
} }

View File

@@ -36,19 +36,25 @@ 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.robolectric.RuntimeEnvironment.application; import static org.robolectric.RuntimeEnvironment.application;
import static org.robolectric.Shadows.shadowOf;
import android.annotation.ColorInt;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.PasswordComplexity; import android.app.admin.DevicePolicyManager.PasswordComplexity;
import android.app.admin.PasswordMetrics; import android.app.admin.PasswordMetrics;
import android.app.admin.PasswordPolicy; import android.app.admin.PasswordPolicy;
import android.content.Intent; import android.content.Intent;
import android.os.Looper;
import android.os.UserHandle; import android.os.UserHandle;
import android.view.View; import android.view.View;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.TextView; import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.LockscreenCredential;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment; import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment;
import com.android.settings.password.ChooseLockPassword.IntentBuilder; import com.android.settings.password.ChooseLockPassword.IntentBuilder;
import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.SettingsShadowResources;
@@ -515,6 +521,52 @@ public class ChooseLockPasswordTest {
assertThat(pinAutoConfirmOption.isChecked()).isFalse(); assertThat(pinAutoConfirmOption.isChecked()).isFalse();
} }
@Test
public void defaultMessage_shouldBeInTextColorPrimary() {
final ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
final ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
final ScrollToParentEditText passwordEntry = passwordActivity.findViewById(R.id.password_entry);
final RecyclerView view = (RecyclerView) fragment.getPasswordRequirementsView();
@ColorInt final int textColorPrimary = Utils.getColorAttrDefaultColor(passwordActivity,
android.R.attr.textColorPrimary);
passwordEntry.setText("");
fragment.updateUi();
shadowOf(Looper.getMainLooper()).idle();
TextView textView = (TextView)view.getLayoutManager().findViewByPosition(0);
assertThat(textView.getCurrentTextColor()).isEqualTo(textColorPrimary);
}
@Test
public void errorMessage_shouldBeColorError() {
final ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
final ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
final ScrollToParentEditText passwordEntry = passwordActivity.findViewById(R.id.password_entry);
final RecyclerView view = (RecyclerView) fragment.getPasswordRequirementsView();
@ColorInt final int textColorPrimary = Utils.getColorAttrDefaultColor(passwordActivity,
android.R.attr.textColorPrimary);
@ColorInt final int colorError = Utils.getColorAttrDefaultColor(passwordActivity,
android.R.attr.colorError);
passwordEntry.setText("");
fragment.updateUi();
shadowOf(Looper.getMainLooper()).idle();
TextView textView = (TextView)view.getLayoutManager().findViewByPosition(0);
assertThat(textView.getCurrentTextColor()).isEqualTo(textColorPrimary);
// Password must be fewer than 17 digits, so this should give an error.
passwordEntry.setText("a".repeat(17));
fragment.updateUi();
shadowOf(Looper.getMainLooper()).idle();
textView = (TextView)view.getLayoutManager().findViewByPosition(0);
assertThat(textView.getCurrentTextColor()).isEqualTo(colorError);
}
private ChooseLockPassword setupActivityWithPinTypeAndDefaultPolicy() { private ChooseLockPassword setupActivityWithPinTypeAndDefaultPolicy() {
PasswordPolicy policy = new PasswordPolicy(); PasswordPolicy policy = new PasswordPolicy();
policy.quality = PASSWORD_QUALITY_UNSPECIFIED; policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
@@ -543,7 +595,7 @@ public class ChooseLockPasswordTest {
.setForFingerprint(addFingerprintExtra) .setForFingerprint(addFingerprintExtra)
.build()); .build());
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity); ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
return Shadows.shadowOf(((GlifLayout) fragment.getView()).getIcon()); return shadowOf(((GlifLayout) fragment.getView()).getIcon());
} }
private void assertPasswordValidationResult(PasswordMetrics minMetrics, private void assertPasswordValidationResult(PasswordMetrics minMetrics,