diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/RichInputConnection.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/RichInputConnection.java | 117 |
1 files changed, 31 insertions, 86 deletions
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index 834f747d9..660a051b9 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -16,14 +16,12 @@ package com.android.inputmethod.latin; -import android.graphics.Color; import android.inputmethodservice.InputMethodService; import android.os.Build; import android.os.Bundle; import android.text.SpannableStringBuilder; -import android.text.Spanned; import android.text.TextUtils; -import android.text.style.BackgroundColorSpan; +import android.text.style.CharacterStyle; import android.util.Log; import android.view.KeyEvent; import android.view.inputmethod.CompletionInfo; @@ -35,6 +33,7 @@ import android.view.inputmethod.InputMethodManager; import com.android.inputmethod.compat.InputConnectionCompatUtils; import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.UnicodeSurrogate; import com.android.inputmethod.latin.common.StringUtils; import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; @@ -91,16 +90,10 @@ public final class RichInputConnection implements PrivateCommandPerformer { private final StringBuilder mComposingText = new StringBuilder(); /** - * This variable is a temporary object used in - * {@link #commitTextWithBackgroundColor(CharSequence,int,int,int)} to avoid object creation. + * This variable is a temporary object used in {@link #commitText(CharSequence,int)} + * to avoid object creation. */ private SpannableStringBuilder mTempObjectForCommitText = new SpannableStringBuilder(); - /** - * This variable is used to track whether the last committed text had the background color or - * not. - * TODO: Omit this flag if possible. - */ - private boolean mLastCommittedTextHasBackgroundColor = false; private final InputMethodService mParent; InputConnection mIC; @@ -239,39 +232,18 @@ public final class RichInputConnection implements PrivateCommandPerformer { // it works, but it's wrong and should be fixed. mCommittedTextBeforeComposingText.append(mComposingText); mComposingText.setLength(0); - // TODO: Clear this flag in setComposingRegion() and setComposingText() as well if needed. - mLastCommittedTextHasBackgroundColor = false; if (null != mIC) { mIC.finishComposingText(); } } /** - * Synonym of {@code commitTextWithBackgroundColor(text, newCursorPosition, Color.TRANSPARENT}. + * Calls {@link InputConnection#commitText(CharSequence, int)}. + * * @param text The text to commit. This may include styles. - * See {@link InputConnection#commitText(CharSequence, int)}. * @param newCursorPosition The new cursor position around the text. - * See {@link InputConnection#commitText(CharSequence, int)}. */ public void commitText(final CharSequence text, final int newCursorPosition) { - commitTextWithBackgroundColor(text, newCursorPosition, Color.TRANSPARENT, text.length()); - } - - /** - * Calls {@link InputConnection#commitText(CharSequence, int)} with the given background color. - * @param text The text to commit. This may include styles. - * See {@link InputConnection#commitText(CharSequence, int)}. - * @param newCursorPosition The new cursor position around the text. - * See {@link InputConnection#commitText(CharSequence, int)}. - * @param color The background color to be attached. Set {@link Color#TRANSPARENT} to disable - * the background color. Note that this method specifies {@link BackgroundColorSpan} with - * {@link Spanned#SPAN_COMPOSING} flag, meaning that the background color persists until - * {@link #finishComposingText()} is called. - * @param coloredTextLength the length of text, in Java chars, which should be rendered with - * the given background color. - */ - public void commitTextWithBackgroundColor(final CharSequence text, final int newCursorPosition, - final int color, final int coloredTextLength) { if (DEBUG_BATCH_NESTING) checkBatchEdit(); if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug(); mCommittedTextBeforeComposingText.append(text); @@ -281,44 +253,32 @@ public final class RichInputConnection implements PrivateCommandPerformer { mExpectedSelStart += text.length() - mComposingText.length(); mExpectedSelEnd = mExpectedSelStart; mComposingText.setLength(0); - mLastCommittedTextHasBackgroundColor = false; if (null != mIC) { - if (color == Color.TRANSPARENT) { - mIC.commitText(text, newCursorPosition); - } else { - mTempObjectForCommitText.clear(); - mTempObjectForCommitText.append(text); - final BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(color); - final int spanLength = Math.min(coloredTextLength, text.length()); - mTempObjectForCommitText.setSpan(backgroundColorSpan, 0, spanLength, - Spanned.SPAN_COMPOSING | Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - mIC.commitText(mTempObjectForCommitText, newCursorPosition); - mLastCommittedTextHasBackgroundColor = true; + mTempObjectForCommitText.clear(); + mTempObjectForCommitText.append(text); + final CharacterStyle[] spans = mTempObjectForCommitText.getSpans( + 0, text.length(), CharacterStyle.class); + for (final CharacterStyle span : spans) { + final int spanStart = mTempObjectForCommitText.getSpanStart(span); + final int spanEnd = mTempObjectForCommitText.getSpanEnd(span); + final int spanFlags = mTempObjectForCommitText.getSpanFlags(span); + // We have to adjust the end of the span to include an additional character. + // This is to avoid splitting a unicode surrogate pair. + // See com.android.inputmethod.latin.common.Constants.UnicodeSurrogate + // See https://b.corp.google.com/issues/19255233 + if (0 < spanEnd && spanEnd < mTempObjectForCommitText.length()) { + final char spanEndChar = mTempObjectForCommitText.charAt(spanEnd - 1); + final char nextChar = mTempObjectForCommitText.charAt(spanEnd); + if (UnicodeSurrogate.isLowSurrogate(spanEndChar) + && UnicodeSurrogate.isHighSurrogate(nextChar)) { + mTempObjectForCommitText.setSpan(span, spanStart, spanEnd + 1, spanFlags); + } + } } + mIC.commitText(mTempObjectForCommitText, newCursorPosition); } } - /** - * Removes the background color from the highlighted text if necessary. Should be called while - * there is no on-going composing text. - * - * <p>CAVEAT: This method internally calls {@link InputConnection#finishComposingText()}. - * Be careful of any unexpected side effects.</p> - */ - public void removeBackgroundColorFromHighlightedTextIfNecessary() { - // TODO: We haven't yet full tested if we really need to check this flag or not. Omit this - // flag if everything works fine without this condition. - if (!mLastCommittedTextHasBackgroundColor) { - return; - } - if (mComposingText.length() > 0) { - Log.e(TAG, "clearSpansWithComposingFlags should be called when composing text is " + - "empty. mComposingText=" + mComposingText); - return; - } - finishComposingText(); - } - public CharSequence getSelectedText(final int flags) { return (null == mIC) ? null : mIC.getSelectedText(flags); } @@ -946,8 +906,6 @@ public final class RichInputConnection implements PrivateCommandPerformer { } } - private boolean mCursorAnchorInfoMonitorEnabled = false; - /** * Requests the editor to call back {@link InputMethodManager#updateCursorAnchorInfo}. * @param enableMonitor {@code true} to request the editor to call back the method whenever the @@ -962,23 +920,10 @@ public final class RichInputConnection implements PrivateCommandPerformer { public boolean requestCursorUpdates(final boolean enableMonitor, final boolean requestImmediateCallback) { mIC = mParent.getCurrentInputConnection(); - final boolean scheduled; - if (null != mIC) { - scheduled = InputConnectionCompatUtils.requestCursorUpdates(mIC, enableMonitor, - requestImmediateCallback); - } else { - scheduled = false; + if (mIC == null) { + return false; } - mCursorAnchorInfoMonitorEnabled = (scheduled && enableMonitor); - return scheduled; - } - - /** - * @return {@code true} if the application reported that the monitor mode of - * {@link InputMethodService#onUpdateCursorAnchorInfo(android.view.inputmethod.CursorAnchorInfo)} - * is currently enabled. - */ - public boolean isCursorAnchorInfoMonitorEnabled() { - return mCursorAnchorInfoMonitorEnabled; + return InputConnectionCompatUtils.requestCursorUpdates( + mIC, enableMonitor, requestImmediateCallback); } } |