aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/RichInputConnection.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/RichInputConnection.java')
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java117
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);
}
}