Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 271bdbf9 authored by Phil Weaver's avatar Phil Weaver Committed by Android (Google) Code Review
Browse files

Merge "Fix accessibility reporting for lock screen PIN"

parents 0ce51f60 c355c7a9
Loading
Loading
Loading
Loading
+48 −5
Original line number Diff line number Diff line
@@ -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;
        }
    }
}