am 9d8d5297: am 10232fe6: Merge "Extracted text problems" into ics-mr1

* commit '9d8d529739b1b9790599364f57cffbe022d15ee2':
  Extracted text problems
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index 4fc63ed..72431f3 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -156,4 +156,27 @@
             mIME.onViewClicked(false);
         }
     }
+
+    /**
+     * Delete the range of text, supposedly valid
+     * @hide
+     */
+    @Override
+    protected void deleteText_internal(int start, int end) {
+        // Do not call the super method. This will change the source TextView instead, which
+        // will update the ExtractTextView.
+        mIME.onExtractedDeleteText(start, end);
+    }
+
+    /**
+     * Replaces the range of text [start, end[ by replacement text
+     * @hide
+     */
+    @Override
+    protected void replaceText_internal(int start, int end, CharSequence text) {
+        // Do not call the super method. This will change the source TextView instead, which
+        // will update the ExtractTextView.
+        mIME.onExtractedReplaceText(start, end, text);
+    }
+
 }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 60188ea..02839db 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1982,7 +1982,29 @@
             conn.setSelection(start, end);
         }
     }
-    
+
+    /**
+     * @hide
+     */
+    public void onExtractedDeleteText(int start, int end) {
+        InputConnection conn = getCurrentInputConnection();
+        if (conn != null) {
+            conn.setSelection(start, start);
+            conn.deleteSurroundingText(0, end-start);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void onExtractedReplaceText(int start, int end, CharSequence text) {
+        InputConnection conn = getCurrentInputConnection();
+        if (conn != null) {
+            conn.setComposingRegion(start, end);
+            conn.commitText(text, 1);
+        }
+    }
+
     /**
      * This is called when the user has clicked on the extracted text view,
      * when running in fullscreen mode.  The default implementation hides
@@ -1998,7 +2020,7 @@
             setCandidatesViewShown(false);
         }
     }
-    
+
     /**
      * This is called when the user has performed a cursor movement in the
      * extracted text view, when it is running in fullscreen mode.  The default
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a62d5cc5a..aa12278 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7977,16 +7977,12 @@
         @Override
         public void onClick(View view) {
             if (view == mDeleteTextView) {
-                deleteText();
-            }
-        }
-
-        private void deleteText() {
-            Editable editable = (Editable) mText;
-            int start = editable.getSpanStart(mEasyEditSpan);
-            int end = editable.getSpanEnd(mEasyEditSpan);
-            if (start >= 0 && end >= 0) {
-                editable.delete(start, end);
+                Editable editable = (Editable) mText;
+                int start = editable.getSpanStart(mEasyEditSpan);
+                int end = editable.getSpanEnd(mEasyEditSpan);
+                if (start >= 0 && end >= 0) {
+                    deleteText_internal(start, end);
+                }
             }
         }
 
@@ -9111,7 +9107,7 @@
 
             case ID_CUT:
                 setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
-                ((Editable) mText).delete(min, max);
+                deleteText_internal(min, max);
                 stopSelectionActionMode();
                 return true;
 
@@ -9142,7 +9138,7 @@
                 if (Character.isSpaceChar(charBefore) && Character.isSpaceChar(charAfter)) {
                     // Two spaces at beginning of paste: remove one
                     final int originalLength = mText.length();
-                    ((Editable) mText).delete(min - 1, min);
+                    deleteText_internal(min - 1, min);
                     // Due to filters, there is no guarantee that exactly one character was
                     // removed: count instead.
                     final int delta = mText.length() - originalLength;
@@ -9152,7 +9148,7 @@
                         !Character.isSpaceChar(charAfter) && charAfter != '\n') {
                     // No space at beginning of paste: add one
                     final int originalLength = mText.length();
-                    ((Editable) mText).replace(min, min, " ");
+                    replaceText_internal(min, min, " ");
                     // Taking possible filters into account as above.
                     final int delta = mText.length() - originalLength;
                     min += delta;
@@ -9166,11 +9162,11 @@
 
                 if (Character.isSpaceChar(charBefore) && Character.isSpaceChar(charAfter)) {
                     // Two spaces at end of paste: remove one
-                    ((Editable) mText).delete(max, max + 1);
+                    deleteText_internal(max, max + 1);
                 } else if (!Character.isSpaceChar(charBefore) && charBefore != '\n' &&
                         !Character.isSpaceChar(charAfter) && charAfter != '\n') {
                     // No space at end of paste: add one
-                    ((Editable) mText).replace(max, max, " ");
+                    replaceText_internal(max, max, " ");
                 }
             }
         }
@@ -9882,9 +9878,7 @@
 
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            TextView textView = (TextView) view;
             Editable editable = (Editable) mText;
-
             SuggestionInfo suggestionInfo = mSuggestionInfos[position];
 
             if (suggestionInfo.suggestionIndex == DELETE_TEXT) {
@@ -9898,7 +9892,7 @@
                             Character.isSpaceChar(editable.charAt(spanUnionStart - 1)))) {
                         spanUnionEnd = spanUnionEnd + 1;
                     }
-                    editable.replace(spanUnionStart, spanUnionEnd, "");
+                    deleteText_internal(spanUnionStart, spanUnionEnd);
                 }
                 hide();
                 return;
@@ -9919,6 +9913,7 @@
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 getContext().startActivity(intent);
                 // There is no way to know if the word was indeed added. Re-check.
+                // TODO The ExtractEditText should remove the span in the original text instead
                 editable.removeSpan(suggestionInfo.suggestionSpan);
                 updateSpellCheckSpans(spanStart, spanEnd);
             } else {
@@ -9946,9 +9941,9 @@
 
                 final int suggestionStart = suggestionInfo.suggestionStart;
                 final int suggestionEnd = suggestionInfo.suggestionEnd;
-                final String suggestion = textView.getText().subSequence(
+                final String suggestion = suggestionInfo.text.subSequence(
                         suggestionStart, suggestionEnd).toString();
-                editable.replace(spanStart, spanEnd, suggestion);
+                replaceText_internal(spanStart, spanEnd, suggestion);
 
                 // Notify source IME of the suggestion pick. Do this before swaping texts.
                 if (!TextUtils.isEmpty(
@@ -9972,6 +9967,7 @@
                     // way to assign them a valid range after replacement
                     if (suggestionSpansStarts[i] <= spanStart &&
                             suggestionSpansEnds[i] >= spanEnd) {
+                        // TODO The ExtractEditText should restore these spans in the original text
                         editable.setSpan(suggestionSpans[i], suggestionSpansStarts[i],
                                 suggestionSpansEnds[i] + lengthDifference, suggestionSpansFlags[i]);
                     }
@@ -11252,7 +11248,7 @@
         int max = extractRangeEndFromLong(minMax);
 
         Selection.setSelection((Spannable) mText, max);
-        ((Editable) mText).replace(min, max, content);
+        replaceText_internal(min, max, content);
 
         if (dragDropIntoItself) {
             int dragSourceStart = dragLocalState.start;
@@ -11265,7 +11261,7 @@
             }
 
             // Delete original selection
-            ((Editable) mText).delete(dragSourceStart, dragSourceEnd);
+            deleteText_internal(dragSourceStart, dragSourceEnd);
 
             // Make sure we do not leave two adjacent spaces.
             if ((dragSourceStart == 0 ||
@@ -11274,7 +11270,7 @@
                     Character.isSpaceChar(mTransformed.charAt(dragSourceStart)))) {
                 final int pos = dragSourceStart == mText.length() ?
                         dragSourceStart - 1 : dragSourceStart;
-                ((Editable) mText).delete(pos, pos + 1);
+                deleteText_internal(pos, pos + 1);
             }
         }
     }
@@ -11435,6 +11431,22 @@
         }
     }
 
+    /**
+     * Deletes the range of text [start, end[.
+     * @hide
+     */
+    protected void deleteText_internal(int start, int end) {
+        ((Editable) mText).delete(start, end);
+    }
+
+    /**
+     * Replaces the range of text [start, end[ by replacement text
+     * @hide
+     */
+    protected void replaceText_internal(int start, int end, CharSequence text) {
+        ((Editable) mText).replace(start, end, text);
+    }
+
     @ViewDebug.ExportedProperty(category = "text")
     private CharSequence            mText;
     private CharSequence            mTransformed;