InputConnectionWrapper.java revision 2bc66171cce4d5ae7bee2c3920e82e45a9d245af
115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root/*
215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2008 The Android Open Source Project
315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * you may not use this file except in compliance with the License.
615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * You may obtain a copy of the License at
715a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
815a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
915a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
1015a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Unless required by applicable law or agreed to in writing, software
1115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * See the License for the specific language governing permissions and
1415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * limitations under the License.
1515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root */
1615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.view;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1945700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawaimport android.annotation.NonNull;
2045700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawaimport android.inputmethodservice.AbstractInputMethodService;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle;
22612cce92ad96eda1146c3abd2afa7aaa4d4f2b3fYohei Yukawaimport android.os.Handler;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.CompletionInfo;
28cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunneimport android.view.inputmethod.CorrectionInfo;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.ExtractedText;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.ExtractedTextRequest;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputConnection;
3219a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawaimport android.view.inputmethod.InputConnectionInspector;
3319a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawaimport android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
34152944f4909c47917473293b258d266435c6ab35Yohei Yukawaimport android.view.inputmethod.InputContentInfo;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3645700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawaimport java.lang.ref.WeakReference;
3745700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class InputConnectionWrapper implements InputConnection {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int MAX_WAIT_TIME_MILLIS = 2000;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final IInputContext mIInputContext;
4145700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa    @NonNull
4245700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa    private final WeakReference<AbstractInputMethodService> mInputMethodService;
4345700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa
4419a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    @MissingMethodFlags
4519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    private final int mMissingMethods;
4619a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class InputContextCallback extends IInputContextCallback.Stub {
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private static final String TAG = "InputConnectionWrapper.ICC";
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mSeq;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean mHaveValue;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public CharSequence mTextBeforeCursor;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public CharSequence mTextAfterCursor;
53a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        public CharSequence mSelectedText;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ExtractedText mExtractedText;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int mCursorCapsMode;
56a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa        public boolean mRequestUpdateCursorAnchorInfoResult;
57adebb52588b098a1af678d4e33a234ef1ce783b2Yohei Yukawa        public boolean mCommitContentResult;
58152944f4909c47917473293b258d266435c6ab35Yohei Yukawa
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // A 'pool' of one InputContextCallback.  Each ICW request will attempt to gain
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // exclusive access to this object.
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private static InputContextCallback sInstance = new InputContextCallback();
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private static int sSequenceNumber = 1;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Returns an InputContextCallback object that is guaranteed not to be in use by
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * any other thread.  The returned object's 'have value' flag is cleared and its expected
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * sequence number is set to a new integer.  We use a sequence number so that replies that
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * occur after a timeout has expired are not interpreted as replies to a later request.
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private static InputContextCallback getInstance() {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (InputContextCallback.class) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Return sInstance if it's non-null, otherwise construct a new callback
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputContextCallback callback;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (sInstance != null) {
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    callback = sInstance;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sInstance = null;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Reset the callback
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    callback.mHaveValue = false;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    callback = new InputContextCallback();
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Set the sequence number
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callback.mSeq = sSequenceNumber++;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return callback;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Makes the given InputContextCallback available for use in the future.
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private void dispose() {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (InputContextCallback.class) {
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // If sInstance is non-null, just let this object be garbage-collected
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (sInstance == null) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Allow any objects being held to be gc'ed
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mTextAfterCursor = null;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mTextBeforeCursor = null;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mExtractedText = null;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sInstance = this;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setTextBeforeCursor(CharSequence textBeforeCursor, int seq) {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (this) {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (seq == mSeq) {
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mTextBeforeCursor = textBeforeCursor;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mHaveValue = true;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    notifyAll();
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.i(TAG, "Got out-of-sequence callback " + seq + " (expected " + mSeq
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + ") in setTextBeforeCursor, ignoring.");
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setTextAfterCursor(CharSequence textAfterCursor, int seq) {
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (this) {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (seq == mSeq) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mTextAfterCursor = textAfterCursor;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mHaveValue = true;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    notifyAll();
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.i(TAG, "Got out-of-sequence callback " + seq + " (expected " + mSeq
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + ") in setTextAfterCursor, ignoring.");
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
132a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        public void setSelectedText(CharSequence selectedText, int seq) {
133a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            synchronized (this) {
134a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                if (seq == mSeq) {
135a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                    mSelectedText = selectedText;
136a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                    mHaveValue = true;
137a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                    notifyAll();
138a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                } else {
139a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                    Log.i(TAG, "Got out-of-sequence callback " + seq + " (expected " + mSeq
140a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                            + ") in setSelectedText, ignoring.");
141a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                }
142a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            }
143a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        }
144a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setCursorCapsMode(int capsMode, int seq) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (this) {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (seq == mSeq) {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCursorCapsMode = capsMode;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mHaveValue = true;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    notifyAll();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.i(TAG, "Got out-of-sequence callback " + seq + " (expected " + mSeq
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + ") in setCursorCapsMode, ignoring.");
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setExtractedText(ExtractedText extractedText, int seq) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (this) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (seq == mSeq) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mExtractedText = extractedText;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mHaveValue = true;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    notifyAll();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.i(TAG, "Got out-of-sequence callback " + seq + " (expected " + mSeq
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + ") in setExtractedText, ignoring.");
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1700023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa
171a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa        public void setRequestUpdateCursorAnchorInfoResult(boolean result, int seq) {
1720023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa            synchronized (this) {
1730023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                if (seq == mSeq) {
174a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa                    mRequestUpdateCursorAnchorInfoResult = result;
1750023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                    mHaveValue = true;
1760023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                    notifyAll();
1770023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                } else {
1780023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                    Log.i(TAG, "Got out-of-sequence callback " + seq + " (expected " + mSeq
1790023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                            + ") in setCursorAnchorInfoRequestResult, ignoring.");
1800023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                }
1810023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa            }
1820023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa        }
1830023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa
184adebb52588b098a1af678d4e33a234ef1ce783b2Yohei Yukawa        public void setCommitContentResult(boolean result, int seq) {
185152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            synchronized (this) {
186152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                if (seq == mSeq) {
187adebb52588b098a1af678d4e33a234ef1ce783b2Yohei Yukawa                    mCommitContentResult = result;
188152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                    mHaveValue = true;
189152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                    notifyAll();
190152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                } else {
191152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                    Log.i(TAG, "Got out-of-sequence callback " + seq + " (expected " + mSeq
192adebb52588b098a1af678d4e33a234ef1ce783b2Yohei Yukawa                            + ") in setCommitContentResult, ignoring.");
193152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                }
194152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            }
195152944f4909c47917473293b258d266435c6ab35Yohei Yukawa        }
196152944f4909c47917473293b258d266435c6ab35Yohei Yukawa
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Waits for a result for up to {@link #MAX_WAIT_TIME_MILLIS} milliseconds.
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * <p>The caller must be synchronized on this callback object.
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void waitForResultLocked() {
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long startTime = SystemClock.uptimeMillis();
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long endTime = startTime + MAX_WAIT_TIME_MILLIS;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (!mHaveValue) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long remainingTime = endTime - SystemClock.uptimeMillis();
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (remainingTime <= 0) {
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.w(TAG, "Timed out waiting on IInputContextCallback");
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    wait(remainingTime);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (InterruptedException e) {
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22045700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa    public InputConnectionWrapper(
22145700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa            @NonNull WeakReference<AbstractInputMethodService> inputMethodService,
22245700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa            IInputContext inputContext, @MissingMethodFlags final int missingMethods) {
22345700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa        mInputMethodService = inputMethodService;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIInputContext = inputContext;
22519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        mMissingMethods = missingMethods;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence getTextAfterCursor(int length, int flags) {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence value = null;
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputContextCallback callback = InputContextCallback.getInstance();
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.getTextAfterCursor(length, flags, callback.mSeq, callback);
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (callback) {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callback.waitForResultLocked();
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (callback.mHaveValue) {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    value = callback.mTextAfterCursor;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            callback.dispose();
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return value;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence getTextBeforeCursor(int length, int flags) {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CharSequence value = null;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputContextCallback callback = InputContextCallback.getInstance();
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.getTextBeforeCursor(length, flags, callback.mSeq, callback);
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (callback) {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callback.waitForResultLocked();
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (callback.mHaveValue) {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    value = callback.mTextBeforeCursor;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            callback.dispose();
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return value;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
26319a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa
264a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani    public CharSequence getSelectedText(int flags) {
26519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        if (isMethodMissing(MissingMethodFlags.GET_SELECTED_TEXT)) {
26619a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            // This method is not implemented.
26719a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            return null;
26819a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        }
269a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        CharSequence value = null;
270a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        try {
271a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            InputContextCallback callback = InputContextCallback.getInstance();
272a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            mIInputContext.getSelectedText(flags, callback.mSeq, callback);
273a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            synchronized (callback) {
274a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                callback.waitForResultLocked();
275a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                if (callback.mHaveValue) {
276a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                    value = callback.mSelectedText;
277a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani                }
278a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            }
279a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            callback.dispose();
280a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        } catch (RemoteException e) {
281a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            return null;
282a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        }
283a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        return value;
284a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani    }
285a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getCursorCapsMode(int reqModes) {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int value = 0;
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputContextCallback callback = InputContextCallback.getInstance();
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.getCursorCapsMode(reqModes, callback.mSeq, callback);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (callback) {
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callback.waitForResultLocked();
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (callback.mHaveValue) {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    value = callback.mCursorCapsMode;
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            callback.dispose();
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return value;
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
303e3797a15fbf769a0abcbe121cfd33b4b658aea1esatok
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ExtractedText value = null;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputContextCallback callback = InputContextCallback.getInstance();
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.getExtractedText(request, flags, callback.mSeq, callback);
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (callback) {
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callback.waitForResultLocked();
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (callback.mHaveValue) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    value = callback.mExtractedText;
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            callback.dispose();
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return value;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean commitText(CharSequence text, int newCursorPosition) {
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.commitText(text, newCursorPosition);
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean commitCompletion(CompletionInfo text) {
33219a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        if (isMethodMissing(MissingMethodFlags.COMMIT_CORRECTION)) {
33319a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            // This method is not implemented.
33419a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            return false;
33519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        }
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.commitCompletion(text);
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
341cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne        }
342cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne    }
343cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne
344cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne    public boolean commitCorrection(CorrectionInfo correctionInfo) {
345cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne        try {
346cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne            mIInputContext.commitCorrection(correctionInfo);
347cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne            return true;
348cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne        } catch (RemoteException e) {
349cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne            return false;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setSelection(int start, int end) {
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.setSelection(start, end);
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean performEditorAction(int actionCode) {
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.performEditorAction(actionCode);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean performContextMenuAction(int id) {
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.performContextMenuAction(id);
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
379a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani
380a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani    public boolean setComposingRegion(int start, int end) {
38119a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        if (isMethodMissing(MissingMethodFlags.SET_COMPOSING_REGION)) {
38219a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            // This method is not implemented.
38319a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            return false;
38419a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        }
385a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        try {
386a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            mIInputContext.setComposingRegion(start, end);
387a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            return true;
388a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        } catch (RemoteException e) {
389a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani            return false;
390a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani        }
391a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani    }
392a90b7f0125389b9e1040d2be82aad4ef74ea6071Amith Yamasani
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setComposingText(CharSequence text, int newCursorPosition) {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.setComposingText(text, newCursorPosition);
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean finishComposingText() {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.finishComposingText();
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean beginBatchEdit() {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.beginBatchEdit();
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean endBatchEdit() {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.endBatchEdit();
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean sendKeyEvent(KeyEvent event) {
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.sendKeyEvent(event);
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean clearMetaKeyStates(int states) {
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.clearMetaKeyStates(states);
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
446c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa
4470c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio    public boolean deleteSurroundingText(int beforeLength, int afterLength) {
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4490c95dd3f4f02564fab9b86a221bbcbb4aafc2981Fabrice Di Meglio            mIInputContext.deleteSurroundingText(beforeLength, afterLength);
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
456c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa    public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
45719a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        if (isMethodMissing(MissingMethodFlags.DELETE_SURROUNDING_TEXT_IN_CODE_POINTS)) {
45819a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            // This method is not implemented.
45919a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            return false;
46019a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        }
461c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa        try {
462c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa            mIInputContext.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
463c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa            return true;
464c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa        } catch (RemoteException e) {
465c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa            return false;
466c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa        }
467c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa    }
468c89e22a6ff227089fde26daea186346029d1b32cYohei Yukawa
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean reportFullscreenMode(boolean enabled) {
4702bc66171cce4d5ae7bee2c3920e82e45a9d245afYohei Yukawa        // Nothing should happen when called from input method.
4712bc66171cce4d5ae7bee2c3920e82e45a9d245afYohei Yukawa        return false;
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean performPrivateCommand(String action, Bundle data) {
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIInputContext.performPrivateCommand(action, data);
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4820023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa
483d8636ea7ca78df83d6b04088eab7853f15f3e999Yohei Yukawa    public boolean requestCursorUpdates(int cursorUpdateMode) {
484a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa        boolean result = false;
48519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        if (isMethodMissing(MissingMethodFlags.REQUEST_CURSOR_UPDATES)) {
48619a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            // This method is not implemented.
48719a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            return false;
48819a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        }
4890023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa        try {
4900023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa            InputContextCallback callback = InputContextCallback.getInstance();
491a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa            mIInputContext.requestUpdateCursorAnchorInfo(cursorUpdateMode, callback.mSeq, callback);
4920023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa            synchronized (callback) {
4930023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                callback.waitForResultLocked();
4940023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                if (callback.mHaveValue) {
495a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa                    result = callback.mRequestUpdateCursorAnchorInfoResult;
4960023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa                }
4970023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa            }
4980023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa            callback.dispose();
4990023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa        } catch (RemoteException e) {
500a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa            return false;
5010023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa        }
502a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa        return result;
5030023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa    }
504612cce92ad96eda1146c3abd2afa7aaa4d4f2b3fYohei Yukawa
505612cce92ad96eda1146c3abd2afa7aaa4d4f2b3fYohei Yukawa    public Handler getHandler() {
506612cce92ad96eda1146c3abd2afa7aaa4d4f2b3fYohei Yukawa        // Nothing should happen when called from input method.
507612cce92ad96eda1146c3abd2afa7aaa4d4f2b3fYohei Yukawa        return null;
508612cce92ad96eda1146c3abd2afa7aaa4d4f2b3fYohei Yukawa    }
50919a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa
5109f9afe526d1f8ad17c628fc9e1e839725ffe913eYohei Yukawa    public void closeConnection() {
5119f9afe526d1f8ad17c628fc9e1e839725ffe913eYohei Yukawa        // Nothing should happen when called from input method.
5129f9afe526d1f8ad17c628fc9e1e839725ffe913eYohei Yukawa    }
5139f9afe526d1f8ad17c628fc9e1e839725ffe913eYohei Yukawa
51445700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa    public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) {
515152944f4909c47917473293b258d266435c6ab35Yohei Yukawa        boolean result = false;
516adebb52588b098a1af678d4e33a234ef1ce783b2Yohei Yukawa        if (isMethodMissing(MissingMethodFlags.COMMIT_CONTENT)) {
517152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            // This method is not implemented.
518152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            return false;
519152944f4909c47917473293b258d266435c6ab35Yohei Yukawa        }
520152944f4909c47917473293b258d266435c6ab35Yohei Yukawa        try {
52179d1c75a3f774bd8c4742f9d7bbd29161c3f1f68Yohei Yukawa            if ((flags & InputConnection.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
52245700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa                final AbstractInputMethodService inputMethodService = mInputMethodService.get();
52345700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa                if (inputMethodService == null) {
52445700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa                    // This basically should not happen, because it's the the caller of this method.
52545700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa                    return false;
52645700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa                }
52745700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa                inputMethodService.exposeContent(inputContentInfo, this);
52845700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa            }
52979d1c75a3f774bd8c4742f9d7bbd29161c3f1f68Yohei Yukawa
530152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            InputContextCallback callback = InputContextCallback.getInstance();
53145700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa            mIInputContext.commitContent(inputContentInfo, flags, opts, callback.mSeq, callback);
532152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            synchronized (callback) {
533152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                callback.waitForResultLocked();
534152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                if (callback.mHaveValue) {
535adebb52588b098a1af678d4e33a234ef1ce783b2Yohei Yukawa                    result = callback.mCommitContentResult;
536152944f4909c47917473293b258d266435c6ab35Yohei Yukawa                }
537152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            }
538152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            callback.dispose();
539152944f4909c47917473293b258d266435c6ab35Yohei Yukawa        } catch (RemoteException e) {
540152944f4909c47917473293b258d266435c6ab35Yohei Yukawa            return false;
541152944f4909c47917473293b258d266435c6ab35Yohei Yukawa        }
542152944f4909c47917473293b258d266435c6ab35Yohei Yukawa        return result;
543152944f4909c47917473293b258d266435c6ab35Yohei Yukawa    }
544152944f4909c47917473293b258d266435c6ab35Yohei Yukawa
54519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    private boolean isMethodMissing(@MissingMethodFlags final int methodFlag) {
54619a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        return (mMissingMethods & methodFlag) == methodFlag;
54719a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    }
54819a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa
54919a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    @Override
55019a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    public String toString() {
55119a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        return "InputConnectionWrapper{idHash=#"
55219a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                + Integer.toHexString(System.identityHashCode(this))
55319a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                + " mMissingMethods="
55419a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                + InputConnectionInspector.getMissingMethodFlagsAsString(mMissingMethods) + "}";
55519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    }
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
557