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

Commit 53c320e2 authored by Jean Chalard's avatar Jean Chalard
Browse files

[IL50] Move the InputUpdater out of LatinIME.

...at last

Bug: 8636060
Change-Id: If5e27a9d28ff64d318dd76792f55edfc8a78d2d7
parent 81e0ca5f
Loading
Loading
Loading
Loading
+11 −161
Original line number Diff line number Diff line
@@ -35,8 +35,6 @@ import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Debug;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
@@ -137,7 +135,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
    private final boolean mIsHardwareAcceleratedDrawingEnabled;

    public final UIHandler mHandler = new UIHandler(this);
    private InputUpdater mInputUpdater;

    public static final class UIHandler extends LeakGuardHandlerWrapper<LatinIME> {
        private static final int MSG_UPDATE_SHIFT_STATE = 0;
@@ -183,8 +180,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
            switch (msg.what) {
            case MSG_UPDATE_SUGGESTION_STRIP:
                latinIme.mInputLogic.performUpdateSuggestionStripSync(
                        latinIme.mSettings.getCurrent(), this /* handler */,
                        latinIme.mInputUpdater);
                        latinIme.mSettings.getCurrent(), this /* handler */);
                break;
            case MSG_UPDATE_SHIFT_STATE:
                switcher.updateShiftState();
@@ -205,8 +201,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                break;
            case MSG_RESUME_SUGGESTIONS:
                latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor(
                        latinIme.mSettings.getCurrent(), latinIme.mKeyboardSwitcher,
                        latinIme.mInputUpdater);
                        latinIme.mSettings.getCurrent(), latinIme.mKeyboardSwitcher);
                break;
            case MSG_REOPEN_DICTIONARIES:
                latinIme.initSuggest();
@@ -216,7 +211,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                postUpdateSuggestionStrip();
                break;
            case MSG_ON_END_BATCH_INPUT:
                latinIme.mInputLogic.onEndBatchInputAsyncInternal(latinIme.mSettings.getCurrent(),
                latinIme.mInputLogic.endBatchInputAsyncInternal(latinIme.mSettings.getCurrent(),
                        (SuggestedWords) msg.obj, latinIme.mKeyboardSwitcher);
                break;
            case MSG_RESET_CACHES:
@@ -496,8 +491,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
        registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);

        DictionaryDecayBroadcastReciever.setUpIntervalAlarmForDictionaryDecaying(this);

        mInputUpdater = new InputUpdater(this);
    }

    // Has to be package-visible for unit tests
@@ -595,9 +588,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
            suggest.close();
            mInputLogic.mSuggest = null;
        }
        if (mInputUpdater != null) {
            mInputUpdater.quitLooper();
        }
        mSettings.onDestroy();
        unregisterReceiver(mReceiver);
        if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
