19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007-2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * License for the specific language governing permissions and limitations under 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Editable; 21f9f01008624e2d28c15a90d942fa36f98c8c967dsatokimport android.text.Spanned; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.method.KeyListener; 23f9f01008624e2d28c15a90d942fa36f98c8c967dsatokimport android.text.style.SuggestionSpan; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.BaseInputConnection; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.CompletionInfo; 27cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunneimport android.view.inputmethod.CorrectionInfo; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.ExtractedText; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.ExtractedTextRequest; 30a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawaimport android.view.inputmethod.InputConnection; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.TextView; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class EditableInputConnection extends BaseInputConnection { 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean DEBUG = false; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "EditableInputConnection"; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final TextView mTextView; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // Keeps track of nested begin/end batch edit to ensure this connection always has a 40c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // balanced impact on its associated TextView. 41c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // A negative value means that this connection has been finished by the InputMethodManager. 42c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne private int mBatchEditNesting; 43c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public EditableInputConnection(TextView textview) { 4551bf077883df4f5cc816fbfec6d19eedffc26d70Dianne Hackborn super(textview, true); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView = textview; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Editable getEditable() { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextView tv = mTextView; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tv != null) { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tv.getEditableText(); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 58cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean beginBatchEdit() { 60c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne synchronized(this) { 61c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne if (mBatchEditNesting >= 0) { 62c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne mTextView.beginBatchEdit(); 63c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne mBatchEditNesting++; 64c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne return true; 65c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne } 66c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne } 67c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne return false; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 69c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 70cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean endBatchEdit() { 72c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne synchronized(this) { 73c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne if (mBatchEditNesting > 0) { 749d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne // When the connection is reset by the InputMethodManager and reportFinish 75c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // is called, some endBatchEdit calls may still be asynchronously received from the 76c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // IME. Do not take these into account, thus ensuring that this IC's final 77c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // contribution to mTextView's nested batch edit count is zero. 78c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne mTextView.endBatchEdit(); 79c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne mBatchEditNesting--; 80c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne return true; 81c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne } 82c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne } 83c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne return false; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 85c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 86cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 879d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne protected void reportFinish() { 889d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne super.reportFinish(); 899d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne 909d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne synchronized(this) { 919d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne while (mBatchEditNesting > 0) { 929d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne endBatchEdit(); 939d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne } 949d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne // Will prevent any further calls to begin or endBatchEdit 959d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne mBatchEditNesting = -1; 969d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne } 979d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne } 989d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne 999d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne @Override 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean clearMetaKeyStates(int states) { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Editable content = getEditable(); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (content == null) return false; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyListener kl = mTextView.getKeyListener(); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (kl != null) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project kl.clearMetaKeyState(mTextView, content, states); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (AbstractMethodError e) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is an old listener that doesn't implement the 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // new method. 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 114c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 115c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne @Override 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean commitCompletion(CompletionInfo text) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "commitCompletion " + text); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.beginBatchEdit(); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.onCommitCompletion(text); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.endBatchEdit(); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 124cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne /** 125cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne * Calls the {@link TextView#onCommitCorrection} method of the associated TextView. 126cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne */ 127cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 128cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne public boolean commitCorrection(CorrectionInfo correctionInfo) { 129cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne if (DEBUG) Log.v(TAG, "commitCorrection" + correctionInfo); 130cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne mTextView.beginBatchEdit(); 131cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne mTextView.onCommitCorrection(correctionInfo); 132cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne mTextView.endBatchEdit(); 133cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne return true; 134cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne } 135cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne 136cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performEditorAction(int actionCode) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "performEditorAction " + actionCode); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.onEditorAction(actionCode); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 143cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performContextMenuAction(int id) { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "performContextMenuAction " + id); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.beginBatchEdit(); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.onTextContextMenuItem(id); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.endBatchEdit(); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 152cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTextView != null) { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ExtractedText et = new ExtractedText(); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTextView.extractText(request, et)) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&GET_EXTRACTED_TEXT_MONITOR) != 0) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.setExtracting(request); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return et; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 165cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne 166cf9cf2f40efc4ccf3f73e6fdb07725d9c00c4f91Gilles Debunne @Override 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean performPrivateCommand(String action, Bundle data) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTextView.onPrivateIMECommand(action, data); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean commitText(CharSequence text, int newCursorPosition) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTextView == null) { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.commitText(text, newCursorPosition); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 177f9f01008624e2d28c15a90d942fa36f98c8c967dsatok if (text instanceof Spanned) { 178f9f01008624e2d28c15a90d942fa36f98c8c967dsatok Spanned spanned = ((Spanned) text); 179f9f01008624e2d28c15a90d942fa36f98c8c967dsatok SuggestionSpan[] spans = spanned.getSpans(0, text.length(), SuggestionSpan.class); 180f9f01008624e2d28c15a90d942fa36f98c8c967dsatok mIMM.registerSuggestionSpansForNotification(spans); 181f9f01008624e2d28c15a90d942fa36f98c8c967dsatok } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 183b7fc63f7aac3689696f7f84953009b5928ac3db3Gilles Debunne mTextView.resetErrorChangedFlag(); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean success = super.commitText(text, newCursorPosition); 185b7fc63f7aac3689696f7f84953009b5928ac3db3Gilles Debunne mTextView.hideErrorIfUnchanged(); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return success; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1890023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa 1900023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa @Override 191d8636ea7ca78df83d6b04088eab7853f15f3e999Yohei Yukawa public boolean requestCursorUpdates(int cursorUpdateMode) { 192a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa if (DEBUG) Log.v(TAG, "requestUpdateCursorAnchorInfo " + cursorUpdateMode); 193a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa 19472d35fa829549a138504dde35a42535a296f79cbYohei Yukawa // It is possible that any other bit is used as a valid flag in a future release. 19572d35fa829549a138504dde35a42535a296f79cbYohei Yukawa // We should reject the entire request in such a case. 196d8636ea7ca78df83d6b04088eab7853f15f3e999Yohei Yukawa final int KNOWN_FLAGS_MASK = InputConnection.CURSOR_UPDATE_IMMEDIATE | 197d8636ea7ca78df83d6b04088eab7853f15f3e999Yohei Yukawa InputConnection.CURSOR_UPDATE_MONITOR; 19872d35fa829549a138504dde35a42535a296f79cbYohei Yukawa final int unknownFlags = cursorUpdateMode & ~KNOWN_FLAGS_MASK; 19972d35fa829549a138504dde35a42535a296f79cbYohei Yukawa if (unknownFlags != 0) { 20072d35fa829549a138504dde35a42535a296f79cbYohei Yukawa if (DEBUG) { 20172d35fa829549a138504dde35a42535a296f79cbYohei Yukawa Log.d(TAG, "Rejecting requestUpdateCursorAnchorInfo due to unknown flags." + 20272d35fa829549a138504dde35a42535a296f79cbYohei Yukawa " cursorUpdateMode=" + cursorUpdateMode + 20372d35fa829549a138504dde35a42535a296f79cbYohei Yukawa " unknownFlags=" + unknownFlags); 20472d35fa829549a138504dde35a42535a296f79cbYohei Yukawa } 20572d35fa829549a138504dde35a42535a296f79cbYohei Yukawa return false; 20672d35fa829549a138504dde35a42535a296f79cbYohei Yukawa } 20772d35fa829549a138504dde35a42535a296f79cbYohei Yukawa 208ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa if (mIMM == null) { 209ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // In this case, TYPE_CURSOR_ANCHOR_INFO is not handled. 210a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa // TODO: Return some notification code rather than false to indicate method that 211ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // CursorAnchorInfo is temporarily unavailable. 212a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa return false; 213ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa } 214a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa mIMM.setUpdateCursorAnchorInfoMode(cursorUpdateMode); 215d8636ea7ca78df83d6b04088eab7853f15f3e999Yohei Yukawa if ((cursorUpdateMode & InputConnection.CURSOR_UPDATE_IMMEDIATE) != 0) { 216ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa if (mTextView == null) { 217ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // In this case, FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE is silently ignored. 218ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // TODO: Return some notification code for the input method that indicates 219ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // FLAG_CURSOR_ANCHOR_INFO_IMMEDIATE is ignored. 220ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa } else if (mTextView.isInLayout()) { 221ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // In this case, the view hierarchy is currently undergoing a layout pass. 222ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // IMM#updateCursorAnchorInfo is supposed to be called soon after the layout 223ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // pass is finished. 224ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa } else { 225ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // This will schedule a layout pass of the view tree, and the layout event 226ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa // eventually triggers IMM#updateCursorAnchorInfo. 227ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa mTextView.requestLayout(); 228ff328ae7438a9c5c2fe49c286833a30e25015e63Yohei Yukawa } 2290023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa } 230a277db28e990d1f6f74ace0c32fe92401660a840Yohei Yukawa return true; 2310023d0e0c4f5339b299d1eacbd4e7181c2fd271fYohei Yukawa } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 233