Disable Recorrection when APIs are not supported.

Change-Id: I3b8fdc149d350215fd4852a50456824fe3fabe0b
This commit is contained in:
satok 2011-03-28 18:45:49 -07:00
parent a1f9cdd6f5
commit 6f18a1fbcc
3 changed files with 39 additions and 79 deletions

View file

@ -16,6 +16,8 @@
package com.android.inputmethod.compat; package com.android.inputmethod.compat;
import com.android.inputmethod.latin.EditingUtils.SelectedWord;
import android.util.Log; import android.util.Log;
import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnection;
@ -33,6 +35,16 @@ public class InputConnectionCompatUtils {
.getConstructor(CLASS_CorrectionInfo, INPUT_TYPE_CorrectionInfo); .getConstructor(CLASS_CorrectionInfo, INPUT_TYPE_CorrectionInfo);
private static final Method METHOD_InputConnection_commitCorrection = CompatUtils private static final Method METHOD_InputConnection_commitCorrection = CompatUtils
.getMethod(InputConnection.class, "commitCorrection", CLASS_CorrectionInfo); .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, public static void commitCorrection(InputConnection ic, int offset, CharSequence oldText,
CharSequence newText) { CharSequence newText) {
@ -55,4 +67,25 @@ public class InputConnectionCompatUtils {
Log.e(TAG, "Error in commitCorrection: InvocationTargetException"); 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);
}
} }

View file

@ -16,13 +16,13 @@
package com.android.inputmethod.latin; package com.android.inputmethod.latin;
import com.android.inputmethod.compat.InputConnectionCompatUtils;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
@ -34,11 +34,6 @@ public class EditingUtils {
*/ */
private static final int LOOKBACK_CHARACTER_NUM = 15; 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() { private EditingUtils() {
// Unintentional empty constructor for singleton. // Unintentional empty constructor for singleton.
} }
@ -241,7 +236,8 @@ public class EditingUtils {
} }
// Extract the selection alone // Extract the selection alone
CharSequence touching = getSelectedText(ic, selStart, selEnd); CharSequence touching = InputConnectionCompatUtils.getSelectedText(
ic, selStart, selEnd);
if (TextUtils.isEmpty(touching)) return null; if (TextUtils.isEmpty(touching)) return null;
// Is any part of the selection a separator? If so, return null. // Is any part of the selection a separator? If so, return null.
final int length = touching.length(); final int length = touching.length();
@ -255,74 +251,4 @@ public class EditingUtils {
} }
return null; 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
}
}
}
} }

View file

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