@@ -1239,176 +1229,35 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
    // Implementation of {@link KeyboardActionListener}.
    @Override
    public void onCodeInput(final int primaryCode, final int x, final int y) {
        mInputLogic.onCodeInput(primaryCode, x, y, mHandler, mInputUpdater,
                mKeyboardSwitcher, mSubtypeSwitcher);
        mInputLogic.onCodeInput(primaryCode, x, y, mHandler, mKeyboardSwitcher, mSubtypeSwitcher);
    }

    // Called from PointerTracker through the KeyboardActionListener interface
    @Override
    public void onTextInput(final String rawText) {
        mInputLogic.onTextInput(mSettings.getCurrent(), rawText, mHandler, mInputUpdater);
        mInputLogic.onTextInput(mSettings.getCurrent(), rawText, mHandler);
        mKeyboardSwitcher.updateShiftState();
        mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT);
    }

    @Override
    public void onStartBatchInput() {
        mInputLogic.onStartBatchInput(mSettings.getCurrent(),  mKeyboardSwitcher, mHandler,
                mInputUpdater);
        mInputLogic.onStartBatchInput(mSettings.getCurrent(),  mKeyboardSwitcher, mHandler);
    }

    @Override
    public void onUpdateBatchInput(final InputPointers batchPointers) {
        mInputLogic.onUpdateBatchInput(mSettings.getCurrent(), batchPointers, mKeyboardSwitcher,
                mInputUpdater);
        mInputLogic.onUpdateBatchInput(mSettings.getCurrent(), batchPointers, mKeyboardSwitcher);
    }

    @Override
    public void onEndBatchInput(final InputPointers batchPointers) {
        mInputLogic.onEndBatchInput(mSettings.getCurrent(), batchPointers, mInputUpdater);
    }

    @Override
    public void onCancelBatchInput() {
        mInputLogic.onCancelBatchInput(mHandler, mInputUpdater);
    }

    // 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;
            }
        mInputLogic.onEndBatchInput(mSettings.getCurrent(), batchPointers);
    }

        /**
         * 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();
        }
        mInputLogic.onCancelBatchInput(mHandler);
    }

    // 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 Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
        final Suggest suggest = mInputLogic.mSuggest;
+33 −39
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ public final class InputLogic {
        // 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.
        tryFixLyingCursorPosition();
        mInputLogicHandler = new InputLogicHandler();
        mInputLogicHandler = new InputLogicHandler(mLatinIME, this);
    }

    /**
@@ -157,11 +157,11 @@ public final class InputLogic {
     * @param rawText the text to input.
     */
    public void onTextInput(final SettingsValues settingsValues, final String rawText,
            // TODO: remove these arguments
            final LatinIME.UIHandler handler, final LatinIME.InputUpdater inputUpdater) {
            // TODO: remove this argument
            final LatinIME.UIHandler handler) {
        mConnection.beginBatchEdit();
        if (mWordComposer.isComposingWord()) {
            commitCurrentAutoCorrection(settingsValues, rawText, handler, inputUpdater);
            commitCurrentAutoCorrection(settingsValues, rawText, handler);
        } else {
            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.
     */
    public void onCodeInput(final int code, final int x, final int y,
            // TODO: remove these four arguments
            final LatinIME.UIHandler handler, final LatinIME.InputUpdater inputUpdater,
            // TODO: remove these three arguments
            final LatinIME.UIHandler handler,
            final KeyboardSwitcher keyboardSwitcher, final SubtypeSwitcher subtypeSwitcher) {
        if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
            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
                // enter key that should input a carriage return.
                didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
                        x, y, spaceState, keyboardSwitcher, handler, inputUpdater);
                        x, y, spaceState, keyboardSwitcher, handler);
            }
            break;
        case Constants.CODE_SHIFT_ENTER:
            didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
                    x, y, spaceState, keyboardSwitcher, handler, inputUpdater);
                    x, y, spaceState, keyboardSwitcher, handler);
            break;
        default:
            didAutoCorrect = handleNonSpecialCharacter(settingsValues,
                    code, x, y, spaceState, keyboardSwitcher, handler, inputUpdater);
                    code, x, y, spaceState, keyboardSwitcher, handler);
            break;
        }
        keyboardSwitcher.onCodeInput(code);
@@ -317,9 +317,8 @@ public final class InputLogic {

    public void onStartBatchInput(final SettingsValues settingsValues,
            // TODO: remove these arguments
            final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler,
            final LatinIME.InputUpdater inputUpdater) {
        inputUpdater.onStartBatchInput();
            final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
        mInputLogicHandler.onStartBatchInput();
        handler.showGesturePreviewAndSuggestionStrip(
                SuggestedWords.EMPTY, false /* dismissGestureFloatingPreviewText */);
        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
                // word, the user would probably have gestured instead.
                commitCurrentAutoCorrection(settingsValues, LastComposedWord.NOT_A_SEPARATOR,
                        handler, inputUpdater);
                        handler);
            } else {
                commitTyped(settingsValues, LastComposedWord.NOT_A_SEPARATOR);
            }
