summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Roos <roosa@google.com>2015-01-15 19:57:51 +0100
committerAdrian Roos <roosa@google.com>2015-02-09 15:55:21 +0000
commita48caee9a717afe80a2210e5db3a4d6dabd952b5 (patch)
treed9cdabbc00b330915a04b3402de598ff58f92a55
parent07c745b525d39309a9ea93605fb5f85c295502f1 (diff)
downloadframeworks_base-a48caee9a717afe80a2210e5db3a4d6dabd952b5.zip
frameworks_base-a48caee9a717afe80a2210e5db3a4d6dabd952b5.tar.gz
frameworks_base-a48caee9a717afe80a2210e5db3a4d6dabd952b5.tar.bz2
Added TEXT_CHANGED event to PasswordTextView
Also creates a TextView-like accessibility node and populates accessibility events with text if required. Bug: 18528774 Change-Id: I4a918a092b1e97879c31f54604cf957e01f4bc86
-rw-r--r--packages/Keyguard/src/com/android/keyguard/PasswordTextView.java76
1 files changed, 76 insertions, 0 deletions
diff --git a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
index 6497f46..67ddcfa 100644
--- a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
@@ -28,9 +28,15 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.provider.Settings;
+import android.text.InputType;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -176,6 +182,7 @@ public class PasswordTextView extends View {
public void append(char c) {
int visibleChars = mTextChars.size();
+ String textbefore = mText;
mText = mText + c;
int newLength = mText.length();
CharState charState;
@@ -196,6 +203,7 @@ public class PasswordTextView extends View {
}
}
userActivity();
+ sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length(), 0, 1);
}
private void userActivity() {
@@ -204,12 +212,14 @@ public class PasswordTextView extends View {
public void deleteLastChar() {
int length = mText.length();
+ String textbefore = mText;
if (length > 0) {
mText = mText.substring(0, length - 1);
CharState charState = mTextChars.get(length - 1);
charState.startRemoveAnimation(0, 0);
}
userActivity();
+ sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
}
public String getText() {
@@ -229,6 +239,7 @@ public class PasswordTextView extends View {
}
public void reset(boolean animated) {
+ String textbefore = mText;
mText = "";
int length = mTextChars.size();
int middleIndex = (length - 1) / 2;
@@ -256,6 +267,71 @@ public class PasswordTextView extends View {
if (!animated) {
mTextChars.clear();
}
+ sendAccessibilityEventTypeViewTextChanged(textbefore, 0, textbefore.length(), 0);
+ }
+
+ void sendAccessibilityEventTypeViewTextChanged(String beforeText, int fromIndex,
+ int removedCount, int addedCount) {
+ if (AccessibilityManager.getInstance(mContext).isEnabled() &&
+ (isFocused() || isSelected() && isShown())) {
+ if (!shouldSpeakPasswordsForAccessibility()) {
+ beforeText = null;
+ }
+ AccessibilityEvent event =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+ event.setFromIndex(fromIndex);
+ event.setRemovedCount(removedCount);
+ event.setAddedCount(addedCount);
+ event.setBeforeText(beforeText);
+ event.setPassword(true);
+ sendAccessibilityEventUnchecked(event);
+ }
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+
+ event.setClassName(PasswordTextView.class.getName());
+ event.setPassword(true);
+ }
+
+ @Override
+ public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+ super.onPopulateAccessibilityEvent(event);
+
+ if (shouldSpeakPasswordsForAccessibility()) {
+ final CharSequence text = mText;
+ if (!TextUtils.isEmpty(text)) {
+ event.getText().add(text);
+ }
+ }
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+
+ info.setClassName(PasswordTextView.class.getName());
+ info.setPassword(true);
+
+ if (shouldSpeakPasswordsForAccessibility()) {
+ info.setText(mText);
+ }
+
+ info.setEditable(true);
+
+ info.setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+ }
+
+ /**
+ * @return true if the user has explicitly allowed accessibility services
+ * to speak passwords.
+ */
+ private boolean shouldSpeakPasswordsForAccessibility() {
+ return (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0,
+ UserHandle.USER_CURRENT_OR_SELF) == 1);
}
private class CharState {