Fix hint text updates in Extracted text mode

Updates to the hint on a TextView were not notified to the
ExtractEditText, so there was no way it could know to update.
This change pipes through the hint value when the extracted
mode becomes visible and informs it of changes.

The Editor#reportExtractedText method has been refactored to
be more readable. Note that checks on whether the content
changed are done in the two places in the code that already
called this method, and we explicitely don't want to check
contents when there is a hint change.

Bug: 63980155
Bug: 65691495
Test: bit CtsWidgetTestCases:.TextViewTest
Change-Id: I357dd5c74b61d149cf8612d1f52c7118ec70c696
diff --git a/api/current.txt b/api/current.txt
index f7bec58..e742ebb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -48368,6 +48368,7 @@
     field public static final int FLAG_SELECTING = 2; // 0x2
     field public static final int FLAG_SINGLE_LINE = 1; // 0x1
     field public int flags;
+    field public java.lang.CharSequence hint;
     field public int partialEndOffset;
     field public int partialStartOffset;
     field public int selectionEnd;
diff --git a/api/system-current.txt b/api/system-current.txt
index d71241a..525c78b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -52061,6 +52061,7 @@
     field public static final int FLAG_SELECTING = 2; // 0x2
     field public static final int FLAG_SINGLE_LINE = 1; // 0x1
     field public int flags;
+    field public java.lang.CharSequence hint;
     field public int partialEndOffset;
     field public int partialStartOffset;
     field public int selectionEnd;
diff --git a/api/test-current.txt b/api/test-current.txt
index 6a59e81..e5f5153 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -48865,6 +48865,7 @@
     field public static final int FLAG_SELECTING = 2; // 0x2
     field public static final int FLAG_SINGLE_LINE = 1; // 0x1
     field public int flags;
+    field public java.lang.CharSequence hint;
     field public int partialEndOffset;
     field public int partialStartOffset;
     field public int selectionEnd;
diff --git a/core/java/android/view/inputmethod/ExtractedText.java b/core/java/android/view/inputmethod/ExtractedText.java
index 0c5d9e9..003f221 100644
--- a/core/java/android/view/inputmethod/ExtractedText.java
+++ b/core/java/android/view/inputmethod/ExtractedText.java
@@ -87,6 +87,11 @@
     public int flags;
 
     /**
+     * The hint that has been extracted.
+     */
+    public CharSequence hint;
+
+    /**
      * Used to package this object into a {@link Parcel}.
      *
      * @param dest The {@link Parcel} to be written.
@@ -100,6 +105,7 @@
         dest.writeInt(selectionStart);
         dest.writeInt(selectionEnd);
         dest.writeInt(this.flags);
+        TextUtils.writeToParcel(hint, dest, flags);
     }
 
     /**
@@ -107,17 +113,18 @@
      */
     public static final Parcelable.Creator<ExtractedText> CREATOR
             = new Parcelable.Creator<ExtractedText>() {
-        public ExtractedText createFromParcel(Parcel source) {
-            ExtractedText res = new ExtractedText();
-            res.text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-            res.startOffset = source.readInt();
-            res.partialStartOffset = source.readInt();
-            res.partialEndOffset = source.readInt();
-            res.selectionStart = source.readInt();
-            res.selectionEnd = source.readInt();
-            res.flags = source.readInt();
-            return res;
-        }
+                public ExtractedText createFromParcel(Parcel source) {
+                    ExtractedText res = new ExtractedText();
+                    res.text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+                    res.startOffset = source.readInt();
+                    res.partialStartOffset = source.readInt();
+                    res.partialEndOffset = source.readInt();
+                    res.selectionStart = source.readInt();
+                    res.selectionEnd = source.readInt();
+                    res.flags = source.readInt();
+                    res.hint = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+                    return res;
+                }
 
         public ExtractedText[] newArray(int size) {
             return new ExtractedText[size];
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index d23dfe4..8234301 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1585,49 +1585,49 @@
         outText.startOffset = 0;
         outText.selectionStart = mTextView.getSelectionStart();
         outText.selectionEnd = mTextView.getSelectionEnd();
+        outText.hint = mTextView.getHint();
         return true;
     }
 
     boolean reportExtractedText() {
         final Editor.InputMethodState ims = mInputMethodState;
-        if (ims != null) {
-            final boolean contentChanged = ims.mContentChanged;
-            if (contentChanged || ims.mSelectionModeChanged) {
-                ims.mContentChanged = false;
-                ims.mSelectionModeChanged = false;
-                final ExtractedTextRequest req = ims.mExtractedTextRequest;
-                if (req != null) {
-                    InputMethodManager imm = InputMethodManager.peekInstance();
-                    if (imm != null) {
-                        if (TextView.DEBUG_EXTRACT) {
-                            Log.v(TextView.LOG_TAG, "Retrieving extracted start="
-                                    + ims.mChangedStart
-                                    + " end=" + ims.mChangedEnd
-                                    + " delta=" + ims.mChangedDelta);
-                        }
-                        if (ims.mChangedStart < 0 && !contentChanged) {
-                            ims.mChangedStart = EXTRACT_NOTHING;
-                        }
-                        if (extractTextInternal(req, ims.mChangedStart, ims.mChangedEnd,
-                                ims.mChangedDelta, ims.mExtractedText)) {
-                            if (TextView.DEBUG_EXTRACT) {
-                                Log.v(TextView.LOG_TAG,
-                                        "Reporting extracted start="
-                                                + ims.mExtractedText.partialStartOffset
-                                                + " end=" + ims.mExtractedText.partialEndOffset
-                                                + ": " + ims.mExtractedText.text);
-                            }
-
-                            imm.updateExtractedText(mTextView, req.token, ims.mExtractedText);
-                            ims.mChangedStart = EXTRACT_UNKNOWN;
-                            ims.mChangedEnd = EXTRACT_UNKNOWN;
-                            ims.mChangedDelta = 0;
-                            ims.mContentChanged = false;
-                            return true;
-                        }
-                    }
-                }
+        if (ims == null) {
+            return false;
+        }
+        ims.mSelectionModeChanged = false;
+        final ExtractedTextRequest req = ims.mExtractedTextRequest;
+        if (req == null) {
+            return false;
+        }
+        final InputMethodManager imm = InputMethodManager.peekInstance();
+        if (imm == null) {
+            return false;
+        }
+        if (TextView.DEBUG_EXTRACT) {
+            Log.v(TextView.LOG_TAG, "Retrieving extracted start="
+                    + ims.mChangedStart
+                    + " end=" + ims.mChangedEnd
+                    + " delta=" + ims.mChangedDelta);
+        }
+        if (ims.mChangedStart < 0 && !ims.mContentChanged) {
+            ims.mChangedStart = EXTRACT_NOTHING;
+        }
+        if (extractTextInternal(req, ims.mChangedStart, ims.mChangedEnd,
+                ims.mChangedDelta, ims.mExtractedText)) {
+            if (TextView.DEBUG_EXTRACT) {
+                Log.v(TextView.LOG_TAG,
+                        "Reporting extracted start="
+                                + ims.mExtractedText.partialStartOffset
+                                + " end=" + ims.mExtractedText.partialEndOffset
+                                + ": " + ims.mExtractedText.text);
             }
+
+            imm.updateExtractedText(mTextView, req.token, ims.mExtractedText);
+            ims.mChangedStart = EXTRACT_UNKNOWN;
+            ims.mChangedEnd = EXTRACT_UNKNOWN;
+            ims.mChangedDelta = 0;
+            ims.mContentChanged = false;
+            return true;
         }
         return false;
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5c621e3..efcc3a2 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5547,6 +5547,14 @@
      */
     @android.view.RemotableViewMethod
     public final void setHint(CharSequence hint) {
+        setHintInternal(hint);
+
+        if (isInputMethodTarget()) {
+            mEditor.reportExtractedText();
+        }
+    }
+
+    private void setHintInternal(CharSequence hint) {
         mHint = TextUtils.stringOrSpannedString(hint);
 
         if (mLayout != null) {
@@ -7644,6 +7652,8 @@
         } else {
             MetaKeyKeyListener.stopSelecting(this, sp);
         }
+
+        setHintInternal(text.hint);
     }
 
     /**