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

Commit 6f18a1fb authored by satok's avatar satok
Browse files

Disable Recorrection when APIs are not supported.

Change-Id: I3b8fdc149d350215fd4852a50456824fe3fabe0b
parent a1f9cdd6
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.inputmethod.compat;

import com.android.inputmethod.latin.EditingUtils.SelectedWord;

import android.util.Log;
import android.view.inputmethod.InputConnection;

@@ -33,6 +35,16 @@ public class InputConnectionCompatUtils {
            .getConstructor(CLASS_CorrectionInfo, INPUT_TYPE_CorrectionInfo);
    private static final Method METHOD_InputConnection_commitCorrection = CompatUtils
            .getMethod(InputConnection.class, "commitCorrection", CLASS_CorrectionInfo);
    private static final Method METHOD_getSelectedText = CompatUtils
            .getMethod(InputConnection.class, "getSelectedText", int.class);
    private static final Method METHOD_setComposingRegion = CompatUtils
            .getMethod(InputConnection.class, "setComposingRegion", int.class, int.class);
    public static final boolean RECORRECTION_SUPPORTED;

    static {
        RECORRECTION_SUPPORTED = METHOD_getSelectedText != null
                && METHOD_setComposingRegion != null;
    }

    public static void commitCorrection(InputConnection ic, int offset, CharSequence oldText,
            CharSequence newText) {
@@ -55,4 +67,25 @@ public class InputConnectionCompatUtils {
            Log.e(TAG, "Error in commitCorrection: InvocationTargetException");
        }
    }


    /**
     * Returns the selected text between the selStart and selEnd positions.
     */
    public static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) {
        // Use reflection, for backward compatibility
        return (CharSequence) CompatUtils.invoke(
                ic, null, METHOD_getSelectedText, 0);
    }

    /**
     * Tries to set the text into composition mode if there is support for it in the framework.
     */
    public static void underlineWord(InputConnection ic, SelectedWord word) {
        // Use reflection, for backward compatibility
        // If method not found, there's nothing we can do. It still works but just wont underline
        // the word.
        CompatUtils.invoke(
                ic, null, METHOD_setComposingRegion, word.mStart, word.mEnd);
    }
}
+4 −78
Original line number Diff line number Diff line
@@ -16,13 +16,13 @@

package com.android.inputmethod.latin;

import com.android.inputmethod.compat.InputConnectionCompatUtils;

import android.text.TextUtils;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Pattern;

/**
@@ -34,11 +34,6 @@ public class EditingUtils {
     */
    private static final int LOOKBACK_CHARACTER_NUM = 15;

    // Cache Method pointers
    private static boolean sMethodsInitialized;
    private static Method sMethodGetSelectedText;
    private static Method sMethodSetComposingRegion;

    private EditingUtils() {
        // Unintentional empty constructor for singleton.
    }
@@ -241,7 +236,8 @@ public class EditingUtils {
            }

            // Extract the selection alone
            CharSequence touching = getSelectedText(ic, selStart, selEnd);
            CharSequence touching = InputConnectionCompatUtils.getSelectedText(
                    ic, selStart, selEnd);
            if (TextUtils.isEmpty(touching)) return null;
            // Is any part of the selection a separator? If so, return null.
            final int length = touching.length();
@@ -255,74 +251,4 @@ public class EditingUtils {
        }
        return null;
    }

    /**
     * Cache method pointers for performance
     */
    private static void initializeMethodsForReflection() {
        try {
            // These will either both exist or not, so no need for separate try/catch blocks.
            // If other methods are added later, use separate try/catch blocks.
            sMethodGetSelectedText = InputConnection.class.getMethod("getSelectedText", int.class);
            sMethodSetComposingRegion = InputConnection.class.getMethod("setComposingRegion",
                    int.class, int.class);
        } catch (NoSuchMethodException exc) {
            // Ignore
        }
        sMethodsInitialized = true;
    }

    /**
     * Returns the selected text between the selStart and selEnd positions.
     */
    private static CharSequence getSelectedText(InputConnection ic, int selStart, int selEnd) {
        // Use reflection, for backward compatibility
        CharSequence result = null;
        if (!sMethodsInitialized) {
            initializeMethodsForReflection();
        }
        if (sMethodGetSelectedText != null) {
            try {
                result = (CharSequence) sMethodGetSelectedText.invoke(ic, 0);
                return result;
            } catch (InvocationTargetException exc) {
                // Ignore
            } catch (IllegalArgumentException e) {
                // Ignore
            } catch (IllegalAccessException e) {
                // Ignore
            }
        }
        // Reflection didn't work, try it the poor way, by moving the cursor to the start,
        // getting the text after the cursor and moving the text back to selected mode.
        // TODO: Verify that this works properly in conjunction with 
        // LatinIME#onUpdateSelection
        ic.setSelection(selStart, selEnd);
        result = ic.getTextAfterCursor(selEnd - selStart, 0);
        ic.setSelection(selStart, selEnd);
        return result;
    }

    /**
     * Tries to set the text into composition mode if there is support for it in the framework.
     */
    public static void underlineWord(InputConnection ic, SelectedWord word) {
        // Use reflection, for backward compatibility
        // If method not found, there's nothing we can do. It still works but just wont underline
        // the word.
        if (!sMethodsInitialized) {
            initializeMethodsForReflection();
        }
        if (sMethodSetComposingRegion != null) {
            try {
                sMethodSetComposingRegion.invoke(ic, word.mStart, word.mEnd);
            } catch (InvocationTargetException exc) {
                // Ignore
            } catch (IllegalArgumentException e) {
                // Ignore
            } catch (IllegalAccessException e) {
                // Ignore
            }
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -1771,6 +1771,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
    }

    private void setOldSuggestions() {
        if (!InputConnectionCompatUtils.RECORRECTION_SUPPORTED) return;
        mVoiceProxy.setShowingVoiceSuggestions(false);
        if (mCandidateView != null && mCandidateView.isShowingAddToDictionaryHint()) {
            return;
@@ -1790,7 +1791,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
                    abortRecorrection(true);
                } else {
                    TextEntryState.selectedForRecorrection();
                    EditingUtils.underlineWord(ic, touching);
                    InputConnectionCompatUtils.underlineWord(ic, touching);
                }

                ic.endBatchEdit();