Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 161dc166 authored by Qi Wang's avatar Qi Wang Committed by Automerger Merge Worker
Browse files

Merge "Fix the SuggestionSpan overwrite logic." into sc-dev am: 590d6a9d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13966713

Change-Id: I705f8b96365b0b7f63802552db3066802df11d62
parents 5aea40f1 590d6a9d
Loading
Loading
Loading
Loading
+31 −27
Original line number Diff line number Diff line
@@ -20,12 +20,10 @@ import android.annotation.Nullable;
import android.text.Editable;
import android.text.Selection;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.WordIterator;
import android.text.style.SpellCheckSpan;
import android.text.style.SuggestionSpan;
import android.util.Log;
import android.util.LruCache;
import android.util.Range;
import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SpellCheckerSession;
@@ -98,10 +96,6 @@ public class SpellChecker implements SpellCheckerSessionListener {

    private Runnable mSpellRunnable;

    private static final int SUGGESTION_SPAN_CACHE_SIZE = 10;
    private final LruCache<Long, SuggestionSpan> mSuggestionSpanCache =
            new LruCache<Long, SuggestionSpan>(SUGGESTION_SPAN_CACHE_SIZE);

    public SpellChecker(TextView textView) {
        mTextView = textView;

@@ -144,7 +138,6 @@ public class SpellChecker implements SpellCheckerSessionListener {

        // Remove existing misspelled SuggestionSpans
        mTextView.removeMisspelledSpans((Editable) mTextView.getText());
        mSuggestionSpanCache.evictAll();
    }

    private void setLocale(Locale locale) {
@@ -410,16 +403,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
                    }
                    if (spellCheckSpanStart >= 0 && spellCheckSpanEnd > spellCheckSpanStart
                            && end > start) {
                        final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
                        final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
                        if (tempSuggestionSpan != null) {
                            if (DBG) {
                                Log.i(TAG, "Remove existing misspelled span. "
                                        + editable.subSequence(start, end));
                            }
                            editable.removeSpan(tempSuggestionSpan);
                            mSuggestionSpanCache.remove(key);
                        }
                        removeErrorSuggestionSpan(editable, start, end, RemoveReason.OBSOLETE);
                    }
                }
                return spellCheckSpan;
@@ -428,6 +412,35 @@ public class SpellChecker implements SpellCheckerSessionListener {
        return null;
    }

    private enum RemoveReason {
        /**
         * Indicates the previous SuggestionSpan is replaced by a new SuggestionSpan.
         */
        REPLACE,
        /**
         * Indicates the previous SuggestionSpan is removed because corresponding text is
         * considered as valid words now.
         */
        OBSOLETE,
    }

    private static void removeErrorSuggestionSpan(
            Editable editable, int start, int end, RemoveReason reason) {
        SuggestionSpan[] spans = editable.getSpans(start, end, SuggestionSpan.class);
        for (SuggestionSpan span : spans) {
            if (editable.getSpanStart(span) == start
                    && editable.getSpanEnd(span) == end
                    && (span.getFlags() & (SuggestionSpan.FLAG_MISSPELLED
                    | SuggestionSpan.FLAG_GRAMMAR_ERROR)) != 0) {
                if (DBG) {
                    Log.i(TAG, "Remove existing misspelled/grammar error span on "
                            + editable.subSequence(start, end) + ", reason: " + reason);
                }
                editable.removeSpan(span);
            }
        }
    }

    @Override
    public void onGetSuggestions(SuggestionsInfo[] results) {
        final Editable editable = (Editable) mTextView.getText();
@@ -543,16 +556,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
        }
        SuggestionSpan suggestionSpan =
                new SuggestionSpan(mTextView.getContext(), suggestions, flags);
        final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
        final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
        if (tempSuggestionSpan != null) {
            if (DBG) {
                Log.i(TAG, "Cached span on the same position is cleard. "
                        + editable.subSequence(start, end));
            }
            editable.removeSpan(tempSuggestionSpan);
        }
        mSuggestionSpanCache.put(key, suggestionSpan);
        removeErrorSuggestionSpan(editable, start, end, RemoveReason.REPLACE);
        editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        mTextView.invalidateRegion(start, end, false /* No cursor involved */);