1621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard/*
2621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * Copyright (C) 2013 The Android Open Source Project
3621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard *
4621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * Licensed under the Apache License, Version 2.0 (the "License");
5621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * you may not use this file except in compliance with the License.
6621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * You may obtain a copy of the License at
7621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard *
8621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard *      http://www.apache.org/licenses/LICENSE-2.0
9621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard *
10621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * Unless required by applicable law or agreed to in writing, software
11621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * distributed under the License is distributed on an "AS IS" BASIS,
12621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * See the License for the specific language governing permissions and
14621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * limitations under the License.
15621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard */
16621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard
17621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalardpackage com.android.inputmethod.latin.inputlogic;
18621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard
19621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalardimport android.os.Handler;
20621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalardimport android.os.HandlerThread;
21621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalardimport android.os.Message;
22621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard
234370ff0998d3240cfda7745d08edbdd11703b984Jean Chalardimport com.android.inputmethod.compat.LooperCompatUtils;
2453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalardimport com.android.inputmethod.latin.LatinIME;
2553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalardimport com.android.inputmethod.latin.SuggestedWords;
2653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalardimport com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
2736799b2aa2982ec17341cd2c5ed81e608bcee8c6Jean Chalardimport com.android.inputmethod.latin.common.InputPointers;
2853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard
29621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard/**
30621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard * A helper to manage deferred tasks for the input logic.
31621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard */
3281255612bcd231e843fc390023b0bd51117b8829Jean Chalardclass InputLogicHandler implements Handler.Callback {
33621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard    final Handler mNonUIThreadHandler;
3453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // TODO: remove this reference.
3553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    final LatinIME mLatinIME;
3653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    final InputLogic mInputLogic;
3753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    private final Object mLock = new Object();
3853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    private boolean mInBatchInput; // synchronized using {@link #mLock}.
3953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard
4053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    private static final int MSG_GET_SUGGESTED_WORDS = 1;
41621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard
42e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard    // A handler that never does anything. This is used for cases where events come before anything
43e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard    // is initialized, though probably only the monkey can actually do this.
44e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard    public static final InputLogicHandler NULL_HANDLER = new InputLogicHandler() {
45e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        @Override
46dbadee96b6bc385b18377bd8b943e79097853849Jean Chalard        public void reset() {}
47e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        @Override
48e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        public boolean handleMessage(final Message msg) { return true; }
49e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        @Override
50e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        public void onStartBatchInput() {}
51e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        @Override
52e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        public void onUpdateBatchInput(final InputPointers batchPointers,
53e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard                final int sequenceNumber) {}
54e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        @Override
55e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        public void onCancelBatchInput() {}
56e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        @Override
57a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard        public void updateTailBatchInput(final InputPointers batchPointers,
58a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard                final int sequenceNumber) {}
59e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        @Override
60e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        public void getSuggestedWords(final int sessionId, final int sequenceNumber,
61e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard                final OnGetSuggestedWordsCallback callback) {}
62e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard    };
63e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard
645f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka    InputLogicHandler() {
65e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        mNonUIThreadHandler = null;
66e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        mLatinIME = null;
67e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard        mInputLogic = null;
68e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard    }
69e1de87ae6984140607d2ca05c064cc69f00b95c1Jean Chalard
7053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    public InputLogicHandler(final LatinIME latinIME, final InputLogic inputLogic) {
71621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard        final HandlerThread handlerThread = new HandlerThread(
72621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard                InputLogicHandler.class.getSimpleName());
73621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard        handlerThread.start();
74621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard        mNonUIThreadHandler = new Handler(handlerThread.getLooper(), this);
7553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        mLatinIME = latinIME;
7653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        mInputLogic = inputLogic;
77621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard    }
78621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard
79dbadee96b6bc385b18377bd8b943e79097853849Jean Chalard    public void reset() {
80dbadee96b6bc385b18377bd8b943e79097853849Jean Chalard        mNonUIThreadHandler.removeCallbacksAndMessages(null);
81621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard    }
82621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard
834370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard    // In unit tests, we create several instances of LatinIME, which results in several instances
844370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard    // of InputLogicHandler. To avoid these handlers lingering, we call this.
854370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard    public void destroy() {
864370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard        LooperCompatUtils.quitSafely(mNonUIThreadHandler.getLooper());
874370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard    }
884370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard
89621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard    /**
90621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard     * Handle a message.
91621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard     * @see android.os.Handler.Callback#handleMessage(android.os.Message)
92621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard     */
9353c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // Called on the Non-UI handler thread by the Handler code.
94621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard    @Override
95621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard    public boolean handleMessage(final Message msg) {
9653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        switch (msg.what) {
9753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard            case MSG_GET_SUGGESTED_WORDS:
98b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard                mLatinIME.getSuggestedWords(msg.arg1 /* inputStyle */,
9953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard                        msg.arg2 /* sequenceNumber */, (OnGetSuggestedWordsCallback) msg.obj);
10053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard                break;
10153c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        }
102621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard        return true;
103621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard    }
10453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard
10553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // Called on the UI thread by InputLogic.
10653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    public void onStartBatchInput() {
10753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        synchronized (mLock) {
10853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard            mInBatchInput = true;
10953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        }
11053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    }
11153c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard
1123aba6263f08e755b55ebcf559673b21b6d46facbJean Chalard    public boolean isInBatchInput() {
1133aba6263f08e755b55ebcf559673b21b6d46facbJean Chalard        return mInBatchInput;
1143aba6263f08e755b55ebcf559673b21b6d46facbJean Chalard    }
1153aba6263f08e755b55ebcf559673b21b6d46facbJean Chalard
11653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    /**
11753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * Fetch suggestions corresponding to an update of a batch input.
11853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * @param batchPointers the updated pointers, including the part that was passed last time.
11953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * @param sequenceNumber the sequence number associated with this batch input.
120a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard     * @param isTailBatchInput true if this is the end of a batch input, false if it's an update.
12153c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     */
12253c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // This method can be called from any thread and will see to it that the correct threads
12353c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // are used for parts that require it. This method will send a message to the Non-UI handler
12453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // thread to pull suggestions, and get the inlined callback to get called on the Non-UI
12553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // handler thread. If this is the end of a batch input, the callback will then proceed to
12653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // send a message to the UI handler in LatinIME so that showing suggestions can be done on
12753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // the UI thread.
12853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    private void updateBatchInput(final InputPointers batchPointers,
129a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard            final int sequenceNumber, final boolean isTailBatchInput) {
13053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        synchronized (mLock) {
13153c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard            if (!mInBatchInput) {
13253c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard                // Batch input has ended or canceled while the message was being delivered.
13353c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard                return;
13453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard            }
13553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard            mInputLogic.mWordComposer.setBatchInputPointers(batchPointers);
1365f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            final OnGetSuggestedWordsCallback callback = new OnGetSuggestedWordsCallback() {
1375f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka                @Override
1385f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka                public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
1395f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka                    showGestureSuggestionsWithPreviewVisuals(suggestedWords, isTailBatchInput);
1405f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka                }
1415f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            };
142b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard            getSuggestedWords(isTailBatchInput ? SuggestedWords.INPUT_STYLE_TAIL_BATCH
1435f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka                    : SuggestedWords.INPUT_STYLE_UPDATE_BATCH, sequenceNumber, callback);
1445f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        }
1455f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka    }
1465f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka
1475f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka    void showGestureSuggestionsWithPreviewVisuals(final SuggestedWords suggestedWordsForBatchInput,
1485f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            final boolean isTailBatchInput) {
1495f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        final SuggestedWords suggestedWordsToShowSuggestions;
1505f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        // We're now inside the callback. This always runs on the Non-UI thread,
1515f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        // no matter what thread updateBatchInput was originally called on.
1525f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        if (suggestedWordsForBatchInput.isEmpty()) {
1535f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            // Use old suggestions if we don't have any new ones.
1545f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            // Previous suggestions are found in InputLogic#mSuggestedWords.
1555f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            // Since these are the most recent ones and we just recomputed
1565f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            // new ones to update them, then the previous ones are there.
1575f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            suggestedWordsToShowSuggestions = mInputLogic.mSuggestedWords;
1585f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        } else {
1595f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            suggestedWordsToShowSuggestions = suggestedWordsForBatchInput;
1605f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        }
1615f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        mLatinIME.mHandler.showGesturePreviewAndSuggestionStrip(suggestedWordsToShowSuggestions,
1625f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka                isTailBatchInput /* dismissGestureFloatingPreviewText */);
1635f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka        if (isTailBatchInput) {
1645f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            mInBatchInput = false;
1655f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            // The following call schedules onEndBatchInputInternal
1665f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            // to be called on the UI thread.
1675f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka            mLatinIME.mHandler.showTailBatchInputResult(suggestedWordsToShowSuggestions);
16853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        }
16953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    }
17053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard
17153c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    /**
17253c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * Update a batch input.
17353c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     *
17453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * This fetches suggestions and updates the suggestion strip and the floating text preview.
17553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     *
17653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * @param batchPointers the updated batch pointers.
17753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * @param sequenceNumber the sequence number associated with this batch input.
17853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     */
17953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // Called on the UI thread by InputLogic.
18053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    public void onUpdateBatchInput(final InputPointers batchPointers,
18153c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard            final int sequenceNumber) {
182a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard        updateBatchInput(batchPointers, sequenceNumber, false /* isTailBatchInput */);
18353c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    }
18453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard
18553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    /**
18653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * Cancel a batch input.
18753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     *
188a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard     * Note that as opposed to updateTailBatchInput, we do the UI side of this immediately on the
18953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * same thread, rather than get this to call a method in LatinIME. This is because
19053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * canceling a batch input does not necessitate the long operation of pulling suggestions.
19153c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     */
19253c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // Called on the UI thread by InputLogic.
19353c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    public void onCancelBatchInput() {
19453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        synchronized (mLock) {
19553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard            mInBatchInput = false;
19653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        }
19753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    }
19853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard
19953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    /**
200a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard     * Trigger an update for a tail batch input.
20153c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     *
202a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard     * A tail batch input is the last update for a gesture, the one that is triggered after the
203a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard     * user lifts their finger. This method schedules fetching suggestions on the non-UI thread,
204a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard     * then when the suggestions are computed it comes back on the UI thread to update the
205a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard     * suggestion strip, commit the first suggestion, and dismiss the floating text preview.
20653c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     *
20753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * @param batchPointers the updated batch pointers.
20853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     * @param sequenceNumber the sequence number associated with this batch input.
20953c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard     */
21053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    // Called on the UI thread by InputLogic.
211a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard    public void updateTailBatchInput(final InputPointers batchPointers,
212a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard            final int sequenceNumber) {
213a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard        updateBatchInput(batchPointers, sequenceNumber, true /* isTailBatchInput */);
21453c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    }
21553c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard
216b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard    public void getSuggestedWords(final int inputStyle, final int sequenceNumber,
21753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard            final OnGetSuggestedWordsCallback callback) {
21853c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard        mNonUIThreadHandler.obtainMessage(
219b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard                MSG_GET_SUGGESTED_WORDS, inputStyle, sequenceNumber, callback).sendToTarget();
22053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard    }
221621dcbc31c2b9c481f9be462a69d3d37afc5d8caJean Chalard}
222