Merge "Deprecate "speak passwords" setting."
diff --git a/api/current.txt b/api/current.txt
index 67cdc9c..475aa54 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -34264,7 +34264,7 @@
method public static final deprecated void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean);
field public static final java.lang.String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = "accessibility_display_inversion_enabled";
field public static final java.lang.String ACCESSIBILITY_ENABLED = "accessibility_enabled";
- field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
+ field public static final deprecated java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
field public static final deprecated java.lang.String ADB_ENABLED = "adb_enabled";
field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
field public static final deprecated java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
diff --git a/api/system-current.txt b/api/system-current.txt
index dcd2103..c80beff 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -37369,7 +37369,7 @@
method public static final deprecated void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean);
field public static final java.lang.String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = "accessibility_display_inversion_enabled";
field public static final java.lang.String ACCESSIBILITY_ENABLED = "accessibility_enabled";
- field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
+ field public static final deprecated java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
field public static final deprecated java.lang.String ADB_ENABLED = "adb_enabled";
field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
field public static final deprecated java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
diff --git a/api/test-current.txt b/api/test-current.txt
index 319d9f3..fec5edc 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -34387,7 +34387,7 @@
method public static final deprecated void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean);
field public static final java.lang.String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED = "accessibility_display_inversion_enabled";
field public static final java.lang.String ACCESSIBILITY_ENABLED = "accessibility_enabled";
- field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
+ field public static final deprecated java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
field public static final deprecated java.lang.String ADB_ENABLED = "adb_enabled";
field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
field public static final deprecated java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index d1000ad..13b9206 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -988,49 +988,31 @@
if (mAccessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
onInitializeAccessibilityEvent(event);
- String text = null;
- // This is very efficient since the properties are cached.
- final boolean speakPassword = Settings.Secure.getIntForUser(
- mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0,
- UserHandle.USER_CURRENT_OR_SELF) != 0;
- // Add text only if password announcement is enabled or if headset is
- // used to avoid leaking passwords.
- if (speakPassword || mAudioManager.isBluetoothA2dpOn()
- || mAudioManager.isWiredHeadsetOn()) {
- switch (code) {
- case Keyboard.KEYCODE_ALT:
- text = mContext.getString(R.string.keyboardview_keycode_alt);
- break;
- case Keyboard.KEYCODE_CANCEL:
- text = mContext.getString(R.string.keyboardview_keycode_cancel);
- break;
- case Keyboard.KEYCODE_DELETE:
- text = mContext.getString(R.string.keyboardview_keycode_delete);
- break;
- case Keyboard.KEYCODE_DONE:
- text = mContext.getString(R.string.keyboardview_keycode_done);
- break;
- case Keyboard.KEYCODE_MODE_CHANGE:
- text = mContext.getString(R.string.keyboardview_keycode_mode_change);
- break;
- case Keyboard.KEYCODE_SHIFT:
- text = mContext.getString(R.string.keyboardview_keycode_shift);
- break;
- case '\n':
- text = mContext.getString(R.string.keyboardview_keycode_enter);
- break;
- default:
- text = String.valueOf((char) code);
- }
- } else if (!mHeadsetRequiredToHearPasswordsAnnounced) {
- // We want the waring for required head set to be send with both the
- // hover enter and hover exit event, so set the flag after the exit.
- if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
- mHeadsetRequiredToHearPasswordsAnnounced = true;
- }
- text = mContext.getString(R.string.keyboard_headset_required_to_hear_password);
- } else {
- text = mContext.getString(R.string.keyboard_password_character_no_headset);
+ final String text;
+ switch (code) {
+ case Keyboard.KEYCODE_ALT:
+ text = mContext.getString(R.string.keyboardview_keycode_alt);
+ break;
+ case Keyboard.KEYCODE_CANCEL:
+ text = mContext.getString(R.string.keyboardview_keycode_cancel);
+ break;
+ case Keyboard.KEYCODE_DELETE:
+ text = mContext.getString(R.string.keyboardview_keycode_delete);
+ break;
+ case Keyboard.KEYCODE_DONE:
+ text = mContext.getString(R.string.keyboardview_keycode_done);
+ break;
+ case Keyboard.KEYCODE_MODE_CHANGE:
+ text = mContext.getString(R.string.keyboardview_keycode_mode_change);
+ break;
+ case Keyboard.KEYCODE_SHIFT:
+ text = mContext.getString(R.string.keyboardview_keycode_shift);
+ break;
+ case '\n':
+ text = mContext.getString(R.string.keyboardview_keycode_enter);
+ break;
+ default:
+ text = String.valueOf((char) code);
}
event.getText().add(text);
mAccessibilityManager.sendAccessibilityEvent(event);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ebc5b88..3ece9b3 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5492,7 +5492,12 @@
/**
* Whether to speak passwords while in accessibility mode.
+ *
+ * @deprecated The speaking of passwords is controlled by individual accessibility services.
+ * Apps should ignore this setting and provide complete information to accessibility
+ * at all times, which was the behavior when this value was {@code true}.
*/
+ @Deprecated
public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
/**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bfaddaf..ab29257 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -63,7 +63,6 @@
import android.os.Parcelable;
import android.os.ParcelableParcel;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.provider.Settings;
import android.text.BoringLayout;
import android.text.DynamicLayout;
@@ -9854,16 +9853,6 @@
}
}
- /**
- * @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);
- }
-
@Override
public CharSequence getAccessibilityClassName() {
return TextView.class.getName();
@@ -10436,13 +10425,7 @@
return mHint;
}
- // Check whether we need to bypass the transformation
- // method and expose unobscured text.
- if (hasPasswordTransformationMethod() && shouldSpeakPasswordsForAccessibility()) {
- return mText;
- }
-
- // Otherwise, speak whatever text is being displayed.
+ // Otherwise, return whatever text is being displayed.
return mTransformed;
}
@@ -11559,9 +11542,7 @@
+ " before=" + before + " after=" + after + ": " + buffer);
}
- if (AccessibilityManager.getInstance(mContext).isEnabled()
- && ((!isPasswordInputType(getInputType()) && !hasPasswordTransformationMethod())
- || shouldSpeakPasswordsForAccessibility())) {
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
mBeforeText = buffer.toString();
}
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 4ba19f4..ae2e0ac 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -1489,21 +1489,10 @@
return bounds;
}
- private boolean shouldSpeakPassword() {
- final boolean speakPassword = Settings.Secure.getIntForUser(
- mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0,
- UserHandle.USER_CURRENT_OR_SELF) != 0;
- final boolean hasHeadphones = mAudioManager != null ?
- (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn())
- : false;
- return speakPassword || hasHeadphones;
- }
-
private CharSequence getTextForVirtualView(int virtualViewId) {
final Resources res = getResources();
- return shouldSpeakPassword() ? res.getString(
- R.string.lockscreen_access_pattern_cell_added_verbose, virtualViewId)
- : res.getString(R.string.lockscreen_access_pattern_cell_added);
+ return res.getString(R.string.lockscreen_access_pattern_cell_added_verbose,
+ virtualViewId);
}
/**
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7069d16..f6da660 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3527,11 +3527,6 @@
<!-- Description of the unlock handle in the Slide unlock screen for tablets. [CHAR LIMIT=NONE] -->
<string name="description_target_unlock_tablet">Swipe to unlock.</string>
- <!-- Announce that a headset is required to hear keyboard keys while typing a password. [CHAR LIMIT=NONE] -->
- <string name="keyboard_headset_required_to_hear_password">Plug in a headset to hear password keys spoken.</string>
- <!-- The value of a keyboard key announced when accessibility is enabled and no headsed is used. [CHAR LIMIT=NONE] -->
- <string name="keyboard_password_character_no_headset">Dot.</string>
-
<!-- Content description for the action bar "home" affordance. [CHAR LIMIT=NONE] -->
<string name="action_bar_home_description">Navigate home</string>
<!-- Content description for the action bar "up" affordance. [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b5a5125..db0298a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -708,8 +708,6 @@
<java-symbol type="string" name="js_dialog_before_unload" />
<java-symbol type="string" name="js_dialog_title" />
<java-symbol type="string" name="js_dialog_title_default" />
- <java-symbol type="string" name="keyboard_headset_required_to_hear_password" />
- <java-symbol type="string" name="keyboard_password_character_no_headset" />
<java-symbol type="string" name="keyboardview_keycode_alt" />
<java-symbol type="string" name="keyboardview_keycode_cancel" />
<java-symbol type="string" name="keyboardview_keycode_delete" />
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 136f17e..f660e1e 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -98,7 +98,7 @@
<bool name="def_accessibility_script_injection">false</bool>
<!-- Default for Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD -->
- <bool name="def_accessibility_speak_password">false</bool>
+ <bool name="def_accessibility_speak_password">true</bool>
<!-- Default for Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS -->
<string name="def_accessibility_web_content_key_bindings" translatable="false">
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 1d89440..a71db85 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2735,7 +2735,7 @@
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 139;
+ private static final int SETTINGS_VERSION = 140;
private final int mUserId;
@@ -3186,6 +3186,16 @@
currentVersion = 139;
}
+ if (currentVersion == 139) {
+ // Version 140: Settings.Secure#ACCESSIBILITY_SPEAK_PASSWORD is deprecated and
+ // the user can no longer change the value of this setting through the UI.
+ // Force to true.
+ final SettingsState secureSettings = getSecureSettingsLocked(userId);
+ secureSettings.updateSettingLocked(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
+ "1", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ currentVersion = 140;
+ }
+
if (currentVersion != newVersion) {
Slog.wtf("SettingsProvider", "warning: upgrading settings database to version "
+ newVersion + " left it at "
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 1518bdc..45f1686 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -89,7 +89,6 @@
setOnClickListener(mListener);
setOnHoverListener(new LiftToActivateListener(context));
- setAccessibilityDelegate(new ObscureSpeechDelegate(context));
mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
@@ -134,14 +133,6 @@
}
@Override
- public void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
- // Reset the "announced headset" flag when detached.
- ObscureSpeechDelegate.sAnnouncedHeadset = false;
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
diff --git a/packages/SystemUI/src/com/android/keyguard/ObscureSpeechDelegate.java b/packages/SystemUI/src/com/android/keyguard/ObscureSpeechDelegate.java
deleted file mode 100644
index 410a43a..0000000
--- a/packages/SystemUI/src/com/android/keyguard/ObscureSpeechDelegate.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.keyguard;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.media.AudioManager;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.view.View;
-import android.view.View.AccessibilityDelegate;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.android.internal.R;
-
-/**
- * Accessibility delegate that obscures speech for a view when the user has
- * not turned on the "speak passwords" preference and is not listening
- * through headphones.
- */
-class ObscureSpeechDelegate extends AccessibilityDelegate {
- /** Whether any client has announced the "headset" notification. */
- static boolean sAnnouncedHeadset = false;
-
- private final ContentResolver mContentResolver;
- private final AudioManager mAudioManager;
-
- public ObscureSpeechDelegate(Context context) {
- mContentResolver = context.getContentResolver();
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- }
-
- @Override
- public void sendAccessibilityEvent(View host, int eventType) {
- super.sendAccessibilityEvent(host, eventType);
-
- // Play the "headset required" announcement the first time the user
- // places accessibility focus on a key.
- if ((eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED)
- && !sAnnouncedHeadset && shouldObscureSpeech()) {
- sAnnouncedHeadset = true;
- host.announceForAccessibility(host.getContext().getString(
- R.string.keyboard_headset_required_to_hear_password));
- }
- }
-
- @Override
- public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
- super.onPopulateAccessibilityEvent(host, event);
-
- if ((event.getEventType() != AccessibilityEvent.TYPE_ANNOUNCEMENT)
- && shouldObscureSpeech()) {
- event.getText().clear();
- event.setContentDescription(host.getContext().getString(
- R.string.keyboard_password_character_no_headset));
- }
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(host, info);
-
- if (shouldObscureSpeech()) {
- final Context ctx = host.getContext();
- info.setText(null);
- info.setContentDescription(
- ctx.getString(R.string.keyboard_password_character_no_headset));
- }
- }
-
- @SuppressWarnings("deprecation")
- private boolean shouldObscureSpeech() {
- // The user can optionally force speaking passwords.
- if (Settings.Secure.getIntForUser(mContentResolver,
- Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0, UserHandle.USER_CURRENT) != 0) {
- return false;
- }
-
- // Always speak if the user is listening through headphones.
- if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn()) {
- return false;
- }
-
- // Don't speak since this key is used to type a password.
- return true;
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index 48737f9..c43820d 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -40,6 +40,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import android.widget.EditText;
import java.util.ArrayList;
import java.util.Stack;
@@ -306,9 +307,6 @@
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);
@@ -324,48 +322,22 @@
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
- event.setClassName(PasswordTextView.class.getName());
+ event.setClassName(EditText.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 {
char whichChar;
ValueAnimator textAnimator;