@@ -391,7 +390,7 @@ public final class InputLogic {
    public void onUpdateBatchInput(final SettingsValues settingsValues,
            final InputPointers batchPointers,
            // TODO: remove these arguments
            final KeyboardSwitcher keyboardSwitcher, final LatinIME.InputUpdater inputUpdater) {
            final KeyboardSwitcher keyboardSwitcher) {
        if (settingsValues.mPhraseGestureEnabled) {
            final SuggestedWordInfo candidate = mSuggestedWords.getAutoCommitCandidate();
            // 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,
            final InputPointers batchPointers,
            // TODO: remove these arguments
            final LatinIME.InputUpdater inputUpdater) {
        inputUpdater.onEndBatchInput(batchPointers, mAutoCommitSequenceNumber);
            final InputPointers batchPointers) {
        mInputLogicHandler.onEndBatchInput(batchPointers, mAutoCommitSequenceNumber);
    }

    // TODO: remove these arguments
    public void onCancelBatchInput(final LatinIME.UIHandler handler,
            final LatinIME.InputUpdater inputUpdater) {
        inputUpdater.onCancelBatchInput();
    // TODO: remove this argument
    public void onCancelBatchInput(final LatinIME.UIHandler handler) {
        mInputLogicHandler.onCancelBatchInput();
        handler.showGesturePreviewAndSuggestionStrip(
                SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */);
    }
@@ -448,14 +444,13 @@ public final class InputLogic {
    private boolean handleNonSpecialCharacter(final SettingsValues settingsValues,
            final int codePoint, final int x, final int y, final int spaceState,
            // TODO: remove these arguments
            final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler,
            final LatinIME.InputUpdater inputUpdater) {
            final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
        mSpaceState = SpaceState.NONE;
        final boolean didAutoCorrect;
        if (settingsValues.isWordSeparator(codePoint)
                || Character.getType(codePoint) == Character.OTHER_SYMBOL) {
            didAutoCorrect = handleSeparator(settingsValues, codePoint, x, y, spaceState,
                    keyboardSwitcher, handler, inputUpdater);
                    keyboardSwitcher, handler);
        } else {
            didAutoCorrect = false;
            if (SpaceState.PHANTOM == spaceState) {
@@ -595,8 +590,7 @@ public final class InputLogic {
    private boolean handleSeparator(final SettingsValues settingsValues,
            final int codePoint, final int x, final int y, final int spaceState,
            // TODO: remove these arguments
            final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler,
            final LatinIME.InputUpdater inputUpdater) {
            final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
        boolean didAutoCorrect = false;
        // We avoid sending spaces in languages without spaces if we were composing.
        final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
@@ -612,7 +606,7 @@ public final class InputLogic {
            if (settingsValues.mCorrectionEnabled) {
                final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
                        : StringUtils.newSingleCodePointString(codePoint);
                commitCurrentAutoCorrection(settingsValues, separator, handler, inputUpdater);
                commitCurrentAutoCorrection(settingsValues, separator, handler);
                didAutoCorrect = true;
            } else {
                commitTyped(settingsValues, StringUtils.newSingleCodePointString(codePoint));
@@ -1008,8 +1002,8 @@ public final class InputLogic {
    }

    public void performUpdateSuggestionStripSync(final SettingsValues settingsValues,
            // TODO: Remove this variable
            final LatinIME.UIHandler handler, final LatinIME.InputUpdater inputUpdater) {
            // TODO: Remove this argument
            final LatinIME.UIHandler handler) {
        handler.cancelUpdateSuggestionStrip();

        // Check if we have a suggestion engine attached.
@@ -1027,7 +1021,7 @@ public final class InputLogic {
        }

        final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<SuggestedWords>();
        inputUpdater.getSuggestedWords(Suggest.SESSION_TYPING,
        mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
                SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
                    @Override
                    public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
@@ -1085,8 +1079,8 @@ public final class InputLogic {
     */
    // TODO: make this private.
    public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues,
            // TODO: Remove these argument.
            final KeyboardSwitcher keyboardSwitcher, final LatinIME.InputUpdater inputUpdater) {
            // TODO: Remove this argument.
            final KeyboardSwitcher keyboardSwitcher) {
        // 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.
        // TODO: remove this.
@@ -1140,7 +1134,7 @@ public final class InputLogic {
        if (suggestions.isEmpty()) {
            // We come here if there weren't any suggestion spans on this word. We will try to
            // compute suggestions for it instead.
            inputUpdater.getSuggestedWords(Suggest.SESSION_TYPING,
            mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
                    SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
                        @Override
                        public void onGetSuggestedWords(
@@ -1530,7 +1524,7 @@ public final class InputLogic {
     * @param settingsValues the current values of the settings.
     * @param suggestedWords suggestedWords to use.
     */
    public void onEndBatchInputAsyncInternal(final SettingsValues settingsValues,
    public void endBatchInputAsyncInternal(final SettingsValues settingsValues,
            final SuggestedWords suggestedWords,
            // TODO: remove this argument
            final KeyboardSwitcher keyboardSwitcher) {
@@ -1613,11 +1607,11 @@ public final class InputLogic {
    // TODO: Make this private
    public void commitCurrentAutoCorrection(final SettingsValues settingsValues,
            final String separator,
            // TODO: Remove these arguments.
            final LatinIME.UIHandler handler, final LatinIME.InputUpdater inputUpdater) {
            // TODO: Remove this argument.
            final LatinIME.UIHandler handler) {
        // Complete any pending suggestions query first
        if (handler.hasPendingUpdateSuggestions()) {
            performUpdateSuggestionStripSync(settingsValues, handler, inputUpdater);
            performUpdateSuggestionStripSync(settingsValues, handler);
        }
        final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
        final String typedWord = mWordComposer.getTypedWord();
+124 −1

File changed.

Preview size limit exceeded, changes collapsed.