diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/keyguard/PasswordTextView.java | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java index 12f75bb2d56c..d3dded0e25b2 100644 --- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java +++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java @@ -31,6 +31,7 @@ import android.os.PowerManager; import android.os.SystemClock; import android.provider.Settings; import android.text.InputType; +import android.text.TextUtils; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; @@ -78,6 +79,8 @@ public class PasswordTextView extends View { */ private static final float OVERSHOOT_TIME_POSITION = 0.5f; + private static char DOT = '\u2022'; + /** * The raw text size, will be multiplied by the scaled density when drawn */ @@ -208,7 +211,7 @@ public class PasswordTextView extends View { public void append(char c) { int visibleChars = mTextChars.size(); - String textbefore = mText; + CharSequence textbefore = getTransformedText(); mText = mText + c; int newLength = mText.length(); CharState charState; @@ -245,7 +248,7 @@ public class PasswordTextView extends View { public void deleteLastChar() { int length = mText.length(); - String textbefore = mText; + CharSequence textbefore = getTransformedText(); if (length > 0) { mText = mText.substring(0, length - 1); CharState charState = mTextChars.get(length - 1); @@ -259,6 +262,21 @@ public class PasswordTextView extends View { return mText; } + private CharSequence getTransformedText() { + int textLength = mTextChars.size(); + StringBuilder stringBuilder = new StringBuilder(textLength); + for (int i = 0; i < textLength; i++) { + CharState charState = mTextChars.get(i); + // If the dot is disappearing, the character is disappearing entirely. Consider + // it gone. + if (charState.dotAnimator != null && !charState.dotAnimationIsGrowing) { + continue; + } + stringBuilder.append(charState.isCharVisibleForA11y() ? charState.whichChar : DOT); + } + return stringBuilder; + } + private CharState obtainCharState(char c) { CharState charState; if(mCharPool.isEmpty()) { @@ -272,7 +290,7 @@ public class PasswordTextView extends View { } public void reset(boolean animated, boolean announce) { - String textbefore = mText; + CharSequence textbefore = getTransformedText(); mText = ""; int length = mTextChars.size(); int middleIndex = (length - 1) / 2; @@ -305,7 +323,7 @@ public class PasswordTextView extends View { } } - void sendAccessibilityEventTypeViewTextChanged(String beforeText, int fromIndex, + void sendAccessibilityEventTypeViewTextChanged(CharSequence beforeText, int fromIndex, int removedCount, int addedCount) { if (AccessibilityManager.getInstance(mContext).isEnabled() && (isFocused() || isSelected() && isShown())) { @@ -315,6 +333,10 @@ public class PasswordTextView extends View { event.setRemovedCount(removedCount); event.setAddedCount(addedCount); event.setBeforeText(beforeText); + CharSequence transformedText = getTransformedText(); + if (!TextUtils.isEmpty(transformedText)) { + event.getText().add(transformedText); + } event.setPassword(true); sendAccessibilityEventUnchecked(event); } @@ -332,8 +354,9 @@ public class PasswordTextView extends View { public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); - info.setClassName(PasswordTextView.class.getName()); + info.setClassName(EditText.class.getName()); info.setPassword(true); + info.setText(getTransformedText()); info.setEditable(true); @@ -420,7 +443,19 @@ public class PasswordTextView extends View { = new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { + boolean textVisibleBefore = isCharVisibleForA11y(); + float beforeTextSizeFactor = currentTextSizeFactor; currentTextSizeFactor = (float) animation.getAnimatedValue(); + if (textVisibleBefore != isCharVisibleForA11y()) { + currentTextSizeFactor = beforeTextSizeFactor; + CharSequence beforeText = getTransformedText(); + currentTextSizeFactor = (float) animation.getAnimatedValue(); + int indexOfThisChar = mTextChars.indexOf(CharState.this); + if (indexOfThisChar >= 0) { + sendAccessibilityEventTypeViewTextChanged( + beforeText, indexOfThisChar, 1, 1); + } + } invalidate(); } }; @@ -673,5 +708,13 @@ public class PasswordTextView extends View { } return charWidth + mCharPadding * currentWidthFactor; } + + public boolean isCharVisibleForA11y() { + // The text has size 0 when it is first added, but we want to count it as visible if + // it will become visible presently. Count text as visible if an animator + // is configured to make it grow. + boolean textIsGrowing = textAnimator != null && textAnimationIsGrowing; + return (currentTextSizeFactor > 0) || textIsGrowing; + } } } |