From 67319f92f31ca5b40e1f80f7b9ae63b9d8886f0e Mon Sep 17 00:00:00 2001
From: Alan Viverette <alanv@google.com>
Date: Fri, 27 Sep 2013 14:15:53 -0700
Subject: [PATCH] Speak auto-corrections for accessibility

BUG: 8669376
Change-Id: Id71b2c2835daa7a8c9d6c92c57a7e302551c289d
---
 java/res/values/strings.xml                   |  5 ++
 .../AccessibilityEntityProvider.java          | 12 ++++-
 .../accessibility/AccessibilityUtils.java     | 53 +++++++++++++++++++
 .../android/inputmethod/latin/LatinIME.java   |  5 ++
 4 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 69da1e8625..06f4b47894 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -174,6 +174,11 @@
     <!-- Spoken description when there is no text entered -->
     <string name="spoken_no_text_entered">No text entered</string>
 
+    <!-- Spoken description to let the user know what auto-correction will be performed when a key is pressed. -->
+    <string name="spoken_auto_correct"><xliff:g id="key" example="Space">%1$s</xliff:g> corrects <xliff:g id="original">%2$s</xliff:g> to <xliff:g id="corrected">%3$s</xliff:g></string>
+    <!-- Spoken description used during obscured (e.g. password) entry to let the user know that auto-correction will be performed when a key is pressed. -->
+    <string name="spoken_auto_correct_obscured"><xliff:g id="key" example="Space">%1$s</xliff:g> has auto-correction</string>
+
     <!-- Spoken description for unknown keyboard keys. -->
     <string name="spoken_description_unknown">Key code %d</string>
     <!-- Spoken description for the "Shift" keyboard key when "Shift" is off. -->
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
index 7639432aa2..c628c5b09d 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
@@ -35,6 +35,8 @@ import android.view.inputmethod.EditorInfo;
 import com.android.inputmethod.keyboard.Key;
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.settings.SettingsValues;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.CoordinateUtils;
 
@@ -285,9 +287,15 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
     private String getKeyDescription(final Key key) {
         final EditorInfo editorInfo = mInputMethodService.getCurrentInputEditorInfo();
         final boolean shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo);
-        final String keyDescription = mKeyCodeDescriptionMapper.getDescriptionForKey(
+        final SettingsValues currentSettings = Settings.getInstance().getCurrent();
+        final String keyCodeDescription = mKeyCodeDescriptionMapper.getDescriptionForKey(
                 mKeyboardView.getContext(), mKeyboardView.getKeyboard(), key, shouldObscure);
-        return keyDescription;
+        if (currentSettings.isWordSeparator(key.getCode())) {
+            return mAccessibilityUtils.getAutoCorrectionDescription(
+                    keyCodeDescription, shouldObscure);
+        } else {
+            return keyCodeDescription;
+        }
     }
 
     /**
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index 8929dc7e96..10fb9fef45 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -23,6 +23,7 @@ import android.os.Build;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
@@ -34,6 +35,7 @@ import android.view.inputmethod.EditorInfo;
 
 import com.android.inputmethod.compat.SettingsSecureCompatUtils;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.utils.InputTypeUtils;
 
 public final class AccessibilityUtils {
@@ -48,6 +50,12 @@ public final class AccessibilityUtils {
     private AccessibilityManager mAccessibilityManager;
     private AudioManager mAudioManager;
 
+    /** The most recent auto-correction. */
+    private String mAutoCorrectionWord;
+
+    /** The most recent typed word for auto-correction. */
+    private String mTypedWord;
+
     /*
      * Setting this constant to {@code false} will disable all keyboard
      * accessibility code, regardless of whether Accessibility is turned on in
@@ -141,6 +149,51 @@ public final class AccessibilityUtils {
         return InputTypeUtils.isPasswordInputType(editorInfo.inputType);
     }
 
+    /**
+     * Sets the current auto-correction word and typed word. These may be used
+     * to provide the user with a spoken description of what auto-correction
+     * will occur when a key is typed.
+     *
+     * @param suggestedWords the list of suggested auto-correction words
+     * @param typedWord the currently typed word
+     */
+    public void setAutoCorrection(final SuggestedWords suggestedWords, final String typedWord) {
+        if (suggestedWords != null && suggestedWords.mWillAutoCorrect) {
+            mAutoCorrectionWord = suggestedWords.getWord(SuggestedWords.INDEX_OF_AUTO_CORRECTION);
+            mTypedWord = typedWord;
+        } else {
+            mAutoCorrectionWord = null;
+            mTypedWord = null;
+        }
+    }
+
+    /**
+     * Obtains a description for an auto-correction key, taking into account the
+     * currently typed word and auto-correction.
+     *
+     * @param keyCodeDescription spoken description of the key that will insert
+     *            an auto-correction
+     * @param shouldObscure whether the key should be obscured
+     * @return a description including a description of the auto-correction, if
+     *         needed
+     */
+    public String getAutoCorrectionDescription(
+            final String keyCodeDescription, final boolean shouldObscure) {
+        if (!TextUtils.isEmpty(mAutoCorrectionWord)) {
+            if (!TextUtils.equals(mAutoCorrectionWord, mTypedWord)) {
+                if (shouldObscure) {
+                    // This should never happen, but just in case...
+                    return mContext.getString(R.string.spoken_auto_correct_obscured,
+                            keyCodeDescription);
+                }
+                return mContext.getString(R.string.spoken_auto_correct, keyCodeDescription,
+                        mTypedWord, mAutoCorrectionWord);
+            }
+        }
+
+        return keyCodeDescription;
+    }
+
     /**
      * Sends the specified text to the {@link AccessibilityManager} to be
      * spoken.
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 270dc4c06e..c383f3e31f 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -2553,6 +2553,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     private void showSuggestionStripWithTypedWord(final SuggestedWords suggestedWords,
             final String typedWord) {
       if (suggestedWords.isEmpty()) {
+          // No auto-correction is available, clear the cached values.
+          AccessibilityUtils.getInstance().setAutoCorrection(null, null);
           clearSuggestionStrip();
           return;
       }
@@ -2561,6 +2563,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
       setSuggestedWords(suggestedWords, isAutoCorrection);
       setAutoCorrectionIndicator(isAutoCorrection);
       setSuggestionStripShown(isSuggestionsStripVisible());
+      // An auto-correction is available, cache it in accessibility code so
+      // we can be speak it if the user touches a key that will insert it.
+      AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords, typedWord);
     }
 
     private void showSuggestionStrip(final SuggestedWords suggestedWords) {
-- 
GitLab