am 53c320e2: [IL50] Move the InputUpdater out of LatinIME.
* commit '53c320e2757ec37e40dc1dc54a2b04a05a995003': [IL50] Move the InputUpdater out of LatinIME.main
commit
17c67ab802
|
@ -35,8 +35,6 @@ import android.inputmethodservice.InputMethodService;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.HandlerThread;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
@ -137,7 +135,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
private final boolean mIsHardwareAcceleratedDrawingEnabled;
|
private final boolean mIsHardwareAcceleratedDrawingEnabled;
|
||||||
|
|
||||||
public final UIHandler mHandler = new UIHandler(this);
|
public final UIHandler mHandler = new UIHandler(this);
|
||||||
private InputUpdater mInputUpdater;
|
|
||||||
|
|
||||||
public static final class UIHandler extends LeakGuardHandlerWrapper<LatinIME> {
|
public static final class UIHandler extends LeakGuardHandlerWrapper<LatinIME> {
|
||||||
private static final int MSG_UPDATE_SHIFT_STATE = 0;
|
private static final int MSG_UPDATE_SHIFT_STATE = 0;
|
||||||
|
@ -183,8 +180,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_UPDATE_SUGGESTION_STRIP:
|
case MSG_UPDATE_SUGGESTION_STRIP:
|
||||||
latinIme.mInputLogic.performUpdateSuggestionStripSync(
|
latinIme.mInputLogic.performUpdateSuggestionStripSync(
|
||||||
latinIme.mSettings.getCurrent(), this /* handler */,
|
latinIme.mSettings.getCurrent(), this /* handler */);
|
||||||
latinIme.mInputUpdater);
|
|
||||||
break;
|
break;
|
||||||
case MSG_UPDATE_SHIFT_STATE:
|
case MSG_UPDATE_SHIFT_STATE:
|
||||||
switcher.updateShiftState();
|
switcher.updateShiftState();
|
||||||
|
@ -205,8 +201,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
break;
|
break;
|
||||||
case MSG_RESUME_SUGGESTIONS:
|
case MSG_RESUME_SUGGESTIONS:
|
||||||
latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor(
|
latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor(
|
||||||
latinIme.mSettings.getCurrent(), latinIme.mKeyboardSwitcher,
|
latinIme.mSettings.getCurrent(), latinIme.mKeyboardSwitcher);
|
||||||
latinIme.mInputUpdater);
|
|
||||||
break;
|
break;
|
||||||
case MSG_REOPEN_DICTIONARIES:
|
case MSG_REOPEN_DICTIONARIES:
|
||||||
latinIme.initSuggest();
|
latinIme.initSuggest();
|
||||||
|
@ -216,7 +211,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
postUpdateSuggestionStrip();
|
postUpdateSuggestionStrip();
|
||||||
break;
|
break;
|
||||||
case MSG_ON_END_BATCH_INPUT:
|
case MSG_ON_END_BATCH_INPUT:
|
||||||
latinIme.mInputLogic.onEndBatchInputAsyncInternal(latinIme.mSettings.getCurrent(),
|
latinIme.mInputLogic.endBatchInputAsyncInternal(latinIme.mSettings.getCurrent(),
|
||||||
(SuggestedWords) msg.obj, latinIme.mKeyboardSwitcher);
|
(SuggestedWords) msg.obj, latinIme.mKeyboardSwitcher);
|
||||||
break;
|
break;
|
||||||
case MSG_RESET_CACHES:
|
case MSG_RESET_CACHES:
|
||||||
|
@ -496,8 +491,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);
|
registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);
|
||||||
|
|
||||||
DictionaryDecayBroadcastReciever.setUpIntervalAlarmForDictionaryDecaying(this);
|
DictionaryDecayBroadcastReciever.setUpIntervalAlarmForDictionaryDecaying(this);
|
||||||
|
|
||||||
mInputUpdater = new InputUpdater(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has to be package-visible for unit tests
|
// Has to be package-visible for unit tests
|
||||||
|
@ -595,9 +588,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
suggest.close();
|
suggest.close();
|
||||||
mInputLogic.mSuggest = null;
|
mInputLogic.mSuggest = null;
|
||||||
}
|
}
|
||||||
if (mInputUpdater != null) {
|
|
||||||
mInputUpdater.quitLooper();
|
|
||||||
}
|
|
||||||
mSettings.onDestroy();
|
mSettings.onDestroy();
|
||||||
unregisterReceiver(mReceiver);
|
unregisterReceiver(mReceiver);
|
||||||
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
||||||
|
@ -1239,176 +1229,35 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// Implementation of {@link KeyboardActionListener}.
|
// Implementation of {@link KeyboardActionListener}.
|
||||||
@Override
|
@Override
|
||||||
public void onCodeInput(final int primaryCode, final int x, final int y) {
|
public void onCodeInput(final int primaryCode, final int x, final int y) {
|
||||||
mInputLogic.onCodeInput(primaryCode, x, y, mHandler, mInputUpdater,
|
mInputLogic.onCodeInput(primaryCode, x, y, mHandler, mKeyboardSwitcher, mSubtypeSwitcher);
|
||||||
mKeyboardSwitcher, mSubtypeSwitcher);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from PointerTracker through the KeyboardActionListener interface
|
// Called from PointerTracker through the KeyboardActionListener interface
|
||||||
@Override
|
@Override
|
||||||
public void onTextInput(final String rawText) {
|
public void onTextInput(final String rawText) {
|
||||||
mInputLogic.onTextInput(mSettings.getCurrent(), rawText, mHandler, mInputUpdater);
|
mInputLogic.onTextInput(mSettings.getCurrent(), rawText, mHandler);
|
||||||
mKeyboardSwitcher.updateShiftState();
|
mKeyboardSwitcher.updateShiftState();
|
||||||
mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT);
|
mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartBatchInput() {
|
public void onStartBatchInput() {
|
||||||
mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler,
|
mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler);
|
||||||
mInputUpdater);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdateBatchInput(final InputPointers batchPointers) {
|
public void onUpdateBatchInput(final InputPointers batchPointers) {
|
||||||
mInputLogic.onUpdateBatchInput(mSettings.getCurrent(), batchPointers, mKeyboardSwitcher,
|
mInputLogic.onUpdateBatchInput(mSettings.getCurrent(), batchPointers, mKeyboardSwitcher);
|
||||||
mInputUpdater);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEndBatchInput(final InputPointers batchPointers) {
|
public void onEndBatchInput(final InputPointers batchPointers) {
|
||||||
mInputLogic.onEndBatchInput(mSettings.getCurrent(), batchPointers, mInputUpdater);
|
mInputLogic.onEndBatchInput(mSettings.getCurrent(), batchPointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCancelBatchInput() {
|
public void onCancelBatchInput() {
|
||||||
mInputLogic.onCancelBatchInput(mHandler, mInputUpdater);
|
mInputLogic.onCancelBatchInput(mHandler);
|
||||||
}
|
|
||||||
|
|
||||||
// TODO[IL]: Make this a package-private standalone class in inputlogic/ and remove all
|
|
||||||
// references to it in LatinIME
|
|
||||||
public static final class InputUpdater implements Handler.Callback {
|
|
||||||
private final Handler mHandler;
|
|
||||||
private final LatinIME mLatinIme;
|
|
||||||
private final Object mLock = new Object();
|
|
||||||
private boolean mInBatchInput; // synchronized using {@link #mLock}.
|
|
||||||
|
|
||||||
InputUpdater(final LatinIME latinIme) {
|
|
||||||
final HandlerThread handlerThread = new HandlerThread(
|
|
||||||
InputUpdater.class.getSimpleName());
|
|
||||||
handlerThread.start();
|
|
||||||
mHandler = new Handler(handlerThread.getLooper(), this);
|
|
||||||
mLatinIme = latinIme;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int MSG_GET_SUGGESTED_WORDS = 1;
|
|
||||||
|
|
||||||
// Called on the InputUpdater thread by the Handler code.
|
|
||||||
@Override
|
|
||||||
public boolean handleMessage(final Message msg) {
|
|
||||||
switch (msg.what) {
|
|
||||||
case MSG_GET_SUGGESTED_WORDS:
|
|
||||||
mLatinIme.getSuggestedWords(msg.arg1 /* sessionId */,
|
|
||||||
msg.arg2 /* sequenceNumber */, (OnGetSuggestedWordsCallback) msg.obj);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called on the UI thread by LatinIME.
|
|
||||||
public void onStartBatchInput() {
|
|
||||||
synchronized (mLock) {
|
|
||||||
mInBatchInput = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch suggestions corresponding to an update of a batch input.
|
|
||||||
* @param batchPointers the updated pointers, including the part that was passed last time.
|
|
||||||
* @param sequenceNumber the sequence number associated with this batch input.
|
|
||||||
* @param forEnd true if this is the end of a batch input, false if it's an update.
|
|
||||||
*/
|
|
||||||
// This method can be called from any thread and will see to it that the correct threads
|
|
||||||
// are used for parts that require it. This method will send a message to the
|
|
||||||
// InputUpdater thread to pull suggestions, and get the inlined callback to get called
|
|
||||||
// on the InputUpdater thread. The callback will then proceed to send a message to the
|
|
||||||
// UI handler in LatinIME so that showing suggestions can be done on the UI thread.
|
|
||||||
private void updateBatchInput(final InputPointers batchPointers,
|
|
||||||
final int sequenceNumber, final boolean forEnd) {
|
|
||||||
synchronized (mLock) {
|
|
||||||
if (!mInBatchInput) {
|
|
||||||
// Batch input has ended or canceled while the message was being delivered.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mLatinIme.mInputLogic.mWordComposer.setBatchInputPointers(batchPointers);
|
|
||||||
getSuggestedWords(Suggest.SESSION_GESTURE, sequenceNumber,
|
|
||||||
new OnGetSuggestedWordsCallback() {
|
|
||||||
@Override
|
|
||||||
public void onGetSuggestedWords(SuggestedWords suggestedWords) {
|
|
||||||
// We're now inside the callback. This always runs on the
|
|
||||||
// InputUpdater thread, no matter what thread updateBatchInput
|
|
||||||
// was called on.
|
|
||||||
if (suggestedWords.isEmpty()) {
|
|
||||||
// Use old suggestions if we don't have any new ones.
|
|
||||||
// Previous suggestions are found in InputLogic#mSuggestedWords.
|
|
||||||
// Since these are the most recent ones and we just recomputed
|
|
||||||
// new ones to update them, then the previous ones are there.
|
|
||||||
suggestedWords = mLatinIme.mInputLogic.mSuggestedWords;
|
|
||||||
}
|
|
||||||
mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
|
|
||||||
suggestedWords,
|
|
||||||
forEnd /* dismissGestureFloatingPreviewText */);
|
|
||||||
if (forEnd) {
|
|
||||||
mInBatchInput = false;
|
|
||||||
// The following call schedules onEndBatchInputAsyncInternal
|
|
||||||
// to be called on the UI thread.
|
|
||||||
mLatinIme.mHandler.onEndBatchInput(suggestedWords);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a batch input.
|
|
||||||
*
|
|
||||||
* This fetches suggestions and updates the suggestion strip and the floating text preview.
|
|
||||||
*
|
|
||||||
* @param batchPointers the updated batch pointers.
|
|
||||||
* @param sequenceNumber the sequence number associated with this batch input.
|
|
||||||
*/
|
|
||||||
// Called on the UI thread by LatinIME.
|
|
||||||
public void onUpdateBatchInput(final InputPointers batchPointers,
|
|
||||||
final int sequenceNumber) {
|
|
||||||
updateBatchInput(batchPointers, sequenceNumber, false /* forEnd */);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel a batch input.
|
|
||||||
*
|
|
||||||
* Note that as opposed to onEndBatchInput, we do the UI side of this immediately on the
|
|
||||||
* same thread, rather than get this to call a method in LatinIME. This is because
|
|
||||||
* cancelling a batch input does not necessitate the long operation of pulling suggestions.
|
|
||||||
*/
|
|
||||||
// Called on the UI thread by LatinIME.
|
|
||||||
public void onCancelBatchInput() {
|
|
||||||
synchronized (mLock) {
|
|
||||||
mInBatchInput = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finish a batch input.
|
|
||||||
*
|
|
||||||
* This fetches suggestions, updates the suggestion strip and commits the first suggestion.
|
|
||||||
* It also dismisses the floating text preview.
|
|
||||||
*
|
|
||||||
* @param batchPointers the updated batch pointers.
|
|
||||||
* @param sequenceNumber the sequence number associated with this batch input.
|
|
||||||
*/
|
|
||||||
// Called on the UI thread by LatinIME.
|
|
||||||
public void onEndBatchInput(final InputPointers batchPointers, final int sequenceNumber) {
|
|
||||||
updateBatchInput(batchPointers, sequenceNumber, true /* forEnd */);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getSuggestedWords(final int sessionId, final int sequenceNumber,
|
|
||||||
final OnGetSuggestedWordsCallback callback) {
|
|
||||||
mHandler.obtainMessage(MSG_GET_SUGGESTED_WORDS, sessionId, sequenceNumber, callback)
|
|
||||||
.sendToTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
void quitLooper() {
|
|
||||||
mHandler.removeMessages(MSG_GET_SUGGESTED_WORDS);
|
|
||||||
mHandler.getLooper().quit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method must run on the UI Thread.
|
// This method must run on the UI Thread.
|
||||||
|
@ -1496,7 +1345,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getSuggestedWords(final int sessionId, final int sequenceNumber,
|
// TODO[IL]: Move this out of LatinIME.
|
||||||
|
public void getSuggestedWords(final int sessionId, final int sequenceNumber,
|
||||||
final OnGetSuggestedWordsCallback callback) {
|
final OnGetSuggestedWordsCallback callback) {
|
||||||
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
|
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
|
||||||
final Suggest suggest = mInputLogic.mSuggest;
|
final Suggest suggest = mInputLogic.mSuggest;
|
||||||
|
|
|
@ -132,7 +132,7 @@ public final class InputLogic {
|
||||||
// In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
|
// In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
|
||||||
// so we try using some heuristics to find out about these and fix them.
|
// so we try using some heuristics to find out about these and fix them.
|
||||||
tryFixLyingCursorPosition();
|
tryFixLyingCursorPosition();
|
||||||
mInputLogicHandler = new InputLogicHandler();
|
mInputLogicHandler = new InputLogicHandler(mLatinIME, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,11 +157,11 @@ public final class InputLogic {
|
||||||
* @param rawText the text to input.
|
* @param rawText the text to input.
|
||||||
*/
|
*/
|
||||||
public void onTextInput(final SettingsValues settingsValues, final String rawText,
|
public void onTextInput(final SettingsValues settingsValues, final String rawText,
|
||||||
// TODO: remove these arguments
|
// TODO: remove this argument
|
||||||
final LatinIME.UIHandler handler, final LatinIME.InputUpdater inputUpdater) {
|
final LatinIME.UIHandler handler) {
|
||||||
mConnection.beginBatchEdit();
|
mConnection.beginBatchEdit();
|
||||||
if (mWordComposer.isComposingWord()) {
|
if (mWordComposer.isComposingWord()) {
|
||||||
commitCurrentAutoCorrection(settingsValues, rawText, handler, inputUpdater);
|
commitCurrentAutoCorrection(settingsValues, rawText, handler);
|
||||||
} else {
|
} else {
|
||||||
resetComposingState(true /* alsoResetLastComposedWord */);
|
resetComposingState(true /* alsoResetLastComposedWord */);
|
||||||
}
|
}
|
||||||
|
@ -197,8 +197,8 @@ public final class InputLogic {
|
||||||
* @param y the y-coordinate where the user pressed the key, or NOT_A_COORDINATE.
|
* @param y the y-coordinate where the user pressed the key, or NOT_A_COORDINATE.
|
||||||
*/
|
*/
|
||||||
public void onCodeInput(final int code, final int x, final int y,
|
public void onCodeInput(final int code, final int x, final int y,
|
||||||
// TODO: remove these four arguments
|
// TODO: remove these three arguments
|
||||||
final LatinIME.UIHandler handler, final LatinIME.InputUpdater inputUpdater,
|
final LatinIME.UIHandler handler,
|
||||||
final KeyboardSwitcher keyboardSwitcher, final SubtypeSwitcher subtypeSwitcher) {
|
final KeyboardSwitcher keyboardSwitcher, final SubtypeSwitcher subtypeSwitcher) {
|
||||||
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
|
||||||
ResearchLogger.latinIME_onCodeInput(code, x, y);
|
ResearchLogger.latinIME_onCodeInput(code, x, y);
|
||||||
|
@ -291,16 +291,16 @@ public final class InputLogic {
|
||||||
// No action label, and the action from imeOptions is NONE: this is a regular
|
// No action label, and the action from imeOptions is NONE: this is a regular
|
||||||
// enter key that should input a carriage return.
|
// enter key that should input a carriage return.
|
||||||
didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
|
didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
|
||||||
x, y, spaceState, keyboardSwitcher, handler, inputUpdater);
|
x, y, spaceState, keyboardSwitcher, handler);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Constants.CODE_SHIFT_ENTER:
|
case Constants.CODE_SHIFT_ENTER:
|
||||||
didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
|
didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
|
||||||
x, y, spaceState, keyboardSwitcher, handler, inputUpdater);
|
x, y, spaceState, keyboardSwitcher, handler);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
didAutoCorrect = handleNonSpecialCharacter(settingsValues,
|
didAutoCorrect = handleNonSpecialCharacter(settingsValues,
|
||||||
code, x, y, spaceState, keyboardSwitcher, handler, inputUpdater);
|
code, x, y, spaceState, keyboardSwitcher, handler);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
keyboardSwitcher.onCodeInput(code);
|
keyboardSwitcher.onCodeInput(code);
|
||||||
|
@ -317,9 +317,8 @@ public final class InputLogic {
|
||||||
|
|
||||||
public void onStartBatchInput(final SettingsValues settingsValues,
|
public void onStartBatchInput(final SettingsValues settingsValues,
|
||||||
// TODO: remove these arguments
|
// TODO: remove these arguments
|
||||||
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler,
|
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
|
||||||
final LatinIME.InputUpdater inputUpdater) {
|
mInputLogicHandler.onStartBatchInput();
|
||||||
inputUpdater.onStartBatchInput();
|
|
||||||
handler.showGesturePreviewAndSuggestionStrip(
|
handler.showGesturePreviewAndSuggestionStrip(
|
||||||
SuggestedWords.EMPTY, false /* dismissGestureFloatingPreviewText */);
|
SuggestedWords.EMPTY, false /* dismissGestureFloatingPreviewText */);
|
||||||
handler.cancelUpdateSuggestionStrip();
|
handler.cancelUpdateSuggestionStrip();
|
||||||
|
@ -346,7 +345,7 @@ public final class InputLogic {
|
||||||
// so we do not attempt to correct, on the assumption that if that was a dictionary
|
// so we do not attempt to correct, on the assumption that if that was a dictionary
|
||||||
// word, the user would probably have gestured instead.
|
// word, the user would probably have gestured instead.
|
||||||
commitCurrentAutoCorrection(settingsValues, LastComposedWord.NOT_A_SEPARATOR,
|
commitCurrentAutoCorrection(settingsValues, LastComposedWord.NOT_A_SEPARATOR,
|
||||||
handler, inputUpdater);
|
handler);
|
||||||
} else {
|
} else {
|
||||||
commitTyped(settingsValues, LastComposedWord.NOT_A_SEPARATOR);
|
commitTyped(settingsValues, LastComposedWord.NOT_A_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
@ -391,7 +390,7 @@ public final class InputLogic {
|
||||||
public void onUpdateBatchInput(final SettingsValues settingsValues,
|
public void onUpdateBatchInput(final SettingsValues settingsValues,
|
||||||
final InputPointers batchPointers,
|
final InputPointers batchPointers,
|
||||||
// TODO: remove these arguments
|
// TODO: remove these arguments
|
||||||
final KeyboardSwitcher keyboardSwitcher, final LatinIME.InputUpdater inputUpdater) {
|
final KeyboardSwitcher keyboardSwitcher) {
|
||||||
if (settingsValues.mPhraseGestureEnabled) {
|
if (settingsValues.mPhraseGestureEnabled) {
|
||||||
final SuggestedWordInfo candidate = mSuggestedWords.getAutoCommitCandidate();
|
final SuggestedWordInfo candidate = mSuggestedWords.getAutoCommitCandidate();
|
||||||
// If these suggested words have been generated with out of date input pointers, then
|
// If these suggested words have been generated with out of date input pointers, then
|
||||||
|
@ -412,20 +411,17 @@ public final class InputLogic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inputUpdater.onUpdateBatchInput(batchPointers, mAutoCommitSequenceNumber);
|
mInputLogicHandler.onUpdateBatchInput(batchPointers, mAutoCommitSequenceNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEndBatchInput(final SettingsValues settingValues,
|
public void onEndBatchInput(final SettingsValues settingValues,
|
||||||
final InputPointers batchPointers,
|
final InputPointers batchPointers) {
|
||||||
// TODO: remove these arguments
|
mInputLogicHandler.onEndBatchInput(batchPointers, mAutoCommitSequenceNumber);
|
||||||
final LatinIME.InputUpdater inputUpdater) {
|
|
||||||
inputUpdater.onEndBatchInput(batchPointers, mAutoCommitSequenceNumber);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove these arguments
|
// TODO: remove this argument
|
||||||
public void onCancelBatchInput(final LatinIME.UIHandler handler,
|
public void onCancelBatchInput(final LatinIME.UIHandler handler) {
|
||||||
final LatinIME.InputUpdater inputUpdater) {
|
mInputLogicHandler.onCancelBatchInput();
|
||||||
inputUpdater.onCancelBatchInput();
|
|
||||||
handler.showGesturePreviewAndSuggestionStrip(
|
handler.showGesturePreviewAndSuggestionStrip(
|
||||||
SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */);
|
SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */);
|
||||||
}
|
}
|
||||||
|
@ -448,14 +444,13 @@ public final class InputLogic {
|
||||||
private boolean handleNonSpecialCharacter(final SettingsValues settingsValues,
|
private boolean handleNonSpecialCharacter(final SettingsValues settingsValues,
|
||||||
final int codePoint, final int x, final int y, final int spaceState,
|
final int codePoint, final int x, final int y, final int spaceState,
|
||||||
// TODO: remove these arguments
|
// TODO: remove these arguments
|
||||||
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler,
|
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
|
||||||
final LatinIME.InputUpdater inputUpdater) {
|
|
||||||
mSpaceState = SpaceState.NONE;
|
mSpaceState = SpaceState.NONE;
|
||||||
final boolean didAutoCorrect;
|
final boolean didAutoCorrect;
|
||||||
if (settingsValues.isWordSeparator(codePoint)
|
if (settingsValues.isWordSeparator(codePoint)
|
||||||
|| Character.getType(codePoint) == Character.OTHER_SYMBOL) {
|
|| Character.getType(codePoint) == Character.OTHER_SYMBOL) {
|
||||||
didAutoCorrect = handleSeparator(settingsValues, codePoint, x, y, spaceState,
|
didAutoCorrect = handleSeparator(settingsValues, codePoint, x, y, spaceState,
|
||||||
keyboardSwitcher, handler, inputUpdater);
|
keyboardSwitcher, handler);
|
||||||
} else {
|
} else {
|
||||||
didAutoCorrect = false;
|
didAutoCorrect = false;
|
||||||
if (SpaceState.PHANTOM == spaceState) {
|
if (SpaceState.PHANTOM == spaceState) {
|
||||||
|
@ -595,8 +590,7 @@ public final class InputLogic {
|
||||||
private boolean handleSeparator(final SettingsValues settingsValues,
|
private boolean handleSeparator(final SettingsValues settingsValues,
|
||||||
final int codePoint, final int x, final int y, final int spaceState,
|
final int codePoint, final int x, final int y, final int spaceState,
|
||||||
// TODO: remove these arguments
|
// TODO: remove these arguments
|
||||||
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler,
|
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
|
||||||
final LatinIME.InputUpdater inputUpdater) {
|
|
||||||
boolean didAutoCorrect = false;
|
boolean didAutoCorrect = false;
|
||||||
// We avoid sending spaces in languages without spaces if we were composing.
|
// We avoid sending spaces in languages without spaces if we were composing.
|
||||||
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
|
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
|
||||||
|
@ -612,7 +606,7 @@ public final class InputLogic {
|
||||||
if (settingsValues.mCorrectionEnabled) {
|
if (settingsValues.mCorrectionEnabled) {
|
||||||
final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
|
final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
|
||||||
: StringUtils.newSingleCodePointString(codePoint);
|
: StringUtils.newSingleCodePointString(codePoint);
|
||||||
commitCurrentAutoCorrection(settingsValues, separator, handler, inputUpdater);
|
commitCurrentAutoCorrection(settingsValues, separator, handler);
|
||||||
didAutoCorrect = true;
|
didAutoCorrect = true;
|
||||||
} else {
|
} else {
|
||||||
commitTyped(settingsValues, StringUtils.newSingleCodePointString(codePoint));
|
commitTyped(settingsValues, StringUtils.newSingleCodePointString(codePoint));
|
||||||
|
@ -1008,8 +1002,8 @@ public final class InputLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void performUpdateSuggestionStripSync(final SettingsValues settingsValues,
|
public void performUpdateSuggestionStripSync(final SettingsValues settingsValues,
|
||||||
// TODO: Remove this variable
|
// TODO: Remove this argument
|
||||||
final LatinIME.UIHandler handler, final LatinIME.InputUpdater inputUpdater) {
|
final LatinIME.UIHandler handler) {
|
||||||
handler.cancelUpdateSuggestionStrip();
|
handler.cancelUpdateSuggestionStrip();
|
||||||
|
|
||||||
// Check if we have a suggestion engine attached.
|
// Check if we have a suggestion engine attached.
|
||||||
|
@ -1027,7 +1021,7 @@ public final class InputLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<SuggestedWords>();
|
final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<SuggestedWords>();
|
||||||
inputUpdater.getSuggestedWords(Suggest.SESSION_TYPING,
|
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
|
||||||
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
|
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
|
public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
|
||||||
|
@ -1085,8 +1079,8 @@ public final class InputLogic {
|
||||||
*/
|
*/
|
||||||
// TODO: make this private.
|
// TODO: make this private.
|
||||||
public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues,
|
public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues,
|
||||||
// TODO: Remove these argument.
|
// TODO: Remove this argument.
|
||||||
final KeyboardSwitcher keyboardSwitcher, final LatinIME.InputUpdater inputUpdater) {
|
final KeyboardSwitcher keyboardSwitcher) {
|
||||||
// HACK: We may want to special-case some apps that exhibit bad behavior in case of
|
// HACK: We may want to special-case some apps that exhibit bad behavior in case of
|
||||||
// recorrection. This is a temporary, stopgap measure that will be removed later.
|
// recorrection. This is a temporary, stopgap measure that will be removed later.
|
||||||
// TODO: remove this.
|
// TODO: remove this.
|
||||||
|
@ -1140,7 +1134,7 @@ public final class InputLogic {
|
||||||
if (suggestions.isEmpty()) {
|
if (suggestions.isEmpty()) {
|
||||||
// We come here if there weren't any suggestion spans on this word. We will try to
|
// We come here if there weren't any suggestion spans on this word. We will try to
|
||||||
// compute suggestions for it instead.
|
// compute suggestions for it instead.
|
||||||
inputUpdater.getSuggestedWords(Suggest.SESSION_TYPING,
|
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
|
||||||
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
|
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onGetSuggestedWords(
|
public void onGetSuggestedWords(
|
||||||
|
@ -1530,7 +1524,7 @@ public final class InputLogic {
|
||||||
* @param settingsValues the current values of the settings.
|
* @param settingsValues the current values of the settings.
|
||||||
* @param suggestedWords suggestedWords to use.
|
* @param suggestedWords suggestedWords to use.
|
||||||
*/
|
*/
|
||||||
public void onEndBatchInputAsyncInternal(final SettingsValues settingsValues,
|
public void endBatchInputAsyncInternal(final SettingsValues settingsValues,
|
||||||
final SuggestedWords suggestedWords,
|
final SuggestedWords suggestedWords,
|
||||||
// TODO: remove this argument
|
// TODO: remove this argument
|
||||||
final KeyboardSwitcher keyboardSwitcher) {
|
final KeyboardSwitcher keyboardSwitcher) {
|
||||||
|
@ -1613,11 +1607,11 @@ public final class InputLogic {
|
||||||
// TODO: Make this private
|
// TODO: Make this private
|
||||||
public void commitCurrentAutoCorrection(final SettingsValues settingsValues,
|
public void commitCurrentAutoCorrection(final SettingsValues settingsValues,
|
||||||
final String separator,
|
final String separator,
|
||||||
// TODO: Remove these arguments.
|
// TODO: Remove this argument.
|
||||||
final LatinIME.UIHandler handler, final LatinIME.InputUpdater inputUpdater) {
|
final LatinIME.UIHandler handler) {
|
||||||
// Complete any pending suggestions query first
|
// Complete any pending suggestions query first
|
||||||
if (handler.hasPendingUpdateSuggestions()) {
|
if (handler.hasPendingUpdateSuggestions()) {
|
||||||
performUpdateSuggestionStripSync(settingsValues, handler, inputUpdater);
|
performUpdateSuggestionStripSync(settingsValues, handler);
|
||||||
}
|
}
|
||||||
final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
|
final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
|
||||||
final String typedWord = mWordComposer.getTypedWord();
|
final String typedWord = mWordComposer.getTypedWord();
|
||||||
|
|
|
@ -20,18 +20,33 @@ import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.InputPointers;
|
||||||
|
import com.android.inputmethod.latin.LatinIME;
|
||||||
|
import com.android.inputmethod.latin.Suggest;
|
||||||
|
import com.android.inputmethod.latin.SuggestedWords;
|
||||||
|
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper to manage deferred tasks for the input logic.
|
* A helper to manage deferred tasks for the input logic.
|
||||||
*/
|
*/
|
||||||
// TODO: Make this package private
|
// TODO: Make this package private
|
||||||
public class InputLogicHandler implements Handler.Callback {
|
public class InputLogicHandler implements Handler.Callback {
|
||||||
final Handler mNonUIThreadHandler;
|
final Handler mNonUIThreadHandler;
|
||||||
|
// TODO: remove this reference.
|
||||||
|
final LatinIME mLatinIME;
|
||||||
|
final InputLogic mInputLogic;
|
||||||
|
private final Object mLock = new Object();
|
||||||
|
private boolean mInBatchInput; // synchronized using {@link #mLock}.
|
||||||
|
|
||||||
public InputLogicHandler() {
|
private static final int MSG_GET_SUGGESTED_WORDS = 1;
|
||||||
|
|
||||||
|
public InputLogicHandler(final LatinIME latinIME, final InputLogic inputLogic) {
|
||||||
final HandlerThread handlerThread = new HandlerThread(
|
final HandlerThread handlerThread = new HandlerThread(
|
||||||
InputLogicHandler.class.getSimpleName());
|
InputLogicHandler.class.getSimpleName());
|
||||||
handlerThread.start();
|
handlerThread.start();
|
||||||
mNonUIThreadHandler = new Handler(handlerThread.getLooper(), this);
|
mNonUIThreadHandler = new Handler(handlerThread.getLooper(), this);
|
||||||
|
mLatinIME = latinIME;
|
||||||
|
mInputLogic = inputLogic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
@ -42,8 +57,116 @@ public class InputLogicHandler implements Handler.Callback {
|
||||||
* Handle a message.
|
* Handle a message.
|
||||||
* @see android.os.Handler.Callback#handleMessage(android.os.Message)
|
* @see android.os.Handler.Callback#handleMessage(android.os.Message)
|
||||||
*/
|
*/
|
||||||
|
// Called on the Non-UI handler thread by the Handler code.
|
||||||
@Override
|
@Override
|
||||||
public boolean handleMessage(final Message msg) {
|
public boolean handleMessage(final Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_GET_SUGGESTED_WORDS:
|
||||||
|
mLatinIME.getSuggestedWords(msg.arg1 /* sessionId */,
|
||||||
|
msg.arg2 /* sequenceNumber */, (OnGetSuggestedWordsCallback) msg.obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called on the UI thread by InputLogic.
|
||||||
|
public void onStartBatchInput() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mInBatchInput = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch suggestions corresponding to an update of a batch input.
|
||||||
|
* @param batchPointers the updated pointers, including the part that was passed last time.
|
||||||
|
* @param sequenceNumber the sequence number associated with this batch input.
|
||||||
|
* @param forEnd true if this is the end of a batch input, false if it's an update.
|
||||||
|
*/
|
||||||
|
// This method can be called from any thread and will see to it that the correct threads
|
||||||
|
// are used for parts that require it. This method will send a message to the Non-UI handler
|
||||||
|
// thread to pull suggestions, and get the inlined callback to get called on the Non-UI
|
||||||
|
// handler thread. If this is the end of a batch input, the callback will then proceed to
|
||||||
|
// send a message to the UI handler in LatinIME so that showing suggestions can be done on
|
||||||
|
// the UI thread.
|
||||||
|
private void updateBatchInput(final InputPointers batchPointers,
|
||||||
|
final int sequenceNumber, final boolean forEnd) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
if (!mInBatchInput) {
|
||||||
|
// Batch input has ended or canceled while the message was being delivered.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mInputLogic.mWordComposer.setBatchInputPointers(batchPointers);
|
||||||
|
getSuggestedWords(Suggest.SESSION_GESTURE, sequenceNumber,
|
||||||
|
new OnGetSuggestedWordsCallback() {
|
||||||
|
@Override
|
||||||
|
public void onGetSuggestedWords(SuggestedWords suggestedWords) {
|
||||||
|
// We're now inside the callback. This always runs on the Non-UI thread,
|
||||||
|
// no matter what thread updateBatchInput was originally called on.
|
||||||
|
if (suggestedWords.isEmpty()) {
|
||||||
|
// Use old suggestions if we don't have any new ones.
|
||||||
|
// Previous suggestions are found in InputLogic#mSuggestedWords.
|
||||||
|
// Since these are the most recent ones and we just recomputed
|
||||||
|
// new ones to update them, then the previous ones are there.
|
||||||
|
suggestedWords = mInputLogic.mSuggestedWords;
|
||||||
|
}
|
||||||
|
mLatinIME.mHandler.showGesturePreviewAndSuggestionStrip(suggestedWords,
|
||||||
|
forEnd /* dismissGestureFloatingPreviewText */);
|
||||||
|
if (forEnd) {
|
||||||
|
mInBatchInput = false;
|
||||||
|
// The following call schedules onEndBatchInputAsyncInternal
|
||||||
|
// to be called on the UI thread.
|
||||||
|
mLatinIME.mHandler.onEndBatchInput(suggestedWords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a batch input.
|
||||||
|
*
|
||||||
|
* This fetches suggestions and updates the suggestion strip and the floating text preview.
|
||||||
|
*
|
||||||
|
* @param batchPointers the updated batch pointers.
|
||||||
|
* @param sequenceNumber the sequence number associated with this batch input.
|
||||||
|
*/
|
||||||
|
// Called on the UI thread by InputLogic.
|
||||||
|
public void onUpdateBatchInput(final InputPointers batchPointers,
|
||||||
|
final int sequenceNumber) {
|
||||||
|
updateBatchInput(batchPointers, sequenceNumber, false /* forEnd */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a batch input.
|
||||||
|
*
|
||||||
|
* Note that as opposed to onEndBatchInput, we do the UI side of this immediately on the
|
||||||
|
* same thread, rather than get this to call a method in LatinIME. This is because
|
||||||
|
* canceling a batch input does not necessitate the long operation of pulling suggestions.
|
||||||
|
*/
|
||||||
|
// Called on the UI thread by InputLogic.
|
||||||
|
public void onCancelBatchInput() {
|
||||||
|
synchronized (mLock) {
|
||||||
|
mInBatchInput = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish a batch input.
|
||||||
|
*
|
||||||
|
* This fetches suggestions, updates the suggestion strip and commits the first suggestion.
|
||||||
|
* It also dismisses the floating text preview.
|
||||||
|
*
|
||||||
|
* @param batchPointers the updated batch pointers.
|
||||||
|
* @param sequenceNumber the sequence number associated with this batch input.
|
||||||
|
*/
|
||||||
|
// Called on the UI thread by InputLogic.
|
||||||
|
public void onEndBatchInput(final InputPointers batchPointers, final int sequenceNumber) {
|
||||||
|
updateBatchInput(batchPointers, sequenceNumber, true /* forEnd */);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getSuggestedWords(final int sessionId, final int sequenceNumber,
|
||||||
|
final OnGetSuggestedWordsCallback callback) {
|
||||||
|
mNonUIThreadHandler.obtainMessage(
|
||||||
|
MSG_GET_SUGGESTED_WORDS, sessionId, sequenceNumber, callback).sendToTarget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue